Home | History | Annotate | Download | only in compiler
      1 // Copyright 2015 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/compiler/bytecode-graph-builder.h"
      6 
      7 #include "src/compiler/bytecode-branch-analysis.h"
      8 #include "src/compiler/linkage.h"
      9 #include "src/compiler/operator-properties.h"
     10 #include "src/interpreter/bytecodes.h"
     11 
     12 namespace v8 {
     13 namespace internal {
     14 namespace compiler {
     15 
     16 // The abstract execution environment simulates the content of the interpreter
     17 // register file. The environment performs SSA-renaming of all tracked nodes at
     18 // split and merge points in the control flow.
     19 class BytecodeGraphBuilder::Environment : public ZoneObject {
     20  public:
     21   Environment(BytecodeGraphBuilder* builder, int register_count,
     22               int parameter_count, Node* control_dependency, Node* context);
     23 
     24   int parameter_count() const { return parameter_count_; }
     25   int register_count() const { return register_count_; }
     26 
     27   Node* LookupAccumulator() const;
     28   Node* LookupRegister(interpreter::Register the_register) const;
     29 
     30   void BindAccumulator(Node* node, FrameStateBeforeAndAfter* states = nullptr);
     31   void BindRegister(interpreter::Register the_register, Node* node,
     32                     FrameStateBeforeAndAfter* states = nullptr);
     33   void BindRegistersToProjections(interpreter::Register first_reg, Node* node,
     34                                   FrameStateBeforeAndAfter* states = nullptr);
     35   void RecordAfterState(Node* node, FrameStateBeforeAndAfter* states);
     36 
     37   // Effect dependency tracked by this environment.
     38   Node* GetEffectDependency() { return effect_dependency_; }
     39   void UpdateEffectDependency(Node* dependency) {
     40     effect_dependency_ = dependency;
     41   }
     42 
     43   // Preserve a checkpoint of the environment for the IR graph. Any
     44   // further mutation of the environment will not affect checkpoints.
     45   Node* Checkpoint(BailoutId bytecode_offset, OutputFrameStateCombine combine);
     46 
     47   // Returns true if the state values are up to date with the current
     48   // environment.
     49   bool StateValuesAreUpToDate(int output_poke_offset, int output_poke_count);
     50 
     51   // Control dependency tracked by this environment.
     52   Node* GetControlDependency() const { return control_dependency_; }
     53   void UpdateControlDependency(Node* dependency) {
     54     control_dependency_ = dependency;
     55   }
     56 
     57   Node* Context() const { return context_; }
     58   void SetContext(Node* new_context) { context_ = new_context; }
     59 
     60   Environment* CopyForConditional() const;
     61   Environment* CopyForLoop();
     62   void Merge(Environment* other);
     63 
     64  private:
     65   explicit Environment(const Environment* copy);
     66   void PrepareForLoop();
     67   bool StateValuesAreUpToDate(Node** state_values, int offset, int count,
     68                               int output_poke_start, int output_poke_end);
     69   bool StateValuesRequireUpdate(Node** state_values, int offset, int count);
     70   void UpdateStateValues(Node** state_values, int offset, int count);
     71 
     72   int RegisterToValuesIndex(interpreter::Register the_register) const;
     73 
     74   Zone* zone() const { return builder_->local_zone(); }
     75   Graph* graph() const { return builder_->graph(); }
     76   CommonOperatorBuilder* common() const { return builder_->common(); }
     77   BytecodeGraphBuilder* builder() const { return builder_; }
     78   const NodeVector* values() const { return &values_; }
     79   NodeVector* values() { return &values_; }
     80   int register_base() const { return register_base_; }
     81   int accumulator_base() const { return accumulator_base_; }
     82 
     83   BytecodeGraphBuilder* builder_;
     84   int register_count_;
     85   int parameter_count_;
     86   Node* context_;
     87   Node* control_dependency_;
     88   Node* effect_dependency_;
     89   NodeVector values_;
     90   Node* parameters_state_values_;
     91   Node* registers_state_values_;
     92   Node* accumulator_state_values_;
     93   int register_base_;
     94   int accumulator_base_;
     95 };
     96 
     97 // Helper for generating frame states for before and after a bytecode.
     98 class BytecodeGraphBuilder::FrameStateBeforeAndAfter {
     99  public:
    100   explicit FrameStateBeforeAndAfter(BytecodeGraphBuilder* builder)
    101       : builder_(builder),
    102         id_after_(BailoutId::None()),
    103         added_to_node_(false),
    104         frame_states_unused_(false),
    105         output_poke_offset_(0),
    106         output_poke_count_(0) {
    107     BailoutId id_before(builder->bytecode_iterator().current_offset());
    108     frame_state_before_ = builder_->environment()->Checkpoint(
    109         id_before, OutputFrameStateCombine::Ignore());
    110     id_after_ = BailoutId(id_before.ToInt() +
    111                           builder->bytecode_iterator().current_bytecode_size());
    112     // Create an explicit checkpoint node for before the operation.
    113     Node* node = builder_->NewNode(builder_->common()->Checkpoint());
    114     DCHECK_EQ(IrOpcode::kDead,
    115               NodeProperties::GetFrameStateInput(node, 0)->opcode());
    116     NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_before_);
    117   }
    118 
    119   ~FrameStateBeforeAndAfter() {
    120     DCHECK(added_to_node_);
    121     DCHECK(frame_states_unused_ ||
    122            builder_->environment()->StateValuesAreUpToDate(output_poke_offset_,
    123                                                            output_poke_count_));
    124   }
    125 
    126  private:
    127   friend class Environment;
    128 
    129   void AddToNode(Node* node, OutputFrameStateCombine combine) {
    130     DCHECK(!added_to_node_);
    131     int count = OperatorProperties::GetFrameStateInputCount(node->op());
    132     DCHECK_LE(count, 2);
    133     if (count >= 1) {
    134       // Add the frame state for after the operation.
    135       DCHECK_EQ(IrOpcode::kDead,
    136                 NodeProperties::GetFrameStateInput(node, 0)->opcode());
    137       Node* frame_state_after =
    138           builder_->environment()->Checkpoint(id_after_, combine);
    139       NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after);
    140     }
    141 
    142     if (count >= 2) {
    143       // Add the frame state for before the operation.
    144       // TODO(mstarzinger): Get rid of frame state input before!
    145       DCHECK_EQ(IrOpcode::kDead,
    146                 NodeProperties::GetFrameStateInput(node, 1)->opcode());
    147       NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_);
    148     }
    149 
    150     if (!combine.IsOutputIgnored()) {
    151       output_poke_offset_ = static_cast<int>(combine.GetOffsetToPokeAt());
    152       output_poke_count_ = node->op()->ValueOutputCount();
    153     }
    154     frame_states_unused_ = count == 0;
    155     added_to_node_ = true;
    156   }
    157 
    158   BytecodeGraphBuilder* builder_;
    159   Node* frame_state_before_;
    160   BailoutId id_after_;
    161 
    162   bool added_to_node_;
    163   bool frame_states_unused_;
    164   int output_poke_offset_;
    165   int output_poke_count_;
    166 };
    167 
    168 
    169 // Issues:
    170 // - Scopes - intimately tied to AST. Need to eval what is needed.
    171 // - Need to resolve closure parameter treatment.
    172 BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder,
    173                                                int register_count,
    174                                                int parameter_count,
    175                                                Node* control_dependency,
    176                                                Node* context)
    177     : builder_(builder),
    178       register_count_(register_count),
    179       parameter_count_(parameter_count),
    180       context_(context),
    181       control_dependency_(control_dependency),
    182       effect_dependency_(control_dependency),
    183       values_(builder->local_zone()),
    184       parameters_state_values_(nullptr),
    185       registers_state_values_(nullptr),
    186       accumulator_state_values_(nullptr) {
    187   // The layout of values_ is:
    188   //
    189   // [receiver] [parameters] [registers] [accumulator]
    190   //
    191   // parameter[0] is the receiver (this), parameters 1..N are the
    192   // parameters supplied to the method (arg0..argN-1). The accumulator
    193   // is stored separately.
    194 
    195   // Parameters including the receiver
    196   for (int i = 0; i < parameter_count; i++) {
    197     const char* debug_name = (i == 0) ? "%this" : nullptr;
    198     const Operator* op = common()->Parameter(i, debug_name);
    199     Node* parameter = builder->graph()->NewNode(op, graph()->start());
    200     values()->push_back(parameter);
    201   }
    202 
    203   // Registers
    204   register_base_ = static_cast<int>(values()->size());
    205   Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
    206   values()->insert(values()->end(), register_count, undefined_constant);
    207 
    208   // Accumulator
    209   accumulator_base_ = static_cast<int>(values()->size());
    210   values()->push_back(undefined_constant);
    211 }
    212 
    213 
    214 BytecodeGraphBuilder::Environment::Environment(
    215     const BytecodeGraphBuilder::Environment* other)
    216     : builder_(other->builder_),
    217       register_count_(other->register_count_),
    218       parameter_count_(other->parameter_count_),
    219       context_(other->context_),
    220       control_dependency_(other->control_dependency_),
    221       effect_dependency_(other->effect_dependency_),
    222       values_(other->zone()),
    223       parameters_state_values_(nullptr),
    224       registers_state_values_(nullptr),
    225       accumulator_state_values_(nullptr),
    226       register_base_(other->register_base_),
    227       accumulator_base_(other->accumulator_base_) {
    228   values_ = other->values_;
    229 }
    230 
    231 
    232 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex(
    233     interpreter::Register the_register) const {
    234   if (the_register.is_parameter()) {
    235     return the_register.ToParameterIndex(parameter_count());
    236   } else {
    237     return the_register.index() + register_base();
    238   }
    239 }
    240 
    241 
    242 Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const {
    243   return values()->at(accumulator_base_);
    244 }
    245 
    246 
    247 Node* BytecodeGraphBuilder::Environment::LookupRegister(
    248     interpreter::Register the_register) const {
    249   if (the_register.is_current_context()) {
    250     return Context();
    251   } else if (the_register.is_function_closure()) {
    252     return builder()->GetFunctionClosure();
    253   } else if (the_register.is_new_target()) {
    254     return builder()->GetNewTarget();
    255   } else {
    256     int values_index = RegisterToValuesIndex(the_register);
    257     return values()->at(values_index);
    258   }
    259 }
    260 
    261 
    262 void BytecodeGraphBuilder::Environment::BindAccumulator(
    263     Node* node, FrameStateBeforeAndAfter* states) {
    264   if (states) {
    265     states->AddToNode(node, OutputFrameStateCombine::PokeAt(0));
    266   }
    267   values()->at(accumulator_base_) = node;
    268 }
    269 
    270 
    271 void BytecodeGraphBuilder::Environment::BindRegister(
    272     interpreter::Register the_register, Node* node,
    273     FrameStateBeforeAndAfter* states) {
    274   int values_index = RegisterToValuesIndex(the_register);
    275   if (states) {
    276     states->AddToNode(node, OutputFrameStateCombine::PokeAt(accumulator_base_ -
    277                                                             values_index));
    278   }
    279   values()->at(values_index) = node;
    280 }
    281 
    282 
    283 void BytecodeGraphBuilder::Environment::BindRegistersToProjections(
    284     interpreter::Register first_reg, Node* node,
    285     FrameStateBeforeAndAfter* states) {
    286   int values_index = RegisterToValuesIndex(first_reg);
    287   if (states) {
    288     states->AddToNode(node, OutputFrameStateCombine::PokeAt(accumulator_base_ -
    289                                                             values_index));
    290   }
    291   for (int i = 0; i < node->op()->ValueOutputCount(); i++) {
    292     values()->at(values_index + i) =
    293         builder()->NewNode(common()->Projection(i), node);
    294   }
    295 }
    296 
    297 
    298 void BytecodeGraphBuilder::Environment::RecordAfterState(
    299     Node* node, FrameStateBeforeAndAfter* states) {
    300   states->AddToNode(node, OutputFrameStateCombine::Ignore());
    301 }
    302 
    303 
    304 BytecodeGraphBuilder::Environment*
    305 BytecodeGraphBuilder::Environment::CopyForLoop() {
    306   PrepareForLoop();
    307   return new (zone()) Environment(this);
    308 }
    309 
    310 
    311 BytecodeGraphBuilder::Environment*
    312 BytecodeGraphBuilder::Environment::CopyForConditional() const {
    313   return new (zone()) Environment(this);
    314 }
    315 
    316 
    317 void BytecodeGraphBuilder::Environment::Merge(
    318     BytecodeGraphBuilder::Environment* other) {
    319   // Create a merge of the control dependencies of both environments and update
    320   // the current environment's control dependency accordingly.
    321   Node* control = builder()->MergeControl(GetControlDependency(),
    322                                           other->GetControlDependency());
    323   UpdateControlDependency(control);
    324 
    325   // Create a merge of the effect dependencies of both environments and update
    326   // the current environment's effect dependency accordingly.
    327   Node* effect = builder()->MergeEffect(GetEffectDependency(),
    328                                         other->GetEffectDependency(), control);
    329   UpdateEffectDependency(effect);
    330 
    331   // Introduce Phi nodes for values that have differing input at merge points,
    332   // potentially extending an existing Phi node if possible.
    333   context_ = builder()->MergeValue(context_, other->context_, control);
    334   for (size_t i = 0; i < values_.size(); i++) {
    335     values_[i] = builder()->MergeValue(values_[i], other->values_[i], control);
    336   }
    337 }
    338 
    339 
    340 void BytecodeGraphBuilder::Environment::PrepareForLoop() {
    341   // Create a control node for the loop header.
    342   Node* control = builder()->NewLoop();
    343 
    344   // Create a Phi for external effects.
    345   Node* effect = builder()->NewEffectPhi(1, GetEffectDependency(), control);
    346   UpdateEffectDependency(effect);
    347 
    348   // Assume everything in the loop is updated.
    349   context_ = builder()->NewPhi(1, context_, control);
    350   int size = static_cast<int>(values()->size());
    351   for (int i = 0; i < size; i++) {
    352     values()->at(i) = builder()->NewPhi(1, values()->at(i), control);
    353   }
    354 
    355   // Connect to the loop end.
    356   Node* terminate = builder()->graph()->NewNode(
    357       builder()->common()->Terminate(), effect, control);
    358   builder()->exit_controls_.push_back(terminate);
    359 }
    360 
    361 
    362 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate(
    363     Node** state_values, int offset, int count) {
    364   if (*state_values == nullptr) {
    365     return true;
    366   }
    367   DCHECK_EQ((*state_values)->InputCount(), count);
    368   DCHECK_LE(static_cast<size_t>(offset + count), values()->size());
    369   Node** env_values = (count == 0) ? nullptr : &values()->at(offset);
    370   for (int i = 0; i < count; i++) {
    371     if ((*state_values)->InputAt(i) != env_values[i]) {
    372       return true;
    373     }
    374   }
    375   return false;
    376 }
    377 
    378 
    379 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values,
    380                                                           int offset,
    381                                                           int count) {
    382   if (StateValuesRequireUpdate(state_values, offset, count)) {
    383     const Operator* op = common()->StateValues(count);
    384     (*state_values) = graph()->NewNode(op, count, &values()->at(offset));
    385   }
    386 }
    387 
    388 
    389 Node* BytecodeGraphBuilder::Environment::Checkpoint(
    390     BailoutId bailout_id, OutputFrameStateCombine combine) {
    391   // TODO(rmcilroy): Consider using StateValuesCache for some state values.
    392   UpdateStateValues(&parameters_state_values_, 0, parameter_count());
    393   UpdateStateValues(&registers_state_values_, register_base(),
    394                     register_count());
    395   UpdateStateValues(&accumulator_state_values_, accumulator_base(), 1);
    396 
    397   const Operator* op = common()->FrameState(
    398       bailout_id, combine, builder()->frame_state_function_info());
    399   Node* result = graph()->NewNode(
    400       op, parameters_state_values_, registers_state_values_,
    401       accumulator_state_values_, Context(), builder()->GetFunctionClosure(),
    402       builder()->graph()->start());
    403 
    404   return result;
    405 }
    406 
    407 
    408 bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate(
    409     Node** state_values, int offset, int count, int output_poke_start,
    410     int output_poke_end) {
    411   DCHECK_LE(static_cast<size_t>(offset + count), values()->size());
    412   for (int i = 0; i < count; i++, offset++) {
    413     if (offset < output_poke_start || offset >= output_poke_end) {
    414       if ((*state_values)->InputAt(i) != values()->at(offset)) {
    415         return false;
    416       }
    417     }
    418   }
    419   return true;
    420 }
    421 
    422 
    423 bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate(
    424     int output_poke_offset, int output_poke_count) {
    425   // Poke offset is relative to the top of the stack (i.e., the accumulator).
    426   int output_poke_start = accumulator_base() - output_poke_offset;
    427   int output_poke_end = output_poke_start + output_poke_count;
    428   return StateValuesAreUpToDate(&parameters_state_values_, 0, parameter_count(),
    429                                 output_poke_start, output_poke_end) &&
    430          StateValuesAreUpToDate(&registers_state_values_, register_base(),
    431                                 register_count(), output_poke_start,
    432                                 output_poke_end) &&
    433          StateValuesAreUpToDate(&accumulator_state_values_, accumulator_base(),
    434                                 1, output_poke_start, output_poke_end);
    435 }
    436 
    437 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone,
    438                                            CompilationInfo* info,
    439                                            JSGraph* jsgraph)
    440     : local_zone_(local_zone),
    441       jsgraph_(jsgraph),
    442       bytecode_array_(handle(info->shared_info()->bytecode_array())),
    443       exception_handler_table_(
    444           handle(HandlerTable::cast(bytecode_array()->handler_table()))),
    445       feedback_vector_(handle(info->closure()->feedback_vector())),
    446       frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
    447           FrameStateType::kInterpretedFunction,
    448           bytecode_array()->parameter_count(),
    449           bytecode_array()->register_count(), info->shared_info())),
    450       merge_environments_(local_zone),
    451       exception_handlers_(local_zone),
    452       current_exception_handler_(0),
    453       input_buffer_size_(0),
    454       input_buffer_(nullptr),
    455       exit_controls_(local_zone) {}
    456 
    457 Node* BytecodeGraphBuilder::GetNewTarget() {
    458   if (!new_target_.is_set()) {
    459     int params = bytecode_array()->parameter_count();
    460     int index = Linkage::GetJSCallNewTargetParamIndex(params);
    461     const Operator* op = common()->Parameter(index, "%new.target");
    462     Node* node = NewNode(op, graph()->start());
    463     new_target_.set(node);
    464   }
    465   return new_target_.get();
    466 }
    467 
    468 
    469 Node* BytecodeGraphBuilder::GetFunctionContext() {
    470   if (!function_context_.is_set()) {
    471     int params = bytecode_array()->parameter_count();
    472     int index = Linkage::GetJSCallContextParamIndex(params);
    473     const Operator* op = common()->Parameter(index, "%context");
    474     Node* node = NewNode(op, graph()->start());
    475     function_context_.set(node);
    476   }
    477   return function_context_.get();
    478 }
    479 
    480 
    481 Node* BytecodeGraphBuilder::GetFunctionClosure() {
    482   if (!function_closure_.is_set()) {
    483     int index = Linkage::kJSCallClosureParamIndex;
    484     const Operator* op = common()->Parameter(index, "%closure");
    485     Node* node = NewNode(op, graph()->start());
    486     function_closure_.set(node);
    487   }
    488   return function_closure_.get();
    489 }
    490 
    491 
    492 Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) {
    493   const Operator* op =
    494       javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true);
    495   Node* native_context = NewNode(op, environment()->Context());
    496   return NewNode(javascript()->LoadContext(0, index, true), native_context);
    497 }
    498 
    499 
    500 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) {
    501   FeedbackVectorSlot slot;
    502   if (slot_id >= TypeFeedbackVector::kReservedIndexCount) {
    503     slot = feedback_vector()->ToSlot(slot_id);
    504   }
    505   return VectorSlotPair(feedback_vector(), slot);
    506 }
    507 
    508 bool BytecodeGraphBuilder::CreateGraph() {
    509   // Set up the basic structure of the graph. Outputs for {Start} are
    510   // the formal parameters (including the receiver) plus context and
    511   // closure.
    512 
    513   // Set up the basic structure of the graph. Outputs for {Start} are the formal
    514   // parameters (including the receiver) plus new target, number of arguments,
    515   // context and closure.
    516   int actual_parameter_count = bytecode_array()->parameter_count() + 4;
    517   graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count)));
    518 
    519   Environment env(this, bytecode_array()->register_count(),
    520                   bytecode_array()->parameter_count(), graph()->start(),
    521                   GetFunctionContext());
    522   set_environment(&env);
    523 
    524   VisitBytecodes();
    525 
    526   // Finish the basic structure of the graph.
    527   DCHECK_NE(0u, exit_controls_.size());
    528   int const input_count = static_cast<int>(exit_controls_.size());
    529   Node** const inputs = &exit_controls_.front();
    530   Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs);
    531   graph()->SetEnd(end);
    532 
    533   return true;
    534 }
    535 
    536 void BytecodeGraphBuilder::VisitBytecodes() {
    537   BytecodeBranchAnalysis analysis(bytecode_array(), local_zone());
    538   analysis.Analyze();
    539   set_branch_analysis(&analysis);
    540   interpreter::BytecodeArrayIterator iterator(bytecode_array());
    541   set_bytecode_iterator(&iterator);
    542   while (!iterator.done()) {
    543     int current_offset = iterator.current_offset();
    544     EnterAndExitExceptionHandlers(current_offset);
    545     SwitchToMergeEnvironment(current_offset);
    546     if (environment() != nullptr) {
    547       BuildLoopHeaderEnvironment(current_offset);
    548 
    549       switch (iterator.current_bytecode()) {
    550 #define BYTECODE_CASE(name, ...)       \
    551   case interpreter::Bytecode::k##name: \
    552     Visit##name();                     \
    553     break;
    554         BYTECODE_LIST(BYTECODE_CASE)
    555 #undef BYTECODE_CODE
    556       }
    557     }
    558     iterator.Advance();
    559   }
    560   set_branch_analysis(nullptr);
    561   set_bytecode_iterator(nullptr);
    562   DCHECK(exception_handlers_.empty());
    563 }
    564 
    565 void BytecodeGraphBuilder::VisitLdaZero() {
    566   Node* node = jsgraph()->ZeroConstant();
    567   environment()->BindAccumulator(node);
    568 }
    569 
    570 void BytecodeGraphBuilder::VisitLdaSmi() {
    571   Node* node = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
    572   environment()->BindAccumulator(node);
    573 }
    574 
    575 void BytecodeGraphBuilder::VisitLdaConstant() {
    576   Node* node =
    577       jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
    578   environment()->BindAccumulator(node);
    579 }
    580 
    581 void BytecodeGraphBuilder::VisitLdaUndefined() {
    582   Node* node = jsgraph()->UndefinedConstant();
    583   environment()->BindAccumulator(node);
    584 }
    585 
    586 void BytecodeGraphBuilder::VisitLdrUndefined() {
    587   Node* node = jsgraph()->UndefinedConstant();
    588   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), node);
    589 }
    590 
    591 void BytecodeGraphBuilder::VisitLdaNull() {
    592   Node* node = jsgraph()->NullConstant();
    593   environment()->BindAccumulator(node);
    594 }
    595 
    596 void BytecodeGraphBuilder::VisitLdaTheHole() {
    597   Node* node = jsgraph()->TheHoleConstant();
    598   environment()->BindAccumulator(node);
    599 }
    600 
    601 void BytecodeGraphBuilder::VisitLdaTrue() {
    602   Node* node = jsgraph()->TrueConstant();
    603   environment()->BindAccumulator(node);
    604 }
    605 
    606 void BytecodeGraphBuilder::VisitLdaFalse() {
    607   Node* node = jsgraph()->FalseConstant();
    608   environment()->BindAccumulator(node);
    609 }
    610 
    611 void BytecodeGraphBuilder::VisitLdar() {
    612   Node* value =
    613       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
    614   environment()->BindAccumulator(value);
    615 }
    616 
    617 void BytecodeGraphBuilder::VisitStar() {
    618   Node* value = environment()->LookupAccumulator();
    619   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value);
    620 }
    621 
    622 void BytecodeGraphBuilder::VisitMov() {
    623   Node* value =
    624       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
    625   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), value);
    626 }
    627 
    628 Node* BytecodeGraphBuilder::BuildLoadGlobal(TypeofMode typeof_mode) {
    629   VectorSlotPair feedback =
    630       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(0));
    631   DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC,
    632             feedback_vector()->GetKind(feedback.slot()));
    633   Handle<Name> name(feedback_vector()->GetName(feedback.slot()));
    634   const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
    635   return NewNode(op, GetFunctionClosure());
    636 }
    637 
    638 void BytecodeGraphBuilder::VisitLdaGlobal() {
    639   FrameStateBeforeAndAfter states(this);
    640   Node* node = BuildLoadGlobal(TypeofMode::NOT_INSIDE_TYPEOF);
    641   environment()->BindAccumulator(node, &states);
    642 }
    643 
    644 void BytecodeGraphBuilder::VisitLdrGlobal() {
    645   FrameStateBeforeAndAfter states(this);
    646   Node* node = BuildLoadGlobal(TypeofMode::NOT_INSIDE_TYPEOF);
    647   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), node,
    648                               &states);
    649 }
    650 
    651 void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() {
    652   FrameStateBeforeAndAfter states(this);
    653   Node* node = BuildLoadGlobal(TypeofMode::INSIDE_TYPEOF);
    654   environment()->BindAccumulator(node, &states);
    655 }
    656 
    657 void BytecodeGraphBuilder::BuildStoreGlobal(LanguageMode language_mode) {
    658   FrameStateBeforeAndAfter states(this);
    659   Handle<Name> name =
    660       Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
    661   VectorSlotPair feedback =
    662       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
    663   Node* value = environment()->LookupAccumulator();
    664 
    665   const Operator* op = javascript()->StoreGlobal(language_mode, name, feedback);
    666   Node* node = NewNode(op, value, GetFunctionClosure());
    667   environment()->RecordAfterState(node, &states);
    668 }
    669 
    670 void BytecodeGraphBuilder::VisitStaGlobalSloppy() {
    671   BuildStoreGlobal(LanguageMode::SLOPPY);
    672 }
    673 
    674 void BytecodeGraphBuilder::VisitStaGlobalStrict() {
    675   BuildStoreGlobal(LanguageMode::STRICT);
    676 }
    677 
    678 Node* BytecodeGraphBuilder::BuildLoadContextSlot() {
    679   // TODO(mythria): LoadContextSlots are unrolled by the required depth when
    680   // generating bytecode. Hence the value of depth is always 0. Update this
    681   // code, when the implementation changes.
    682   // TODO(mythria): immutable flag is also set to false. This information is not
    683   // available in bytecode array. update this code when the implementation
    684   // changes.
    685   const Operator* op = javascript()->LoadContext(
    686       0, bytecode_iterator().GetIndexOperand(1), false);
    687   Node* context =
    688       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
    689   return NewNode(op, context);
    690 }
    691 
    692 void BytecodeGraphBuilder::VisitLdaContextSlot() {
    693   Node* node = BuildLoadContextSlot();
    694   environment()->BindAccumulator(node);
    695 }
    696 
    697 void BytecodeGraphBuilder::VisitLdrContextSlot() {
    698   Node* node = BuildLoadContextSlot();
    699   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(2), node);
    700 }
    701 
    702 void BytecodeGraphBuilder::VisitStaContextSlot() {
    703   // TODO(mythria): LoadContextSlots are unrolled by the required depth when
    704   // generating bytecode. Hence the value of depth is always 0. Update this
    705   // code, when the implementation changes.
    706   const Operator* op =
    707       javascript()->StoreContext(0, bytecode_iterator().GetIndexOperand(1));
    708   Node* context =
    709       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
    710   Node* value = environment()->LookupAccumulator();
    711   NewNode(op, context, value);
    712 }
    713 
    714 void BytecodeGraphBuilder::BuildLdaLookupSlot(TypeofMode typeof_mode) {
    715   FrameStateBeforeAndAfter states(this);
    716   Node* name =
    717       jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
    718   const Operator* op =
    719       javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
    720                                     ? Runtime::kLoadLookupSlot
    721                                     : Runtime::kLoadLookupSlotInsideTypeof);
    722   Node* value = NewNode(op, name);
    723   environment()->BindAccumulator(value, &states);
    724 }
    725 
    726 void BytecodeGraphBuilder::VisitLdaLookupSlot() {
    727   BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF);
    728 }
    729 
    730 void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() {
    731   BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF);
    732 }
    733 
    734 void BytecodeGraphBuilder::BuildStaLookupSlot(LanguageMode language_mode) {
    735   FrameStateBeforeAndAfter states(this);
    736   Node* value = environment()->LookupAccumulator();
    737   Node* name =
    738       jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
    739   const Operator* op = javascript()->CallRuntime(
    740       is_strict(language_mode) ? Runtime::kStoreLookupSlot_Strict
    741                                : Runtime::kStoreLookupSlot_Sloppy);
    742   Node* store = NewNode(op, name, value);
    743   environment()->BindAccumulator(store, &states);
    744 }
    745 
    746 void BytecodeGraphBuilder::VisitStaLookupSlotSloppy() {
    747   BuildStaLookupSlot(LanguageMode::SLOPPY);
    748 }
    749 
    750 void BytecodeGraphBuilder::VisitStaLookupSlotStrict() {
    751   BuildStaLookupSlot(LanguageMode::STRICT);
    752 }
    753 
    754 Node* BytecodeGraphBuilder::BuildNamedLoad() {
    755   Node* object =
    756       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
    757   Handle<Name> name =
    758       Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(1));
    759   VectorSlotPair feedback =
    760       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
    761 
    762   const Operator* op = javascript()->LoadNamed(name, feedback);
    763   return NewNode(op, object, GetFunctionClosure());
    764 }
    765 
    766 void BytecodeGraphBuilder::VisitLdaNamedProperty() {
    767   FrameStateBeforeAndAfter states(this);
    768   Node* node = BuildNamedLoad();
    769   environment()->BindAccumulator(node, &states);
    770 }
    771 
    772 void BytecodeGraphBuilder::VisitLdrNamedProperty() {
    773   FrameStateBeforeAndAfter states(this);
    774   Node* node = BuildNamedLoad();
    775   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3), node,
    776                               &states);
    777 }
    778 
    779 Node* BytecodeGraphBuilder::BuildKeyedLoad() {
    780   Node* key = environment()->LookupAccumulator();
    781   Node* object =
    782       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
    783   VectorSlotPair feedback =
    784       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
    785 
    786   const Operator* op = javascript()->LoadProperty(feedback);
    787   return NewNode(op, object, key, GetFunctionClosure());
    788 }
    789 
    790 void BytecodeGraphBuilder::VisitLdaKeyedProperty() {
    791   FrameStateBeforeAndAfter states(this);
    792   Node* node = BuildKeyedLoad();
    793   environment()->BindAccumulator(node, &states);
    794 }
    795 
    796 void BytecodeGraphBuilder::VisitLdrKeyedProperty() {
    797   FrameStateBeforeAndAfter states(this);
    798   Node* node = BuildKeyedLoad();
    799   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(2), node,
    800                               &states);
    801 }
    802 
    803 void BytecodeGraphBuilder::BuildNamedStore(LanguageMode language_mode) {
    804   FrameStateBeforeAndAfter states(this);
    805   Node* value = environment()->LookupAccumulator();
    806   Node* object =
    807       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
    808   Handle<Name> name =
    809       Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(1));
    810   VectorSlotPair feedback =
    811       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
    812 
    813   const Operator* op = javascript()->StoreNamed(language_mode, name, feedback);
    814   Node* node = NewNode(op, object, value, GetFunctionClosure());
    815   environment()->RecordAfterState(node, &states);
    816 }
    817 
    818 void BytecodeGraphBuilder::VisitStaNamedPropertySloppy() {
    819   BuildNamedStore(LanguageMode::SLOPPY);
    820 }
    821 
    822 void BytecodeGraphBuilder::VisitStaNamedPropertyStrict() {
    823   BuildNamedStore(LanguageMode::STRICT);
    824 }
    825 
    826 void BytecodeGraphBuilder::BuildKeyedStore(LanguageMode language_mode) {
    827   FrameStateBeforeAndAfter states(this);
    828   Node* value = environment()->LookupAccumulator();
    829   Node* object =
    830       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
    831   Node* key =
    832       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
    833   VectorSlotPair feedback =
    834       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
    835 
    836   const Operator* op = javascript()->StoreProperty(language_mode, feedback);
    837   Node* node = NewNode(op, object, key, value, GetFunctionClosure());
    838   environment()->RecordAfterState(node, &states);
    839 }
    840 
    841 void BytecodeGraphBuilder::VisitStaKeyedPropertySloppy() {
    842   BuildKeyedStore(LanguageMode::SLOPPY);
    843 }
    844 
    845 void BytecodeGraphBuilder::VisitStaKeyedPropertyStrict() {
    846   BuildKeyedStore(LanguageMode::STRICT);
    847 }
    848 
    849 void BytecodeGraphBuilder::VisitPushContext() {
    850   Node* new_context = environment()->LookupAccumulator();
    851   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0),
    852                               environment()->Context());
    853   environment()->SetContext(new_context);
    854 }
    855 
    856 void BytecodeGraphBuilder::VisitPopContext() {
    857   Node* context =
    858       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
    859   environment()->SetContext(context);
    860 }
    861 
    862 void BytecodeGraphBuilder::VisitCreateClosure() {
    863   Handle<SharedFunctionInfo> shared_info = Handle<SharedFunctionInfo>::cast(
    864       bytecode_iterator().GetConstantForIndexOperand(0));
    865   PretenureFlag tenured =
    866       bytecode_iterator().GetFlagOperand(1) ? TENURED : NOT_TENURED;
    867   const Operator* op = javascript()->CreateClosure(shared_info, tenured);
    868   Node* closure = NewNode(op);
    869   environment()->BindAccumulator(closure);
    870 }
    871 
    872 void BytecodeGraphBuilder::BuildCreateArguments(CreateArgumentsType type) {
    873   FrameStateBeforeAndAfter states(this);
    874   const Operator* op = javascript()->CreateArguments(type);
    875   Node* object = NewNode(op, GetFunctionClosure());
    876   environment()->BindAccumulator(object, &states);
    877 }
    878 
    879 void BytecodeGraphBuilder::VisitCreateMappedArguments() {
    880   BuildCreateArguments(CreateArgumentsType::kMappedArguments);
    881 }
    882 
    883 void BytecodeGraphBuilder::VisitCreateUnmappedArguments() {
    884   BuildCreateArguments(CreateArgumentsType::kUnmappedArguments);
    885 }
    886 
    887 void BytecodeGraphBuilder::VisitCreateRestParameter() {
    888   BuildCreateArguments(CreateArgumentsType::kRestParameter);
    889 }
    890 
    891 void BytecodeGraphBuilder::BuildCreateLiteral(const Operator* op) {
    892   FrameStateBeforeAndAfter states(this);
    893   Node* literal = NewNode(op, GetFunctionClosure());
    894   environment()->BindAccumulator(literal, &states);
    895 }
    896 
    897 void BytecodeGraphBuilder::VisitCreateRegExpLiteral() {
    898   Handle<String> constant_pattern =
    899       Handle<String>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
    900   int literal_index = bytecode_iterator().GetIndexOperand(1);
    901   int literal_flags = bytecode_iterator().GetFlagOperand(2);
    902   const Operator* op = javascript()->CreateLiteralRegExp(
    903       constant_pattern, literal_flags, literal_index);
    904   BuildCreateLiteral(op);
    905 }
    906 
    907 void BytecodeGraphBuilder::VisitCreateArrayLiteral() {
    908   Handle<FixedArray> constant_elements = Handle<FixedArray>::cast(
    909       bytecode_iterator().GetConstantForIndexOperand(0));
    910   int literal_index = bytecode_iterator().GetIndexOperand(1);
    911   int literal_flags = bytecode_iterator().GetFlagOperand(2);
    912   int number_of_elements = constant_elements->length();
    913   const Operator* op = javascript()->CreateLiteralArray(
    914       constant_elements, literal_flags, literal_index, number_of_elements);
    915   BuildCreateLiteral(op);
    916 }
    917 
    918 void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
    919   Handle<FixedArray> constant_properties = Handle<FixedArray>::cast(
    920       bytecode_iterator().GetConstantForIndexOperand(0));
    921   int literal_index = bytecode_iterator().GetIndexOperand(1);
    922   int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
    923   int literal_flags =
    924       interpreter::CreateObjectLiteralFlags::FlagsBits::decode(bytecode_flags);
    925   // TODO(mstarzinger): Thread through number of properties.
    926   int number_of_properties = constant_properties->length() / 2;
    927   const Operator* op = javascript()->CreateLiteralObject(
    928       constant_properties, literal_flags, literal_index, number_of_properties);
    929   BuildCreateLiteral(op);
    930 }
    931 
    932 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
    933                                                  Node* callee,
    934                                                  interpreter::Register receiver,
    935                                                  size_t arity) {
    936   Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity));
    937   all[0] = callee;
    938   all[1] = environment()->LookupRegister(receiver);
    939   int receiver_index = receiver.index();
    940   for (int i = 2; i < static_cast<int>(arity); ++i) {
    941     all[i] = environment()->LookupRegister(
    942         interpreter::Register(receiver_index + i - 1));
    943   }
    944   Node* value = MakeNode(call_op, static_cast<int>(arity), all, false);
    945   return value;
    946 }
    947 
    948 void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode) {
    949   FrameStateBeforeAndAfter states(this);
    950   // TODO(rmcilroy): Set receiver_hint correctly based on whether the receiver
    951   // register has been loaded with null / undefined explicitly or we are sure it
    952   // is not null / undefined.
    953   ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny;
    954   Node* callee =
    955       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
    956   interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
    957   size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
    958   VectorSlotPair feedback =
    959       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(3));
    960 
    961   const Operator* call = javascript()->CallFunction(
    962       arg_count + 1, feedback, receiver_hint, tail_call_mode);
    963   Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
    964   environment()->BindAccumulator(value, &states);
    965 }
    966 
    967 void BytecodeGraphBuilder::VisitCall() { BuildCall(TailCallMode::kDisallow); }
    968 
    969 void BytecodeGraphBuilder::VisitTailCall() {
    970   TailCallMode tail_call_mode =
    971       bytecode_array_->GetIsolate()->is_tail_call_elimination_enabled()
    972           ? TailCallMode::kAllow
    973           : TailCallMode::kDisallow;
    974   BuildCall(tail_call_mode);
    975 }
    976 
    977 void BytecodeGraphBuilder::VisitCallJSRuntime() {
    978   FrameStateBeforeAndAfter states(this);
    979   Node* callee =
    980       BuildLoadNativeContextField(bytecode_iterator().GetIndexOperand(0));
    981   interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
    982   size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
    983 
    984   // Create node to perform the JS runtime call.
    985   const Operator* call = javascript()->CallFunction(arg_count + 1);
    986   Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
    987   environment()->BindAccumulator(value, &states);
    988 }
    989 
    990 Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
    991     const Operator* call_runtime_op, interpreter::Register first_arg,
    992     size_t arity) {
    993   Node** all = local_zone()->NewArray<Node*>(arity);
    994   int first_arg_index = first_arg.index();
    995   for (int i = 0; i < static_cast<int>(arity); ++i) {
    996     all[i] = environment()->LookupRegister(
    997         interpreter::Register(first_arg_index + i));
    998   }
    999   Node* value = MakeNode(call_runtime_op, static_cast<int>(arity), all, false);
   1000   return value;
   1001 }
   1002 
   1003 void BytecodeGraphBuilder::VisitCallRuntime() {
   1004   FrameStateBeforeAndAfter states(this);
   1005   Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
   1006   interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
   1007   size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
   1008 
   1009   // Create node to perform the runtime call.
   1010   const Operator* call = javascript()->CallRuntime(functionId, arg_count);
   1011   Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
   1012   environment()->BindAccumulator(value, &states);
   1013 }
   1014 
   1015 void BytecodeGraphBuilder::VisitCallRuntimeForPair() {
   1016   FrameStateBeforeAndAfter states(this);
   1017   Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
   1018   interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
   1019   size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
   1020   interpreter::Register first_return =
   1021       bytecode_iterator().GetRegisterOperand(3);
   1022 
   1023   // Create node to perform the runtime call.
   1024   const Operator* call = javascript()->CallRuntime(functionId, arg_count);
   1025   Node* return_pair = ProcessCallRuntimeArguments(call, first_arg, arg_count);
   1026   environment()->BindRegistersToProjections(first_return, return_pair, &states);
   1027 }
   1028 
   1029 void BytecodeGraphBuilder::VisitInvokeIntrinsic() {
   1030   FrameStateBeforeAndAfter states(this);
   1031   Runtime::FunctionId functionId = bytecode_iterator().GetIntrinsicIdOperand(0);
   1032   interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
   1033   size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
   1034 
   1035   // Create node to perform the runtime call. Turbofan will take care of the
   1036   // lowering.
   1037   const Operator* call = javascript()->CallRuntime(functionId, arg_count);
   1038   Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
   1039   environment()->BindAccumulator(value, &states);
   1040 }
   1041 
   1042 Node* BytecodeGraphBuilder::ProcessCallNewArguments(
   1043     const Operator* call_new_op, Node* callee, Node* new_target,
   1044     interpreter::Register first_arg, size_t arity) {
   1045   Node** all = local_zone()->NewArray<Node*>(arity);
   1046   all[0] = new_target;
   1047   int first_arg_index = first_arg.index();
   1048   for (int i = 1; i < static_cast<int>(arity) - 1; ++i) {
   1049     all[i] = environment()->LookupRegister(
   1050         interpreter::Register(first_arg_index + i - 1));
   1051   }
   1052   all[arity - 1] = callee;
   1053   Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false);
   1054   return value;
   1055 }
   1056 
   1057 void BytecodeGraphBuilder::VisitNew() {
   1058   FrameStateBeforeAndAfter states(this);
   1059   interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
   1060   interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
   1061   size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
   1062 
   1063   Node* new_target = environment()->LookupAccumulator();
   1064   Node* callee = environment()->LookupRegister(callee_reg);
   1065   // TODO(turbofan): Pass the feedback here.
   1066   const Operator* call = javascript()->CallConstruct(
   1067       static_cast<int>(arg_count) + 2, VectorSlotPair());
   1068   Node* value = ProcessCallNewArguments(call, callee, new_target, first_arg,
   1069                                         arg_count + 2);
   1070   environment()->BindAccumulator(value, &states);
   1071 }
   1072 
   1073 void BytecodeGraphBuilder::BuildThrow() {
   1074   FrameStateBeforeAndAfter states(this);
   1075   Node* value = environment()->LookupAccumulator();
   1076   Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value);
   1077   environment()->BindAccumulator(call, &states);
   1078 }
   1079 
   1080 void BytecodeGraphBuilder::VisitThrow() {
   1081   BuildThrow();
   1082   Node* call = environment()->LookupAccumulator();
   1083   Node* control = NewNode(common()->Throw(), call);
   1084   MergeControlToLeaveFunction(control);
   1085 }
   1086 
   1087 void BytecodeGraphBuilder::VisitReThrow() {
   1088   Node* value = environment()->LookupAccumulator();
   1089   Node* call = NewNode(javascript()->CallRuntime(Runtime::kReThrow), value);
   1090   Node* control = NewNode(common()->Throw(), call);
   1091   MergeControlToLeaveFunction(control);
   1092 }
   1093 
   1094 void BytecodeGraphBuilder::BuildBinaryOp(const Operator* js_op) {
   1095   FrameStateBeforeAndAfter states(this);
   1096   Node* left =
   1097       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1098   Node* right = environment()->LookupAccumulator();
   1099   Node* node = NewNode(js_op, left, right);
   1100   environment()->BindAccumulator(node, &states);
   1101 }
   1102 
   1103 void BytecodeGraphBuilder::VisitAdd() {
   1104   BinaryOperationHints hints = BinaryOperationHints::Any();
   1105   BuildBinaryOp(javascript()->Add(hints));
   1106 }
   1107 
   1108 void BytecodeGraphBuilder::VisitSub() {
   1109   BinaryOperationHints hints = BinaryOperationHints::Any();
   1110   BuildBinaryOp(javascript()->Subtract(hints));
   1111 }
   1112 
   1113 void BytecodeGraphBuilder::VisitMul() {
   1114   BinaryOperationHints hints = BinaryOperationHints::Any();
   1115   BuildBinaryOp(javascript()->Multiply(hints));
   1116 }
   1117 
   1118 void BytecodeGraphBuilder::VisitDiv() {
   1119   BinaryOperationHints hints = BinaryOperationHints::Any();
   1120   BuildBinaryOp(javascript()->Divide(hints));
   1121 }
   1122 
   1123 void BytecodeGraphBuilder::VisitMod() {
   1124   BinaryOperationHints hints = BinaryOperationHints::Any();
   1125   BuildBinaryOp(javascript()->Modulus(hints));
   1126 }
   1127 
   1128 void BytecodeGraphBuilder::VisitBitwiseOr() {
   1129   BinaryOperationHints hints = BinaryOperationHints::Any();
   1130   BuildBinaryOp(javascript()->BitwiseOr(hints));
   1131 }
   1132 
   1133 void BytecodeGraphBuilder::VisitBitwiseXor() {
   1134   BinaryOperationHints hints = BinaryOperationHints::Any();
   1135   BuildBinaryOp(javascript()->BitwiseXor(hints));
   1136 }
   1137 
   1138 void BytecodeGraphBuilder::VisitBitwiseAnd() {
   1139   BinaryOperationHints hints = BinaryOperationHints::Any();
   1140   BuildBinaryOp(javascript()->BitwiseAnd(hints));
   1141 }
   1142 
   1143 void BytecodeGraphBuilder::VisitShiftLeft() {
   1144   BinaryOperationHints hints = BinaryOperationHints::Any();
   1145   BuildBinaryOp(javascript()->ShiftLeft(hints));
   1146 }
   1147 
   1148 void BytecodeGraphBuilder::VisitShiftRight() {
   1149   BinaryOperationHints hints = BinaryOperationHints::Any();
   1150   BuildBinaryOp(javascript()->ShiftRight(hints));
   1151 }
   1152 
   1153 void BytecodeGraphBuilder::VisitShiftRightLogical() {
   1154   BinaryOperationHints hints = BinaryOperationHints::Any();
   1155   BuildBinaryOp(javascript()->ShiftRightLogical(hints));
   1156 }
   1157 
   1158 void BytecodeGraphBuilder::VisitInc() {
   1159   FrameStateBeforeAndAfter states(this);
   1160   // Note: Use subtract -1 here instead of add 1 to ensure we always convert to
   1161   // a number, not a string.
   1162   const Operator* js_op = javascript()->Subtract(BinaryOperationHints::Any());
   1163   Node* node = NewNode(js_op, environment()->LookupAccumulator(),
   1164                        jsgraph()->Constant(-1.0));
   1165   environment()->BindAccumulator(node, &states);
   1166 }
   1167 
   1168 void BytecodeGraphBuilder::VisitDec() {
   1169   FrameStateBeforeAndAfter states(this);
   1170   const Operator* js_op = javascript()->Subtract(BinaryOperationHints::Any());
   1171   Node* node = NewNode(js_op, environment()->LookupAccumulator(),
   1172                        jsgraph()->OneConstant());
   1173   environment()->BindAccumulator(node, &states);
   1174 }
   1175 
   1176 void BytecodeGraphBuilder::VisitLogicalNot() {
   1177   Node* value = environment()->LookupAccumulator();
   1178   Node* node = NewNode(common()->Select(MachineRepresentation::kTagged), value,
   1179                        jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
   1180   environment()->BindAccumulator(node);
   1181 }
   1182 
   1183 void BytecodeGraphBuilder::VisitToBooleanLogicalNot() {
   1184   Node* value = NewNode(javascript()->ToBoolean(ToBooleanHint::kAny),
   1185                         environment()->LookupAccumulator());
   1186   Node* node = NewNode(common()->Select(MachineRepresentation::kTagged), value,
   1187                        jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
   1188   environment()->BindAccumulator(node);
   1189 }
   1190 
   1191 void BytecodeGraphBuilder::VisitTypeOf() {
   1192   Node* node =
   1193       NewNode(javascript()->TypeOf(), environment()->LookupAccumulator());
   1194   environment()->BindAccumulator(node);
   1195 }
   1196 
   1197 void BytecodeGraphBuilder::BuildDelete(LanguageMode language_mode) {
   1198   FrameStateBeforeAndAfter states(this);
   1199   Node* key = environment()->LookupAccumulator();
   1200   Node* object =
   1201       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1202   Node* node =
   1203       NewNode(javascript()->DeleteProperty(language_mode), object, key);
   1204   environment()->BindAccumulator(node, &states);
   1205 }
   1206 
   1207 void BytecodeGraphBuilder::VisitDeletePropertyStrict() {
   1208   BuildDelete(LanguageMode::STRICT);
   1209 }
   1210 
   1211 void BytecodeGraphBuilder::VisitDeletePropertySloppy() {
   1212   BuildDelete(LanguageMode::SLOPPY);
   1213 }
   1214 
   1215 void BytecodeGraphBuilder::BuildCompareOp(const Operator* js_op) {
   1216   FrameStateBeforeAndAfter states(this);
   1217   Node* left =
   1218       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1219   Node* right = environment()->LookupAccumulator();
   1220   Node* node = NewNode(js_op, left, right);
   1221   environment()->BindAccumulator(node, &states);
   1222 }
   1223 
   1224 void BytecodeGraphBuilder::VisitTestEqual() {
   1225   CompareOperationHints hints = CompareOperationHints::Any();
   1226   BuildCompareOp(javascript()->Equal(hints));
   1227 }
   1228 
   1229 void BytecodeGraphBuilder::VisitTestNotEqual() {
   1230   CompareOperationHints hints = CompareOperationHints::Any();
   1231   BuildCompareOp(javascript()->NotEqual(hints));
   1232 }
   1233 
   1234 void BytecodeGraphBuilder::VisitTestEqualStrict() {
   1235   CompareOperationHints hints = CompareOperationHints::Any();
   1236   BuildCompareOp(javascript()->StrictEqual(hints));
   1237 }
   1238 
   1239 void BytecodeGraphBuilder::VisitTestLessThan() {
   1240   CompareOperationHints hints = CompareOperationHints::Any();
   1241   BuildCompareOp(javascript()->LessThan(hints));
   1242 }
   1243 
   1244 void BytecodeGraphBuilder::VisitTestGreaterThan() {
   1245   CompareOperationHints hints = CompareOperationHints::Any();
   1246   BuildCompareOp(javascript()->GreaterThan(hints));
   1247 }
   1248 
   1249 void BytecodeGraphBuilder::VisitTestLessThanOrEqual() {
   1250   CompareOperationHints hints = CompareOperationHints::Any();
   1251   BuildCompareOp(javascript()->LessThanOrEqual(hints));
   1252 }
   1253 
   1254 void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual() {
   1255   CompareOperationHints hints = CompareOperationHints::Any();
   1256   BuildCompareOp(javascript()->GreaterThanOrEqual(hints));
   1257 }
   1258 
   1259 void BytecodeGraphBuilder::VisitTestIn() {
   1260   BuildCompareOp(javascript()->HasProperty());
   1261 }
   1262 
   1263 void BytecodeGraphBuilder::VisitTestInstanceOf() {
   1264   BuildCompareOp(javascript()->InstanceOf());
   1265 }
   1266 
   1267 void BytecodeGraphBuilder::BuildCastOperator(const Operator* js_op) {
   1268   FrameStateBeforeAndAfter states(this);
   1269   Node* node = NewNode(js_op, environment()->LookupAccumulator());
   1270   environment()->BindAccumulator(node, &states);
   1271 }
   1272 
   1273 void BytecodeGraphBuilder::VisitToName() {
   1274   BuildCastOperator(javascript()->ToName());
   1275 }
   1276 
   1277 void BytecodeGraphBuilder::VisitToObject() {
   1278   BuildCastOperator(javascript()->ToObject());
   1279 }
   1280 
   1281 void BytecodeGraphBuilder::VisitToNumber() {
   1282   BuildCastOperator(javascript()->ToNumber());
   1283 }
   1284 
   1285 void BytecodeGraphBuilder::VisitJump() { BuildJump(); }
   1286 
   1287 void BytecodeGraphBuilder::VisitJumpConstant() { BuildJump(); }
   1288 
   1289 
   1290 void BytecodeGraphBuilder::VisitJumpIfTrue() {
   1291   BuildJumpIfEqual(jsgraph()->TrueConstant());
   1292 }
   1293 
   1294 void BytecodeGraphBuilder::VisitJumpIfTrueConstant() {
   1295   BuildJumpIfEqual(jsgraph()->TrueConstant());
   1296 }
   1297 
   1298 void BytecodeGraphBuilder::VisitJumpIfFalse() {
   1299   BuildJumpIfEqual(jsgraph()->FalseConstant());
   1300 }
   1301 
   1302 void BytecodeGraphBuilder::VisitJumpIfFalseConstant() {
   1303   BuildJumpIfEqual(jsgraph()->FalseConstant());
   1304 }
   1305 
   1306 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue() {
   1307   BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
   1308 }
   1309 
   1310 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant() {
   1311   BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
   1312 }
   1313 
   1314 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse() {
   1315   BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
   1316 }
   1317 
   1318 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant() {
   1319   BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
   1320 }
   1321 
   1322 void BytecodeGraphBuilder::VisitJumpIfNotHole() { BuildJumpIfNotHole(); }
   1323 
   1324 void BytecodeGraphBuilder::VisitJumpIfNotHoleConstant() {
   1325   BuildJumpIfNotHole();
   1326 }
   1327 
   1328 void BytecodeGraphBuilder::VisitJumpIfNull() {
   1329   BuildJumpIfEqual(jsgraph()->NullConstant());
   1330 }
   1331 
   1332 void BytecodeGraphBuilder::VisitJumpIfNullConstant() {
   1333   BuildJumpIfEqual(jsgraph()->NullConstant());
   1334 }
   1335 
   1336 void BytecodeGraphBuilder::VisitJumpIfUndefined() {
   1337   BuildJumpIfEqual(jsgraph()->UndefinedConstant());
   1338 }
   1339 
   1340 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant() {
   1341   BuildJumpIfEqual(jsgraph()->UndefinedConstant());
   1342 }
   1343 
   1344 void BytecodeGraphBuilder::VisitStackCheck() {
   1345   FrameStateBeforeAndAfter states(this);
   1346   Node* node = NewNode(javascript()->StackCheck());
   1347   environment()->RecordAfterState(node, &states);
   1348 }
   1349 
   1350 void BytecodeGraphBuilder::VisitReturn() {
   1351   Node* control =
   1352       NewNode(common()->Return(), environment()->LookupAccumulator());
   1353   MergeControlToLeaveFunction(control);
   1354 }
   1355 
   1356 void BytecodeGraphBuilder::VisitDebugger() {
   1357   FrameStateBeforeAndAfter states(this);
   1358   Node* call =
   1359       NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement));
   1360   environment()->BindAccumulator(call, &states);
   1361 }
   1362 
   1363 // We cannot create a graph from the debugger copy of the bytecode array.
   1364 #define DEBUG_BREAK(Name, ...) \
   1365   void BytecodeGraphBuilder::Visit##Name() { UNREACHABLE(); }
   1366 DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK);
   1367 #undef DEBUG_BREAK
   1368 
   1369 void BytecodeGraphBuilder::BuildForInPrepare() {
   1370   FrameStateBeforeAndAfter states(this);
   1371   Node* receiver = environment()->LookupAccumulator();
   1372   Node* prepare = NewNode(javascript()->ForInPrepare(), receiver);
   1373   environment()->BindRegistersToProjections(
   1374       bytecode_iterator().GetRegisterOperand(0), prepare, &states);
   1375 }
   1376 
   1377 void BytecodeGraphBuilder::VisitForInPrepare() { BuildForInPrepare(); }
   1378 
   1379 void BytecodeGraphBuilder::VisitForInDone() {
   1380   FrameStateBeforeAndAfter states(this);
   1381   Node* index =
   1382       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1383   Node* cache_length =
   1384       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
   1385   Node* exit_cond = NewNode(javascript()->ForInDone(), index, cache_length);
   1386   environment()->BindAccumulator(exit_cond, &states);
   1387 }
   1388 
   1389 void BytecodeGraphBuilder::BuildForInNext() {
   1390   FrameStateBeforeAndAfter states(this);
   1391   Node* receiver =
   1392       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1393   Node* index =
   1394       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
   1395   int catch_reg_pair_index = bytecode_iterator().GetRegisterOperand(2).index();
   1396   Node* cache_type = environment()->LookupRegister(
   1397       interpreter::Register(catch_reg_pair_index));
   1398   Node* cache_array = environment()->LookupRegister(
   1399       interpreter::Register(catch_reg_pair_index + 1));
   1400 
   1401   Node* value = NewNode(javascript()->ForInNext(), receiver, cache_array,
   1402                         cache_type, index);
   1403   environment()->BindAccumulator(value, &states);
   1404 }
   1405 
   1406 void BytecodeGraphBuilder::VisitForInNext() { BuildForInNext(); }
   1407 
   1408 void BytecodeGraphBuilder::VisitForInStep() {
   1409   FrameStateBeforeAndAfter states(this);
   1410   Node* index =
   1411       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1412   index = NewNode(javascript()->ForInStep(), index);
   1413   environment()->BindAccumulator(index, &states);
   1414 }
   1415 
   1416 void BytecodeGraphBuilder::VisitSuspendGenerator() {
   1417   Node* state = environment()->LookupAccumulator();
   1418   Node* generator = environment()->LookupRegister(
   1419       bytecode_iterator().GetRegisterOperand(0));
   1420   // The offsets used by the bytecode iterator are relative to a different base
   1421   // than what is used in the interpreter, hence the addition.
   1422   Node* offset =
   1423       jsgraph()->Constant(bytecode_iterator().current_offset() +
   1424                           (BytecodeArray::kHeaderSize - kHeapObjectTag));
   1425 
   1426   int register_count = environment()->register_count();
   1427   int value_input_count = 3 + register_count;
   1428 
   1429   Node** value_inputs = local_zone()->NewArray<Node*>(value_input_count);
   1430   value_inputs[0] = generator;
   1431   value_inputs[1] = state;
   1432   value_inputs[2] = offset;
   1433   for (int i = 0; i < register_count; ++i) {
   1434     value_inputs[3 + i] =
   1435         environment()->LookupRegister(interpreter::Register(i));
   1436   }
   1437 
   1438   MakeNode(javascript()->GeneratorStore(register_count), value_input_count,
   1439            value_inputs, false);
   1440 }
   1441 
   1442 void BytecodeGraphBuilder::VisitResumeGenerator() {
   1443   FrameStateBeforeAndAfter states(this);
   1444 
   1445   Node* generator = environment()->LookupRegister(
   1446       bytecode_iterator().GetRegisterOperand(0));
   1447 
   1448   // Bijection between registers and array indices must match that used in
   1449   // InterpreterAssembler::ExportRegisterFile.
   1450   for (int i = 0; i < environment()->register_count(); ++i) {
   1451     Node* value = NewNode(javascript()->GeneratorRestoreRegister(i), generator);
   1452     environment()->BindRegister(interpreter::Register(i), value);
   1453   }
   1454 
   1455   Node* state =
   1456       NewNode(javascript()->GeneratorRestoreContinuation(), generator);
   1457 
   1458   environment()->BindAccumulator(state, &states);
   1459 }
   1460 
   1461 void BytecodeGraphBuilder::VisitWide() {
   1462   // Consumed by the BytecodeArrayIterator.
   1463   UNREACHABLE();
   1464 }
   1465 
   1466 void BytecodeGraphBuilder::VisitExtraWide() {
   1467   // Consumed by the BytecodeArrayIterator.
   1468   UNREACHABLE();
   1469 }
   1470 
   1471 void BytecodeGraphBuilder::VisitIllegal() {
   1472   // Not emitted in valid bytecode.
   1473   UNREACHABLE();
   1474 }
   1475 
   1476 void BytecodeGraphBuilder::VisitNop() {}
   1477 
   1478 void BytecodeGraphBuilder::SwitchToMergeEnvironment(int current_offset) {
   1479   if (merge_environments_[current_offset] != nullptr) {
   1480     if (environment() != nullptr) {
   1481       merge_environments_[current_offset]->Merge(environment());
   1482     }
   1483     set_environment(merge_environments_[current_offset]);
   1484   }
   1485 }
   1486 
   1487 void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) {
   1488   if (branch_analysis()->backward_branches_target(current_offset)) {
   1489     // Add loop header and store a copy so we can connect merged back
   1490     // edge inputs to the loop header.
   1491     merge_environments_[current_offset] = environment()->CopyForLoop();
   1492   }
   1493 }
   1494 
   1495 void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(int target_offset) {
   1496   if (merge_environments_[target_offset] == nullptr) {
   1497     // Append merge nodes to the environment. We may merge here with another
   1498     // environment. So add a place holder for merge nodes. We may add redundant
   1499     // but will be eliminated in a later pass.
   1500     // TODO(mstarzinger): Be smarter about this!
   1501     NewMerge();
   1502     merge_environments_[target_offset] = environment();
   1503   } else {
   1504     merge_environments_[target_offset]->Merge(environment());
   1505   }
   1506   set_environment(nullptr);
   1507 }
   1508 
   1509 void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
   1510   exit_controls_.push_back(exit);
   1511   set_environment(nullptr);
   1512 }
   1513 
   1514 void BytecodeGraphBuilder::BuildJump() {
   1515   MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
   1516 }
   1517 
   1518 
   1519 void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) {
   1520   NewBranch(condition);
   1521   Environment* if_false_environment = environment()->CopyForConditional();
   1522   NewIfTrue();
   1523   MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
   1524   set_environment(if_false_environment);
   1525   NewIfFalse();
   1526 }
   1527 
   1528 
   1529 void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
   1530   Node* accumulator = environment()->LookupAccumulator();
   1531   Node* condition =
   1532       NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
   1533               accumulator, comperand);
   1534   BuildConditionalJump(condition);
   1535 }
   1536 
   1537 
   1538 void BytecodeGraphBuilder::BuildJumpIfToBooleanEqual(Node* comperand) {
   1539   Node* accumulator = environment()->LookupAccumulator();
   1540   Node* to_boolean =
   1541       NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
   1542   Node* condition =
   1543       NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
   1544               to_boolean, comperand);
   1545   BuildConditionalJump(condition);
   1546 }
   1547 
   1548 void BytecodeGraphBuilder::BuildJumpIfNotHole() {
   1549   Node* accumulator = environment()->LookupAccumulator();
   1550   Node* condition =
   1551       NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
   1552               accumulator, jsgraph()->TheHoleConstant());
   1553   Node* node =
   1554       NewNode(common()->Select(MachineRepresentation::kTagged), condition,
   1555               jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
   1556   BuildConditionalJump(node);
   1557 }
   1558 
   1559 Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) {
   1560   if (size > input_buffer_size_) {
   1561     size = size + kInputBufferSizeIncrement + input_buffer_size_;
   1562     input_buffer_ = local_zone()->NewArray<Node*>(size);
   1563     input_buffer_size_ = size;
   1564   }
   1565   return input_buffer_;
   1566 }
   1567 
   1568 void BytecodeGraphBuilder::EnterAndExitExceptionHandlers(int current_offset) {
   1569   Handle<HandlerTable> table = exception_handler_table();
   1570   int num_entries = table->NumberOfRangeEntries();
   1571 
   1572   // Potentially exit exception handlers.
   1573   while (!exception_handlers_.empty()) {
   1574     int current_end = exception_handlers_.top().end_offset_;
   1575     if (current_offset < current_end) break;  // Still covered by range.
   1576     exception_handlers_.pop();
   1577   }
   1578 
   1579   // Potentially enter exception handlers.
   1580   while (current_exception_handler_ < num_entries) {
   1581     int next_start = table->GetRangeStart(current_exception_handler_);
   1582     if (current_offset < next_start) break;  // Not yet covered by range.
   1583     int next_end = table->GetRangeEnd(current_exception_handler_);
   1584     int next_handler = table->GetRangeHandler(current_exception_handler_);
   1585     int context_register = table->GetRangeData(current_exception_handler_);
   1586     CatchPrediction pred =
   1587         table->GetRangePrediction(current_exception_handler_);
   1588     exception_handlers_.push(
   1589         {next_start, next_end, next_handler, context_register, pred});
   1590     current_exception_handler_++;
   1591   }
   1592 }
   1593 
   1594 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
   1595                                      Node** value_inputs, bool incomplete) {
   1596   DCHECK_EQ(op->ValueInputCount(), value_input_count);
   1597 
   1598   bool has_context = OperatorProperties::HasContextInput(op);
   1599   int frame_state_count = OperatorProperties::GetFrameStateInputCount(op);
   1600   bool has_control = op->ControlInputCount() == 1;
   1601   bool has_effect = op->EffectInputCount() == 1;
   1602 
   1603   DCHECK_LT(op->ControlInputCount(), 2);
   1604   DCHECK_LT(op->EffectInputCount(), 2);
   1605 
   1606   Node* result = nullptr;
   1607   if (!has_context && frame_state_count == 0 && !has_control && !has_effect) {
   1608     result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
   1609   } else {
   1610     bool inside_handler = !exception_handlers_.empty();
   1611     int input_count_with_deps = value_input_count;
   1612     if (has_context) ++input_count_with_deps;
   1613     input_count_with_deps += frame_state_count;
   1614     if (has_control) ++input_count_with_deps;
   1615     if (has_effect) ++input_count_with_deps;
   1616     Node** buffer = EnsureInputBufferSize(input_count_with_deps);
   1617     memcpy(buffer, value_inputs, kPointerSize * value_input_count);
   1618     Node** current_input = buffer + value_input_count;
   1619     if (has_context) {
   1620       *current_input++ = environment()->Context();
   1621     }
   1622     for (int i = 0; i < frame_state_count; i++) {
   1623       // The frame state will be inserted later. Here we misuse
   1624       // the {Dead} node as a sentinel to be later overwritten
   1625       // with the real frame state.
   1626       *current_input++ = jsgraph()->Dead();
   1627     }
   1628     if (has_effect) {
   1629       *current_input++ = environment()->GetEffectDependency();
   1630     }
   1631     if (has_control) {
   1632       *current_input++ = environment()->GetControlDependency();
   1633     }
   1634     result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
   1635     // Update the current control dependency for control-producing nodes.
   1636     if (NodeProperties::IsControl(result)) {
   1637       environment()->UpdateControlDependency(result);
   1638     }
   1639     // Update the current effect dependency for effect-producing nodes.
   1640     if (result->op()->EffectOutputCount() > 0) {
   1641       environment()->UpdateEffectDependency(result);
   1642     }
   1643     // Add implicit exception continuation for throwing nodes.
   1644     if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
   1645       int handler_offset = exception_handlers_.top().handler_offset_;
   1646       int context_index = exception_handlers_.top().context_register_;
   1647       CatchPrediction prediction = exception_handlers_.top().pred_;
   1648       interpreter::Register context_register(context_index);
   1649       IfExceptionHint hint = prediction == CatchPrediction::CAUGHT
   1650                                  ? IfExceptionHint::kLocallyCaught
   1651                                  : IfExceptionHint::kLocallyUncaught;
   1652       Environment* success_env = environment()->CopyForConditional();
   1653       const Operator* op = common()->IfException(hint);
   1654       Node* effect = environment()->GetEffectDependency();
   1655       Node* on_exception = graph()->NewNode(op, effect, result);
   1656       Node* context = environment()->LookupRegister(context_register);
   1657       environment()->UpdateControlDependency(on_exception);
   1658       environment()->UpdateEffectDependency(on_exception);
   1659       environment()->BindAccumulator(on_exception);
   1660       environment()->SetContext(context);
   1661       MergeIntoSuccessorEnvironment(handler_offset);
   1662       set_environment(success_env);
   1663     }
   1664     // Add implicit success continuation for throwing nodes.
   1665     if (!result->op()->HasProperty(Operator::kNoThrow)) {
   1666       const Operator* if_success = common()->IfSuccess();
   1667       Node* on_success = graph()->NewNode(if_success, result);
   1668       environment()->UpdateControlDependency(on_success);
   1669     }
   1670   }
   1671 
   1672   return result;
   1673 }
   1674 
   1675 
   1676 Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) {
   1677   const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
   1678   Node** buffer = EnsureInputBufferSize(count + 1);
   1679   MemsetPointer(buffer, input, count);
   1680   buffer[count] = control;
   1681   return graph()->NewNode(phi_op, count + 1, buffer, true);
   1682 }
   1683 
   1684 
   1685 Node* BytecodeGraphBuilder::NewEffectPhi(int count, Node* input,
   1686                                          Node* control) {
   1687   const Operator* phi_op = common()->EffectPhi(count);
   1688   Node** buffer = EnsureInputBufferSize(count + 1);
   1689   MemsetPointer(buffer, input, count);
   1690   buffer[count] = control;
   1691   return graph()->NewNode(phi_op, count + 1, buffer, true);
   1692 }
   1693 
   1694 
   1695 Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) {
   1696   int inputs = control->op()->ControlInputCount() + 1;
   1697   if (control->opcode() == IrOpcode::kLoop) {
   1698     // Control node for loop exists, add input.
   1699     const Operator* op = common()->Loop(inputs);
   1700     control->AppendInput(graph_zone(), other);
   1701     NodeProperties::ChangeOp(control, op);
   1702   } else if (control->opcode() == IrOpcode::kMerge) {
   1703     // Control node for merge exists, add input.
   1704     const Operator* op = common()->Merge(inputs);
   1705     control->AppendInput(graph_zone(), other);
   1706     NodeProperties::ChangeOp(control, op);
   1707   } else {
   1708     // Control node is a singleton, introduce a merge.
   1709     const Operator* op = common()->Merge(inputs);
   1710     Node* merge_inputs[] = {control, other};
   1711     control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true);
   1712   }
   1713   return control;
   1714 }
   1715 
   1716 
   1717 Node* BytecodeGraphBuilder::MergeEffect(Node* value, Node* other,
   1718                                         Node* control) {
   1719   int inputs = control->op()->ControlInputCount();
   1720   if (value->opcode() == IrOpcode::kEffectPhi &&
   1721       NodeProperties::GetControlInput(value) == control) {
   1722     // Phi already exists, add input.
   1723     value->InsertInput(graph_zone(), inputs - 1, other);
   1724     NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
   1725   } else if (value != other) {
   1726     // Phi does not exist yet, introduce one.
   1727     value = NewEffectPhi(inputs, value, control);
   1728     value->ReplaceInput(inputs - 1, other);
   1729   }
   1730   return value;
   1731 }
   1732 
   1733 
   1734 Node* BytecodeGraphBuilder::MergeValue(Node* value, Node* other,
   1735                                        Node* control) {
   1736   int inputs = control->op()->ControlInputCount();
   1737   if (value->opcode() == IrOpcode::kPhi &&
   1738       NodeProperties::GetControlInput(value) == control) {
   1739     // Phi already exists, add input.
   1740     value->InsertInput(graph_zone(), inputs - 1, other);
   1741     NodeProperties::ChangeOp(
   1742         value, common()->Phi(MachineRepresentation::kTagged, inputs));
   1743   } else if (value != other) {
   1744     // Phi does not exist yet, introduce one.
   1745     value = NewPhi(inputs, value, control);
   1746     value->ReplaceInput(inputs - 1, other);
   1747   }
   1748   return value;
   1749 }
   1750 
   1751 }  // namespace compiler
   1752 }  // namespace internal
   1753 }  // namespace v8
   1754