diff --git a/src/compiler/bytecode-graph-builder.cc b/src/compiler/bytecode-graph-builder.cc
index cf0b6ab..e28c19d 100644
--- a/src/compiler/bytecode-graph-builder.cc
+++ b/src/compiler/bytecode-graph-builder.cc
@@ -13,25 +13,108 @@
 namespace internal {
 namespace compiler {
 
+// The abstract execution environment simulates the content of the interpreter
+// register file. The environment performs SSA-renaming of all tracked nodes at
+// split and merge points in the control flow.
+class BytecodeGraphBuilder::Environment : public ZoneObject {
+ public:
+  Environment(BytecodeGraphBuilder* builder, int register_count,
+              int parameter_count, Node* control_dependency, Node* context);
+
+  int parameter_count() const { return parameter_count_; }
+  int register_count() const { return register_count_; }
+
+  Node* LookupAccumulator() const;
+  Node* LookupRegister(interpreter::Register the_register) const;
+
+  void BindAccumulator(Node* node, FrameStateBeforeAndAfter* states = nullptr);
+  void BindRegister(interpreter::Register the_register, Node* node,
+                    FrameStateBeforeAndAfter* states = nullptr);
+  void BindRegistersToProjections(interpreter::Register first_reg, Node* node,
+                                  FrameStateBeforeAndAfter* states = nullptr);
+  void RecordAfterState(Node* node, FrameStateBeforeAndAfter* states);
+
+  // Effect dependency tracked by this environment.
+  Node* GetEffectDependency() { return effect_dependency_; }
+  void UpdateEffectDependency(Node* dependency) {
+    effect_dependency_ = dependency;
+  }
+
+  // Preserve a checkpoint of the environment for the IR graph. Any
+  // further mutation of the environment will not affect checkpoints.
+  Node* Checkpoint(BailoutId bytecode_offset, OutputFrameStateCombine combine);
+
+  // Returns true if the state values are up to date with the current
+  // environment.
+  bool StateValuesAreUpToDate(int output_poke_offset, int output_poke_count);
+
+  // Control dependency tracked by this environment.
+  Node* GetControlDependency() const { return control_dependency_; }
+  void UpdateControlDependency(Node* dependency) {
+    control_dependency_ = dependency;
+  }
+
+  Node* Context() const { return context_; }
+  void SetContext(Node* new_context) { context_ = new_context; }
+
+  Environment* CopyForConditional() const;
+  Environment* CopyForLoop();
+  void Merge(Environment* other);
+
+ private:
+  explicit Environment(const Environment* copy);
+  void PrepareForLoop();
+  bool StateValuesAreUpToDate(Node** state_values, int offset, int count,
+                              int output_poke_start, int output_poke_end);
+  bool StateValuesRequireUpdate(Node** state_values, int offset, int count);
+  void UpdateStateValues(Node** state_values, int offset, int count);
+
+  int RegisterToValuesIndex(interpreter::Register the_register) const;
+
+  Zone* zone() const { return builder_->local_zone(); }
+  Graph* graph() const { return builder_->graph(); }
+  CommonOperatorBuilder* common() const { return builder_->common(); }
+  BytecodeGraphBuilder* builder() const { return builder_; }
+  const NodeVector* values() const { return &values_; }
+  NodeVector* values() { return &values_; }
+  int register_base() const { return register_base_; }
+  int accumulator_base() const { return accumulator_base_; }
+
+  BytecodeGraphBuilder* builder_;
+  int register_count_;
+  int parameter_count_;
+  Node* context_;
+  Node* control_dependency_;
+  Node* effect_dependency_;
+  NodeVector values_;
+  Node* parameters_state_values_;
+  Node* registers_state_values_;
+  Node* accumulator_state_values_;
+  int register_base_;
+  int accumulator_base_;
+};
+
 // Helper for generating frame states for before and after a bytecode.
 class BytecodeGraphBuilder::FrameStateBeforeAndAfter {
  public:
-  FrameStateBeforeAndAfter(BytecodeGraphBuilder* builder,
-                           const interpreter::BytecodeArrayIterator& iterator)
+  explicit FrameStateBeforeAndAfter(BytecodeGraphBuilder* builder)
       : builder_(builder),
         id_after_(BailoutId::None()),
         added_to_node_(false),
+        frame_states_unused_(false),
         output_poke_offset_(0),
         output_poke_count_(0) {
-    BailoutId id_before(iterator.current_offset());
+    BailoutId id_before(builder->bytecode_iterator().current_offset());
     frame_state_before_ = builder_->environment()->Checkpoint(
         id_before, OutputFrameStateCombine::Ignore());
-    id_after_ = BailoutId(id_before.ToInt() + iterator.current_bytecode_size());
+    id_after_ = BailoutId(id_before.ToInt() +
+                          builder->bytecode_iterator().current_bytecode_size());
   }
 
   ~FrameStateBeforeAndAfter() {
     DCHECK(added_to_node_);
-    DCHECK(builder_->environment()->StateValuesAreUpToDate(output_poke_offset_,
+    DCHECK(frame_states_unused_ ||
+           builder_->environment()->StateValuesAreUpToDate(output_poke_offset_,
                                                            output_poke_count_));
   }
 
@@ -62,6 +145,7 @@
       output_poke_offset_ = static_cast<int>(combine.GetOffsetToPokeAt());
       output_poke_count_ = node->op()->ValueOutputCount();
     }
+    frame_states_unused_ = count == 0;
     added_to_node_ = true;
   }
 
@@ -70,6 +154,7 @@
   BailoutId id_after_;
 
   bool added_to_node_;
+  bool frame_states_unused_;
   int output_poke_offset_;
   int output_poke_count_;
 };
@@ -155,8 +240,8 @@
 
 Node* BytecodeGraphBuilder::Environment::LookupRegister(
     interpreter::Register the_register) const {
-  if (the_register.is_function_context()) {
-    return builder()->GetFunctionContext();
+  if (the_register.is_current_context()) {
+    return Context();
   } else if (the_register.is_function_closure()) {
     return builder()->GetFunctionClosure();
   } else if (the_register.is_new_target()) {
@@ -168,16 +253,6 @@
 }
 
 
-void BytecodeGraphBuilder::Environment::ExchangeRegisters(
-    interpreter::Register reg0, interpreter::Register reg1) {
-  int reg0_index = RegisterToValuesIndex(reg0);
-  int reg1_index = RegisterToValuesIndex(reg1);
-  Node* saved_reg0_value = values()->at(reg0_index);
-  values()->at(reg0_index) = values()->at(reg1_index);
-  values()->at(reg1_index) = saved_reg0_value;
-}
-
-
 void BytecodeGraphBuilder::Environment::BindAccumulator(
     Node* node, FrameStateBeforeAndAfter* states) {
   if (states) {
@@ -220,16 +295,6 @@
 }
 
 
-bool BytecodeGraphBuilder::Environment::IsMarkedAsUnreachable() const {
-  return GetControlDependency()->opcode() == IrOpcode::kDead;
-}
-
-
-void BytecodeGraphBuilder::Environment::MarkAsUnreachable() {
-  UpdateControlDependency(builder()->jsgraph()->Dead());
-}
-
-
 BytecodeGraphBuilder::Environment*
 BytecodeGraphBuilder::Environment::CopyForLoop() {
   PrepareForLoop();
@@ -245,11 +310,6 @@
 
 void BytecodeGraphBuilder::Environment::Merge(
     BytecodeGraphBuilder::Environment* other) {
-  // Nothing to do if the other environment is dead.
-  if (other->IsMarkedAsUnreachable()) {
-    return;
-  }
-
   // Create a merge of the control dependencies of both environments and update
   // the current environment's control dependency accordingly.
   Node* control = builder()->MergeControl(GetControlDependency(),
@@ -295,7 +355,7 @@
 
 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate(
     Node** state_values, int offset, int count) {
-  if (!builder()->info()->is_deoptimization_enabled()) {
+  if (!builder()->deoptimization_enabled_) {
     return false;
   }
   if (*state_values == nullptr) {
@@ -325,7 +385,7 @@
 
 Node* BytecodeGraphBuilder::Environment::Checkpoint(
     BailoutId bailout_id, OutputFrameStateCombine combine) {
-  if (!builder()->info()->is_deoptimization_enabled()) {
+  if (!builder()->deoptimization_enabled_) {
     return builder()->jsgraph()->EmptyFrameState();
   }
 
@@ -363,6 +423,7 @@
 
 bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate(
     int output_poke_offset, int output_poke_count) {
+  if (!builder()->deoptimization_enabled_) return true;
   // Poke offset is relative to the top of the stack (i.e., the accumulator).
   int output_poke_start = accumulator_base() - output_poke_offset;
   int output_poke_end = output_poke_start + output_poke_count;
@@ -375,26 +436,27 @@
                                 1, output_poke_start, output_poke_end);
 }
 
-
 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone,
-                                           CompilationInfo* compilation_info,
+                                           CompilationInfo* info,
                                            JSGraph* jsgraph)
     : local_zone_(local_zone),
-      info_(compilation_info),
       jsgraph_(jsgraph),
-      bytecode_array_(handle(info()->shared_info()->bytecode_array())),
+      bytecode_array_(handle(info->shared_info()->bytecode_array())),
+      exception_handler_table_(
+          handle(HandlerTable::cast(bytecode_array()->handler_table()))),
+      feedback_vector_(info->feedback_vector()),
       frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
           FrameStateType::kInterpretedFunction,
           bytecode_array()->parameter_count(),
-          bytecode_array()->register_count(), info()->shared_info(),
-          CALL_MAINTAINS_NATIVE_CONTEXT)),
+          bytecode_array()->register_count(), info->shared_info())),
+      deoptimization_enabled_(info->is_deoptimization_enabled()),
       merge_environments_(local_zone),
-      loop_header_environments_(local_zone),
+      exception_handlers_(local_zone),
+      current_exception_handler_(0),
       input_buffer_size_(0),
       input_buffer_(nullptr),
       exit_controls_(local_zone) {}
 
-
 Node* BytecodeGraphBuilder::GetNewTarget() {
   if (!new_target_.is_set()) {
     int params = bytecode_array()->parameter_count();
@@ -430,21 +492,6 @@
 }
 
 
-Node* BytecodeGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
-  return NewNode(jsgraph()->machine()->Load(MachineType::AnyTagged()), object,
-                 jsgraph()->IntPtrConstant(offset - kHeapObjectTag));
-}
-
-
-Node* BytecodeGraphBuilder::BuildLoadImmutableObjectField(Node* object,
-                                                          int offset) {
-  return graph()->NewNode(jsgraph()->machine()->Load(MachineType::AnyTagged()),
-                          object,
-                          jsgraph()->IntPtrConstant(offset - kHeapObjectTag),
-                          graph()->start(), graph()->start());
-}
-
-
 Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) {
   const Operator* op =
       javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true);
@@ -453,30 +500,15 @@
 }
 
 
-Node* BytecodeGraphBuilder::BuildLoadFeedbackVector() {
-  if (!feedback_vector_.is_set()) {
-    Node* closure = GetFunctionClosure();
-    Node* shared = BuildLoadImmutableObjectField(
-        closure, JSFunction::kSharedFunctionInfoOffset);
-    Node* vector = BuildLoadImmutableObjectField(
-        shared, SharedFunctionInfo::kFeedbackVectorOffset);
-    feedback_vector_.set(vector);
-  }
-  return feedback_vector_.get();
-}
-
-
 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) {
-  Handle<TypeFeedbackVector> feedback_vector = info()->feedback_vector();
   FeedbackVectorSlot slot;
   if (slot_id >= TypeFeedbackVector::kReservedIndexCount) {
-    slot = feedback_vector->ToSlot(slot_id);
+    slot = feedback_vector()->ToSlot(slot_id);
   }
-  return VectorSlotPair(feedback_vector, slot);
+  return VectorSlotPair(feedback_vector(), slot);
 }
 
-
-bool BytecodeGraphBuilder::CreateGraph(bool stack_check) {
+bool BytecodeGraphBuilder::CreateGraph() {
   // Set up the basic structure of the graph. Outputs for {Start} are
   // the formal parameters (including the receiver) plus context and
   // closure.
@@ -492,7 +524,7 @@
                   GetFunctionContext());
   set_environment(&env);
 
-  CreateGraphBody(stack_check);
+  VisitBytecodes();
 
   // Finish the basic structure of the graph.
   DCHECK_NE(0u, exit_controls_.size());
@@ -504,20 +536,6 @@
   return true;
 }
 
-
-void BytecodeGraphBuilder::CreateGraphBody(bool stack_check) {
-  // TODO(oth): Review ast-graph-builder equivalent, i.e. arguments
-  // object setup, this function variable if used, tracing hooks.
-
-  if (stack_check) {
-    Node* node = NewNode(javascript()->StackCheck());
-    PrepareEntryFrameState(node);
-  }
-
-  VisitBytecodes();
-}
-
-
 void BytecodeGraphBuilder::VisitBytecodes() {
   BytecodeBranchAnalysis analysis(bytecode_array(), local_zone());
   analysis.Analyze();
@@ -526,14 +544,15 @@
   set_bytecode_iterator(&iterator);
   while (!iterator.done()) {
     int current_offset = iterator.current_offset();
-    if (analysis.is_reachable(current_offset)) {
-      MergeEnvironmentsOfForwardBranches(current_offset);
-      BuildLoopHeaderForBackwardBranches(current_offset);
+    EnterAndExitExceptionHandlers(current_offset);
+    SwitchToMergeEnvironment(current_offset);
+    if (environment() != nullptr) {
+      BuildLoopHeaderEnvironment(current_offset);
 
       switch (iterator.current_bytecode()) {
 #define BYTECODE_CASE(name, ...)       \
   case interpreter::Bytecode::k##name: \
-    Visit##name(iterator);             \
+    Visit##name();                     \
     break;
         BYTECODE_LIST(BYTECODE_CASE)
 #undef BYTECODE_CODE
@@ -543,635 +562,417 @@
   }
   set_branch_analysis(nullptr);
   set_bytecode_iterator(nullptr);
+  DCHECK(exception_handlers_.empty());
 }
 
-
-void BytecodeGraphBuilder::VisitLdaZero(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitLdaZero() {
   Node* node = jsgraph()->ZeroConstant();
   environment()->BindAccumulator(node);
 }
 
-
-void BytecodeGraphBuilder::VisitLdaSmi8(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  Node* node = jsgraph()->Constant(iterator.GetImmediateOperand(0));
+void BytecodeGraphBuilder::VisitLdaSmi8() {
+  Node* node = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
   environment()->BindAccumulator(node);
 }
 
-
-void BytecodeGraphBuilder::VisitLdaConstantWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  Node* node = jsgraph()->Constant(iterator.GetConstantForIndexOperand(0));
+void BytecodeGraphBuilder::VisitLdaConstantWide() {
+  Node* node =
+      jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
   environment()->BindAccumulator(node);
 }
 
-
-void BytecodeGraphBuilder::VisitLdaConstant(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  Node* node = jsgraph()->Constant(iterator.GetConstantForIndexOperand(0));
+void BytecodeGraphBuilder::VisitLdaConstant() {
+  Node* node =
+      jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
   environment()->BindAccumulator(node);
 }
 
-
-void BytecodeGraphBuilder::VisitLdaUndefined(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitLdaUndefined() {
   Node* node = jsgraph()->UndefinedConstant();
   environment()->BindAccumulator(node);
 }
 
-
-void BytecodeGraphBuilder::VisitLdaNull(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitLdaNull() {
   Node* node = jsgraph()->NullConstant();
   environment()->BindAccumulator(node);
 }
 
-
-void BytecodeGraphBuilder::VisitLdaTheHole(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitLdaTheHole() {
   Node* node = jsgraph()->TheHoleConstant();
   environment()->BindAccumulator(node);
 }
 
-
-void BytecodeGraphBuilder::VisitLdaTrue(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitLdaTrue() {
   Node* node = jsgraph()->TrueConstant();
   environment()->BindAccumulator(node);
 }
 
-
-void BytecodeGraphBuilder::VisitLdaFalse(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitLdaFalse() {
   Node* node = jsgraph()->FalseConstant();
   environment()->BindAccumulator(node);
 }
 
-
-void BytecodeGraphBuilder::VisitLdar(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  Node* value = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+void BytecodeGraphBuilder::VisitLdar() {
+  Node* value =
+      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   environment()->BindAccumulator(value);
 }
 
-
-void BytecodeGraphBuilder::VisitStar(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitStar() {
   Node* value = environment()->LookupAccumulator();
-  environment()->BindRegister(iterator.GetRegisterOperand(0), value);
+  environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value);
 }
 
-
-void BytecodeGraphBuilder::VisitMov(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  Node* value = environment()->LookupRegister(iterator.GetRegisterOperand(0));
-  environment()->BindRegister(iterator.GetRegisterOperand(1), value);
+void BytecodeGraphBuilder::VisitMov() {
+  Node* value =
+      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
+  environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), value);
 }
 
-
-void BytecodeGraphBuilder::VisitExchange(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  environment()->ExchangeRegisters(iterator.GetRegisterOperand(0),
-                                   iterator.GetRegisterOperand(1));
-}
-
-
-void BytecodeGraphBuilder::VisitExchangeWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  environment()->ExchangeRegisters(iterator.GetRegisterOperand(0),
-                                   iterator.GetRegisterOperand(1));
-}
-
+void BytecodeGraphBuilder::VisitMovWide() { VisitMov(); }
 
 void BytecodeGraphBuilder::BuildLoadGlobal(
-    const interpreter::BytecodeArrayIterator& iterator,
     TypeofMode typeof_mode) {
-  FrameStateBeforeAndAfter states(this, iterator);
+  FrameStateBeforeAndAfter states(this);
   Handle<Name> name =
-      Handle<Name>::cast(iterator.GetConstantForIndexOperand(0));
-  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1));
+      Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
+  VectorSlotPair feedback =
+      CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
 
   const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
-  Node* node = NewNode(op, BuildLoadFeedbackVector());
+  Node* node = NewNode(op, GetFunctionClosure());
   environment()->BindAccumulator(node, &states);
 }
 
-
-void BytecodeGraphBuilder::VisitLdaGlobalSloppy(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_sloppy(language_mode()));
-  BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF);
+void BytecodeGraphBuilder::VisitLdaGlobal() {
+  BuildLoadGlobal(TypeofMode::NOT_INSIDE_TYPEOF);
 }
 
-
-void BytecodeGraphBuilder::VisitLdaGlobalStrict(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_strict(language_mode()));
-  BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF);
+void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() {
+  BuildLoadGlobal(TypeofMode::INSIDE_TYPEOF);
 }
 
-
-void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofSloppy(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_sloppy(language_mode()));
-  BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF);
+void BytecodeGraphBuilder::VisitLdaGlobalWide() {
+  BuildLoadGlobal(TypeofMode::NOT_INSIDE_TYPEOF);
 }
 
-
-void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofStrict(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_strict(language_mode()));
-  BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF);
+void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofWide() {
+  BuildLoadGlobal(TypeofMode::INSIDE_TYPEOF);
 }
 
-
-void BytecodeGraphBuilder::VisitLdaGlobalSloppyWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_sloppy(language_mode()));
-  BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF);
-}
-
-
-void BytecodeGraphBuilder::VisitLdaGlobalStrictWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_strict(language_mode()));
-  BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF);
-}
-
-
-void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofSloppyWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_sloppy(language_mode()));
-  BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF);
-}
-
-
-void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofStrictWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_strict(language_mode()));
-  BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF);
-}
-
-
-void BytecodeGraphBuilder::BuildStoreGlobal(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
+void BytecodeGraphBuilder::BuildStoreGlobal(LanguageMode language_mode) {
+  FrameStateBeforeAndAfter states(this);
   Handle<Name> name =
-      Handle<Name>::cast(iterator.GetConstantForIndexOperand(0));
-  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1));
+      Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
+  VectorSlotPair feedback =
+      CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
   Node* value = environment()->LookupAccumulator();
 
-  const Operator* op =
-      javascript()->StoreGlobal(language_mode(), name, feedback);
-  Node* node = NewNode(op, value, BuildLoadFeedbackVector());
+  const Operator* op = javascript()->StoreGlobal(language_mode, name, feedback);
+  Node* node = NewNode(op, value, GetFunctionClosure());
   environment()->RecordAfterState(node, &states);
 }
 
-
-void BytecodeGraphBuilder::VisitStaGlobalSloppy(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_sloppy(language_mode()));
-  BuildStoreGlobal(iterator);
+void BytecodeGraphBuilder::VisitStaGlobalSloppy() {
+  BuildStoreGlobal(LanguageMode::SLOPPY);
 }
 
-
-void BytecodeGraphBuilder::VisitStaGlobalStrict(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_strict(language_mode()));
-  BuildStoreGlobal(iterator);
+void BytecodeGraphBuilder::VisitStaGlobalStrict() {
+  BuildStoreGlobal(LanguageMode::STRICT);
 }
 
-void BytecodeGraphBuilder::VisitStaGlobalSloppyWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_sloppy(language_mode()));
-  BuildStoreGlobal(iterator);
+void BytecodeGraphBuilder::VisitStaGlobalSloppyWide() {
+  BuildStoreGlobal(LanguageMode::SLOPPY);
 }
 
-
-void BytecodeGraphBuilder::VisitStaGlobalStrictWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_strict(language_mode()));
-  BuildStoreGlobal(iterator);
+void BytecodeGraphBuilder::VisitStaGlobalStrictWide() {
+  BuildStoreGlobal(LanguageMode::STRICT);
 }
 
-
-void BytecodeGraphBuilder::VisitLdaContextSlot(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitLdaContextSlot() {
   // TODO(mythria): LoadContextSlots are unrolled by the required depth when
   // generating bytecode. Hence the value of depth is always 0. Update this
   // code, when the implementation changes.
   // TODO(mythria): immutable flag is also set to false. This information is not
   // available in bytecode array. update this code when the implementation
   // changes.
-  const Operator* op =
-      javascript()->LoadContext(0, iterator.GetIndexOperand(1), false);
-  Node* context = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+  const Operator* op = javascript()->LoadContext(
+      0, bytecode_iterator().GetIndexOperand(1), false);
+  Node* context =
+      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   Node* node = NewNode(op, context);
   environment()->BindAccumulator(node);
 }
 
+void BytecodeGraphBuilder::VisitLdaContextSlotWide() { VisitLdaContextSlot(); }
 
-void BytecodeGraphBuilder::VisitLdaContextSlotWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  VisitLdaContextSlot(iterator);
-}
-
-
-void BytecodeGraphBuilder::VisitStaContextSlot(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitStaContextSlot() {
   // TODO(mythria): LoadContextSlots are unrolled by the required depth when
   // generating bytecode. Hence the value of depth is always 0. Update this
   // code, when the implementation changes.
   const Operator* op =
-      javascript()->StoreContext(0, iterator.GetIndexOperand(1));
-  Node* context = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+      javascript()->StoreContext(0, bytecode_iterator().GetIndexOperand(1));
+  Node* context =
+      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   Node* value = environment()->LookupAccumulator();
   NewNode(op, context, value);
 }
 
+void BytecodeGraphBuilder::VisitStaContextSlotWide() { VisitStaContextSlot(); }
 
-void BytecodeGraphBuilder::VisitStaContextSlotWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  VisitStaContextSlot(iterator);
-}
-
-
-void BytecodeGraphBuilder::BuildLdaLookupSlot(
-    TypeofMode typeof_mode,
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
-  Handle<String> name =
-      Handle<String>::cast(iterator.GetConstantForIndexOperand(0));
-  const Operator* op = javascript()->LoadDynamic(name, typeof_mode);
-  Node* value =
-      NewNode(op, BuildLoadFeedbackVector(), environment()->Context());
+void BytecodeGraphBuilder::BuildLdaLookupSlot(TypeofMode typeof_mode) {
+  FrameStateBeforeAndAfter states(this);
+  Node* name =
+      jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
+  const Operator* op =
+      javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
+                                    ? Runtime::kLoadLookupSlot
+                                    : Runtime::kLoadLookupSlotInsideTypeof);
+  Node* value = NewNode(op, name);
   environment()->BindAccumulator(value, &states);
 }
 
-
-void BytecodeGraphBuilder::VisitLdaLookupSlot(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF, iterator);
+void BytecodeGraphBuilder::VisitLdaLookupSlot() {
+  BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF);
 }
 
-
-void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF, iterator);
+void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() {
+  BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF);
 }
 
-
-void BytecodeGraphBuilder::BuildStaLookupSlot(
-    LanguageMode language_mode,
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
+void BytecodeGraphBuilder::BuildStaLookupSlot(LanguageMode language_mode) {
+  FrameStateBeforeAndAfter states(this);
   Node* value = environment()->LookupAccumulator();
-  Node* name = jsgraph()->Constant(iterator.GetConstantForIndexOperand(0));
-  Node* language = jsgraph()->Constant(language_mode);
-  const Operator* op = javascript()->CallRuntime(Runtime::kStoreLookupSlot, 4);
-  Node* store = NewNode(op, value, environment()->Context(), name, language);
+  Node* name =
+      jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
+  const Operator* op = javascript()->CallRuntime(
+      is_strict(language_mode) ? Runtime::kStoreLookupSlot_Strict
+                               : Runtime::kStoreLookupSlot_Sloppy);
+  Node* store = NewNode(op, name, value);
   environment()->BindAccumulator(store, &states);
 }
 
+void BytecodeGraphBuilder::VisitLdaLookupSlotWide() { VisitLdaLookupSlot(); }
 
-void BytecodeGraphBuilder::VisitLdaLookupSlotWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  VisitLdaLookupSlot(iterator);
+void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeofWide() {
+  VisitLdaLookupSlotInsideTypeof();
 }
 
-
-void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeofWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  VisitLdaLookupSlotInsideTypeof(iterator);
+void BytecodeGraphBuilder::VisitStaLookupSlotSloppy() {
+  BuildStaLookupSlot(LanguageMode::SLOPPY);
 }
 
-
-void BytecodeGraphBuilder::VisitStaLookupSlotSloppy(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildStaLookupSlot(LanguageMode::SLOPPY, iterator);
+void BytecodeGraphBuilder::VisitStaLookupSlotStrict() {
+  BuildStaLookupSlot(LanguageMode::STRICT);
 }
 
-
-void BytecodeGraphBuilder::VisitStaLookupSlotStrict(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildStaLookupSlot(LanguageMode::STRICT, iterator);
+void BytecodeGraphBuilder::VisitStaLookupSlotSloppyWide() {
+  VisitStaLookupSlotSloppy();
 }
 
-
-void BytecodeGraphBuilder::VisitStaLookupSlotSloppyWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  VisitStaLookupSlotSloppy(iterator);
+void BytecodeGraphBuilder::VisitStaLookupSlotStrictWide() {
+  VisitStaLookupSlotStrict();
 }
 
-
-void BytecodeGraphBuilder::VisitStaLookupSlotStrictWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  VisitStaLookupSlotStrict(iterator);
-}
-
-
-void BytecodeGraphBuilder::BuildNamedLoad(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
-  Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+void BytecodeGraphBuilder::BuildNamedLoad() {
+  FrameStateBeforeAndAfter states(this);
+  Node* object =
+      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   Handle<Name> name =
-      Handle<Name>::cast(iterator.GetConstantForIndexOperand(1));
-  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2));
+      Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(1));
+  VectorSlotPair feedback =
+      CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
 
-  const Operator* op = javascript()->LoadNamed(language_mode(), name, feedback);
-  Node* node = NewNode(op, object, BuildLoadFeedbackVector());
+  const Operator* op = javascript()->LoadNamed(name, feedback);
+  Node* node = NewNode(op, object, GetFunctionClosure());
   environment()->BindAccumulator(node, &states);
 }
 
+void BytecodeGraphBuilder::VisitLoadIC() { BuildNamedLoad(); }
 
-void BytecodeGraphBuilder::VisitLoadICSloppy(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_sloppy(language_mode()));
-  BuildNamedLoad(iterator);
-}
+void BytecodeGraphBuilder::VisitLoadICWide() { BuildNamedLoad(); }
 
-
-void BytecodeGraphBuilder::VisitLoadICStrict(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_strict(language_mode()));
-  BuildNamedLoad(iterator);
-}
-
-
-void BytecodeGraphBuilder::VisitLoadICSloppyWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_sloppy(language_mode()));
-  BuildNamedLoad(iterator);
-}
-
-
-void BytecodeGraphBuilder::VisitLoadICStrictWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_strict(language_mode()));
-  BuildNamedLoad(iterator);
-}
-
-
-void BytecodeGraphBuilder::BuildKeyedLoad(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
+void BytecodeGraphBuilder::BuildKeyedLoad() {
+  FrameStateBeforeAndAfter states(this);
   Node* key = environment()->LookupAccumulator();
-  Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0));
-  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1));
+  Node* object =
+      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
+  VectorSlotPair feedback =
+      CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
 
-  const Operator* op = javascript()->LoadProperty(language_mode(), feedback);
-  Node* node = NewNode(op, object, key, BuildLoadFeedbackVector());
+  const Operator* op = javascript()->LoadProperty(feedback);
+  Node* node = NewNode(op, object, key, GetFunctionClosure());
   environment()->BindAccumulator(node, &states);
 }
 
+void BytecodeGraphBuilder::VisitKeyedLoadIC() { BuildKeyedLoad(); }
 
-void BytecodeGraphBuilder::VisitKeyedLoadICSloppy(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_sloppy(language_mode()));
-  BuildKeyedLoad(iterator);
-}
+void BytecodeGraphBuilder::VisitKeyedLoadICWide() { BuildKeyedLoad(); }
 
-
-void BytecodeGraphBuilder::VisitKeyedLoadICStrict(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_strict(language_mode()));
-  BuildKeyedLoad(iterator);
-}
-
-
-void BytecodeGraphBuilder::VisitKeyedLoadICSloppyWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_sloppy(language_mode()));
-  BuildKeyedLoad(iterator);
-}
-
-
-void BytecodeGraphBuilder::VisitKeyedLoadICStrictWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_strict(language_mode()));
-  BuildKeyedLoad(iterator);
-}
-
-
-void BytecodeGraphBuilder::BuildNamedStore(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
+void BytecodeGraphBuilder::BuildNamedStore(LanguageMode language_mode) {
+  FrameStateBeforeAndAfter states(this);
   Node* value = environment()->LookupAccumulator();
-  Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+  Node* object =
+      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   Handle<Name> name =
-      Handle<Name>::cast(iterator.GetConstantForIndexOperand(1));
-  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2));
+      Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(1));
+  VectorSlotPair feedback =
+      CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
 
-  const Operator* op =
-      javascript()->StoreNamed(language_mode(), name, feedback);
-  Node* node = NewNode(op, object, value, BuildLoadFeedbackVector());
+  const Operator* op = javascript()->StoreNamed(language_mode, name, feedback);
+  Node* node = NewNode(op, object, value, GetFunctionClosure());
   environment()->RecordAfterState(node, &states);
 }
 
-
-void BytecodeGraphBuilder::VisitStoreICSloppy(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_sloppy(language_mode()));
-  BuildNamedStore(iterator);
+void BytecodeGraphBuilder::VisitStoreICSloppy() {
+  BuildNamedStore(LanguageMode::SLOPPY);
 }
 
-
-void BytecodeGraphBuilder::VisitStoreICStrict(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_strict(language_mode()));
-  BuildNamedStore(iterator);
+void BytecodeGraphBuilder::VisitStoreICStrict() {
+  BuildNamedStore(LanguageMode::STRICT);
 }
 
-
-void BytecodeGraphBuilder::VisitStoreICSloppyWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_sloppy(language_mode()));
-  BuildNamedStore(iterator);
+void BytecodeGraphBuilder::VisitStoreICSloppyWide() {
+  BuildNamedStore(LanguageMode::SLOPPY);
 }
 
-
-void BytecodeGraphBuilder::VisitStoreICStrictWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_strict(language_mode()));
-  BuildNamedStore(iterator);
+void BytecodeGraphBuilder::VisitStoreICStrictWide() {
+  BuildNamedStore(LanguageMode::STRICT);
 }
 
-
-void BytecodeGraphBuilder::BuildKeyedStore(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
+void BytecodeGraphBuilder::BuildKeyedStore(LanguageMode language_mode) {
+  FrameStateBeforeAndAfter states(this);
   Node* value = environment()->LookupAccumulator();
-  Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0));
-  Node* key = environment()->LookupRegister(iterator.GetRegisterOperand(1));
-  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2));
+  Node* object =
+      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
+  Node* key =
+      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
+  VectorSlotPair feedback =
+      CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
 
-  const Operator* op = javascript()->StoreProperty(language_mode(), feedback);
-  Node* node = NewNode(op, object, key, value, BuildLoadFeedbackVector());
+  const Operator* op = javascript()->StoreProperty(language_mode, feedback);
+  Node* node = NewNode(op, object, key, value, GetFunctionClosure());
   environment()->RecordAfterState(node, &states);
 }
 
-
-void BytecodeGraphBuilder::VisitKeyedStoreICSloppy(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_sloppy(language_mode()));
-  BuildKeyedStore(iterator);
+void BytecodeGraphBuilder::VisitKeyedStoreICSloppy() {
+  BuildKeyedStore(LanguageMode::SLOPPY);
 }
 
-
-void BytecodeGraphBuilder::VisitKeyedStoreICStrict(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_strict(language_mode()));
-  BuildKeyedStore(iterator);
+void BytecodeGraphBuilder::VisitKeyedStoreICStrict() {
+  BuildKeyedStore(LanguageMode::STRICT);
 }
 
-
-void BytecodeGraphBuilder::VisitKeyedStoreICSloppyWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_sloppy(language_mode()));
-  BuildKeyedStore(iterator);
+void BytecodeGraphBuilder::VisitKeyedStoreICSloppyWide() {
+  BuildKeyedStore(LanguageMode::SLOPPY);
 }
 
-
-void BytecodeGraphBuilder::VisitKeyedStoreICStrictWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_strict(language_mode()));
-  BuildKeyedStore(iterator);
+void BytecodeGraphBuilder::VisitKeyedStoreICStrictWide() {
+  BuildKeyedStore(LanguageMode::STRICT);
 }
 
+void BytecodeGraphBuilder::VisitPushContext() {
+  Node* new_context = environment()->LookupAccumulator();
+  environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0),
+                              environment()->Context());
+  environment()->SetContext(new_context);
+}
 
-void BytecodeGraphBuilder::VisitPushContext(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  Node* context = environment()->LookupAccumulator();
-  environment()->BindRegister(iterator.GetRegisterOperand(0), context);
+void BytecodeGraphBuilder::VisitPopContext() {
+  Node* context =
+      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   environment()->SetContext(context);
 }
 
-
-void BytecodeGraphBuilder::VisitPopContext(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  Node* context = environment()->LookupRegister(iterator.GetRegisterOperand(0));
-  environment()->SetContext(context);
-}
-
-
-void BytecodeGraphBuilder::VisitCreateClosure(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  Handle<SharedFunctionInfo> shared_info =
-      Handle<SharedFunctionInfo>::cast(iterator.GetConstantForIndexOperand(0));
+void BytecodeGraphBuilder::VisitCreateClosure() {
+  Handle<SharedFunctionInfo> shared_info = Handle<SharedFunctionInfo>::cast(
+      bytecode_iterator().GetConstantForIndexOperand(0));
   PretenureFlag tenured =
-      iterator.GetImmediateOperand(1) ? TENURED : NOT_TENURED;
+      bytecode_iterator().GetImmediateOperand(1) ? TENURED : NOT_TENURED;
   const Operator* op = javascript()->CreateClosure(shared_info, tenured);
   Node* closure = NewNode(op);
   environment()->BindAccumulator(closure);
 }
 
+void BytecodeGraphBuilder::VisitCreateClosureWide() { VisitCreateClosure(); }
 
-void BytecodeGraphBuilder::VisitCreateClosureWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  VisitCreateClosure(iterator);
-}
-
-
-void BytecodeGraphBuilder::BuildCreateArguments(
-    CreateArgumentsParameters::Type type,
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
-  const Operator* op = javascript()->CreateArguments(type, 0);
+void BytecodeGraphBuilder::BuildCreateArguments(CreateArgumentsType type) {
+  FrameStateBeforeAndAfter states(this);
+  const Operator* op = javascript()->CreateArguments(type);
   Node* object = NewNode(op, GetFunctionClosure());
   environment()->BindAccumulator(object, &states);
 }
 
-
-void BytecodeGraphBuilder::VisitCreateMappedArguments(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCreateArguments(CreateArgumentsParameters::kMappedArguments, iterator);
+void BytecodeGraphBuilder::VisitCreateMappedArguments() {
+  BuildCreateArguments(CreateArgumentsType::kMappedArguments);
 }
 
-
-void BytecodeGraphBuilder::VisitCreateUnmappedArguments(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCreateArguments(CreateArgumentsParameters::kUnmappedArguments, iterator);
+void BytecodeGraphBuilder::VisitCreateUnmappedArguments() {
+  BuildCreateArguments(CreateArgumentsType::kUnmappedArguments);
 }
 
+void BytecodeGraphBuilder::VisitCreateRestParameter() {
+  BuildCreateArguments(CreateArgumentsType::kRestParameter);
+}
 
-void BytecodeGraphBuilder::BuildCreateLiteral(
-    const Operator* op, const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
+void BytecodeGraphBuilder::BuildCreateLiteral(const Operator* op) {
+  FrameStateBeforeAndAfter states(this);
   Node* literal = NewNode(op, GetFunctionClosure());
   environment()->BindAccumulator(literal, &states);
 }
 
-
-void BytecodeGraphBuilder::BuildCreateRegExpLiteral(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::BuildCreateRegExpLiteral() {
   Handle<String> constant_pattern =
-      Handle<String>::cast(iterator.GetConstantForIndexOperand(0));
-  int literal_index = iterator.GetIndexOperand(1);
-  int literal_flags = iterator.GetImmediateOperand(2);
+      Handle<String>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
+  int literal_index = bytecode_iterator().GetIndexOperand(1);
+  int literal_flags = bytecode_iterator().GetImmediateOperand(2);
   const Operator* op = javascript()->CreateLiteralRegExp(
       constant_pattern, literal_flags, literal_index);
-  BuildCreateLiteral(op, iterator);
+  BuildCreateLiteral(op);
 }
 
-
-void BytecodeGraphBuilder::VisitCreateRegExpLiteral(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCreateRegExpLiteral(iterator);
+void BytecodeGraphBuilder::VisitCreateRegExpLiteral() {
+  BuildCreateRegExpLiteral();
 }
 
-
-void BytecodeGraphBuilder::VisitCreateRegExpLiteralWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCreateRegExpLiteral(iterator);
+void BytecodeGraphBuilder::VisitCreateRegExpLiteralWide() {
+  BuildCreateRegExpLiteral();
 }
 
-
-void BytecodeGraphBuilder::BuildCreateArrayLiteral(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  Handle<FixedArray> constant_elements =
-      Handle<FixedArray>::cast(iterator.GetConstantForIndexOperand(0));
-  int literal_index = iterator.GetIndexOperand(1);
-  int literal_flags = iterator.GetImmediateOperand(2);
+void BytecodeGraphBuilder::BuildCreateArrayLiteral() {
+  Handle<FixedArray> constant_elements = Handle<FixedArray>::cast(
+      bytecode_iterator().GetConstantForIndexOperand(0));
+  int literal_index = bytecode_iterator().GetIndexOperand(1);
+  int literal_flags = bytecode_iterator().GetImmediateOperand(2);
   const Operator* op = javascript()->CreateLiteralArray(
       constant_elements, literal_flags, literal_index);
-  BuildCreateLiteral(op, iterator);
+  BuildCreateLiteral(op);
 }
 
-
-void BytecodeGraphBuilder::VisitCreateArrayLiteral(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCreateArrayLiteral(iterator);
+void BytecodeGraphBuilder::VisitCreateArrayLiteral() {
+  BuildCreateArrayLiteral();
 }
 
-
-void BytecodeGraphBuilder::VisitCreateArrayLiteralWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCreateArrayLiteral(iterator);
+void BytecodeGraphBuilder::VisitCreateArrayLiteralWide() {
+  BuildCreateArrayLiteral();
 }
 
-
-void BytecodeGraphBuilder::BuildCreateObjectLiteral(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  Handle<FixedArray> constant_properties =
-      Handle<FixedArray>::cast(iterator.GetConstantForIndexOperand(0));
-  int literal_index = iterator.GetIndexOperand(1);
-  int literal_flags = iterator.GetImmediateOperand(2);
+void BytecodeGraphBuilder::BuildCreateObjectLiteral() {
+  Handle<FixedArray> constant_properties = Handle<FixedArray>::cast(
+      bytecode_iterator().GetConstantForIndexOperand(0));
+  int literal_index = bytecode_iterator().GetIndexOperand(1);
+  int literal_flags = bytecode_iterator().GetImmediateOperand(2);
   const Operator* op = javascript()->CreateLiteralObject(
       constant_properties, literal_flags, literal_index);
-  BuildCreateLiteral(op, iterator);
+  BuildCreateLiteral(op);
 }
 
-
-void BytecodeGraphBuilder::VisitCreateObjectLiteral(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCreateObjectLiteral(iterator);
+void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
+  BuildCreateObjectLiteral();
 }
 
-
-void BytecodeGraphBuilder::VisitCreateObjectLiteralWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCreateObjectLiteral(iterator);
+void BytecodeGraphBuilder::VisitCreateObjectLiteralWide() {
+  BuildCreateObjectLiteral();
 }
 
 
@@ -1179,7 +980,7 @@
                                                  Node* callee,
                                                  interpreter::Register receiver,
                                                  size_t arity) {
-  Node** all = info()->zone()->NewArray<Node*>(static_cast<int>(arity));
+  Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity));
   all[0] = callee;
   all[1] = environment()->LookupRegister(receiver);
   int receiver_index = receiver.index();
@@ -1191,57 +992,58 @@
   return value;
 }
 
-
-void BytecodeGraphBuilder::BuildCall(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
+void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode) {
+  FrameStateBeforeAndAfter states(this);
   // TODO(rmcilroy): Set receiver_hint correctly based on whether the receiver
   // register has been loaded with null / undefined explicitly or we are sure it
   // is not null / undefined.
   ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny;
-  Node* callee = environment()->LookupRegister(iterator.GetRegisterOperand(0));
-  interpreter::Register receiver = iterator.GetRegisterOperand(1);
-  size_t arg_count = iterator.GetCountOperand(2);
-  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(3));
+  Node* callee =
+      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
+  interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
+  size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
+  VectorSlotPair feedback =
+      CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(3));
 
   const Operator* call = javascript()->CallFunction(
-      arg_count + 2, language_mode(), feedback, receiver_hint);
-  Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 2);
+      arg_count + 1, feedback, receiver_hint, tail_call_mode);
+  Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
   environment()->BindAccumulator(value, &states);
 }
 
+void BytecodeGraphBuilder::VisitCall() { BuildCall(TailCallMode::kDisallow); }
 
-void BytecodeGraphBuilder::VisitCall(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCall(iterator);
+void BytecodeGraphBuilder::VisitCallWide() {
+  BuildCall(TailCallMode::kDisallow);
 }
 
+void BytecodeGraphBuilder::VisitTailCall() { BuildCall(TailCallMode::kAllow); }
 
-void BytecodeGraphBuilder::VisitCallWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCall(iterator);
+void BytecodeGraphBuilder::VisitTailCallWide() {
+  BuildCall(TailCallMode::kAllow);
 }
 
-
-void BytecodeGraphBuilder::VisitCallJSRuntime(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
-  Node* callee = BuildLoadNativeContextField(iterator.GetIndexOperand(0));
-  interpreter::Register receiver = iterator.GetRegisterOperand(1);
-  size_t arg_count = iterator.GetCountOperand(2);
+void BytecodeGraphBuilder::BuildCallJSRuntime() {
+  FrameStateBeforeAndAfter states(this);
+  Node* callee =
+      BuildLoadNativeContextField(bytecode_iterator().GetIndexOperand(0));
+  interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
+  size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
 
   // Create node to perform the JS runtime call.
-  const Operator* call =
-      javascript()->CallFunction(arg_count + 2, language_mode());
-  Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 2);
+  const Operator* call = javascript()->CallFunction(arg_count + 1);
+  Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
   environment()->BindAccumulator(value, &states);
 }
 
+void BytecodeGraphBuilder::VisitCallJSRuntime() { BuildCallJSRuntime(); }
+
+void BytecodeGraphBuilder::VisitCallJSRuntimeWide() { BuildCallJSRuntime(); }
 
 Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
     const Operator* call_runtime_op, interpreter::Register first_arg,
     size_t arity) {
-  Node** all = info()->zone()->NewArray<Node*>(arity);
+  Node** all = local_zone()->NewArray<Node*>(arity);
   int first_arg_index = first_arg.index();
   for (int i = 0; i < static_cast<int>(arity); ++i) {
     all[i] = environment()->LookupRegister(
@@ -1251,14 +1053,12 @@
   return value;
 }
 
-
-void BytecodeGraphBuilder::VisitCallRuntime(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
+void BytecodeGraphBuilder::BuildCallRuntime() {
+  FrameStateBeforeAndAfter states(this);
   Runtime::FunctionId functionId =
-      static_cast<Runtime::FunctionId>(iterator.GetIndexOperand(0));
-  interpreter::Register first_arg = iterator.GetRegisterOperand(1);
-  size_t arg_count = iterator.GetCountOperand(2);
+      static_cast<Runtime::FunctionId>(bytecode_iterator().GetIndexOperand(0));
+  interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
+  size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
 
   // Create node to perform the runtime call.
   const Operator* call = javascript()->CallRuntime(functionId, arg_count);
@@ -1266,15 +1066,18 @@
   environment()->BindAccumulator(value, &states);
 }
 
+void BytecodeGraphBuilder::VisitCallRuntime() { BuildCallRuntime(); }
 
-void BytecodeGraphBuilder::VisitCallRuntimeForPair(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
+void BytecodeGraphBuilder::VisitCallRuntimeWide() { BuildCallRuntime(); }
+
+void BytecodeGraphBuilder::BuildCallRuntimeForPair() {
+  FrameStateBeforeAndAfter states(this);
   Runtime::FunctionId functionId =
-      static_cast<Runtime::FunctionId>(iterator.GetIndexOperand(0));
-  interpreter::Register first_arg = iterator.GetRegisterOperand(1);
-  size_t arg_count = iterator.GetCountOperand(2);
-  interpreter::Register first_return = iterator.GetRegisterOperand(3);
+      static_cast<Runtime::FunctionId>(bytecode_iterator().GetIndexOperand(0));
+  interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
+  size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
+  interpreter::Register first_return =
+      bytecode_iterator().GetRegisterOperand(3);
 
   // Create node to perform the runtime call.
   const Operator* call = javascript()->CallRuntime(functionId, arg_count);
@@ -1282,164 +1085,151 @@
   environment()->BindRegistersToProjections(first_return, return_pair, &states);
 }
 
+void BytecodeGraphBuilder::VisitCallRuntimeForPair() {
+  BuildCallRuntimeForPair();
+}
+
+void BytecodeGraphBuilder::VisitCallRuntimeForPairWide() {
+  BuildCallRuntimeForPair();
+}
 
 Node* BytecodeGraphBuilder::ProcessCallNewArguments(
-    const Operator* call_new_op, interpreter::Register callee,
+    const Operator* call_new_op, Node* callee, Node* new_target,
     interpreter::Register first_arg, size_t arity) {
-  Node** all = info()->zone()->NewArray<Node*>(arity);
-  all[0] = environment()->LookupRegister(callee);
+  Node** all = local_zone()->NewArray<Node*>(arity);
+  all[0] = new_target;
   int first_arg_index = first_arg.index();
   for (int i = 1; i < static_cast<int>(arity) - 1; ++i) {
     all[i] = environment()->LookupRegister(
         interpreter::Register(first_arg_index + i - 1));
   }
-  // Original constructor is the same as the callee.
-  all[arity - 1] = environment()->LookupRegister(callee);
+  all[arity - 1] = callee;
   Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false);
   return value;
 }
 
+void BytecodeGraphBuilder::BuildCallConstruct() {
+  FrameStateBeforeAndAfter states(this);
+  interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
+  interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
+  size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
 
-void BytecodeGraphBuilder::VisitNew(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
-  interpreter::Register callee = iterator.GetRegisterOperand(0);
-  interpreter::Register first_arg = iterator.GetRegisterOperand(1);
-  size_t arg_count = iterator.GetCountOperand(2);
-
+  Node* new_target = environment()->LookupAccumulator();
+  Node* callee = environment()->LookupRegister(callee_reg);
   // TODO(turbofan): Pass the feedback here.
   const Operator* call = javascript()->CallConstruct(
       static_cast<int>(arg_count) + 2, VectorSlotPair());
-  Node* value = ProcessCallNewArguments(call, callee, first_arg, arg_count + 2);
+  Node* value = ProcessCallNewArguments(call, callee, new_target, first_arg,
+                                        arg_count + 2);
   environment()->BindAccumulator(value, &states);
 }
 
+void BytecodeGraphBuilder::VisitNew() { BuildCallConstruct(); }
 
-void BytecodeGraphBuilder::VisitThrow(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
+void BytecodeGraphBuilder::VisitNewWide() { BuildCallConstruct(); }
+
+void BytecodeGraphBuilder::BuildThrow() {
+  FrameStateBeforeAndAfter states(this);
   Node* value = environment()->LookupAccumulator();
-  // TODO(mythria): Change to Runtime::kThrow when we have deoptimization
-  // information support in the interpreter.
-  NewNode(javascript()->CallRuntime(Runtime::kReThrow, 1), value);
-  Node* control = NewNode(common()->Throw(), value);
-  environment()->RecordAfterState(control, &states);
-  UpdateControlDependencyToLeaveFunction(control);
+  Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value);
+  environment()->BindAccumulator(call, &states);
 }
 
+void BytecodeGraphBuilder::VisitThrow() {
+  BuildThrow();
+  Node* call = environment()->LookupAccumulator();
+  Node* control = NewNode(common()->Throw(), call);
+  MergeControlToLeaveFunction(control);
+}
 
-void BytecodeGraphBuilder::BuildBinaryOp(
-    const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
-  Node* left = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+void BytecodeGraphBuilder::VisitReThrow() {
+  Node* value = environment()->LookupAccumulator();
+  Node* call = NewNode(javascript()->CallRuntime(Runtime::kReThrow), value);
+  Node* control = NewNode(common()->Throw(), call);
+  MergeControlToLeaveFunction(control);
+}
+
+void BytecodeGraphBuilder::BuildBinaryOp(const Operator* js_op) {
+  FrameStateBeforeAndAfter states(this);
+  Node* left =
+      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   Node* right = environment()->LookupAccumulator();
   Node* node = NewNode(js_op, left, right);
   environment()->BindAccumulator(node, &states);
 }
 
-
-void BytecodeGraphBuilder::VisitAdd(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitAdd() {
   BinaryOperationHints hints = BinaryOperationHints::Any();
-  BuildBinaryOp(javascript()->Add(language_mode(), hints), iterator);
+  BuildBinaryOp(javascript()->Add(hints));
 }
 
-
-void BytecodeGraphBuilder::VisitSub(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitSub() {
   BinaryOperationHints hints = BinaryOperationHints::Any();
-  BuildBinaryOp(javascript()->Subtract(language_mode(), hints), iterator);
+  BuildBinaryOp(javascript()->Subtract(hints));
 }
 
-
-void BytecodeGraphBuilder::VisitMul(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitMul() {
   BinaryOperationHints hints = BinaryOperationHints::Any();
-  BuildBinaryOp(javascript()->Multiply(language_mode(), hints), iterator);
+  BuildBinaryOp(javascript()->Multiply(hints));
 }
 
-
-void BytecodeGraphBuilder::VisitDiv(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitDiv() {
   BinaryOperationHints hints = BinaryOperationHints::Any();
-  BuildBinaryOp(javascript()->Divide(language_mode(), hints), iterator);
+  BuildBinaryOp(javascript()->Divide(hints));
 }
 
-
-void BytecodeGraphBuilder::VisitMod(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitMod() {
   BinaryOperationHints hints = BinaryOperationHints::Any();
-  BuildBinaryOp(javascript()->Modulus(language_mode(), hints), iterator);
+  BuildBinaryOp(javascript()->Modulus(hints));
 }
 
-
-void BytecodeGraphBuilder::VisitBitwiseOr(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitBitwiseOr() {
   BinaryOperationHints hints = BinaryOperationHints::Any();
-  BuildBinaryOp(javascript()->BitwiseOr(language_mode(), hints), iterator);
+  BuildBinaryOp(javascript()->BitwiseOr(hints));
 }
 
-
-void BytecodeGraphBuilder::VisitBitwiseXor(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitBitwiseXor() {
   BinaryOperationHints hints = BinaryOperationHints::Any();
-  BuildBinaryOp(javascript()->BitwiseXor(language_mode(), hints), iterator);
+  BuildBinaryOp(javascript()->BitwiseXor(hints));
 }
 
-
-void BytecodeGraphBuilder::VisitBitwiseAnd(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitBitwiseAnd() {
   BinaryOperationHints hints = BinaryOperationHints::Any();
-  BuildBinaryOp(javascript()->BitwiseAnd(language_mode(), hints), iterator);
+  BuildBinaryOp(javascript()->BitwiseAnd(hints));
 }
 
-
-void BytecodeGraphBuilder::VisitShiftLeft(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitShiftLeft() {
   BinaryOperationHints hints = BinaryOperationHints::Any();
-  BuildBinaryOp(javascript()->ShiftLeft(language_mode(), hints), iterator);
+  BuildBinaryOp(javascript()->ShiftLeft(hints));
 }
 
-
-void BytecodeGraphBuilder::VisitShiftRight(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitShiftRight() {
   BinaryOperationHints hints = BinaryOperationHints::Any();
-  BuildBinaryOp(javascript()->ShiftRight(language_mode(), hints), iterator);
+  BuildBinaryOp(javascript()->ShiftRight(hints));
 }
 
-
-void BytecodeGraphBuilder::VisitShiftRightLogical(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitShiftRightLogical() {
   BinaryOperationHints hints = BinaryOperationHints::Any();
-  BuildBinaryOp(javascript()->ShiftRightLogical(language_mode(), hints),
-                iterator);
+  BuildBinaryOp(javascript()->ShiftRightLogical(hints));
 }
 
-
-void BytecodeGraphBuilder::VisitInc(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
-  const Operator* js_op =
-      javascript()->Add(language_mode(), BinaryOperationHints::Any());
+void BytecodeGraphBuilder::VisitInc() {
+  FrameStateBeforeAndAfter states(this);
+  const Operator* js_op = javascript()->Add(BinaryOperationHints::Any());
   Node* node = NewNode(js_op, environment()->LookupAccumulator(),
                        jsgraph()->OneConstant());
   environment()->BindAccumulator(node, &states);
 }
 
-
-void BytecodeGraphBuilder::VisitDec(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
-  const Operator* js_op =
-      javascript()->Subtract(language_mode(), BinaryOperationHints::Any());
+void BytecodeGraphBuilder::VisitDec() {
+  FrameStateBeforeAndAfter states(this);
+  const Operator* js_op = javascript()->Subtract(BinaryOperationHints::Any());
   Node* node = NewNode(js_op, environment()->LookupAccumulator(),
                        jsgraph()->OneConstant());
   environment()->BindAccumulator(node, &states);
 }
 
-
-void BytecodeGraphBuilder::VisitLogicalNot(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitLogicalNot() {
   Node* value = NewNode(javascript()->ToBoolean(ToBooleanHint::kAny),
                         environment()->LookupAccumulator());
   Node* node = NewNode(common()->Select(MachineRepresentation::kTagged), value,
@@ -1447,408 +1237,307 @@
   environment()->BindAccumulator(node);
 }
 
-
-void BytecodeGraphBuilder::VisitTypeOf(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitTypeOf() {
   Node* node =
       NewNode(javascript()->TypeOf(), environment()->LookupAccumulator());
   environment()->BindAccumulator(node);
 }
 
-
-void BytecodeGraphBuilder::BuildDelete(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
+void BytecodeGraphBuilder::BuildDelete(LanguageMode language_mode) {
+  FrameStateBeforeAndAfter states(this);
   Node* key = environment()->LookupAccumulator();
-  Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+  Node* object =
+      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   Node* node =
-      NewNode(javascript()->DeleteProperty(language_mode()), object, key);
+      NewNode(javascript()->DeleteProperty(language_mode), object, key);
   environment()->BindAccumulator(node, &states);
 }
 
-
-void BytecodeGraphBuilder::VisitDeletePropertyStrict(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_strict(language_mode()));
-  BuildDelete(iterator);
+void BytecodeGraphBuilder::VisitDeletePropertyStrict() {
+  BuildDelete(LanguageMode::STRICT);
 }
 
-
-void BytecodeGraphBuilder::VisitDeletePropertySloppy(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  DCHECK(is_sloppy(language_mode()));
-  BuildDelete(iterator);
+void BytecodeGraphBuilder::VisitDeletePropertySloppy() {
+  BuildDelete(LanguageMode::SLOPPY);
 }
 
-
-void BytecodeGraphBuilder::VisitDeleteLookupSlot(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
-  Node* name = environment()->LookupAccumulator();
-  const Operator* op = javascript()->CallRuntime(Runtime::kDeleteLookupSlot, 2);
-  Node* result = NewNode(op, environment()->Context(), name);
-  environment()->BindAccumulator(result, &states);
-}
-
-
-void BytecodeGraphBuilder::BuildCompareOp(
-    const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
-  Node* left = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+void BytecodeGraphBuilder::BuildCompareOp(const Operator* js_op) {
+  FrameStateBeforeAndAfter states(this);
+  Node* left =
+      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   Node* right = environment()->LookupAccumulator();
   Node* node = NewNode(js_op, left, right);
   environment()->BindAccumulator(node, &states);
 }
 
-
-void BytecodeGraphBuilder::VisitTestEqual(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCompareOp(javascript()->Equal(), iterator);
+void BytecodeGraphBuilder::VisitTestEqual() {
+  BuildCompareOp(javascript()->Equal());
 }
 
-
-void BytecodeGraphBuilder::VisitTestNotEqual(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCompareOp(javascript()->NotEqual(), iterator);
+void BytecodeGraphBuilder::VisitTestNotEqual() {
+  BuildCompareOp(javascript()->NotEqual());
 }
 
-
-void BytecodeGraphBuilder::VisitTestEqualStrict(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCompareOp(javascript()->StrictEqual(), iterator);
+void BytecodeGraphBuilder::VisitTestEqualStrict() {
+  BuildCompareOp(javascript()->StrictEqual());
 }
 
-
-void BytecodeGraphBuilder::VisitTestNotEqualStrict(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCompareOp(javascript()->StrictNotEqual(), iterator);
+void BytecodeGraphBuilder::VisitTestNotEqualStrict() {
+  BuildCompareOp(javascript()->StrictNotEqual());
 }
 
-
-void BytecodeGraphBuilder::VisitTestLessThan(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCompareOp(javascript()->LessThan(language_mode()), iterator);
+void BytecodeGraphBuilder::VisitTestLessThan() {
+  BuildCompareOp(javascript()->LessThan());
 }
 
-
-void BytecodeGraphBuilder::VisitTestGreaterThan(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCompareOp(javascript()->GreaterThan(language_mode()), iterator);
+void BytecodeGraphBuilder::VisitTestGreaterThan() {
+  BuildCompareOp(javascript()->GreaterThan());
 }
 
-
-void BytecodeGraphBuilder::VisitTestLessThanOrEqual(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCompareOp(javascript()->LessThanOrEqual(language_mode()), iterator);
+void BytecodeGraphBuilder::VisitTestLessThanOrEqual() {
+  BuildCompareOp(javascript()->LessThanOrEqual());
 }
 
-
-void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCompareOp(javascript()->GreaterThanOrEqual(language_mode()), iterator);
+void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual() {
+  BuildCompareOp(javascript()->GreaterThanOrEqual());
 }
 
-
-void BytecodeGraphBuilder::VisitTestIn(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCompareOp(javascript()->HasProperty(), iterator);
+void BytecodeGraphBuilder::VisitTestIn() {
+  BuildCompareOp(javascript()->HasProperty());
 }
 
-
-void BytecodeGraphBuilder::VisitTestInstanceOf(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCompareOp(javascript()->InstanceOf(), iterator);
+void BytecodeGraphBuilder::VisitTestInstanceOf() {
+  BuildCompareOp(javascript()->InstanceOf());
 }
 
-
-void BytecodeGraphBuilder::BuildCastOperator(
-    const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
+void BytecodeGraphBuilder::BuildCastOperator(const Operator* js_op) {
+  FrameStateBeforeAndAfter states(this);
   Node* node = NewNode(js_op, environment()->LookupAccumulator());
   environment()->BindAccumulator(node, &states);
 }
 
-
-void BytecodeGraphBuilder::VisitToName(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCastOperator(javascript()->ToName(), iterator);
+void BytecodeGraphBuilder::VisitToName() {
+  BuildCastOperator(javascript()->ToName());
 }
 
-
-void BytecodeGraphBuilder::VisitToObject(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCastOperator(javascript()->ToObject(), iterator);
+void BytecodeGraphBuilder::VisitToObject() {
+  BuildCastOperator(javascript()->ToObject());
 }
 
-
-void BytecodeGraphBuilder::VisitToNumber(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildCastOperator(javascript()->ToNumber(), iterator);
+void BytecodeGraphBuilder::VisitToNumber() {
+  BuildCastOperator(javascript()->ToNumber());
 }
 
+void BytecodeGraphBuilder::VisitJump() { BuildJump(); }
 
-void BytecodeGraphBuilder::VisitJump(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildJump();
-}
+void BytecodeGraphBuilder::VisitJumpConstant() { BuildJump(); }
 
+void BytecodeGraphBuilder::VisitJumpConstantWide() { BuildJump(); }
 
-void BytecodeGraphBuilder::VisitJumpConstant(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildJump();
-}
-
-
-void BytecodeGraphBuilder::VisitJumpConstantWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  BuildJump();
-}
-
-
-void BytecodeGraphBuilder::VisitJumpIfTrue(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitJumpIfTrue() {
   BuildJumpIfEqual(jsgraph()->TrueConstant());
 }
 
-
-void BytecodeGraphBuilder::VisitJumpIfTrueConstant(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitJumpIfTrueConstant() {
   BuildJumpIfEqual(jsgraph()->TrueConstant());
 }
 
-
-void BytecodeGraphBuilder::VisitJumpIfTrueConstantWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitJumpIfTrueConstantWide() {
   BuildJumpIfEqual(jsgraph()->TrueConstant());
 }
 
-
-void BytecodeGraphBuilder::VisitJumpIfFalse(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitJumpIfFalse() {
   BuildJumpIfEqual(jsgraph()->FalseConstant());
 }
 
-
-void BytecodeGraphBuilder::VisitJumpIfFalseConstant(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitJumpIfFalseConstant() {
   BuildJumpIfEqual(jsgraph()->FalseConstant());
 }
 
-
-void BytecodeGraphBuilder::VisitJumpIfFalseConstantWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitJumpIfFalseConstantWide() {
   BuildJumpIfEqual(jsgraph()->FalseConstant());
 }
 
-
-void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue() {
   BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
 }
 
-
-void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant() {
   BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
 }
 
-
-void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstantWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstantWide() {
   BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
 }
 
-
-void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse() {
   BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
 }
 
-
-void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant() {
   BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
 }
 
-
-void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstantWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstantWide() {
   BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
 }
 
+void BytecodeGraphBuilder::VisitJumpIfNotHole() { BuildJumpIfNotHole(); }
 
-void BytecodeGraphBuilder::VisitJumpIfNull(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitJumpIfNotHoleConstant() {
+  BuildJumpIfNotHole();
+}
+
+void BytecodeGraphBuilder::VisitJumpIfNotHoleConstantWide() {
+  BuildJumpIfNotHole();
+}
+
+void BytecodeGraphBuilder::VisitJumpIfNull() {
   BuildJumpIfEqual(jsgraph()->NullConstant());
 }
 
-
-void BytecodeGraphBuilder::VisitJumpIfNullConstant(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitJumpIfNullConstant() {
   BuildJumpIfEqual(jsgraph()->NullConstant());
 }
 
-
-void BytecodeGraphBuilder::VisitJumpIfNullConstantWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitJumpIfNullConstantWide() {
   BuildJumpIfEqual(jsgraph()->NullConstant());
 }
 
-
-void BytecodeGraphBuilder::VisitJumpIfUndefined(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitJumpIfUndefined() {
   BuildJumpIfEqual(jsgraph()->UndefinedConstant());
 }
 
-
-void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant() {
   BuildJumpIfEqual(jsgraph()->UndefinedConstant());
 }
 
-
-void BytecodeGraphBuilder::VisitJumpIfUndefinedConstantWide(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitJumpIfUndefinedConstantWide() {
   BuildJumpIfEqual(jsgraph()->UndefinedConstant());
 }
 
+void BytecodeGraphBuilder::VisitStackCheck() {
+  FrameStateBeforeAndAfter states(this);
+  Node* node = NewNode(javascript()->StackCheck());
+  environment()->RecordAfterState(node, &states);
+}
 
-void BytecodeGraphBuilder::VisitReturn(
-    const interpreter::BytecodeArrayIterator& iterator) {
+void BytecodeGraphBuilder::VisitReturn() {
   Node* control =
       NewNode(common()->Return(), environment()->LookupAccumulator());
-  UpdateControlDependencyToLeaveFunction(control);
-  set_environment(nullptr);
+  MergeControlToLeaveFunction(control);
 }
 
-
-void BytecodeGraphBuilder::VisitForInPrepare(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  Node* prepare = nullptr;
-  {
-    FrameStateBeforeAndAfter states(this, iterator);
-    Node* receiver = environment()->LookupAccumulator();
-    prepare = NewNode(javascript()->ForInPrepare(), receiver);
-    environment()->RecordAfterState(prepare, &states);
-  }
-  // Project cache_type, cache_array, cache_length into register
-  // operands 1, 2, 3.
-  for (int i = 0; i < 3; i++) {
-    environment()->BindRegister(iterator.GetRegisterOperand(i),
-                                NewNode(common()->Projection(i), prepare));
-  }
+void BytecodeGraphBuilder::VisitDebugger() {
+  FrameStateBeforeAndAfter states(this);
+  Node* call =
+      NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement));
+  environment()->BindAccumulator(call, &states);
 }
 
+// We cannot create a graph from the debugger copy of the bytecode array.
+#define DEBUG_BREAK(Name, ...) \
+  void BytecodeGraphBuilder::Visit##Name() { UNREACHABLE(); }
+DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK);
+#undef DEBUG_BREAK
 
-void BytecodeGraphBuilder::VisitForInDone(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
-  Node* index = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+void BytecodeGraphBuilder::BuildForInPrepare() {
+  FrameStateBeforeAndAfter states(this);
+  Node* receiver = environment()->LookupAccumulator();
+  Node* prepare = NewNode(javascript()->ForInPrepare(), receiver);
+  environment()->BindRegistersToProjections(
+      bytecode_iterator().GetRegisterOperand(0), prepare, &states);
+}
+
+void BytecodeGraphBuilder::VisitForInPrepare() { BuildForInPrepare(); }
+
+void BytecodeGraphBuilder::VisitForInPrepareWide() { BuildForInPrepare(); }
+
+void BytecodeGraphBuilder::VisitForInDone() {
+  FrameStateBeforeAndAfter states(this);
+  Node* index =
+      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   Node* cache_length =
-      environment()->LookupRegister(iterator.GetRegisterOperand(1));
+      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
   Node* exit_cond = NewNode(javascript()->ForInDone(), index, cache_length);
   environment()->BindAccumulator(exit_cond, &states);
 }
 
-
-void BytecodeGraphBuilder::VisitForInNext(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
+void BytecodeGraphBuilder::BuildForInNext() {
+  FrameStateBeforeAndAfter states(this);
   Node* receiver =
-      environment()->LookupRegister(iterator.GetRegisterOperand(0));
-  Node* cache_type =
-      environment()->LookupRegister(iterator.GetRegisterOperand(1));
-  Node* cache_array =
-      environment()->LookupRegister(iterator.GetRegisterOperand(2));
-  Node* index = environment()->LookupRegister(iterator.GetRegisterOperand(3));
+      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
+  Node* index =
+      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
+  int catch_reg_pair_index = bytecode_iterator().GetRegisterOperand(2).index();
+  Node* cache_type = environment()->LookupRegister(
+      interpreter::Register(catch_reg_pair_index));
+  Node* cache_array = environment()->LookupRegister(
+      interpreter::Register(catch_reg_pair_index + 1));
+
   Node* value = NewNode(javascript()->ForInNext(), receiver, cache_array,
                         cache_type, index);
   environment()->BindAccumulator(value, &states);
 }
 
+void BytecodeGraphBuilder::VisitForInNext() { BuildForInNext(); }
 
-void BytecodeGraphBuilder::VisitForInStep(
-    const interpreter::BytecodeArrayIterator& iterator) {
-  FrameStateBeforeAndAfter states(this, iterator);
-  Node* index = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+void BytecodeGraphBuilder::VisitForInNextWide() { BuildForInNext(); }
+
+void BytecodeGraphBuilder::VisitForInStep() {
+  FrameStateBeforeAndAfter states(this);
+  Node* index =
+      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   index = NewNode(javascript()->ForInStep(), index);
   environment()->BindAccumulator(index, &states);
 }
 
-
-void BytecodeGraphBuilder::MergeEnvironmentsOfBackwardBranches(
-    int source_offset, int target_offset) {
-  DCHECK_GE(source_offset, target_offset);
-  const ZoneVector<int>* branch_sites =
-      branch_analysis()->BackwardBranchesTargetting(target_offset);
-  if (branch_sites->back() == source_offset) {
-    // The set of back branches is complete, merge them.
-    DCHECK_GE(branch_sites->at(0), target_offset);
-    Environment* merged = merge_environments_[branch_sites->at(0)];
-    for (size_t i = 1; i < branch_sites->size(); i++) {
-      DCHECK_GE(branch_sites->at(i), target_offset);
-      merged->Merge(merge_environments_[branch_sites->at(i)]);
+void BytecodeGraphBuilder::SwitchToMergeEnvironment(int current_offset) {
+  if (merge_environments_[current_offset] != nullptr) {
+    if (environment() != nullptr) {
+      merge_environments_[current_offset]->Merge(environment());
     }
-    // And now merge with loop header environment created when loop
-    // header was visited.
-    loop_header_environments_[target_offset]->Merge(merged);
+    set_environment(merge_environments_[current_offset]);
   }
 }
 
-
-void BytecodeGraphBuilder::MergeEnvironmentsOfForwardBranches(
-    int source_offset) {
-  if (branch_analysis()->forward_branches_target(source_offset)) {
-    // Merge environments of branches that reach this bytecode.
-    auto branch_sites =
-        branch_analysis()->ForwardBranchesTargetting(source_offset);
-    DCHECK_LT(branch_sites->at(0), source_offset);
-    Environment* merged = merge_environments_[branch_sites->at(0)];
-    for (size_t i = 1; i < branch_sites->size(); i++) {
-      DCHECK_LT(branch_sites->at(i), source_offset);
-      merged->Merge(merge_environments_[branch_sites->at(i)]);
-    }
-    if (environment()) {
-      merged->Merge(environment());
-    }
-    set_environment(merged);
-  }
-}
-
-
-void BytecodeGraphBuilder::BuildLoopHeaderForBackwardBranches(
-    int source_offset) {
-  if (branch_analysis()->backward_branches_target(source_offset)) {
+void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) {
+  if (branch_analysis()->backward_branches_target(current_offset)) {
     // Add loop header and store a copy so we can connect merged back
     // edge inputs to the loop header.
-    loop_header_environments_[source_offset] = environment()->CopyForLoop();
+    merge_environments_[current_offset] = environment()->CopyForLoop();
   }
 }
 
-
-void BytecodeGraphBuilder::BuildJump(int source_offset, int target_offset) {
-  DCHECK_NULL(merge_environments_[source_offset]);
-  merge_environments_[source_offset] = environment();
-  if (source_offset >= target_offset) {
-    MergeEnvironmentsOfBackwardBranches(source_offset, target_offset);
+void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(int target_offset) {
+  if (merge_environments_[target_offset] == nullptr) {
+    // Append merge nodes to the environment. We may merge here with another
+    // environment. So add a place holder for merge nodes. We may add redundant
+    // but will be eliminated in a later pass.
+    // TODO(mstarzinger): Be smarter about this!
+    NewMerge();
+    merge_environments_[target_offset] = environment();
+  } else {
+    merge_environments_[target_offset]->Merge(environment());
   }
   set_environment(nullptr);
 }
 
+void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
+  exit_controls_.push_back(exit);
+  set_environment(nullptr);
+}
 
 void BytecodeGraphBuilder::BuildJump() {
-  int source_offset = bytecode_iterator()->current_offset();
-  int target_offset = bytecode_iterator()->GetJumpTargetOffset();
-  BuildJump(source_offset, target_offset);
+  MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
 }
 
 
 void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) {
-  int source_offset = bytecode_iterator()->current_offset();
   NewBranch(condition);
   Environment* if_false_environment = environment()->CopyForConditional();
   NewIfTrue();
-  BuildJump(source_offset, bytecode_iterator()->GetJumpTargetOffset());
+  MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
   set_environment(if_false_environment);
   NewIfFalse();
 }
@@ -1870,6 +1559,15 @@
   BuildConditionalJump(condition);
 }
 
+void BytecodeGraphBuilder::BuildJumpIfNotHole() {
+  Node* accumulator = environment()->LookupAccumulator();
+  Node* condition = NewNode(javascript()->StrictEqual(), accumulator,
+                            jsgraph()->TheHoleConstant());
+  Node* node =
+      NewNode(common()->Select(MachineRepresentation::kTagged), condition,
+              jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
+  BuildConditionalJump(node);
+}
 
 Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) {
   if (size > input_buffer_size_) {
@@ -1880,17 +1578,32 @@
   return input_buffer_;
 }
 
+void BytecodeGraphBuilder::EnterAndExitExceptionHandlers(int current_offset) {
+  Handle<HandlerTable> table = exception_handler_table();
+  int num_entries = table->NumberOfRangeEntries();
 
-void BytecodeGraphBuilder::PrepareEntryFrameState(Node* node) {
-  DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
-  DCHECK_EQ(IrOpcode::kDead,
-            NodeProperties::GetFrameStateInput(node, 0)->opcode());
-  NodeProperties::ReplaceFrameStateInput(
-      node, 0, environment()->Checkpoint(BailoutId(0),
-                                         OutputFrameStateCombine::Ignore()));
+  // Potentially exit exception handlers.
+  while (!exception_handlers_.empty()) {
+    int current_end = exception_handlers_.top().end_offset_;
+    if (current_offset < current_end) break;  // Still covered by range.
+    exception_handlers_.pop();
+  }
+
+  // Potentially enter exception handlers.
+  while (current_exception_handler_ < num_entries) {
+    int next_start = table->GetRangeStart(current_exception_handler_);
+    if (current_offset < next_start) break;  // Not yet covered by range.
+    int next_end = table->GetRangeEnd(current_exception_handler_);
+    int next_handler = table->GetRangeHandler(current_exception_handler_);
+    int context_register = table->GetRangeData(current_exception_handler_);
+    CatchPrediction pred =
+        table->GetRangePrediction(current_exception_handler_);
+    exception_handlers_.push(
+        {next_start, next_end, next_handler, context_register, pred});
+    current_exception_handler_++;
+  }
 }
 
-
 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
                                      Node** value_inputs, bool incomplete) {
   DCHECK_EQ(op->ValueInputCount(), value_input_count);
@@ -1907,6 +1620,7 @@
   if (!has_context && frame_state_count == 0 && !has_control && !has_effect) {
     result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
   } else {
+    bool inside_handler = !exception_handlers_.empty();
     int input_count_with_deps = value_input_count;
     if (has_context) ++input_count_with_deps;
     input_count_with_deps += frame_state_count;
@@ -1931,21 +1645,40 @@
       *current_input++ = environment()->GetControlDependency();
     }
     result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
-    if (!environment()->IsMarkedAsUnreachable()) {
-      // Update the current control dependency for control-producing nodes.
-      if (NodeProperties::IsControl(result)) {
-        environment()->UpdateControlDependency(result);
-      }
-      // Update the current effect dependency for effect-producing nodes.
-      if (result->op()->EffectOutputCount() > 0) {
-        environment()->UpdateEffectDependency(result);
-      }
-      // Add implicit success continuation for throwing nodes.
-      if (!result->op()->HasProperty(Operator::kNoThrow)) {
-        const Operator* if_success = common()->IfSuccess();
-        Node* on_success = graph()->NewNode(if_success, result);
-        environment_->UpdateControlDependency(on_success);
-      }
+    // Update the current control dependency for control-producing nodes.
+    if (NodeProperties::IsControl(result)) {
+      environment()->UpdateControlDependency(result);
+    }
+    // Update the current effect dependency for effect-producing nodes.
+    if (result->op()->EffectOutputCount() > 0) {
+      environment()->UpdateEffectDependency(result);
+    }
+    // Add implicit exception continuation for throwing nodes.
+    if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
+      int handler_offset = exception_handlers_.top().handler_offset_;
+      int context_index = exception_handlers_.top().context_register_;
+      CatchPrediction prediction = exception_handlers_.top().pred_;
+      interpreter::Register context_register(context_index);
+      IfExceptionHint hint = prediction == CatchPrediction::CAUGHT
+                                 ? IfExceptionHint::kLocallyCaught
+                                 : IfExceptionHint::kLocallyUncaught;
+      Environment* success_env = environment()->CopyForConditional();
+      const Operator* op = common()->IfException(hint);
+      Node* effect = environment()->GetEffectDependency();
+      Node* on_exception = graph()->NewNode(op, effect, result);
+      Node* context = environment()->LookupRegister(context_register);
+      environment()->UpdateControlDependency(on_exception);
+      environment()->UpdateEffectDependency(on_exception);
+      environment()->BindAccumulator(on_exception);
+      environment()->SetContext(context);
+      MergeIntoSuccessorEnvironment(handler_offset);
+      set_environment(success_env);
+    }
+    // Add implicit success continuation for throwing nodes.
+    if (!result->op()->HasProperty(Operator::kNoThrow)) {
+      const Operator* if_success = common()->IfSuccess();
+      Node* on_success = graph()->NewNode(if_success, result);
+      environment()->UpdateControlDependency(on_success);
     }
   }
 
@@ -2028,13 +1761,6 @@
   return value;
 }
 
-
-void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
-  if (environment()->IsMarkedAsUnreachable()) return;
-  environment()->MarkAsUnreachable();
-  exit_controls_.push_back(exit);
-}
-
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
