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 // Helper for generating frame states for before and after a bytecode.
     17 class BytecodeGraphBuilder::FrameStateBeforeAndAfter {
     18  public:
     19   FrameStateBeforeAndAfter(BytecodeGraphBuilder* builder,
     20                            const interpreter::BytecodeArrayIterator& iterator)
     21       : builder_(builder),
     22         id_after_(BailoutId::None()),
     23         added_to_node_(false),
     24         output_poke_offset_(0),
     25         output_poke_count_(0) {
     26     BailoutId id_before(iterator.current_offset());
     27     frame_state_before_ = builder_->environment()->Checkpoint(
     28         id_before, OutputFrameStateCombine::Ignore());
     29     id_after_ = BailoutId(id_before.ToInt() + iterator.current_bytecode_size());
     30   }
     31 
     32   ~FrameStateBeforeAndAfter() {
     33     DCHECK(added_to_node_);
     34     DCHECK(builder_->environment()->StateValuesAreUpToDate(output_poke_offset_,
     35                                                            output_poke_count_));
     36   }
     37 
     38  private:
     39   friend class Environment;
     40 
     41   void AddToNode(Node* node, OutputFrameStateCombine combine) {
     42     DCHECK(!added_to_node_);
     43     int count = OperatorProperties::GetFrameStateInputCount(node->op());
     44     DCHECK_LE(count, 2);
     45     if (count >= 1) {
     46       // Add the frame state for after the operation.
     47       DCHECK_EQ(IrOpcode::kDead,
     48                 NodeProperties::GetFrameStateInput(node, 0)->opcode());
     49       Node* frame_state_after =
     50           builder_->environment()->Checkpoint(id_after_, combine);
     51       NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after);
     52     }
     53 
     54     if (count >= 2) {
     55       // Add the frame state for before the operation.
     56       DCHECK_EQ(IrOpcode::kDead,
     57                 NodeProperties::GetFrameStateInput(node, 1)->opcode());
     58       NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_);
     59     }
     60 
     61     if (!combine.IsOutputIgnored()) {
     62       output_poke_offset_ = static_cast<int>(combine.GetOffsetToPokeAt());
     63       output_poke_count_ = node->op()->ValueOutputCount();
     64     }
     65     added_to_node_ = true;
     66   }
     67 
     68   BytecodeGraphBuilder* builder_;
     69   Node* frame_state_before_;
     70   BailoutId id_after_;
     71 
     72   bool added_to_node_;
     73   int output_poke_offset_;
     74   int output_poke_count_;
     75 };
     76 
     77 
     78 // Issues:
     79 // - Scopes - intimately tied to AST. Need to eval what is needed.
     80 // - Need to resolve closure parameter treatment.
     81 BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder,
     82                                                int register_count,
     83                                                int parameter_count,
     84                                                Node* control_dependency,
     85                                                Node* context)
     86     : builder_(builder),
     87       register_count_(register_count),
     88       parameter_count_(parameter_count),
     89       context_(context),
     90       control_dependency_(control_dependency),
     91       effect_dependency_(control_dependency),
     92       values_(builder->local_zone()),
     93       parameters_state_values_(nullptr),
     94       registers_state_values_(nullptr),
     95       accumulator_state_values_(nullptr) {
     96   // The layout of values_ is:
     97   //
     98   // [receiver] [parameters] [registers] [accumulator]
     99   //
    100   // parameter[0] is the receiver (this), parameters 1..N are the
    101   // parameters supplied to the method (arg0..argN-1). The accumulator
    102   // is stored separately.
    103 
    104   // Parameters including the receiver
    105   for (int i = 0; i < parameter_count; i++) {
    106     const char* debug_name = (i == 0) ? "%this" : nullptr;
    107     const Operator* op = common()->Parameter(i, debug_name);
    108     Node* parameter = builder->graph()->NewNode(op, graph()->start());
    109     values()->push_back(parameter);
    110   }
    111 
    112   // Registers
    113   register_base_ = static_cast<int>(values()->size());
    114   Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
    115   values()->insert(values()->end(), register_count, undefined_constant);
    116 
    117   // Accumulator
    118   accumulator_base_ = static_cast<int>(values()->size());
    119   values()->push_back(undefined_constant);
    120 }
    121 
    122 
    123 BytecodeGraphBuilder::Environment::Environment(
    124     const BytecodeGraphBuilder::Environment* other)
    125     : builder_(other->builder_),
    126       register_count_(other->register_count_),
    127       parameter_count_(other->parameter_count_),
    128       context_(other->context_),
    129       control_dependency_(other->control_dependency_),
    130       effect_dependency_(other->effect_dependency_),
    131       values_(other->zone()),
    132       parameters_state_values_(nullptr),
    133       registers_state_values_(nullptr),
    134       accumulator_state_values_(nullptr),
    135       register_base_(other->register_base_),
    136       accumulator_base_(other->accumulator_base_) {
    137   values_ = other->values_;
    138 }
    139 
    140 
    141 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex(
    142     interpreter::Register the_register) const {
    143   if (the_register.is_parameter()) {
    144     return the_register.ToParameterIndex(parameter_count());
    145   } else {
    146     return the_register.index() + register_base();
    147   }
    148 }
    149 
    150 
    151 Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const {
    152   return values()->at(accumulator_base_);
    153 }
    154 
    155 
    156 Node* BytecodeGraphBuilder::Environment::LookupRegister(
    157     interpreter::Register the_register) const {
    158   if (the_register.is_function_context()) {
    159     return builder()->GetFunctionContext();
    160   } else if (the_register.is_function_closure()) {
    161     return builder()->GetFunctionClosure();
    162   } else if (the_register.is_new_target()) {
    163     return builder()->GetNewTarget();
    164   } else {
    165     int values_index = RegisterToValuesIndex(the_register);
    166     return values()->at(values_index);
    167   }
    168 }
    169 
    170 
    171 void BytecodeGraphBuilder::Environment::ExchangeRegisters(
    172     interpreter::Register reg0, interpreter::Register reg1) {
    173   int reg0_index = RegisterToValuesIndex(reg0);
    174   int reg1_index = RegisterToValuesIndex(reg1);
    175   Node* saved_reg0_value = values()->at(reg0_index);
    176   values()->at(reg0_index) = values()->at(reg1_index);
    177   values()->at(reg1_index) = saved_reg0_value;
    178 }
    179 
    180 
    181 void BytecodeGraphBuilder::Environment::BindAccumulator(
    182     Node* node, FrameStateBeforeAndAfter* states) {
    183   if (states) {
    184     states->AddToNode(node, OutputFrameStateCombine::PokeAt(0));
    185   }
    186   values()->at(accumulator_base_) = node;
    187 }
    188 
    189 
    190 void BytecodeGraphBuilder::Environment::BindRegister(
    191     interpreter::Register the_register, Node* node,
    192     FrameStateBeforeAndAfter* states) {
    193   int values_index = RegisterToValuesIndex(the_register);
    194   if (states) {
    195     states->AddToNode(node, OutputFrameStateCombine::PokeAt(accumulator_base_ -
    196                                                             values_index));
    197   }
    198   values()->at(values_index) = node;
    199 }
    200 
    201 
    202 void BytecodeGraphBuilder::Environment::BindRegistersToProjections(
    203     interpreter::Register first_reg, Node* node,
    204     FrameStateBeforeAndAfter* states) {
    205   int values_index = RegisterToValuesIndex(first_reg);
    206   if (states) {
    207     states->AddToNode(node, OutputFrameStateCombine::PokeAt(accumulator_base_ -
    208                                                             values_index));
    209   }
    210   for (int i = 0; i < node->op()->ValueOutputCount(); i++) {
    211     values()->at(values_index + i) =
    212         builder()->NewNode(common()->Projection(i), node);
    213   }
    214 }
    215 
    216 
    217 void BytecodeGraphBuilder::Environment::RecordAfterState(
    218     Node* node, FrameStateBeforeAndAfter* states) {
    219   states->AddToNode(node, OutputFrameStateCombine::Ignore());
    220 }
    221 
    222 
    223 bool BytecodeGraphBuilder::Environment::IsMarkedAsUnreachable() const {
    224   return GetControlDependency()->opcode() == IrOpcode::kDead;
    225 }
    226 
    227 
    228 void BytecodeGraphBuilder::Environment::MarkAsUnreachable() {
    229   UpdateControlDependency(builder()->jsgraph()->Dead());
    230 }
    231 
    232 
    233 BytecodeGraphBuilder::Environment*
    234 BytecodeGraphBuilder::Environment::CopyForLoop() {
    235   PrepareForLoop();
    236   return new (zone()) Environment(this);
    237 }
    238 
    239 
    240 BytecodeGraphBuilder::Environment*
    241 BytecodeGraphBuilder::Environment::CopyForConditional() const {
    242   return new (zone()) Environment(this);
    243 }
    244 
    245 
    246 void BytecodeGraphBuilder::Environment::Merge(
    247     BytecodeGraphBuilder::Environment* other) {
    248   // Nothing to do if the other environment is dead.
    249   if (other->IsMarkedAsUnreachable()) {
    250     return;
    251   }
    252 
    253   // Create a merge of the control dependencies of both environments and update
    254   // the current environment's control dependency accordingly.
    255   Node* control = builder()->MergeControl(GetControlDependency(),
    256                                           other->GetControlDependency());
    257   UpdateControlDependency(control);
    258 
    259   // Create a merge of the effect dependencies of both environments and update
    260   // the current environment's effect dependency accordingly.
    261   Node* effect = builder()->MergeEffect(GetEffectDependency(),
    262                                         other->GetEffectDependency(), control);
    263   UpdateEffectDependency(effect);
    264 
    265   // Introduce Phi nodes for values that have differing input at merge points,
    266   // potentially extending an existing Phi node if possible.
    267   context_ = builder()->MergeValue(context_, other->context_, control);
    268   for (size_t i = 0; i < values_.size(); i++) {
    269     values_[i] = builder()->MergeValue(values_[i], other->values_[i], control);
    270   }
    271 }
    272 
    273 
    274 void BytecodeGraphBuilder::Environment::PrepareForLoop() {
    275   // Create a control node for the loop header.
    276   Node* control = builder()->NewLoop();
    277 
    278   // Create a Phi for external effects.
    279   Node* effect = builder()->NewEffectPhi(1, GetEffectDependency(), control);
    280   UpdateEffectDependency(effect);
    281 
    282   // Assume everything in the loop is updated.
    283   context_ = builder()->NewPhi(1, context_, control);
    284   int size = static_cast<int>(values()->size());
    285   for (int i = 0; i < size; i++) {
    286     values()->at(i) = builder()->NewPhi(1, values()->at(i), control);
    287   }
    288 
    289   // Connect to the loop end.
    290   Node* terminate = builder()->graph()->NewNode(
    291       builder()->common()->Terminate(), effect, control);
    292   builder()->exit_controls_.push_back(terminate);
    293 }
    294 
    295 
    296 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate(
    297     Node** state_values, int offset, int count) {
    298   if (!builder()->info()->is_deoptimization_enabled()) {
    299     return false;
    300   }
    301   if (*state_values == nullptr) {
    302     return true;
    303   }
    304   DCHECK_EQ((*state_values)->InputCount(), count);
    305   DCHECK_LE(static_cast<size_t>(offset + count), values()->size());
    306   Node** env_values = (count == 0) ? nullptr : &values()->at(offset);
    307   for (int i = 0; i < count; i++) {
    308     if ((*state_values)->InputAt(i) != env_values[i]) {
    309       return true;
    310     }
    311   }
    312   return false;
    313 }
    314 
    315 
    316 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values,
    317                                                           int offset,
    318                                                           int count) {
    319   if (StateValuesRequireUpdate(state_values, offset, count)) {
    320     const Operator* op = common()->StateValues(count);
    321     (*state_values) = graph()->NewNode(op, count, &values()->at(offset));
    322   }
    323 }
    324 
    325 
    326 Node* BytecodeGraphBuilder::Environment::Checkpoint(
    327     BailoutId bailout_id, OutputFrameStateCombine combine) {
    328   if (!builder()->info()->is_deoptimization_enabled()) {
    329     return builder()->jsgraph()->EmptyFrameState();
    330   }
    331 
    332   // TODO(rmcilroy): Consider using StateValuesCache for some state values.
    333   UpdateStateValues(&parameters_state_values_, 0, parameter_count());
    334   UpdateStateValues(&registers_state_values_, register_base(),
    335                     register_count());
    336   UpdateStateValues(&accumulator_state_values_, accumulator_base(), 1);
    337 
    338   const Operator* op = common()->FrameState(
    339       bailout_id, combine, builder()->frame_state_function_info());
    340   Node* result = graph()->NewNode(
    341       op, parameters_state_values_, registers_state_values_,
    342       accumulator_state_values_, Context(), builder()->GetFunctionClosure(),
    343       builder()->graph()->start());
    344 
    345   return result;
    346 }
    347 
    348 
    349 bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate(
    350     Node** state_values, int offset, int count, int output_poke_start,
    351     int output_poke_end) {
    352   DCHECK_LE(static_cast<size_t>(offset + count), values()->size());
    353   for (int i = 0; i < count; i++, offset++) {
    354     if (offset < output_poke_start || offset >= output_poke_end) {
    355       if ((*state_values)->InputAt(i) != values()->at(offset)) {
    356         return false;
    357       }
    358     }
    359   }
    360   return true;
    361 }
    362 
    363 
    364 bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate(
    365     int output_poke_offset, int output_poke_count) {
    366   // Poke offset is relative to the top of the stack (i.e., the accumulator).
    367   int output_poke_start = accumulator_base() - output_poke_offset;
    368   int output_poke_end = output_poke_start + output_poke_count;
    369   return StateValuesAreUpToDate(&parameters_state_values_, 0, parameter_count(),
    370                                 output_poke_start, output_poke_end) &&
    371          StateValuesAreUpToDate(&registers_state_values_, register_base(),
    372                                 register_count(), output_poke_start,
    373                                 output_poke_end) &&
    374          StateValuesAreUpToDate(&accumulator_state_values_, accumulator_base(),
    375                                 1, output_poke_start, output_poke_end);
    376 }
    377 
    378 
    379 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone,
    380                                            CompilationInfo* compilation_info,
    381                                            JSGraph* jsgraph)
    382     : local_zone_(local_zone),
    383       info_(compilation_info),
    384       jsgraph_(jsgraph),
    385       bytecode_array_(handle(info()->shared_info()->bytecode_array())),
    386       frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
    387           FrameStateType::kInterpretedFunction,
    388           bytecode_array()->parameter_count(),
    389           bytecode_array()->register_count(), info()->shared_info(),
    390           CALL_MAINTAINS_NATIVE_CONTEXT)),
    391       merge_environments_(local_zone),
    392       loop_header_environments_(local_zone),
    393       input_buffer_size_(0),
    394       input_buffer_(nullptr),
    395       exit_controls_(local_zone) {}
    396 
    397 
    398 Node* BytecodeGraphBuilder::GetNewTarget() {
    399   if (!new_target_.is_set()) {
    400     int params = bytecode_array()->parameter_count();
    401     int index = Linkage::GetJSCallNewTargetParamIndex(params);
    402     const Operator* op = common()->Parameter(index, "%new.target");
    403     Node* node = NewNode(op, graph()->start());
    404     new_target_.set(node);
    405   }
    406   return new_target_.get();
    407 }
    408 
    409 
    410 Node* BytecodeGraphBuilder::GetFunctionContext() {
    411   if (!function_context_.is_set()) {
    412     int params = bytecode_array()->parameter_count();
    413     int index = Linkage::GetJSCallContextParamIndex(params);
    414     const Operator* op = common()->Parameter(index, "%context");
    415     Node* node = NewNode(op, graph()->start());
    416     function_context_.set(node);
    417   }
    418   return function_context_.get();
    419 }
    420 
    421 
    422 Node* BytecodeGraphBuilder::GetFunctionClosure() {
    423   if (!function_closure_.is_set()) {
    424     int index = Linkage::kJSCallClosureParamIndex;
    425     const Operator* op = common()->Parameter(index, "%closure");
    426     Node* node = NewNode(op, graph()->start());
    427     function_closure_.set(node);
    428   }
    429   return function_closure_.get();
    430 }
    431 
    432 
    433 Node* BytecodeGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
    434   return NewNode(jsgraph()->machine()->Load(MachineType::AnyTagged()), object,
    435                  jsgraph()->IntPtrConstant(offset - kHeapObjectTag));
    436 }
    437 
    438 
    439 Node* BytecodeGraphBuilder::BuildLoadImmutableObjectField(Node* object,
    440                                                           int offset) {
    441   return graph()->NewNode(jsgraph()->machine()->Load(MachineType::AnyTagged()),
    442                           object,
    443                           jsgraph()->IntPtrConstant(offset - kHeapObjectTag),
    444                           graph()->start(), graph()->start());
    445 }
    446 
    447 
    448 Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) {
    449   const Operator* op =
    450       javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true);
    451   Node* native_context = NewNode(op, environment()->Context());
    452   return NewNode(javascript()->LoadContext(0, index, true), native_context);
    453 }
    454 
    455 
    456 Node* BytecodeGraphBuilder::BuildLoadFeedbackVector() {
    457   if (!feedback_vector_.is_set()) {
    458     Node* closure = GetFunctionClosure();
    459     Node* shared = BuildLoadImmutableObjectField(
    460         closure, JSFunction::kSharedFunctionInfoOffset);
    461     Node* vector = BuildLoadImmutableObjectField(
    462         shared, SharedFunctionInfo::kFeedbackVectorOffset);
    463     feedback_vector_.set(vector);
    464   }
    465   return feedback_vector_.get();
    466 }
    467 
    468 
    469 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) {
    470   Handle<TypeFeedbackVector> feedback_vector = info()->feedback_vector();
    471   FeedbackVectorSlot slot;
    472   if (slot_id >= TypeFeedbackVector::kReservedIndexCount) {
    473     slot = feedback_vector->ToSlot(slot_id);
    474   }
    475   return VectorSlotPair(feedback_vector, slot);
    476 }
    477 
    478 
    479 bool BytecodeGraphBuilder::CreateGraph(bool stack_check) {
    480   // Set up the basic structure of the graph. Outputs for {Start} are
    481   // the formal parameters (including the receiver) plus context and
    482   // closure.
    483 
    484   // Set up the basic structure of the graph. Outputs for {Start} are the formal
    485   // parameters (including the receiver) plus new target, number of arguments,
    486   // context and closure.
    487   int actual_parameter_count = bytecode_array()->parameter_count() + 4;
    488   graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count)));
    489 
    490   Environment env(this, bytecode_array()->register_count(),
    491                   bytecode_array()->parameter_count(), graph()->start(),
    492                   GetFunctionContext());
    493   set_environment(&env);
    494 
    495   CreateGraphBody(stack_check);
    496 
    497   // Finish the basic structure of the graph.
    498   DCHECK_NE(0u, exit_controls_.size());
    499   int const input_count = static_cast<int>(exit_controls_.size());
    500   Node** const inputs = &exit_controls_.front();
    501   Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs);
    502   graph()->SetEnd(end);
    503 
    504   return true;
    505 }
    506 
    507 
    508 void BytecodeGraphBuilder::CreateGraphBody(bool stack_check) {
    509   // TODO(oth): Review ast-graph-builder equivalent, i.e. arguments
    510   // object setup, this function variable if used, tracing hooks.
    511 
    512   if (stack_check) {
    513     Node* node = NewNode(javascript()->StackCheck());
    514     PrepareEntryFrameState(node);
    515   }
    516 
    517   VisitBytecodes();
    518 }
    519 
    520 
    521 void BytecodeGraphBuilder::VisitBytecodes() {
    522   BytecodeBranchAnalysis analysis(bytecode_array(), local_zone());
    523   analysis.Analyze();
    524   set_branch_analysis(&analysis);
    525   interpreter::BytecodeArrayIterator iterator(bytecode_array());
    526   set_bytecode_iterator(&iterator);
    527   while (!iterator.done()) {
    528     int current_offset = iterator.current_offset();
    529     if (analysis.is_reachable(current_offset)) {
    530       MergeEnvironmentsOfForwardBranches(current_offset);
    531       BuildLoopHeaderForBackwardBranches(current_offset);
    532 
    533       switch (iterator.current_bytecode()) {
    534 #define BYTECODE_CASE(name, ...)       \
    535   case interpreter::Bytecode::k##name: \
    536     Visit##name(iterator);             \
    537     break;
    538         BYTECODE_LIST(BYTECODE_CASE)
    539 #undef BYTECODE_CODE
    540       }
    541     }
    542     iterator.Advance();
    543   }
    544   set_branch_analysis(nullptr);
    545   set_bytecode_iterator(nullptr);
    546 }
    547 
    548 
    549 void BytecodeGraphBuilder::VisitLdaZero(
    550     const interpreter::BytecodeArrayIterator& iterator) {
    551   Node* node = jsgraph()->ZeroConstant();
    552   environment()->BindAccumulator(node);
    553 }
    554 
    555 
    556 void BytecodeGraphBuilder::VisitLdaSmi8(
    557     const interpreter::BytecodeArrayIterator& iterator) {
    558   Node* node = jsgraph()->Constant(iterator.GetImmediateOperand(0));
    559   environment()->BindAccumulator(node);
    560 }
    561 
    562 
    563 void BytecodeGraphBuilder::VisitLdaConstantWide(
    564     const interpreter::BytecodeArrayIterator& iterator) {
    565   Node* node = jsgraph()->Constant(iterator.GetConstantForIndexOperand(0));
    566   environment()->BindAccumulator(node);
    567 }
    568 
    569 
    570 void BytecodeGraphBuilder::VisitLdaConstant(
    571     const interpreter::BytecodeArrayIterator& iterator) {
    572   Node* node = jsgraph()->Constant(iterator.GetConstantForIndexOperand(0));
    573   environment()->BindAccumulator(node);
    574 }
    575 
    576 
    577 void BytecodeGraphBuilder::VisitLdaUndefined(
    578     const interpreter::BytecodeArrayIterator& iterator) {
    579   Node* node = jsgraph()->UndefinedConstant();
    580   environment()->BindAccumulator(node);
    581 }
    582 
    583 
    584 void BytecodeGraphBuilder::VisitLdaNull(
    585     const interpreter::BytecodeArrayIterator& iterator) {
    586   Node* node = jsgraph()->NullConstant();
    587   environment()->BindAccumulator(node);
    588 }
    589 
    590 
    591 void BytecodeGraphBuilder::VisitLdaTheHole(
    592     const interpreter::BytecodeArrayIterator& iterator) {
    593   Node* node = jsgraph()->TheHoleConstant();
    594   environment()->BindAccumulator(node);
    595 }
    596 
    597 
    598 void BytecodeGraphBuilder::VisitLdaTrue(
    599     const interpreter::BytecodeArrayIterator& iterator) {
    600   Node* node = jsgraph()->TrueConstant();
    601   environment()->BindAccumulator(node);
    602 }
    603 
    604 
    605 void BytecodeGraphBuilder::VisitLdaFalse(
    606     const interpreter::BytecodeArrayIterator& iterator) {
    607   Node* node = jsgraph()->FalseConstant();
    608   environment()->BindAccumulator(node);
    609 }
    610 
    611 
    612 void BytecodeGraphBuilder::VisitLdar(
    613     const interpreter::BytecodeArrayIterator& iterator) {
    614   Node* value = environment()->LookupRegister(iterator.GetRegisterOperand(0));
    615   environment()->BindAccumulator(value);
    616 }
    617 
    618 
    619 void BytecodeGraphBuilder::VisitStar(
    620     const interpreter::BytecodeArrayIterator& iterator) {
    621   Node* value = environment()->LookupAccumulator();
    622   environment()->BindRegister(iterator.GetRegisterOperand(0), value);
    623 }
    624 
    625 
    626 void BytecodeGraphBuilder::VisitMov(
    627     const interpreter::BytecodeArrayIterator& iterator) {
    628   Node* value = environment()->LookupRegister(iterator.GetRegisterOperand(0));
    629   environment()->BindRegister(iterator.GetRegisterOperand(1), value);
    630 }
    631 
    632 
    633 void BytecodeGraphBuilder::VisitExchange(
    634     const interpreter::BytecodeArrayIterator& iterator) {
    635   environment()->ExchangeRegisters(iterator.GetRegisterOperand(0),
    636                                    iterator.GetRegisterOperand(1));
    637 }
    638 
    639 
    640 void BytecodeGraphBuilder::VisitExchangeWide(
    641     const interpreter::BytecodeArrayIterator& iterator) {
    642   environment()->ExchangeRegisters(iterator.GetRegisterOperand(0),
    643                                    iterator.GetRegisterOperand(1));
    644 }
    645 
    646 
    647 void BytecodeGraphBuilder::BuildLoadGlobal(
    648     const interpreter::BytecodeArrayIterator& iterator,
    649     TypeofMode typeof_mode) {
    650   FrameStateBeforeAndAfter states(this, iterator);
    651   Handle<Name> name =
    652       Handle<Name>::cast(iterator.GetConstantForIndexOperand(0));
    653   VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1));
    654 
    655   const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
    656   Node* node = NewNode(op, BuildLoadFeedbackVector());
    657   environment()->BindAccumulator(node, &states);
    658 }
    659 
    660 
    661 void BytecodeGraphBuilder::VisitLdaGlobalSloppy(
    662     const interpreter::BytecodeArrayIterator& iterator) {
    663   DCHECK(is_sloppy(language_mode()));
    664   BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF);
    665 }
    666 
    667 
    668 void BytecodeGraphBuilder::VisitLdaGlobalStrict(
    669     const interpreter::BytecodeArrayIterator& iterator) {
    670   DCHECK(is_strict(language_mode()));
    671   BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF);
    672 }
    673 
    674 
    675 void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofSloppy(
    676     const interpreter::BytecodeArrayIterator& iterator) {
    677   DCHECK(is_sloppy(language_mode()));
    678   BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF);
    679 }
    680 
    681 
    682 void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofStrict(
    683     const interpreter::BytecodeArrayIterator& iterator) {
    684   DCHECK(is_strict(language_mode()));
    685   BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF);
    686 }
    687 
    688 
    689 void BytecodeGraphBuilder::VisitLdaGlobalSloppyWide(
    690     const interpreter::BytecodeArrayIterator& iterator) {
    691   DCHECK(is_sloppy(language_mode()));
    692   BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF);
    693 }
    694 
    695 
    696 void BytecodeGraphBuilder::VisitLdaGlobalStrictWide(
    697     const interpreter::BytecodeArrayIterator& iterator) {
    698   DCHECK(is_strict(language_mode()));
    699   BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF);
    700 }
    701 
    702 
    703 void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofSloppyWide(
    704     const interpreter::BytecodeArrayIterator& iterator) {
    705   DCHECK(is_sloppy(language_mode()));
    706   BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF);
    707 }
    708 
    709 
    710 void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofStrictWide(
    711     const interpreter::BytecodeArrayIterator& iterator) {
    712   DCHECK(is_strict(language_mode()));
    713   BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF);
    714 }
    715 
    716 
    717 void BytecodeGraphBuilder::BuildStoreGlobal(
    718     const interpreter::BytecodeArrayIterator& iterator) {
    719   FrameStateBeforeAndAfter states(this, iterator);
    720   Handle<Name> name =
    721       Handle<Name>::cast(iterator.GetConstantForIndexOperand(0));
    722   VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1));
    723   Node* value = environment()->LookupAccumulator();
    724 
    725   const Operator* op =
    726       javascript()->StoreGlobal(language_mode(), name, feedback);
    727   Node* node = NewNode(op, value, BuildLoadFeedbackVector());
    728   environment()->RecordAfterState(node, &states);
    729 }
    730 
    731 
    732 void BytecodeGraphBuilder::VisitStaGlobalSloppy(
    733     const interpreter::BytecodeArrayIterator& iterator) {
    734   DCHECK(is_sloppy(language_mode()));
    735   BuildStoreGlobal(iterator);
    736 }
    737 
    738 
    739 void BytecodeGraphBuilder::VisitStaGlobalStrict(
    740     const interpreter::BytecodeArrayIterator& iterator) {
    741   DCHECK(is_strict(language_mode()));
    742   BuildStoreGlobal(iterator);
    743 }
    744 
    745 void BytecodeGraphBuilder::VisitStaGlobalSloppyWide(
    746     const interpreter::BytecodeArrayIterator& iterator) {
    747   DCHECK(is_sloppy(language_mode()));
    748   BuildStoreGlobal(iterator);
    749 }
    750 
    751 
    752 void BytecodeGraphBuilder::VisitStaGlobalStrictWide(
    753     const interpreter::BytecodeArrayIterator& iterator) {
    754   DCHECK(is_strict(language_mode()));
    755   BuildStoreGlobal(iterator);
    756 }
    757 
    758 
    759 void BytecodeGraphBuilder::VisitLdaContextSlot(
    760     const interpreter::BytecodeArrayIterator& iterator) {
    761   // TODO(mythria): LoadContextSlots are unrolled by the required depth when
    762   // generating bytecode. Hence the value of depth is always 0. Update this
    763   // code, when the implementation changes.
    764   // TODO(mythria): immutable flag is also set to false. This information is not
    765   // available in bytecode array. update this code when the implementation
    766   // changes.
    767   const Operator* op =
    768       javascript()->LoadContext(0, iterator.GetIndexOperand(1), false);
    769   Node* context = environment()->LookupRegister(iterator.GetRegisterOperand(0));
    770   Node* node = NewNode(op, context);
    771   environment()->BindAccumulator(node);
    772 }
    773 
    774 
    775 void BytecodeGraphBuilder::VisitLdaContextSlotWide(
    776     const interpreter::BytecodeArrayIterator& iterator) {
    777   VisitLdaContextSlot(iterator);
    778 }
    779 
    780 
    781 void BytecodeGraphBuilder::VisitStaContextSlot(
    782     const interpreter::BytecodeArrayIterator& iterator) {
    783   // TODO(mythria): LoadContextSlots are unrolled by the required depth when
    784   // generating bytecode. Hence the value of depth is always 0. Update this
    785   // code, when the implementation changes.
    786   const Operator* op =
    787       javascript()->StoreContext(0, iterator.GetIndexOperand(1));
    788   Node* context = environment()->LookupRegister(iterator.GetRegisterOperand(0));
    789   Node* value = environment()->LookupAccumulator();
    790   NewNode(op, context, value);
    791 }
    792 
    793 
    794 void BytecodeGraphBuilder::VisitStaContextSlotWide(
    795     const interpreter::BytecodeArrayIterator& iterator) {
    796   VisitStaContextSlot(iterator);
    797 }
    798 
    799 
    800 void BytecodeGraphBuilder::BuildLdaLookupSlot(
    801     TypeofMode typeof_mode,
    802     const interpreter::BytecodeArrayIterator& iterator) {
    803   FrameStateBeforeAndAfter states(this, iterator);
    804   Handle<String> name =
    805       Handle<String>::cast(iterator.GetConstantForIndexOperand(0));
    806   const Operator* op = javascript()->LoadDynamic(name, typeof_mode);
    807   Node* value =
    808       NewNode(op, BuildLoadFeedbackVector(), environment()->Context());
    809   environment()->BindAccumulator(value, &states);
    810 }
    811 
    812 
    813 void BytecodeGraphBuilder::VisitLdaLookupSlot(
    814     const interpreter::BytecodeArrayIterator& iterator) {
    815   BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF, iterator);
    816 }
    817 
    818 
    819 void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof(
    820     const interpreter::BytecodeArrayIterator& iterator) {
    821   BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF, iterator);
    822 }
    823 
    824 
    825 void BytecodeGraphBuilder::BuildStaLookupSlot(
    826     LanguageMode language_mode,
    827     const interpreter::BytecodeArrayIterator& iterator) {
    828   FrameStateBeforeAndAfter states(this, iterator);
    829   Node* value = environment()->LookupAccumulator();
    830   Node* name = jsgraph()->Constant(iterator.GetConstantForIndexOperand(0));
    831   Node* language = jsgraph()->Constant(language_mode);
    832   const Operator* op = javascript()->CallRuntime(Runtime::kStoreLookupSlot, 4);
    833   Node* store = NewNode(op, value, environment()->Context(), name, language);
    834   environment()->BindAccumulator(store, &states);
    835 }
    836 
    837 
    838 void BytecodeGraphBuilder::VisitLdaLookupSlotWide(
    839     const interpreter::BytecodeArrayIterator& iterator) {
    840   VisitLdaLookupSlot(iterator);
    841 }
    842 
    843 
    844 void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeofWide(
    845     const interpreter::BytecodeArrayIterator& iterator) {
    846   VisitLdaLookupSlotInsideTypeof(iterator);
    847 }
    848 
    849 
    850 void BytecodeGraphBuilder::VisitStaLookupSlotSloppy(
    851     const interpreter::BytecodeArrayIterator& iterator) {
    852   BuildStaLookupSlot(LanguageMode::SLOPPY, iterator);
    853 }
    854 
    855 
    856 void BytecodeGraphBuilder::VisitStaLookupSlotStrict(
    857     const interpreter::BytecodeArrayIterator& iterator) {
    858   BuildStaLookupSlot(LanguageMode::STRICT, iterator);
    859 }
    860 
    861 
    862 void BytecodeGraphBuilder::VisitStaLookupSlotSloppyWide(
    863     const interpreter::BytecodeArrayIterator& iterator) {
    864   VisitStaLookupSlotSloppy(iterator);
    865 }
    866 
    867 
    868 void BytecodeGraphBuilder::VisitStaLookupSlotStrictWide(
    869     const interpreter::BytecodeArrayIterator& iterator) {
    870   VisitStaLookupSlotStrict(iterator);
    871 }
    872 
    873 
    874 void BytecodeGraphBuilder::BuildNamedLoad(
    875     const interpreter::BytecodeArrayIterator& iterator) {
    876   FrameStateBeforeAndAfter states(this, iterator);
    877   Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0));
    878   Handle<Name> name =
    879       Handle<Name>::cast(iterator.GetConstantForIndexOperand(1));
    880   VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2));
    881 
    882   const Operator* op = javascript()->LoadNamed(language_mode(), name, feedback);
    883   Node* node = NewNode(op, object, BuildLoadFeedbackVector());
    884   environment()->BindAccumulator(node, &states);
    885 }
    886 
    887 
    888 void BytecodeGraphBuilder::VisitLoadICSloppy(
    889     const interpreter::BytecodeArrayIterator& iterator) {
    890   DCHECK(is_sloppy(language_mode()));
    891   BuildNamedLoad(iterator);
    892 }
    893 
    894 
    895 void BytecodeGraphBuilder::VisitLoadICStrict(
    896     const interpreter::BytecodeArrayIterator& iterator) {
    897   DCHECK(is_strict(language_mode()));
    898   BuildNamedLoad(iterator);
    899 }
    900 
    901 
    902 void BytecodeGraphBuilder::VisitLoadICSloppyWide(
    903     const interpreter::BytecodeArrayIterator& iterator) {
    904   DCHECK(is_sloppy(language_mode()));
    905   BuildNamedLoad(iterator);
    906 }
    907 
    908 
    909 void BytecodeGraphBuilder::VisitLoadICStrictWide(
    910     const interpreter::BytecodeArrayIterator& iterator) {
    911   DCHECK(is_strict(language_mode()));
    912   BuildNamedLoad(iterator);
    913 }
    914 
    915 
    916 void BytecodeGraphBuilder::BuildKeyedLoad(
    917     const interpreter::BytecodeArrayIterator& iterator) {
    918   FrameStateBeforeAndAfter states(this, iterator);
    919   Node* key = environment()->LookupAccumulator();
    920   Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0));
    921   VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1));
    922 
    923   const Operator* op = javascript()->LoadProperty(language_mode(), feedback);
    924   Node* node = NewNode(op, object, key, BuildLoadFeedbackVector());
    925   environment()->BindAccumulator(node, &states);
    926 }
    927 
    928 
    929 void BytecodeGraphBuilder::VisitKeyedLoadICSloppy(
    930     const interpreter::BytecodeArrayIterator& iterator) {
    931   DCHECK(is_sloppy(language_mode()));
    932   BuildKeyedLoad(iterator);
    933 }
    934 
    935 
    936 void BytecodeGraphBuilder::VisitKeyedLoadICStrict(
    937     const interpreter::BytecodeArrayIterator& iterator) {
    938   DCHECK(is_strict(language_mode()));
    939   BuildKeyedLoad(iterator);
    940 }
    941 
    942 
    943 void BytecodeGraphBuilder::VisitKeyedLoadICSloppyWide(
    944     const interpreter::BytecodeArrayIterator& iterator) {
    945   DCHECK(is_sloppy(language_mode()));
    946   BuildKeyedLoad(iterator);
    947 }
    948 
    949 
    950 void BytecodeGraphBuilder::VisitKeyedLoadICStrictWide(
    951     const interpreter::BytecodeArrayIterator& iterator) {
    952   DCHECK(is_strict(language_mode()));
    953   BuildKeyedLoad(iterator);
    954 }
    955 
    956 
    957 void BytecodeGraphBuilder::BuildNamedStore(
    958     const interpreter::BytecodeArrayIterator& iterator) {
    959   FrameStateBeforeAndAfter states(this, iterator);
    960   Node* value = environment()->LookupAccumulator();
    961   Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0));
    962   Handle<Name> name =
    963       Handle<Name>::cast(iterator.GetConstantForIndexOperand(1));
    964   VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2));
    965 
    966   const Operator* op =
    967       javascript()->StoreNamed(language_mode(), name, feedback);
    968   Node* node = NewNode(op, object, value, BuildLoadFeedbackVector());
    969   environment()->RecordAfterState(node, &states);
    970 }
    971 
    972 
    973 void BytecodeGraphBuilder::VisitStoreICSloppy(
    974     const interpreter::BytecodeArrayIterator& iterator) {
    975   DCHECK(is_sloppy(language_mode()));
    976   BuildNamedStore(iterator);
    977 }
    978 
    979 
    980 void BytecodeGraphBuilder::VisitStoreICStrict(
    981     const interpreter::BytecodeArrayIterator& iterator) {
    982   DCHECK(is_strict(language_mode()));
    983   BuildNamedStore(iterator);
    984 }
    985 
    986 
    987 void BytecodeGraphBuilder::VisitStoreICSloppyWide(
    988     const interpreter::BytecodeArrayIterator& iterator) {
    989   DCHECK(is_sloppy(language_mode()));
    990   BuildNamedStore(iterator);
    991 }
    992 
    993 
    994 void BytecodeGraphBuilder::VisitStoreICStrictWide(
    995     const interpreter::BytecodeArrayIterator& iterator) {
    996   DCHECK(is_strict(language_mode()));
    997   BuildNamedStore(iterator);
    998 }
    999 
   1000 
   1001 void BytecodeGraphBuilder::BuildKeyedStore(
   1002     const interpreter::BytecodeArrayIterator& iterator) {
   1003   FrameStateBeforeAndAfter states(this, iterator);
   1004   Node* value = environment()->LookupAccumulator();
   1005   Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0));
   1006   Node* key = environment()->LookupRegister(iterator.GetRegisterOperand(1));
   1007   VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2));
   1008 
   1009   const Operator* op = javascript()->StoreProperty(language_mode(), feedback);
   1010   Node* node = NewNode(op, object, key, value, BuildLoadFeedbackVector());
   1011   environment()->RecordAfterState(node, &states);
   1012 }
   1013 
   1014 
   1015 void BytecodeGraphBuilder::VisitKeyedStoreICSloppy(
   1016     const interpreter::BytecodeArrayIterator& iterator) {
   1017   DCHECK(is_sloppy(language_mode()));
   1018   BuildKeyedStore(iterator);
   1019 }
   1020 
   1021 
   1022 void BytecodeGraphBuilder::VisitKeyedStoreICStrict(
   1023     const interpreter::BytecodeArrayIterator& iterator) {
   1024   DCHECK(is_strict(language_mode()));
   1025   BuildKeyedStore(iterator);
   1026 }
   1027 
   1028 
   1029 void BytecodeGraphBuilder::VisitKeyedStoreICSloppyWide(
   1030     const interpreter::BytecodeArrayIterator& iterator) {
   1031   DCHECK(is_sloppy(language_mode()));
   1032   BuildKeyedStore(iterator);
   1033 }
   1034 
   1035 
   1036 void BytecodeGraphBuilder::VisitKeyedStoreICStrictWide(
   1037     const interpreter::BytecodeArrayIterator& iterator) {
   1038   DCHECK(is_strict(language_mode()));
   1039   BuildKeyedStore(iterator);
   1040 }
   1041 
   1042 
   1043 void BytecodeGraphBuilder::VisitPushContext(
   1044     const interpreter::BytecodeArrayIterator& iterator) {
   1045   Node* context = environment()->LookupAccumulator();
   1046   environment()->BindRegister(iterator.GetRegisterOperand(0), context);
   1047   environment()->SetContext(context);
   1048 }
   1049 
   1050 
   1051 void BytecodeGraphBuilder::VisitPopContext(
   1052     const interpreter::BytecodeArrayIterator& iterator) {
   1053   Node* context = environment()->LookupRegister(iterator.GetRegisterOperand(0));
   1054   environment()->SetContext(context);
   1055 }
   1056 
   1057 
   1058 void BytecodeGraphBuilder::VisitCreateClosure(
   1059     const interpreter::BytecodeArrayIterator& iterator) {
   1060   Handle<SharedFunctionInfo> shared_info =
   1061       Handle<SharedFunctionInfo>::cast(iterator.GetConstantForIndexOperand(0));
   1062   PretenureFlag tenured =
   1063       iterator.GetImmediateOperand(1) ? TENURED : NOT_TENURED;
   1064   const Operator* op = javascript()->CreateClosure(shared_info, tenured);
   1065   Node* closure = NewNode(op);
   1066   environment()->BindAccumulator(closure);
   1067 }
   1068 
   1069 
   1070 void BytecodeGraphBuilder::VisitCreateClosureWide(
   1071     const interpreter::BytecodeArrayIterator& iterator) {
   1072   VisitCreateClosure(iterator);
   1073 }
   1074 
   1075 
   1076 void BytecodeGraphBuilder::BuildCreateArguments(
   1077     CreateArgumentsParameters::Type type,
   1078     const interpreter::BytecodeArrayIterator& iterator) {
   1079   FrameStateBeforeAndAfter states(this, iterator);
   1080   const Operator* op = javascript()->CreateArguments(type, 0);
   1081   Node* object = NewNode(op, GetFunctionClosure());
   1082   environment()->BindAccumulator(object, &states);
   1083 }
   1084 
   1085 
   1086 void BytecodeGraphBuilder::VisitCreateMappedArguments(
   1087     const interpreter::BytecodeArrayIterator& iterator) {
   1088   BuildCreateArguments(CreateArgumentsParameters::kMappedArguments, iterator);
   1089 }
   1090 
   1091 
   1092 void BytecodeGraphBuilder::VisitCreateUnmappedArguments(
   1093     const interpreter::BytecodeArrayIterator& iterator) {
   1094   BuildCreateArguments(CreateArgumentsParameters::kUnmappedArguments, iterator);
   1095 }
   1096 
   1097 
   1098 void BytecodeGraphBuilder::BuildCreateLiteral(
   1099     const Operator* op, const interpreter::BytecodeArrayIterator& iterator) {
   1100   FrameStateBeforeAndAfter states(this, iterator);
   1101   Node* literal = NewNode(op, GetFunctionClosure());
   1102   environment()->BindAccumulator(literal, &states);
   1103 }
   1104 
   1105 
   1106 void BytecodeGraphBuilder::BuildCreateRegExpLiteral(
   1107     const interpreter::BytecodeArrayIterator& iterator) {
   1108   Handle<String> constant_pattern =
   1109       Handle<String>::cast(iterator.GetConstantForIndexOperand(0));
   1110   int literal_index = iterator.GetIndexOperand(1);
   1111   int literal_flags = iterator.GetImmediateOperand(2);
   1112   const Operator* op = javascript()->CreateLiteralRegExp(
   1113       constant_pattern, literal_flags, literal_index);
   1114   BuildCreateLiteral(op, iterator);
   1115 }
   1116 
   1117 
   1118 void BytecodeGraphBuilder::VisitCreateRegExpLiteral(
   1119     const interpreter::BytecodeArrayIterator& iterator) {
   1120   BuildCreateRegExpLiteral(iterator);
   1121 }
   1122 
   1123 
   1124 void BytecodeGraphBuilder::VisitCreateRegExpLiteralWide(
   1125     const interpreter::BytecodeArrayIterator& iterator) {
   1126   BuildCreateRegExpLiteral(iterator);
   1127 }
   1128 
   1129 
   1130 void BytecodeGraphBuilder::BuildCreateArrayLiteral(
   1131     const interpreter::BytecodeArrayIterator& iterator) {
   1132   Handle<FixedArray> constant_elements =
   1133       Handle<FixedArray>::cast(iterator.GetConstantForIndexOperand(0));
   1134   int literal_index = iterator.GetIndexOperand(1);
   1135   int literal_flags = iterator.GetImmediateOperand(2);
   1136   const Operator* op = javascript()->CreateLiteralArray(
   1137       constant_elements, literal_flags, literal_index);
   1138   BuildCreateLiteral(op, iterator);
   1139 }
   1140 
   1141 
   1142 void BytecodeGraphBuilder::VisitCreateArrayLiteral(
   1143     const interpreter::BytecodeArrayIterator& iterator) {
   1144   BuildCreateArrayLiteral(iterator);
   1145 }
   1146 
   1147 
   1148 void BytecodeGraphBuilder::VisitCreateArrayLiteralWide(
   1149     const interpreter::BytecodeArrayIterator& iterator) {
   1150   BuildCreateArrayLiteral(iterator);
   1151 }
   1152 
   1153 
   1154 void BytecodeGraphBuilder::BuildCreateObjectLiteral(
   1155     const interpreter::BytecodeArrayIterator& iterator) {
   1156   Handle<FixedArray> constant_properties =
   1157       Handle<FixedArray>::cast(iterator.GetConstantForIndexOperand(0));
   1158   int literal_index = iterator.GetIndexOperand(1);
   1159   int literal_flags = iterator.GetImmediateOperand(2);
   1160   const Operator* op = javascript()->CreateLiteralObject(
   1161       constant_properties, literal_flags, literal_index);
   1162   BuildCreateLiteral(op, iterator);
   1163 }
   1164 
   1165 
   1166 void BytecodeGraphBuilder::VisitCreateObjectLiteral(
   1167     const interpreter::BytecodeArrayIterator& iterator) {
   1168   BuildCreateObjectLiteral(iterator);
   1169 }
   1170 
   1171 
   1172 void BytecodeGraphBuilder::VisitCreateObjectLiteralWide(
   1173     const interpreter::BytecodeArrayIterator& iterator) {
   1174   BuildCreateObjectLiteral(iterator);
   1175 }
   1176 
   1177 
   1178 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
   1179                                                  Node* callee,
   1180                                                  interpreter::Register receiver,
   1181                                                  size_t arity) {
   1182   Node** all = info()->zone()->NewArray<Node*>(static_cast<int>(arity));
   1183   all[0] = callee;
   1184   all[1] = environment()->LookupRegister(receiver);
   1185   int receiver_index = receiver.index();
   1186   for (int i = 2; i < static_cast<int>(arity); ++i) {
   1187     all[i] = environment()->LookupRegister(
   1188         interpreter::Register(receiver_index + i - 1));
   1189   }
   1190   Node* value = MakeNode(call_op, static_cast<int>(arity), all, false);
   1191   return value;
   1192 }
   1193 
   1194 
   1195 void BytecodeGraphBuilder::BuildCall(
   1196     const interpreter::BytecodeArrayIterator& iterator) {
   1197   FrameStateBeforeAndAfter states(this, iterator);
   1198   // TODO(rmcilroy): Set receiver_hint correctly based on whether the receiver
   1199   // register has been loaded with null / undefined explicitly or we are sure it
   1200   // is not null / undefined.
   1201   ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny;
   1202   Node* callee = environment()->LookupRegister(iterator.GetRegisterOperand(0));
   1203   interpreter::Register receiver = iterator.GetRegisterOperand(1);
   1204   size_t arg_count = iterator.GetCountOperand(2);
   1205   VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(3));
   1206 
   1207   const Operator* call = javascript()->CallFunction(
   1208       arg_count + 2, language_mode(), feedback, receiver_hint);
   1209   Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 2);
   1210   environment()->BindAccumulator(value, &states);
   1211 }
   1212 
   1213 
   1214 void BytecodeGraphBuilder::VisitCall(
   1215     const interpreter::BytecodeArrayIterator& iterator) {
   1216   BuildCall(iterator);
   1217 }
   1218 
   1219 
   1220 void BytecodeGraphBuilder::VisitCallWide(
   1221     const interpreter::BytecodeArrayIterator& iterator) {
   1222   BuildCall(iterator);
   1223 }
   1224 
   1225 
   1226 void BytecodeGraphBuilder::VisitCallJSRuntime(
   1227     const interpreter::BytecodeArrayIterator& iterator) {
   1228   FrameStateBeforeAndAfter states(this, iterator);
   1229   Node* callee = BuildLoadNativeContextField(iterator.GetIndexOperand(0));
   1230   interpreter::Register receiver = iterator.GetRegisterOperand(1);
   1231   size_t arg_count = iterator.GetCountOperand(2);
   1232 
   1233   // Create node to perform the JS runtime call.
   1234   const Operator* call =
   1235       javascript()->CallFunction(arg_count + 2, language_mode());
   1236   Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 2);
   1237   environment()->BindAccumulator(value, &states);
   1238 }
   1239 
   1240 
   1241 Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
   1242     const Operator* call_runtime_op, interpreter::Register first_arg,
   1243     size_t arity) {
   1244   Node** all = info()->zone()->NewArray<Node*>(arity);
   1245   int first_arg_index = first_arg.index();
   1246   for (int i = 0; i < static_cast<int>(arity); ++i) {
   1247     all[i] = environment()->LookupRegister(
   1248         interpreter::Register(first_arg_index + i));
   1249   }
   1250   Node* value = MakeNode(call_runtime_op, static_cast<int>(arity), all, false);
   1251   return value;
   1252 }
   1253 
   1254 
   1255 void BytecodeGraphBuilder::VisitCallRuntime(
   1256     const interpreter::BytecodeArrayIterator& iterator) {
   1257   FrameStateBeforeAndAfter states(this, iterator);
   1258   Runtime::FunctionId functionId =
   1259       static_cast<Runtime::FunctionId>(iterator.GetIndexOperand(0));
   1260   interpreter::Register first_arg = iterator.GetRegisterOperand(1);
   1261   size_t arg_count = iterator.GetCountOperand(2);
   1262 
   1263   // Create node to perform the runtime call.
   1264   const Operator* call = javascript()->CallRuntime(functionId, arg_count);
   1265   Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
   1266   environment()->BindAccumulator(value, &states);
   1267 }
   1268 
   1269 
   1270 void BytecodeGraphBuilder::VisitCallRuntimeForPair(
   1271     const interpreter::BytecodeArrayIterator& iterator) {
   1272   FrameStateBeforeAndAfter states(this, iterator);
   1273   Runtime::FunctionId functionId =
   1274       static_cast<Runtime::FunctionId>(iterator.GetIndexOperand(0));
   1275   interpreter::Register first_arg = iterator.GetRegisterOperand(1);
   1276   size_t arg_count = iterator.GetCountOperand(2);
   1277   interpreter::Register first_return = iterator.GetRegisterOperand(3);
   1278 
   1279   // Create node to perform the runtime call.
   1280   const Operator* call = javascript()->CallRuntime(functionId, arg_count);
   1281   Node* return_pair = ProcessCallRuntimeArguments(call, first_arg, arg_count);
   1282   environment()->BindRegistersToProjections(first_return, return_pair, &states);
   1283 }
   1284 
   1285 
   1286 Node* BytecodeGraphBuilder::ProcessCallNewArguments(
   1287     const Operator* call_new_op, interpreter::Register callee,
   1288     interpreter::Register first_arg, size_t arity) {
   1289   Node** all = info()->zone()->NewArray<Node*>(arity);
   1290   all[0] = environment()->LookupRegister(callee);
   1291   int first_arg_index = first_arg.index();
   1292   for (int i = 1; i < static_cast<int>(arity) - 1; ++i) {
   1293     all[i] = environment()->LookupRegister(
   1294         interpreter::Register(first_arg_index + i - 1));
   1295   }
   1296   // Original constructor is the same as the callee.
   1297   all[arity - 1] = environment()->LookupRegister(callee);
   1298   Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false);
   1299   return value;
   1300 }
   1301 
   1302 
   1303 void BytecodeGraphBuilder::VisitNew(
   1304     const interpreter::BytecodeArrayIterator& iterator) {
   1305   FrameStateBeforeAndAfter states(this, iterator);
   1306   interpreter::Register callee = iterator.GetRegisterOperand(0);
   1307   interpreter::Register first_arg = iterator.GetRegisterOperand(1);
   1308   size_t arg_count = iterator.GetCountOperand(2);
   1309 
   1310   // TODO(turbofan): Pass the feedback here.
   1311   const Operator* call = javascript()->CallConstruct(
   1312       static_cast<int>(arg_count) + 2, VectorSlotPair());
   1313   Node* value = ProcessCallNewArguments(call, callee, first_arg, arg_count + 2);
   1314   environment()->BindAccumulator(value, &states);
   1315 }
   1316 
   1317 
   1318 void BytecodeGraphBuilder::VisitThrow(
   1319     const interpreter::BytecodeArrayIterator& iterator) {
   1320   FrameStateBeforeAndAfter states(this, iterator);
   1321   Node* value = environment()->LookupAccumulator();
   1322   // TODO(mythria): Change to Runtime::kThrow when we have deoptimization
   1323   // information support in the interpreter.
   1324   NewNode(javascript()->CallRuntime(Runtime::kReThrow, 1), value);
   1325   Node* control = NewNode(common()->Throw(), value);
   1326   environment()->RecordAfterState(control, &states);
   1327   UpdateControlDependencyToLeaveFunction(control);
   1328 }
   1329 
   1330 
   1331 void BytecodeGraphBuilder::BuildBinaryOp(
   1332     const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) {
   1333   FrameStateBeforeAndAfter states(this, iterator);
   1334   Node* left = environment()->LookupRegister(iterator.GetRegisterOperand(0));
   1335   Node* right = environment()->LookupAccumulator();
   1336   Node* node = NewNode(js_op, left, right);
   1337   environment()->BindAccumulator(node, &states);
   1338 }
   1339 
   1340 
   1341 void BytecodeGraphBuilder::VisitAdd(
   1342     const interpreter::BytecodeArrayIterator& iterator) {
   1343   BinaryOperationHints hints = BinaryOperationHints::Any();
   1344   BuildBinaryOp(javascript()->Add(language_mode(), hints), iterator);
   1345 }
   1346 
   1347 
   1348 void BytecodeGraphBuilder::VisitSub(
   1349     const interpreter::BytecodeArrayIterator& iterator) {
   1350   BinaryOperationHints hints = BinaryOperationHints::Any();
   1351   BuildBinaryOp(javascript()->Subtract(language_mode(), hints), iterator);
   1352 }
   1353 
   1354 
   1355 void BytecodeGraphBuilder::VisitMul(
   1356     const interpreter::BytecodeArrayIterator& iterator) {
   1357   BinaryOperationHints hints = BinaryOperationHints::Any();
   1358   BuildBinaryOp(javascript()->Multiply(language_mode(), hints), iterator);
   1359 }
   1360 
   1361 
   1362 void BytecodeGraphBuilder::VisitDiv(
   1363     const interpreter::BytecodeArrayIterator& iterator) {
   1364   BinaryOperationHints hints = BinaryOperationHints::Any();
   1365   BuildBinaryOp(javascript()->Divide(language_mode(), hints), iterator);
   1366 }
   1367 
   1368 
   1369 void BytecodeGraphBuilder::VisitMod(
   1370     const interpreter::BytecodeArrayIterator& iterator) {
   1371   BinaryOperationHints hints = BinaryOperationHints::Any();
   1372   BuildBinaryOp(javascript()->Modulus(language_mode(), hints), iterator);
   1373 }
   1374 
   1375 
   1376 void BytecodeGraphBuilder::VisitBitwiseOr(
   1377     const interpreter::BytecodeArrayIterator& iterator) {
   1378   BinaryOperationHints hints = BinaryOperationHints::Any();
   1379   BuildBinaryOp(javascript()->BitwiseOr(language_mode(), hints), iterator);
   1380 }
   1381 
   1382 
   1383 void BytecodeGraphBuilder::VisitBitwiseXor(
   1384     const interpreter::BytecodeArrayIterator& iterator) {
   1385   BinaryOperationHints hints = BinaryOperationHints::Any();
   1386   BuildBinaryOp(javascript()->BitwiseXor(language_mode(), hints), iterator);
   1387 }
   1388 
   1389 
   1390 void BytecodeGraphBuilder::VisitBitwiseAnd(
   1391     const interpreter::BytecodeArrayIterator& iterator) {
   1392   BinaryOperationHints hints = BinaryOperationHints::Any();
   1393   BuildBinaryOp(javascript()->BitwiseAnd(language_mode(), hints), iterator);
   1394 }
   1395 
   1396 
   1397 void BytecodeGraphBuilder::VisitShiftLeft(
   1398     const interpreter::BytecodeArrayIterator& iterator) {
   1399   BinaryOperationHints hints = BinaryOperationHints::Any();
   1400   BuildBinaryOp(javascript()->ShiftLeft(language_mode(), hints), iterator);
   1401 }
   1402 
   1403 
   1404 void BytecodeGraphBuilder::VisitShiftRight(
   1405     const interpreter::BytecodeArrayIterator& iterator) {
   1406   BinaryOperationHints hints = BinaryOperationHints::Any();
   1407   BuildBinaryOp(javascript()->ShiftRight(language_mode(), hints), iterator);
   1408 }
   1409 
   1410 
   1411 void BytecodeGraphBuilder::VisitShiftRightLogical(
   1412     const interpreter::BytecodeArrayIterator& iterator) {
   1413   BinaryOperationHints hints = BinaryOperationHints::Any();
   1414   BuildBinaryOp(javascript()->ShiftRightLogical(language_mode(), hints),
   1415                 iterator);
   1416 }
   1417 
   1418 
   1419 void BytecodeGraphBuilder::VisitInc(
   1420     const interpreter::BytecodeArrayIterator& iterator) {
   1421   FrameStateBeforeAndAfter states(this, iterator);
   1422   const Operator* js_op =
   1423       javascript()->Add(language_mode(), BinaryOperationHints::Any());
   1424   Node* node = NewNode(js_op, environment()->LookupAccumulator(),
   1425                        jsgraph()->OneConstant());
   1426   environment()->BindAccumulator(node, &states);
   1427 }
   1428 
   1429 
   1430 void BytecodeGraphBuilder::VisitDec(
   1431     const interpreter::BytecodeArrayIterator& iterator) {
   1432   FrameStateBeforeAndAfter states(this, iterator);
   1433   const Operator* js_op =
   1434       javascript()->Subtract(language_mode(), BinaryOperationHints::Any());
   1435   Node* node = NewNode(js_op, environment()->LookupAccumulator(),
   1436                        jsgraph()->OneConstant());
   1437   environment()->BindAccumulator(node, &states);
   1438 }
   1439 
   1440 
   1441 void BytecodeGraphBuilder::VisitLogicalNot(
   1442     const interpreter::BytecodeArrayIterator& iterator) {
   1443   Node* value = NewNode(javascript()->ToBoolean(ToBooleanHint::kAny),
   1444                         environment()->LookupAccumulator());
   1445   Node* node = NewNode(common()->Select(MachineRepresentation::kTagged), value,
   1446                        jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
   1447   environment()->BindAccumulator(node);
   1448 }
   1449 
   1450 
   1451 void BytecodeGraphBuilder::VisitTypeOf(
   1452     const interpreter::BytecodeArrayIterator& iterator) {
   1453   Node* node =
   1454       NewNode(javascript()->TypeOf(), environment()->LookupAccumulator());
   1455   environment()->BindAccumulator(node);
   1456 }
   1457 
   1458 
   1459 void BytecodeGraphBuilder::BuildDelete(
   1460     const interpreter::BytecodeArrayIterator& iterator) {
   1461   FrameStateBeforeAndAfter states(this, iterator);
   1462   Node* key = environment()->LookupAccumulator();
   1463   Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0));
   1464   Node* node =
   1465       NewNode(javascript()->DeleteProperty(language_mode()), object, key);
   1466   environment()->BindAccumulator(node, &states);
   1467 }
   1468 
   1469 
   1470 void BytecodeGraphBuilder::VisitDeletePropertyStrict(
   1471     const interpreter::BytecodeArrayIterator& iterator) {
   1472   DCHECK(is_strict(language_mode()));
   1473   BuildDelete(iterator);
   1474 }
   1475 
   1476 
   1477 void BytecodeGraphBuilder::VisitDeletePropertySloppy(
   1478     const interpreter::BytecodeArrayIterator& iterator) {
   1479   DCHECK(is_sloppy(language_mode()));
   1480   BuildDelete(iterator);
   1481 }
   1482 
   1483 
   1484 void BytecodeGraphBuilder::VisitDeleteLookupSlot(
   1485     const interpreter::BytecodeArrayIterator& iterator) {
   1486   FrameStateBeforeAndAfter states(this, iterator);
   1487   Node* name = environment()->LookupAccumulator();
   1488   const Operator* op = javascript()->CallRuntime(Runtime::kDeleteLookupSlot, 2);
   1489   Node* result = NewNode(op, environment()->Context(), name);
   1490   environment()->BindAccumulator(result, &states);
   1491 }
   1492 
   1493 
   1494 void BytecodeGraphBuilder::BuildCompareOp(
   1495     const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) {
   1496   FrameStateBeforeAndAfter states(this, iterator);
   1497   Node* left = environment()->LookupRegister(iterator.GetRegisterOperand(0));
   1498   Node* right = environment()->LookupAccumulator();
   1499   Node* node = NewNode(js_op, left, right);
   1500   environment()->BindAccumulator(node, &states);
   1501 }
   1502 
   1503 
   1504 void BytecodeGraphBuilder::VisitTestEqual(
   1505     const interpreter::BytecodeArrayIterator& iterator) {
   1506   BuildCompareOp(javascript()->Equal(), iterator);
   1507 }
   1508 
   1509 
   1510 void BytecodeGraphBuilder::VisitTestNotEqual(
   1511     const interpreter::BytecodeArrayIterator& iterator) {
   1512   BuildCompareOp(javascript()->NotEqual(), iterator);
   1513 }
   1514 
   1515 
   1516 void BytecodeGraphBuilder::VisitTestEqualStrict(
   1517     const interpreter::BytecodeArrayIterator& iterator) {
   1518   BuildCompareOp(javascript()->StrictEqual(), iterator);
   1519 }
   1520 
   1521 
   1522 void BytecodeGraphBuilder::VisitTestNotEqualStrict(
   1523     const interpreter::BytecodeArrayIterator& iterator) {
   1524   BuildCompareOp(javascript()->StrictNotEqual(), iterator);
   1525 }
   1526 
   1527 
   1528 void BytecodeGraphBuilder::VisitTestLessThan(
   1529     const interpreter::BytecodeArrayIterator& iterator) {
   1530   BuildCompareOp(javascript()->LessThan(language_mode()), iterator);
   1531 }
   1532 
   1533 
   1534 void BytecodeGraphBuilder::VisitTestGreaterThan(
   1535     const interpreter::BytecodeArrayIterator& iterator) {
   1536   BuildCompareOp(javascript()->GreaterThan(language_mode()), iterator);
   1537 }
   1538 
   1539 
   1540 void BytecodeGraphBuilder::VisitTestLessThanOrEqual(
   1541     const interpreter::BytecodeArrayIterator& iterator) {
   1542   BuildCompareOp(javascript()->LessThanOrEqual(language_mode()), iterator);
   1543 }
   1544 
   1545 
   1546 void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual(
   1547     const interpreter::BytecodeArrayIterator& iterator) {
   1548   BuildCompareOp(javascript()->GreaterThanOrEqual(language_mode()), iterator);
   1549 }
   1550 
   1551 
   1552 void BytecodeGraphBuilder::VisitTestIn(
   1553     const interpreter::BytecodeArrayIterator& iterator) {
   1554   BuildCompareOp(javascript()->HasProperty(), iterator);
   1555 }
   1556 
   1557 
   1558 void BytecodeGraphBuilder::VisitTestInstanceOf(
   1559     const interpreter::BytecodeArrayIterator& iterator) {
   1560   BuildCompareOp(javascript()->InstanceOf(), iterator);
   1561 }
   1562 
   1563 
   1564 void BytecodeGraphBuilder::BuildCastOperator(
   1565     const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) {
   1566   FrameStateBeforeAndAfter states(this, iterator);
   1567   Node* node = NewNode(js_op, environment()->LookupAccumulator());
   1568   environment()->BindAccumulator(node, &states);
   1569 }
   1570 
   1571 
   1572 void BytecodeGraphBuilder::VisitToName(
   1573     const interpreter::BytecodeArrayIterator& iterator) {
   1574   BuildCastOperator(javascript()->ToName(), iterator);
   1575 }
   1576 
   1577 
   1578 void BytecodeGraphBuilder::VisitToObject(
   1579     const interpreter::BytecodeArrayIterator& iterator) {
   1580   BuildCastOperator(javascript()->ToObject(), iterator);
   1581 }
   1582 
   1583 
   1584 void BytecodeGraphBuilder::VisitToNumber(
   1585     const interpreter::BytecodeArrayIterator& iterator) {
   1586   BuildCastOperator(javascript()->ToNumber(), iterator);
   1587 }
   1588 
   1589 
   1590 void BytecodeGraphBuilder::VisitJump(
   1591     const interpreter::BytecodeArrayIterator& iterator) {
   1592   BuildJump();
   1593 }
   1594 
   1595 
   1596 void BytecodeGraphBuilder::VisitJumpConstant(
   1597     const interpreter::BytecodeArrayIterator& iterator) {
   1598   BuildJump();
   1599 }
   1600 
   1601 
   1602 void BytecodeGraphBuilder::VisitJumpConstantWide(
   1603     const interpreter::BytecodeArrayIterator& iterator) {
   1604   BuildJump();
   1605 }
   1606 
   1607 
   1608 void BytecodeGraphBuilder::VisitJumpIfTrue(
   1609     const interpreter::BytecodeArrayIterator& iterator) {
   1610   BuildJumpIfEqual(jsgraph()->TrueConstant());
   1611 }
   1612 
   1613 
   1614 void BytecodeGraphBuilder::VisitJumpIfTrueConstant(
   1615     const interpreter::BytecodeArrayIterator& iterator) {
   1616   BuildJumpIfEqual(jsgraph()->TrueConstant());
   1617 }
   1618 
   1619 
   1620 void BytecodeGraphBuilder::VisitJumpIfTrueConstantWide(
   1621     const interpreter::BytecodeArrayIterator& iterator) {
   1622   BuildJumpIfEqual(jsgraph()->TrueConstant());
   1623 }
   1624 
   1625 
   1626 void BytecodeGraphBuilder::VisitJumpIfFalse(
   1627     const interpreter::BytecodeArrayIterator& iterator) {
   1628   BuildJumpIfEqual(jsgraph()->FalseConstant());
   1629 }
   1630 
   1631 
   1632 void BytecodeGraphBuilder::VisitJumpIfFalseConstant(
   1633     const interpreter::BytecodeArrayIterator& iterator) {
   1634   BuildJumpIfEqual(jsgraph()->FalseConstant());
   1635 }
   1636 
   1637 
   1638 void BytecodeGraphBuilder::VisitJumpIfFalseConstantWide(
   1639     const interpreter::BytecodeArrayIterator& iterator) {
   1640   BuildJumpIfEqual(jsgraph()->FalseConstant());
   1641 }
   1642 
   1643 
   1644 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue(
   1645     const interpreter::BytecodeArrayIterator& iterator) {
   1646   BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
   1647 }
   1648 
   1649 
   1650 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant(
   1651     const interpreter::BytecodeArrayIterator& iterator) {
   1652   BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
   1653 }
   1654 
   1655 
   1656 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstantWide(
   1657     const interpreter::BytecodeArrayIterator& iterator) {
   1658   BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
   1659 }
   1660 
   1661 
   1662 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse(
   1663     const interpreter::BytecodeArrayIterator& iterator) {
   1664   BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
   1665 }
   1666 
   1667 
   1668 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant(
   1669     const interpreter::BytecodeArrayIterator& iterator) {
   1670   BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
   1671 }
   1672 
   1673 
   1674 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstantWide(
   1675     const interpreter::BytecodeArrayIterator& iterator) {
   1676   BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
   1677 }
   1678 
   1679 
   1680 void BytecodeGraphBuilder::VisitJumpIfNull(
   1681     const interpreter::BytecodeArrayIterator& iterator) {
   1682   BuildJumpIfEqual(jsgraph()->NullConstant());
   1683 }
   1684 
   1685 
   1686 void BytecodeGraphBuilder::VisitJumpIfNullConstant(
   1687     const interpreter::BytecodeArrayIterator& iterator) {
   1688   BuildJumpIfEqual(jsgraph()->NullConstant());
   1689 }
   1690 
   1691 
   1692 void BytecodeGraphBuilder::VisitJumpIfNullConstantWide(
   1693     const interpreter::BytecodeArrayIterator& iterator) {
   1694   BuildJumpIfEqual(jsgraph()->NullConstant());
   1695 }
   1696 
   1697 
   1698 void BytecodeGraphBuilder::VisitJumpIfUndefined(
   1699     const interpreter::BytecodeArrayIterator& iterator) {
   1700   BuildJumpIfEqual(jsgraph()->UndefinedConstant());
   1701 }
   1702 
   1703 
   1704 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant(
   1705     const interpreter::BytecodeArrayIterator& iterator) {
   1706   BuildJumpIfEqual(jsgraph()->UndefinedConstant());
   1707 }
   1708 
   1709 
   1710 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstantWide(
   1711     const interpreter::BytecodeArrayIterator& iterator) {
   1712   BuildJumpIfEqual(jsgraph()->UndefinedConstant());
   1713 }
   1714 
   1715 
   1716 void BytecodeGraphBuilder::VisitReturn(
   1717     const interpreter::BytecodeArrayIterator& iterator) {
   1718   Node* control =
   1719       NewNode(common()->Return(), environment()->LookupAccumulator());
   1720   UpdateControlDependencyToLeaveFunction(control);
   1721   set_environment(nullptr);
   1722 }
   1723 
   1724 
   1725 void BytecodeGraphBuilder::VisitForInPrepare(
   1726     const interpreter::BytecodeArrayIterator& iterator) {
   1727   Node* prepare = nullptr;
   1728   {
   1729     FrameStateBeforeAndAfter states(this, iterator);
   1730     Node* receiver = environment()->LookupAccumulator();
   1731     prepare = NewNode(javascript()->ForInPrepare(), receiver);
   1732     environment()->RecordAfterState(prepare, &states);
   1733   }
   1734   // Project cache_type, cache_array, cache_length into register
   1735   // operands 1, 2, 3.
   1736   for (int i = 0; i < 3; i++) {
   1737     environment()->BindRegister(iterator.GetRegisterOperand(i),
   1738                                 NewNode(common()->Projection(i), prepare));
   1739   }
   1740 }
   1741 
   1742 
   1743 void BytecodeGraphBuilder::VisitForInDone(
   1744     const interpreter::BytecodeArrayIterator& iterator) {
   1745   FrameStateBeforeAndAfter states(this, iterator);
   1746   Node* index = environment()->LookupRegister(iterator.GetRegisterOperand(0));
   1747   Node* cache_length =
   1748       environment()->LookupRegister(iterator.GetRegisterOperand(1));
   1749   Node* exit_cond = NewNode(javascript()->ForInDone(), index, cache_length);
   1750   environment()->BindAccumulator(exit_cond, &states);
   1751 }
   1752 
   1753 
   1754 void BytecodeGraphBuilder::VisitForInNext(
   1755     const interpreter::BytecodeArrayIterator& iterator) {
   1756   FrameStateBeforeAndAfter states(this, iterator);
   1757   Node* receiver =
   1758       environment()->LookupRegister(iterator.GetRegisterOperand(0));
   1759   Node* cache_type =
   1760       environment()->LookupRegister(iterator.GetRegisterOperand(1));
   1761   Node* cache_array =
   1762       environment()->LookupRegister(iterator.GetRegisterOperand(2));
   1763   Node* index = environment()->LookupRegister(iterator.GetRegisterOperand(3));
   1764   Node* value = NewNode(javascript()->ForInNext(), receiver, cache_array,
   1765                         cache_type, index);
   1766   environment()->BindAccumulator(value, &states);
   1767 }
   1768 
   1769 
   1770 void BytecodeGraphBuilder::VisitForInStep(
   1771     const interpreter::BytecodeArrayIterator& iterator) {
   1772   FrameStateBeforeAndAfter states(this, iterator);
   1773   Node* index = environment()->LookupRegister(iterator.GetRegisterOperand(0));
   1774   index = NewNode(javascript()->ForInStep(), index);
   1775   environment()->BindAccumulator(index, &states);
   1776 }
   1777 
   1778 
   1779 void BytecodeGraphBuilder::MergeEnvironmentsOfBackwardBranches(
   1780     int source_offset, int target_offset) {
   1781   DCHECK_GE(source_offset, target_offset);
   1782   const ZoneVector<int>* branch_sites =
   1783       branch_analysis()->BackwardBranchesTargetting(target_offset);
   1784   if (branch_sites->back() == source_offset) {
   1785     // The set of back branches is complete, merge them.
   1786     DCHECK_GE(branch_sites->at(0), target_offset);
   1787     Environment* merged = merge_environments_[branch_sites->at(0)];
   1788     for (size_t i = 1; i < branch_sites->size(); i++) {
   1789       DCHECK_GE(branch_sites->at(i), target_offset);
   1790       merged->Merge(merge_environments_[branch_sites->at(i)]);
   1791     }
   1792     // And now merge with loop header environment created when loop
   1793     // header was visited.
   1794     loop_header_environments_[target_offset]->Merge(merged);
   1795   }
   1796 }
   1797 
   1798 
   1799 void BytecodeGraphBuilder::MergeEnvironmentsOfForwardBranches(
   1800     int source_offset) {
   1801   if (branch_analysis()->forward_branches_target(source_offset)) {
   1802     // Merge environments of branches that reach this bytecode.
   1803     auto branch_sites =
   1804         branch_analysis()->ForwardBranchesTargetting(source_offset);
   1805     DCHECK_LT(branch_sites->at(0), source_offset);
   1806     Environment* merged = merge_environments_[branch_sites->at(0)];
   1807     for (size_t i = 1; i < branch_sites->size(); i++) {
   1808       DCHECK_LT(branch_sites->at(i), source_offset);
   1809       merged->Merge(merge_environments_[branch_sites->at(i)]);
   1810     }
   1811     if (environment()) {
   1812       merged->Merge(environment());
   1813     }
   1814     set_environment(merged);
   1815   }
   1816 }
   1817 
   1818 
   1819 void BytecodeGraphBuilder::BuildLoopHeaderForBackwardBranches(
   1820     int source_offset) {
   1821   if (branch_analysis()->backward_branches_target(source_offset)) {
   1822     // Add loop header and store a copy so we can connect merged back
   1823     // edge inputs to the loop header.
   1824     loop_header_environments_[source_offset] = environment()->CopyForLoop();
   1825   }
   1826 }
   1827 
   1828 
   1829 void BytecodeGraphBuilder::BuildJump(int source_offset, int target_offset) {
   1830   DCHECK_NULL(merge_environments_[source_offset]);
   1831   merge_environments_[source_offset] = environment();
   1832   if (source_offset >= target_offset) {
   1833     MergeEnvironmentsOfBackwardBranches(source_offset, target_offset);
   1834   }
   1835   set_environment(nullptr);
   1836 }
   1837 
   1838 
   1839 void BytecodeGraphBuilder::BuildJump() {
   1840   int source_offset = bytecode_iterator()->current_offset();
   1841   int target_offset = bytecode_iterator()->GetJumpTargetOffset();
   1842   BuildJump(source_offset, target_offset);
   1843 }
   1844 
   1845 
   1846 void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) {
   1847   int source_offset = bytecode_iterator()->current_offset();
   1848   NewBranch(condition);
   1849   Environment* if_false_environment = environment()->CopyForConditional();
   1850   NewIfTrue();
   1851   BuildJump(source_offset, bytecode_iterator()->GetJumpTargetOffset());
   1852   set_environment(if_false_environment);
   1853   NewIfFalse();
   1854 }
   1855 
   1856 
   1857 void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
   1858   Node* accumulator = environment()->LookupAccumulator();
   1859   Node* condition =
   1860       NewNode(javascript()->StrictEqual(), accumulator, comperand);
   1861   BuildConditionalJump(condition);
   1862 }
   1863 
   1864 
   1865 void BytecodeGraphBuilder::BuildJumpIfToBooleanEqual(Node* comperand) {
   1866   Node* accumulator = environment()->LookupAccumulator();
   1867   Node* to_boolean =
   1868       NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
   1869   Node* condition = NewNode(javascript()->StrictEqual(), to_boolean, comperand);
   1870   BuildConditionalJump(condition);
   1871 }
   1872 
   1873 
   1874 Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) {
   1875   if (size > input_buffer_size_) {
   1876     size = size + kInputBufferSizeIncrement + input_buffer_size_;
   1877     input_buffer_ = local_zone()->NewArray<Node*>(size);
   1878     input_buffer_size_ = size;
   1879   }
   1880   return input_buffer_;
   1881 }
   1882 
   1883 
   1884 void BytecodeGraphBuilder::PrepareEntryFrameState(Node* node) {
   1885   DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
   1886   DCHECK_EQ(IrOpcode::kDead,
   1887             NodeProperties::GetFrameStateInput(node, 0)->opcode());
   1888   NodeProperties::ReplaceFrameStateInput(
   1889       node, 0, environment()->Checkpoint(BailoutId(0),
   1890                                          OutputFrameStateCombine::Ignore()));
   1891 }
   1892 
   1893 
   1894 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
   1895                                      Node** value_inputs, bool incomplete) {
   1896   DCHECK_EQ(op->ValueInputCount(), value_input_count);
   1897 
   1898   bool has_context = OperatorProperties::HasContextInput(op);
   1899   int frame_state_count = OperatorProperties::GetFrameStateInputCount(op);
   1900   bool has_control = op->ControlInputCount() == 1;
   1901   bool has_effect = op->EffectInputCount() == 1;
   1902 
   1903   DCHECK_LT(op->ControlInputCount(), 2);
   1904   DCHECK_LT(op->EffectInputCount(), 2);
   1905 
   1906   Node* result = nullptr;
   1907   if (!has_context && frame_state_count == 0 && !has_control && !has_effect) {
   1908     result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
   1909   } else {
   1910     int input_count_with_deps = value_input_count;
   1911     if (has_context) ++input_count_with_deps;
   1912     input_count_with_deps += frame_state_count;
   1913     if (has_control) ++input_count_with_deps;
   1914     if (has_effect) ++input_count_with_deps;
   1915     Node** buffer = EnsureInputBufferSize(input_count_with_deps);
   1916     memcpy(buffer, value_inputs, kPointerSize * value_input_count);
   1917     Node** current_input = buffer + value_input_count;
   1918     if (has_context) {
   1919       *current_input++ = environment()->Context();
   1920     }
   1921     for (int i = 0; i < frame_state_count; i++) {
   1922       // The frame state will be inserted later. Here we misuse
   1923       // the {Dead} node as a sentinel to be later overwritten
   1924       // with the real frame state.
   1925       *current_input++ = jsgraph()->Dead();
   1926     }
   1927     if (has_effect) {
   1928       *current_input++ = environment()->GetEffectDependency();
   1929     }
   1930     if (has_control) {
   1931       *current_input++ = environment()->GetControlDependency();
   1932     }
   1933     result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
   1934     if (!environment()->IsMarkedAsUnreachable()) {
   1935       // Update the current control dependency for control-producing nodes.
   1936       if (NodeProperties::IsControl(result)) {
   1937         environment()->UpdateControlDependency(result);
   1938       }
   1939       // Update the current effect dependency for effect-producing nodes.
   1940       if (result->op()->EffectOutputCount() > 0) {
   1941         environment()->UpdateEffectDependency(result);
   1942       }
   1943       // Add implicit success continuation for throwing nodes.
   1944       if (!result->op()->HasProperty(Operator::kNoThrow)) {
   1945         const Operator* if_success = common()->IfSuccess();
   1946         Node* on_success = graph()->NewNode(if_success, result);
   1947         environment_->UpdateControlDependency(on_success);
   1948       }
   1949     }
   1950   }
   1951 
   1952   return result;
   1953 }
   1954 
   1955 
   1956 Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) {
   1957   const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
   1958   Node** buffer = EnsureInputBufferSize(count + 1);
   1959   MemsetPointer(buffer, input, count);
   1960   buffer[count] = control;
   1961   return graph()->NewNode(phi_op, count + 1, buffer, true);
   1962 }
   1963 
   1964 
   1965 Node* BytecodeGraphBuilder::NewEffectPhi(int count, Node* input,
   1966                                          Node* control) {
   1967   const Operator* phi_op = common()->EffectPhi(count);
   1968   Node** buffer = EnsureInputBufferSize(count + 1);
   1969   MemsetPointer(buffer, input, count);
   1970   buffer[count] = control;
   1971   return graph()->NewNode(phi_op, count + 1, buffer, true);
   1972 }
   1973 
   1974 
   1975 Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) {
   1976   int inputs = control->op()->ControlInputCount() + 1;
   1977   if (control->opcode() == IrOpcode::kLoop) {
   1978     // Control node for loop exists, add input.
   1979     const Operator* op = common()->Loop(inputs);
   1980     control->AppendInput(graph_zone(), other);
   1981     NodeProperties::ChangeOp(control, op);
   1982   } else if (control->opcode() == IrOpcode::kMerge) {
   1983     // Control node for merge exists, add input.
   1984     const Operator* op = common()->Merge(inputs);
   1985     control->AppendInput(graph_zone(), other);
   1986     NodeProperties::ChangeOp(control, op);
   1987   } else {
   1988     // Control node is a singleton, introduce a merge.
   1989     const Operator* op = common()->Merge(inputs);
   1990     Node* merge_inputs[] = {control, other};
   1991     control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true);
   1992   }
   1993   return control;
   1994 }
   1995 
   1996 
   1997 Node* BytecodeGraphBuilder::MergeEffect(Node* value, Node* other,
   1998                                         Node* control) {
   1999   int inputs = control->op()->ControlInputCount();
   2000   if (value->opcode() == IrOpcode::kEffectPhi &&
   2001       NodeProperties::GetControlInput(value) == control) {
   2002     // Phi already exists, add input.
   2003     value->InsertInput(graph_zone(), inputs - 1, other);
   2004     NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
   2005   } else if (value != other) {
   2006     // Phi does not exist yet, introduce one.
   2007     value = NewEffectPhi(inputs, value, control);
   2008     value->ReplaceInput(inputs - 1, other);
   2009   }
   2010   return value;
   2011 }
   2012 
   2013 
   2014 Node* BytecodeGraphBuilder::MergeValue(Node* value, Node* other,
   2015                                        Node* control) {
   2016   int inputs = control->op()->ControlInputCount();
   2017   if (value->opcode() == IrOpcode::kPhi &&
   2018       NodeProperties::GetControlInput(value) == control) {
   2019     // Phi already exists, add input.
   2020     value->InsertInput(graph_zone(), inputs - 1, other);
   2021     NodeProperties::ChangeOp(
   2022         value, common()->Phi(MachineRepresentation::kTagged, inputs));
   2023   } else if (value != other) {
   2024     // Phi does not exist yet, introduce one.
   2025     value = NewPhi(inputs, value, control);
   2026     value->ReplaceInput(inputs - 1, other);
   2027   }
   2028   return value;
   2029 }
   2030 
   2031 
   2032 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
   2033   if (environment()->IsMarkedAsUnreachable()) return;
   2034   environment()->MarkAsUnreachable();
   2035   exit_controls_.push_back(exit);
   2036 }
   2037 
   2038 }  // namespace compiler
   2039 }  // namespace internal
   2040 }  // namespace v8
   2041