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/ast/ast.h"
      8 #include "src/ast/scopes.h"
      9 #include "src/compiler/access-builder.h"
     10 #include "src/compiler/compiler-source-position-table.h"
     11 #include "src/compiler/linkage.h"
     12 #include "src/compiler/node-matchers.h"
     13 #include "src/compiler/operator-properties.h"
     14 #include "src/compiler/simplified-operator.h"
     15 #include "src/interpreter/bytecodes.h"
     16 #include "src/objects-inl.h"
     17 #include "src/objects/js-array-inl.h"
     18 #include "src/objects/js-generator.h"
     19 #include "src/objects/literal-objects-inl.h"
     20 #include "src/vector-slot-pair.h"
     21 
     22 namespace v8 {
     23 namespace internal {
     24 namespace compiler {
     25 
     26 // The abstract execution environment simulates the content of the interpreter
     27 // register file. The environment performs SSA-renaming of all tracked nodes at
     28 // split and merge points in the control flow.
     29 class BytecodeGraphBuilder::Environment : public ZoneObject {
     30  public:
     31   Environment(BytecodeGraphBuilder* builder, int register_count,
     32               int parameter_count,
     33               interpreter::Register incoming_new_target_or_generator,
     34               Node* control_dependency);
     35 
     36   // Specifies whether environment binding methods should attach frame state
     37   // inputs to nodes representing the value being bound. This is done because
     38   // the {OutputFrameStateCombine} is closely related to the binding method.
     39   enum FrameStateAttachmentMode { kAttachFrameState, kDontAttachFrameState };
     40 
     41   int parameter_count() const { return parameter_count_; }
     42   int register_count() const { return register_count_; }
     43 
     44   Node* LookupAccumulator() const;
     45   Node* LookupRegister(interpreter::Register the_register) const;
     46   Node* LookupGeneratorState() const;
     47 
     48   void BindAccumulator(Node* node,
     49                        FrameStateAttachmentMode mode = kDontAttachFrameState);
     50   void BindRegister(interpreter::Register the_register, Node* node,
     51                     FrameStateAttachmentMode mode = kDontAttachFrameState);
     52   void BindRegistersToProjections(
     53       interpreter::Register first_reg, Node* node,
     54       FrameStateAttachmentMode mode = kDontAttachFrameState);
     55   void BindGeneratorState(Node* node);
     56   void RecordAfterState(Node* node,
     57                         FrameStateAttachmentMode mode = kDontAttachFrameState);
     58 
     59   // Effect dependency tracked by this environment.
     60   Node* GetEffectDependency() { return effect_dependency_; }
     61   void UpdateEffectDependency(Node* dependency) {
     62     effect_dependency_ = dependency;
     63   }
     64 
     65   // Preserve a checkpoint of the environment for the IR graph. Any
     66   // further mutation of the environment will not affect checkpoints.
     67   Node* Checkpoint(BailoutId bytecode_offset, OutputFrameStateCombine combine,
     68                    const BytecodeLivenessState* liveness);
     69 
     70   // Control dependency tracked by this environment.
     71   Node* GetControlDependency() const { return control_dependency_; }
     72   void UpdateControlDependency(Node* dependency) {
     73     control_dependency_ = dependency;
     74   }
     75 
     76   Node* Context() const { return context_; }
     77   void SetContext(Node* new_context) { context_ = new_context; }
     78 
     79   Environment* Copy();
     80   void Merge(Environment* other, const BytecodeLivenessState* liveness);
     81 
     82   void FillWithOsrValues();
     83   void PrepareForLoop(const BytecodeLoopAssignments& assignments,
     84                       const BytecodeLivenessState* liveness);
     85   void PrepareForLoopExit(Node* loop,
     86                           const BytecodeLoopAssignments& assignments,
     87                           const BytecodeLivenessState* liveness);
     88 
     89  private:
     90   explicit Environment(const Environment* copy);
     91 
     92   bool StateValuesRequireUpdate(Node** state_values, Node** values, int count);
     93   void UpdateStateValues(Node** state_values, Node** values, int count);
     94   Node* GetStateValuesFromCache(Node** values, int count,
     95                                 const BitVector* liveness, int liveness_offset);
     96 
     97   int RegisterToValuesIndex(interpreter::Register the_register) const;
     98 
     99   Zone* zone() const { return builder_->local_zone(); }
    100   Graph* graph() const { return builder_->graph(); }
    101   CommonOperatorBuilder* common() const { return builder_->common(); }
    102   BytecodeGraphBuilder* builder() const { return builder_; }
    103   const NodeVector* values() const { return &values_; }
    104   NodeVector* values() { return &values_; }
    105   int register_base() const { return register_base_; }
    106   int accumulator_base() const { return accumulator_base_; }
    107 
    108   BytecodeGraphBuilder* builder_;
    109   int register_count_;
    110   int parameter_count_;
    111   Node* context_;
    112   Node* control_dependency_;
    113   Node* effect_dependency_;
    114   NodeVector values_;
    115   Node* parameters_state_values_;
    116   Node* generator_state_;
    117   int register_base_;
    118   int accumulator_base_;
    119 };
    120 
    121 // A helper for creating a temporary sub-environment for simple branches.
    122 struct BytecodeGraphBuilder::SubEnvironment final {
    123  public:
    124   explicit SubEnvironment(BytecodeGraphBuilder* builder)
    125       : builder_(builder), parent_(builder->environment()->Copy()) {}
    126 
    127   ~SubEnvironment() { builder_->set_environment(parent_); }
    128 
    129  private:
    130   BytecodeGraphBuilder* builder_;
    131   BytecodeGraphBuilder::Environment* parent_;
    132 };
    133 
    134 // Issues:
    135 // - Scopes - intimately tied to AST. Need to eval what is needed.
    136 // - Need to resolve closure parameter treatment.
    137 BytecodeGraphBuilder::Environment::Environment(
    138     BytecodeGraphBuilder* builder, int register_count, int parameter_count,
    139     interpreter::Register incoming_new_target_or_generator,
    140     Node* control_dependency)
    141     : builder_(builder),
    142       register_count_(register_count),
    143       parameter_count_(parameter_count),
    144       control_dependency_(control_dependency),
    145       effect_dependency_(control_dependency),
    146       values_(builder->local_zone()),
    147       parameters_state_values_(nullptr),
    148       generator_state_(nullptr) {
    149   // The layout of values_ is:
    150   //
    151   // [receiver] [parameters] [registers] [accumulator]
    152   //
    153   // parameter[0] is the receiver (this), parameters 1..N are the
    154   // parameters supplied to the method (arg0..argN-1). The accumulator
    155   // is stored separately.
    156 
    157   // Parameters including the receiver
    158   for (int i = 0; i < parameter_count; i++) {
    159     const char* debug_name = (i == 0) ? "%this" : nullptr;
    160     const Operator* op = common()->Parameter(i, debug_name);
    161     Node* parameter = builder->graph()->NewNode(op, graph()->start());
    162     values()->push_back(parameter);
    163   }
    164 
    165   // Registers
    166   register_base_ = static_cast<int>(values()->size());
    167   Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
    168   values()->insert(values()->end(), register_count, undefined_constant);
    169 
    170   // Accumulator
    171   accumulator_base_ = static_cast<int>(values()->size());
    172   values()->push_back(undefined_constant);
    173 
    174   // Context
    175   int context_index = Linkage::GetJSCallContextParamIndex(parameter_count);
    176   const Operator* op = common()->Parameter(context_index, "%context");
    177   context_ = builder->graph()->NewNode(op, graph()->start());
    178 
    179   // Incoming new.target or generator register
    180   if (incoming_new_target_or_generator.is_valid()) {
    181     int new_target_index =
    182         Linkage::GetJSCallNewTargetParamIndex(parameter_count);
    183     const Operator* op = common()->Parameter(new_target_index, "%new.target");
    184     Node* new_target_node = builder->graph()->NewNode(op, graph()->start());
    185 
    186     int values_index = RegisterToValuesIndex(incoming_new_target_or_generator);
    187     values()->at(values_index) = new_target_node;
    188   }
    189 }
    190 
    191 BytecodeGraphBuilder::Environment::Environment(
    192     const BytecodeGraphBuilder::Environment* other)
    193     : builder_(other->builder_),
    194       register_count_(other->register_count_),
    195       parameter_count_(other->parameter_count_),
    196       context_(other->context_),
    197       control_dependency_(other->control_dependency_),
    198       effect_dependency_(other->effect_dependency_),
    199       values_(other->zone()),
    200       parameters_state_values_(other->parameters_state_values_),
    201       generator_state_(other->generator_state_),
    202       register_base_(other->register_base_),
    203       accumulator_base_(other->accumulator_base_) {
    204   values_ = other->values_;
    205 }
    206 
    207 
    208 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex(
    209     interpreter::Register the_register) const {
    210   if (the_register.is_parameter()) {
    211     return the_register.ToParameterIndex(parameter_count());
    212   } else {
    213     return the_register.index() + register_base();
    214   }
    215 }
    216 
    217 Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const {
    218   return values()->at(accumulator_base_);
    219 }
    220 
    221 Node* BytecodeGraphBuilder::Environment::LookupGeneratorState() const {
    222   DCHECK_NOT_NULL(generator_state_);
    223   return generator_state_;
    224 }
    225 
    226 Node* BytecodeGraphBuilder::Environment::LookupRegister(
    227     interpreter::Register the_register) const {
    228   if (the_register.is_current_context()) {
    229     return Context();
    230   } else if (the_register.is_function_closure()) {
    231     return builder()->GetFunctionClosure();
    232   } else {
    233     int values_index = RegisterToValuesIndex(the_register);
    234     return values()->at(values_index);
    235   }
    236 }
    237 
    238 void BytecodeGraphBuilder::Environment::BindAccumulator(
    239     Node* node, FrameStateAttachmentMode mode) {
    240   if (mode == FrameStateAttachmentMode::kAttachFrameState) {
    241     builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(0));
    242   }
    243   values()->at(accumulator_base_) = node;
    244 }
    245 
    246 void BytecodeGraphBuilder::Environment::BindGeneratorState(Node* node) {
    247   generator_state_ = node;
    248 }
    249 
    250 void BytecodeGraphBuilder::Environment::BindRegister(
    251     interpreter::Register the_register, Node* node,
    252     FrameStateAttachmentMode mode) {
    253   int values_index = RegisterToValuesIndex(the_register);
    254   if (mode == FrameStateAttachmentMode::kAttachFrameState) {
    255     builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(
    256                                            accumulator_base_ - values_index));
    257   }
    258   values()->at(values_index) = node;
    259 }
    260 
    261 void BytecodeGraphBuilder::Environment::BindRegistersToProjections(
    262     interpreter::Register first_reg, Node* node,
    263     FrameStateAttachmentMode mode) {
    264   int values_index = RegisterToValuesIndex(first_reg);
    265   if (mode == FrameStateAttachmentMode::kAttachFrameState) {
    266     builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(
    267                                            accumulator_base_ - values_index));
    268   }
    269   for (int i = 0; i < node->op()->ValueOutputCount(); i++) {
    270     values()->at(values_index + i) =
    271         builder()->NewNode(common()->Projection(i), node);
    272   }
    273 }
    274 
    275 void BytecodeGraphBuilder::Environment::RecordAfterState(
    276     Node* node, FrameStateAttachmentMode mode) {
    277   if (mode == FrameStateAttachmentMode::kAttachFrameState) {
    278     builder()->PrepareFrameState(node, OutputFrameStateCombine::Ignore());
    279   }
    280 }
    281 
    282 BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::Environment::Copy() {
    283   return new (zone()) Environment(this);
    284 }
    285 
    286 void BytecodeGraphBuilder::Environment::Merge(
    287     BytecodeGraphBuilder::Environment* other,
    288     const BytecodeLivenessState* liveness) {
    289   // Create a merge of the control dependencies of both environments and update
    290   // the current environment's control dependency accordingly.
    291   Node* control = builder()->MergeControl(GetControlDependency(),
    292                                           other->GetControlDependency());
    293   UpdateControlDependency(control);
    294 
    295   // Create a merge of the effect dependencies of both environments and update
    296   // the current environment's effect dependency accordingly.
    297   Node* effect = builder()->MergeEffect(GetEffectDependency(),
    298                                         other->GetEffectDependency(), control);
    299   UpdateEffectDependency(effect);
    300 
    301   // Introduce Phi nodes for values that are live and have differing inputs at
    302   // the merge point, potentially extending an existing Phi node if possible.
    303   context_ = builder()->MergeValue(context_, other->context_, control);
    304   for (int i = 0; i < parameter_count(); i++) {
    305     values_[i] = builder()->MergeValue(values_[i], other->values_[i], control);
    306   }
    307   for (int i = 0; i < register_count(); i++) {
    308     int index = register_base() + i;
    309     if (liveness == nullptr || liveness->RegisterIsLive(i)) {
    310 #if DEBUG
    311       // We only do these DCHECKs when we are not in the resume path of a
    312       // generator -- this is, when either there is no generator state at all,
    313       // or the generator state is not the constant "executing" value.
    314       if (generator_state_ == nullptr ||
    315           NumberMatcher(generator_state_)
    316               .Is(JSGeneratorObject::kGeneratorExecuting)) {
    317         DCHECK_NE(values_[index], builder()->jsgraph()->OptimizedOutConstant());
    318         DCHECK_NE(other->values_[index],
    319                   builder()->jsgraph()->OptimizedOutConstant());
    320       }
    321 #endif
    322 
    323       values_[index] =
    324           builder()->MergeValue(values_[index], other->values_[index], control);
    325 
    326     } else {
    327       values_[index] = builder()->jsgraph()->OptimizedOutConstant();
    328     }
    329   }
    330 
    331   if (liveness == nullptr || liveness->AccumulatorIsLive()) {
    332     DCHECK_NE(values_[accumulator_base()],
    333               builder()->jsgraph()->OptimizedOutConstant());
    334     DCHECK_NE(other->values_[accumulator_base()],
    335               builder()->jsgraph()->OptimizedOutConstant());
    336 
    337     values_[accumulator_base()] =
    338         builder()->MergeValue(values_[accumulator_base()],
    339                               other->values_[accumulator_base()], control);
    340   } else {
    341     values_[accumulator_base()] = builder()->jsgraph()->OptimizedOutConstant();
    342   }
    343 
    344   if (generator_state_ != nullptr) {
    345     DCHECK_NOT_NULL(other->generator_state_);
    346     generator_state_ = builder()->MergeValue(generator_state_,
    347                                              other->generator_state_, control);
    348   }
    349 }
    350 
    351 void BytecodeGraphBuilder::Environment::PrepareForLoop(
    352     const BytecodeLoopAssignments& assignments,
    353     const BytecodeLivenessState* liveness) {
    354   // Create a control node for the loop header.
    355   Node* control = builder()->NewLoop();
    356 
    357   // Create a Phi for external effects.
    358   Node* effect = builder()->NewEffectPhi(1, GetEffectDependency(), control);
    359   UpdateEffectDependency(effect);
    360 
    361   // Create Phis for any values that are live on entry to the loop and may be
    362   // updated by the end of the loop.
    363   context_ = builder()->NewPhi(1, context_, control);
    364   for (int i = 0; i < parameter_count(); i++) {
    365     if (assignments.ContainsParameter(i)) {
    366       values_[i] = builder()->NewPhi(1, values_[i], control);
    367     }
    368   }
    369   for (int i = 0; i < register_count(); i++) {
    370     if (assignments.ContainsLocal(i) &&
    371         (liveness == nullptr || liveness->RegisterIsLive(i))) {
    372       int index = register_base() + i;
    373       values_[index] = builder()->NewPhi(1, values_[index], control);
    374     }
    375   }
    376   // The accumulator should not be live on entry.
    377   DCHECK_IMPLIES(liveness != nullptr, !liveness->AccumulatorIsLive());
    378 
    379   if (generator_state_ != nullptr) {
    380     generator_state_ = builder()->NewPhi(1, generator_state_, control);
    381   }
    382 
    383   // Connect to the loop end.
    384   Node* terminate = builder()->graph()->NewNode(
    385       builder()->common()->Terminate(), effect, control);
    386   builder()->exit_controls_.push_back(terminate);
    387 }
    388 
    389 void BytecodeGraphBuilder::Environment::FillWithOsrValues() {
    390   Node* start = graph()->start();
    391 
    392   // Create OSR values for each environment value.
    393   SetContext(graph()->NewNode(
    394       common()->OsrValue(Linkage::kOsrContextSpillSlotIndex), start));
    395   int size = static_cast<int>(values()->size());
    396   for (int i = 0; i < size; i++) {
    397     int idx = i;  // Indexing scheme follows {StandardFrame}, adapt accordingly.
    398     if (i >= register_base()) idx += InterpreterFrameConstants::kExtraSlotCount;
    399     if (i >= accumulator_base()) idx = Linkage::kOsrAccumulatorRegisterIndex;
    400     values()->at(i) = graph()->NewNode(common()->OsrValue(idx), start);
    401   }
    402 }
    403 
    404 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate(
    405     Node** state_values, Node** values, int count) {
    406   if (*state_values == nullptr) {
    407     return true;
    408   }
    409   Node::Inputs inputs = (*state_values)->inputs();
    410   if (inputs.count() != count) return true;
    411   for (int i = 0; i < count; i++) {
    412     if (inputs[i] != values[i]) {
    413       return true;
    414     }
    415   }
    416   return false;
    417 }
    418 
    419 void BytecodeGraphBuilder::Environment::PrepareForLoopExit(
    420     Node* loop, const BytecodeLoopAssignments& assignments,
    421     const BytecodeLivenessState* liveness) {
    422   DCHECK_EQ(loop->opcode(), IrOpcode::kLoop);
    423 
    424   Node* control = GetControlDependency();
    425 
    426   // Create the loop exit node.
    427   Node* loop_exit = graph()->NewNode(common()->LoopExit(), control, loop);
    428   UpdateControlDependency(loop_exit);
    429 
    430   // Rename the effect.
    431   Node* effect_rename = graph()->NewNode(common()->LoopExitEffect(),
    432                                          GetEffectDependency(), loop_exit);
    433   UpdateEffectDependency(effect_rename);
    434 
    435   // TODO(jarin) We should also rename context here. However, unconditional
    436   // renaming confuses global object and native context specialization.
    437   // We should only rename if the context is assigned in the loop.
    438 
    439   // Rename the environment values if they were assigned in the loop and are
    440   // live after exiting the loop.
    441   for (int i = 0; i < parameter_count(); i++) {
    442     if (assignments.ContainsParameter(i)) {
    443       Node* rename =
    444           graph()->NewNode(common()->LoopExitValue(), values_[i], loop_exit);
    445       values_[i] = rename;
    446     }
    447   }
    448   for (int i = 0; i < register_count(); i++) {
    449     if (assignments.ContainsLocal(i) &&
    450         (liveness == nullptr || liveness->RegisterIsLive(i))) {
    451       Node* rename = graph()->NewNode(common()->LoopExitValue(),
    452                                       values_[register_base() + i], loop_exit);
    453       values_[register_base() + i] = rename;
    454     }
    455   }
    456   if (liveness == nullptr || liveness->AccumulatorIsLive()) {
    457     Node* rename = graph()->NewNode(common()->LoopExitValue(),
    458                                     values_[accumulator_base()], loop_exit);
    459     values_[accumulator_base()] = rename;
    460   }
    461 
    462   if (generator_state_ != nullptr) {
    463     generator_state_ = graph()->NewNode(common()->LoopExitValue(),
    464                                         generator_state_, loop_exit);
    465   }
    466 }
    467 
    468 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values,
    469                                                           Node** values,
    470                                                           int count) {
    471   if (StateValuesRequireUpdate(state_values, values, count)) {
    472     const Operator* op = common()->StateValues(count, SparseInputMask::Dense());
    473     (*state_values) = graph()->NewNode(op, count, values);
    474   }
    475 }
    476 
    477 Node* BytecodeGraphBuilder::Environment::GetStateValuesFromCache(
    478     Node** values, int count, const BitVector* liveness, int liveness_offset) {
    479   return builder_->state_values_cache_.GetNodeForValues(
    480       values, static_cast<size_t>(count), liveness, liveness_offset);
    481 }
    482 
    483 Node* BytecodeGraphBuilder::Environment::Checkpoint(
    484     BailoutId bailout_id, OutputFrameStateCombine combine,
    485     const BytecodeLivenessState* liveness) {
    486   if (parameter_count() == register_count()) {
    487     // Re-use the state-value cache if the number of local registers happens
    488     // to match the parameter count.
    489     parameters_state_values_ = GetStateValuesFromCache(
    490         &values()->at(0), parameter_count(), nullptr, 0);
    491   } else {
    492     UpdateStateValues(&parameters_state_values_, &values()->at(0),
    493                       parameter_count());
    494   }
    495 
    496   Node* registers_state_values =
    497       GetStateValuesFromCache(&values()->at(register_base()), register_count(),
    498                               liveness ? &liveness->bit_vector() : nullptr, 0);
    499 
    500   bool accumulator_is_live = !liveness || liveness->AccumulatorIsLive();
    501   Node* accumulator_state_value =
    502       accumulator_is_live && combine != OutputFrameStateCombine::PokeAt(0)
    503           ? values()->at(accumulator_base())
    504           : builder()->jsgraph()->OptimizedOutConstant();
    505 
    506   const Operator* op = common()->FrameState(
    507       bailout_id, combine, builder()->frame_state_function_info());
    508   Node* result = graph()->NewNode(
    509       op, parameters_state_values_, registers_state_values,
    510       accumulator_state_value, Context(), builder()->GetFunctionClosure(),
    511       builder()->graph()->start());
    512 
    513   return result;
    514 }
    515 
    516 BytecodeGraphBuilder::BytecodeGraphBuilder(
    517     Zone* local_zone, Handle<SharedFunctionInfo> shared_info,
    518     Handle<FeedbackVector> feedback_vector, BailoutId osr_offset,
    519     JSGraph* jsgraph, CallFrequency& invocation_frequency,
    520     SourcePositionTable* source_positions, Handle<Context> native_context,
    521     int inlining_id, JSTypeHintLowering::Flags flags, bool stack_check,
    522     bool analyze_environment_liveness)
    523     : local_zone_(local_zone),
    524       jsgraph_(jsgraph),
    525       invocation_frequency_(invocation_frequency),
    526       bytecode_array_(
    527           handle(shared_info->GetBytecodeArray(), jsgraph->isolate())),
    528       feedback_vector_(feedback_vector),
    529       type_hint_lowering_(jsgraph, feedback_vector, flags),
    530       frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
    531           FrameStateType::kInterpretedFunction,
    532           bytecode_array()->parameter_count(),
    533           bytecode_array()->register_count(), shared_info)),
    534       bytecode_iterator_(nullptr),
    535       bytecode_analysis_(nullptr),
    536       environment_(nullptr),
    537       osr_offset_(osr_offset),
    538       currently_peeled_loop_offset_(-1),
    539       stack_check_(stack_check),
    540       analyze_environment_liveness_(analyze_environment_liveness),
    541       merge_environments_(local_zone),
    542       generator_merge_environments_(local_zone),
    543       exception_handlers_(local_zone),
    544       current_exception_handler_(0),
    545       input_buffer_size_(0),
    546       input_buffer_(nullptr),
    547       needs_eager_checkpoint_(true),
    548       exit_controls_(local_zone),
    549       state_values_cache_(jsgraph),
    550       source_positions_(source_positions),
    551       start_position_(shared_info->StartPosition(), inlining_id),
    552       native_context_(native_context) {}
    553 
    554 Node* BytecodeGraphBuilder::GetFunctionClosure() {
    555   if (!function_closure_.is_set()) {
    556     int index = Linkage::kJSCallClosureParamIndex;
    557     const Operator* op = common()->Parameter(index, "%closure");
    558     Node* node = NewNode(op, graph()->start());
    559     function_closure_.set(node);
    560   }
    561   return function_closure_.get();
    562 }
    563 
    564 Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) {
    565   const Operator* op =
    566       javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true);
    567   Node* native_context = NewNode(op);
    568   Node* result = NewNode(javascript()->LoadContext(0, index, true));
    569   NodeProperties::ReplaceContextInput(result, native_context);
    570   return result;
    571 }
    572 
    573 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) {
    574   return VectorSlotPair(feedback_vector(), FeedbackVector::ToSlot(slot_id));
    575 }
    576 
    577 void BytecodeGraphBuilder::CreateGraph() {
    578   SourcePositionTable::Scope pos_scope(source_positions_, start_position_);
    579 
    580   // Set up the basic structure of the graph. Outputs for {Start} are the formal
    581   // parameters (including the receiver) plus new target, number of arguments,
    582   // context and closure.
    583   int actual_parameter_count = bytecode_array()->parameter_count() + 4;
    584   graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count)));
    585 
    586   Environment env(this, bytecode_array()->register_count(),
    587                   bytecode_array()->parameter_count(),
    588                   bytecode_array()->incoming_new_target_or_generator_register(),
    589                   graph()->start());
    590   set_environment(&env);
    591 
    592   VisitBytecodes();
    593 
    594   // Finish the basic structure of the graph.
    595   DCHECK_NE(0u, exit_controls_.size());
    596   int const input_count = static_cast<int>(exit_controls_.size());
    597   Node** const inputs = &exit_controls_.front();
    598   Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs);
    599   graph()->SetEnd(end);
    600 }
    601 
    602 void BytecodeGraphBuilder::PrepareEagerCheckpoint() {
    603   if (needs_eager_checkpoint()) {
    604     // Create an explicit checkpoint node for before the operation. This only
    605     // needs to happen if we aren't effect-dominated by a {Checkpoint} already.
    606     mark_as_needing_eager_checkpoint(false);
    607     Node* node = NewNode(common()->Checkpoint());
    608     DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
    609     DCHECK_EQ(IrOpcode::kDead,
    610               NodeProperties::GetFrameStateInput(node)->opcode());
    611     BailoutId bailout_id(bytecode_iterator().current_offset());
    612 
    613     const BytecodeLivenessState* liveness_before =
    614         bytecode_analysis()->GetInLivenessFor(
    615             bytecode_iterator().current_offset());
    616 
    617     Node* frame_state_before = environment()->Checkpoint(
    618         bailout_id, OutputFrameStateCombine::Ignore(), liveness_before);
    619     NodeProperties::ReplaceFrameStateInput(node, frame_state_before);
    620 #ifdef DEBUG
    621   } else {
    622     // In case we skipped checkpoint creation above, we must be able to find an
    623     // existing checkpoint that effect-dominates the nodes about to be created.
    624     // Starting a search from the current effect-dependency has to succeed.
    625     Node* effect = environment()->GetEffectDependency();
    626     while (effect->opcode() != IrOpcode::kCheckpoint) {
    627       DCHECK(effect->op()->HasProperty(Operator::kNoWrite));
    628       DCHECK_EQ(1, effect->op()->EffectInputCount());
    629       effect = NodeProperties::GetEffectInput(effect);
    630     }
    631   }
    632 #else
    633   }
    634 #endif  // DEBUG
    635 }
    636 
    637 void BytecodeGraphBuilder::PrepareFrameState(Node* node,
    638                                              OutputFrameStateCombine combine) {
    639   if (OperatorProperties::HasFrameStateInput(node->op())) {
    640     // Add the frame state for after the operation. The node in question has
    641     // already been created and had a {Dead} frame state input up until now.
    642     DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
    643     DCHECK_EQ(IrOpcode::kDead,
    644               NodeProperties::GetFrameStateInput(node)->opcode());
    645     BailoutId bailout_id(bytecode_iterator().current_offset());
    646 
    647     const BytecodeLivenessState* liveness_after =
    648         bytecode_analysis()->GetOutLivenessFor(
    649             bytecode_iterator().current_offset());
    650 
    651     Node* frame_state_after =
    652         environment()->Checkpoint(bailout_id, combine, liveness_after);
    653     NodeProperties::ReplaceFrameStateInput(node, frame_state_after);
    654   }
    655 }
    656 
    657 // Stores the state of the SourcePosition iterator, and the index to the
    658 // current exception handlers stack. We need, during the OSR graph generation,
    659 // to backup the states of these iterators at the LoopHeader offset of each
    660 // outer loop which contains the OSR loop. The iterators are then restored when
    661 // peeling the loops, so that both exception handling and synchronisation with
    662 // the source position can be achieved.
    663 class BytecodeGraphBuilder::OsrIteratorState {
    664  public:
    665   OsrIteratorState(interpreter::BytecodeArrayIterator* iterator,
    666                    SourcePositionTableIterator* source_position_iterator,
    667                    BytecodeGraphBuilder* graph_builder)
    668       : iterator_(iterator),
    669         source_position_iterator_(source_position_iterator),
    670         graph_builder_(graph_builder),
    671         saved_states_(graph_builder->local_zone()) {}
    672 
    673   void ProcessOsrPrelude() {
    674     ZoneVector<int> outer_loop_offsets(graph_builder_->local_zone());
    675 
    676     const BytecodeAnalysis& bytecode_analysis =
    677         *(graph_builder_->bytecode_analysis());
    678     int osr_offset = bytecode_analysis.osr_entry_point();
    679 
    680     // We find here the outermost loop which contains the OSR loop.
    681     int outermost_loop_offset = osr_offset;
    682     while ((outermost_loop_offset =
    683                 bytecode_analysis.GetLoopInfoFor(outermost_loop_offset)
    684                     .parent_offset()) != -1) {
    685       outer_loop_offsets.push_back(outermost_loop_offset);
    686     }
    687     outermost_loop_offset =
    688         outer_loop_offsets.empty() ? osr_offset : outer_loop_offsets.back();
    689 
    690     // We will not processs any bytecode before the outermost_loop_offset, but
    691     // the source_position_iterator needs to be advanced step by step through
    692     // the bytecode.
    693     for (; iterator_->current_offset() != outermost_loop_offset;
    694          iterator_->Advance()) {
    695       graph_builder_->UpdateSourcePosition(source_position_iterator_,
    696                                            iterator_->current_offset());
    697     }
    698 
    699     // We save some iterators states at the offsets of the loop headers of the
    700     // outer loops (the ones containing the OSR loop). They will be used for
    701     // jumping back in the bytecode.
    702     for (ZoneVector<int>::const_reverse_iterator it =
    703              outer_loop_offsets.crbegin();
    704          it != outer_loop_offsets.crend(); ++it) {
    705       int next_loop_offset = *it;
    706       for (; iterator_->current_offset() != next_loop_offset;
    707            iterator_->Advance()) {
    708         graph_builder_->UpdateSourcePosition(source_position_iterator_,
    709                                              iterator_->current_offset());
    710       }
    711       graph_builder_->ExitThenEnterExceptionHandlers(
    712           iterator_->current_offset());
    713       saved_states_.push(
    714           IteratorsStates(graph_builder_->current_exception_handler(),
    715                           source_position_iterator_->GetState()));
    716     }
    717 
    718     // Finishing by advancing to the OSR entry
    719     for (; iterator_->current_offset() != osr_offset; iterator_->Advance()) {
    720       graph_builder_->UpdateSourcePosition(source_position_iterator_,
    721                                            iterator_->current_offset());
    722     }
    723 
    724     // Enters all remaining exception handler which end before the OSR loop
    725     // so that on next call of VisitSingleBytecode they will get popped from
    726     // the exception handlers stack.
    727     graph_builder_->ExitThenEnterExceptionHandlers(osr_offset);
    728     graph_builder_->set_currently_peeled_loop_offset(
    729         bytecode_analysis.GetLoopInfoFor(osr_offset).parent_offset());
    730   }
    731 
    732   void RestoreState(int target_offset, int new_parent_offset) {
    733     iterator_->SetOffset(target_offset);
    734     // In case of a return, we must not build loop exits for
    735     // not-yet-built outer loops.
    736     graph_builder_->set_currently_peeled_loop_offset(new_parent_offset);
    737     IteratorsStates saved_state = saved_states_.top();
    738     source_position_iterator_->RestoreState(saved_state.source_iterator_state_);
    739     graph_builder_->set_current_exception_handler(
    740         saved_state.exception_handler_index_);
    741     saved_states_.pop();
    742   }
    743 
    744  private:
    745   struct IteratorsStates {
    746     int exception_handler_index_;
    747     SourcePositionTableIterator::IndexAndPosition source_iterator_state_;
    748 
    749     IteratorsStates(
    750         int exception_handler_index,
    751         SourcePositionTableIterator::IndexAndPosition source_iterator_state)
    752         : exception_handler_index_(exception_handler_index),
    753           source_iterator_state_(source_iterator_state) {}
    754   };
    755 
    756   interpreter::BytecodeArrayIterator* iterator_;
    757   SourcePositionTableIterator* source_position_iterator_;
    758   BytecodeGraphBuilder* graph_builder_;
    759   ZoneStack<IteratorsStates> saved_states_;
    760 };
    761 
    762 void BytecodeGraphBuilder::RemoveMergeEnvironmentsBeforeOffset(
    763     int limit_offset) {
    764   if (!merge_environments_.empty()) {
    765     ZoneMap<int, Environment*>::iterator it = merge_environments_.begin();
    766     ZoneMap<int, Environment*>::iterator stop_it = merge_environments_.end();
    767     while (it != stop_it && it->first <= limit_offset) {
    768       it = merge_environments_.erase(it);
    769     }
    770   }
    771 }
    772 
    773 // We will iterate through the OSR loop, then its parent, and so on
    774 // until we have reached the outmost loop containing the OSR loop. We do
    775 // not generate nodes for anything before the outermost loop.
    776 void BytecodeGraphBuilder::AdvanceToOsrEntryAndPeelLoops(
    777     interpreter::BytecodeArrayIterator* iterator,
    778     SourcePositionTableIterator* source_position_iterator) {
    779   const BytecodeAnalysis& analysis = *(bytecode_analysis());
    780   int osr_offset = analysis.osr_entry_point();
    781   OsrIteratorState iterator_states(iterator, source_position_iterator, this);
    782 
    783   iterator_states.ProcessOsrPrelude();
    784   DCHECK_EQ(iterator->current_offset(), osr_offset);
    785 
    786   environment()->FillWithOsrValues();
    787 
    788   // Suppose we have n nested loops, loop_0 being the outermost one, and
    789   // loop_n being the OSR loop. We start iterating the bytecode at the header
    790   // of loop_n (the OSR loop), and then we peel the part of the the body of
    791   // loop_{n-1} following the end of loop_n. We then rewind the iterator to
    792   // the header of loop_{n-1}, and so on until we have partly peeled loop 0.
    793   // The full loop_0 body will be generating with the rest of the function,
    794   // outside the OSR generation.
    795 
    796   // To do so, if we are visiting a loop, we continue to visit what's left
    797   // of its parent, and then when reaching the parent's JumpLoop, we do not
    798   // create any jump for that but rewind the bytecode iterator to visit the
    799   // parent loop entirely, and so on.
    800 
    801   int current_parent_offset =
    802       analysis.GetLoopInfoFor(osr_offset).parent_offset();
    803   while (current_parent_offset != -1) {
    804     LoopInfo current_parent_loop =
    805         analysis.GetLoopInfoFor(current_parent_offset);
    806     // We iterate until the back edge of the parent loop, which we detect by
    807     // the offset that the JumpLoop targets.
    808     for (; !iterator->done(); iterator->Advance()) {
    809       if (iterator->current_bytecode() == interpreter::Bytecode::kJumpLoop &&
    810           iterator->GetJumpTargetOffset() == current_parent_offset) {
    811         // Reached the end of the current parent loop.
    812         break;
    813       }
    814       VisitSingleBytecode(source_position_iterator);
    815     }
    816     DCHECK(!iterator->done());  // Should have found the loop's jump target.
    817 
    818     // We also need to take care of the merge environments and exceptions
    819     // handlers here because the omitted JumpLoop bytecode can still be the
    820     // target of jumps or the first bytecode after a try block.
    821     ExitThenEnterExceptionHandlers(iterator->current_offset());
    822     SwitchToMergeEnvironment(iterator->current_offset());
    823 
    824     // This jump is the jump of our parent loop, which is not yet created.
    825     // So we do not build the jump nodes, but restore the bytecode and the
    826     // SourcePosition iterators to the values they had when we were visiting
    827     // the offset pointed at by the JumpLoop we've just reached.
    828     // We have already built nodes for inner loops, but now we will
    829     // iterate again over them and build new nodes corresponding to the same
    830     // bytecode offsets. Any jump or reference to this inner loops must now
    831     // point to the new nodes we will build, hence we clear the relevant part
    832     // of the environment.
    833     // Completely clearing the environment is not possible because merge
    834     // environments for forward jumps out of the loop need to be preserved
    835     // (e.g. a return or a labeled break in the middle of a loop).
    836     RemoveMergeEnvironmentsBeforeOffset(iterator->current_offset());
    837     iterator_states.RestoreState(current_parent_offset,
    838                                  current_parent_loop.parent_offset());
    839     current_parent_offset = current_parent_loop.parent_offset();
    840   }
    841 }
    842 
    843 void BytecodeGraphBuilder::VisitSingleBytecode(
    844     SourcePositionTableIterator* source_position_iterator) {
    845   const interpreter::BytecodeArrayIterator& iterator = bytecode_iterator();
    846   int current_offset = iterator.current_offset();
    847   UpdateSourcePosition(source_position_iterator, current_offset);
    848   ExitThenEnterExceptionHandlers(current_offset);
    849   DCHECK_GE(exception_handlers_.empty() ? current_offset
    850                                         : exception_handlers_.top().end_offset_,
    851             current_offset);
    852   SwitchToMergeEnvironment(current_offset);
    853 
    854   if (environment() != nullptr) {
    855     BuildLoopHeaderEnvironment(current_offset);
    856 
    857     // Skip the first stack check if stack_check is false
    858     if (!stack_check() &&
    859         iterator.current_bytecode() == interpreter::Bytecode::kStackCheck) {
    860       set_stack_check(true);
    861       return;
    862     }
    863 
    864     switch (iterator.current_bytecode()) {
    865 #define BYTECODE_CASE(name, ...)       \
    866   case interpreter::Bytecode::k##name: \
    867     Visit##name();                     \
    868     break;
    869       BYTECODE_LIST(BYTECODE_CASE)
    870 #undef BYTECODE_CODE
    871     }
    872   }
    873 }
    874 
    875 void BytecodeGraphBuilder::VisitBytecodes() {
    876   BytecodeAnalysis bytecode_analysis(bytecode_array(), local_zone(),
    877                                      analyze_environment_liveness());
    878   bytecode_analysis.Analyze(osr_offset_);
    879   set_bytecode_analysis(&bytecode_analysis);
    880 
    881   interpreter::BytecodeArrayIterator iterator(bytecode_array());
    882   set_bytecode_iterator(&iterator);
    883   SourcePositionTableIterator source_position_iterator(
    884       handle(bytecode_array()->SourcePositionTable(), isolate()));
    885 
    886   if (analyze_environment_liveness() && FLAG_trace_environment_liveness) {
    887     StdoutStream of;
    888     bytecode_analysis.PrintLivenessTo(of);
    889   }
    890 
    891   if (!bytecode_analysis.resume_jump_targets().empty()) {
    892     environment()->BindGeneratorState(
    893         jsgraph()->SmiConstant(JSGeneratorObject::kGeneratorExecuting));
    894   }
    895 
    896   if (bytecode_analysis.HasOsrEntryPoint()) {
    897     // We peel the OSR loop and any outer loop containing it except that we
    898     // leave the nodes corresponding to the whole outermost loop (including
    899     // the last copies of the loops it contains) to be generated by the normal
    900     // bytecode iteration below.
    901     AdvanceToOsrEntryAndPeelLoops(&iterator, &source_position_iterator);
    902   }
    903 
    904   for (; !iterator.done(); iterator.Advance()) {
    905     VisitSingleBytecode(&source_position_iterator);
    906   }
    907   set_bytecode_analysis(nullptr);
    908   set_bytecode_iterator(nullptr);
    909   DCHECK(exception_handlers_.empty());
    910 }
    911 
    912 void BytecodeGraphBuilder::VisitLdaZero() {
    913   Node* node = jsgraph()->ZeroConstant();
    914   environment()->BindAccumulator(node);
    915 }
    916 
    917 void BytecodeGraphBuilder::VisitLdaSmi() {
    918   Node* node = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
    919   environment()->BindAccumulator(node);
    920 }
    921 
    922 void BytecodeGraphBuilder::VisitLdaConstant() {
    923   Node* node = jsgraph()->Constant(
    924       handle(bytecode_iterator().GetConstantForIndexOperand(0), isolate()));
    925   environment()->BindAccumulator(node);
    926 }
    927 
    928 void BytecodeGraphBuilder::VisitLdaUndefined() {
    929   Node* node = jsgraph()->UndefinedConstant();
    930   environment()->BindAccumulator(node);
    931 }
    932 
    933 void BytecodeGraphBuilder::VisitLdaNull() {
    934   Node* node = jsgraph()->NullConstant();
    935   environment()->BindAccumulator(node);
    936 }
    937 
    938 void BytecodeGraphBuilder::VisitLdaTheHole() {
    939   Node* node = jsgraph()->TheHoleConstant();
    940   environment()->BindAccumulator(node);
    941 }
    942 
    943 void BytecodeGraphBuilder::VisitLdaTrue() {
    944   Node* node = jsgraph()->TrueConstant();
    945   environment()->BindAccumulator(node);
    946 }
    947 
    948 void BytecodeGraphBuilder::VisitLdaFalse() {
    949   Node* node = jsgraph()->FalseConstant();
    950   environment()->BindAccumulator(node);
    951 }
    952 
    953 void BytecodeGraphBuilder::VisitLdar() {
    954   Node* value =
    955       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
    956   environment()->BindAccumulator(value);
    957 }
    958 
    959 void BytecodeGraphBuilder::VisitStar() {
    960   Node* value = environment()->LookupAccumulator();
    961   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value);
    962 }
    963 
    964 void BytecodeGraphBuilder::VisitMov() {
    965   Node* value =
    966       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
    967   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), value);
    968 }
    969 
    970 Node* BytecodeGraphBuilder::BuildLoadGlobal(Handle<Name> name,
    971                                             uint32_t feedback_slot_index,
    972                                             TypeofMode typeof_mode) {
    973   VectorSlotPair feedback = CreateVectorSlotPair(feedback_slot_index);
    974   DCHECK(IsLoadGlobalICKind(feedback_vector()->GetKind(feedback.slot())));
    975   const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
    976   return NewNode(op);
    977 }
    978 
    979 void BytecodeGraphBuilder::VisitLdaGlobal() {
    980   PrepareEagerCheckpoint();
    981   Handle<Name> name(
    982       Name::cast(bytecode_iterator().GetConstantForIndexOperand(0)), isolate());
    983   uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
    984   Node* node =
    985       BuildLoadGlobal(name, feedback_slot_index, TypeofMode::NOT_INSIDE_TYPEOF);
    986   environment()->BindAccumulator(node, Environment::kAttachFrameState);
    987 }
    988 
    989 void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() {
    990   PrepareEagerCheckpoint();
    991   Handle<Name> name(
    992       Name::cast(bytecode_iterator().GetConstantForIndexOperand(0)), isolate());
    993   uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
    994   Node* node =
    995       BuildLoadGlobal(name, feedback_slot_index, TypeofMode::INSIDE_TYPEOF);
    996   environment()->BindAccumulator(node, Environment::kAttachFrameState);
    997 }
    998 
    999 void BytecodeGraphBuilder::VisitStaGlobal() {
   1000   PrepareEagerCheckpoint();
   1001   Handle<Name> name(
   1002       Name::cast(bytecode_iterator().GetConstantForIndexOperand(0)), isolate());
   1003   VectorSlotPair feedback =
   1004       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
   1005   Node* value = environment()->LookupAccumulator();
   1006 
   1007   LanguageMode language_mode =
   1008       feedback.vector()->GetLanguageMode(feedback.slot());
   1009   const Operator* op = javascript()->StoreGlobal(language_mode, name, feedback);
   1010   Node* node = NewNode(op, value);
   1011   environment()->RecordAfterState(node, Environment::kAttachFrameState);
   1012 }
   1013 
   1014 void BytecodeGraphBuilder::VisitStaInArrayLiteral() {
   1015   PrepareEagerCheckpoint();
   1016   Node* value = environment()->LookupAccumulator();
   1017   Node* array =
   1018       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1019   Node* index =
   1020       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
   1021   VectorSlotPair feedback =
   1022       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
   1023   const Operator* op = javascript()->StoreInArrayLiteral(feedback);
   1024 
   1025   JSTypeHintLowering::LoweringResult lowering =
   1026       TryBuildSimplifiedStoreKeyed(op, array, index, value, feedback.slot());
   1027   if (lowering.IsExit()) return;
   1028 
   1029   Node* node = nullptr;
   1030   if (lowering.IsSideEffectFree()) {
   1031     node = lowering.value();
   1032   } else {
   1033     DCHECK(!lowering.Changed());
   1034     node = NewNode(op, array, index, value);
   1035   }
   1036 
   1037   environment()->RecordAfterState(node, Environment::kAttachFrameState);
   1038 }
   1039 
   1040 void BytecodeGraphBuilder::VisitStaDataPropertyInLiteral() {
   1041   PrepareEagerCheckpoint();
   1042 
   1043   Node* object =
   1044       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1045   Node* name =
   1046       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
   1047   Node* value = environment()->LookupAccumulator();
   1048   int flags = bytecode_iterator().GetFlagOperand(2);
   1049   VectorSlotPair feedback =
   1050       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(3));
   1051 
   1052   const Operator* op = javascript()->StoreDataPropertyInLiteral(feedback);
   1053   Node* node = NewNode(op, object, name, value, jsgraph()->Constant(flags));
   1054   environment()->RecordAfterState(node, Environment::kAttachFrameState);
   1055 }
   1056 
   1057 void BytecodeGraphBuilder::VisitCollectTypeProfile() {
   1058   PrepareEagerCheckpoint();
   1059 
   1060   Node* position =
   1061       jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
   1062   Node* value = environment()->LookupAccumulator();
   1063   Node* vector = jsgraph()->Constant(feedback_vector());
   1064 
   1065   const Operator* op = javascript()->CallRuntime(Runtime::kCollectTypeProfile);
   1066 
   1067   Node* node = NewNode(op, position, value, vector);
   1068   environment()->RecordAfterState(node, Environment::kAttachFrameState);
   1069 }
   1070 
   1071 void BytecodeGraphBuilder::VisitLdaContextSlot() {
   1072   const Operator* op = javascript()->LoadContext(
   1073       bytecode_iterator().GetUnsignedImmediateOperand(2),
   1074       bytecode_iterator().GetIndexOperand(1), false);
   1075   Node* node = NewNode(op);
   1076   Node* context =
   1077       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1078   NodeProperties::ReplaceContextInput(node, context);
   1079   environment()->BindAccumulator(node);
   1080 }
   1081 
   1082 void BytecodeGraphBuilder::VisitLdaImmutableContextSlot() {
   1083   const Operator* op = javascript()->LoadContext(
   1084       bytecode_iterator().GetUnsignedImmediateOperand(2),
   1085       bytecode_iterator().GetIndexOperand(1), true);
   1086   Node* node = NewNode(op);
   1087   Node* context =
   1088       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1089   NodeProperties::ReplaceContextInput(node, context);
   1090   environment()->BindAccumulator(node);
   1091 }
   1092 
   1093 void BytecodeGraphBuilder::VisitLdaCurrentContextSlot() {
   1094   const Operator* op = javascript()->LoadContext(
   1095       0, bytecode_iterator().GetIndexOperand(0), false);
   1096   Node* node = NewNode(op);
   1097   environment()->BindAccumulator(node);
   1098 }
   1099 
   1100 void BytecodeGraphBuilder::VisitLdaImmutableCurrentContextSlot() {
   1101   const Operator* op = javascript()->LoadContext(
   1102       0, bytecode_iterator().GetIndexOperand(0), true);
   1103   Node* node = NewNode(op);
   1104   environment()->BindAccumulator(node);
   1105 }
   1106 
   1107 void BytecodeGraphBuilder::VisitStaContextSlot() {
   1108   const Operator* op = javascript()->StoreContext(
   1109       bytecode_iterator().GetUnsignedImmediateOperand(2),
   1110       bytecode_iterator().GetIndexOperand(1));
   1111   Node* value = environment()->LookupAccumulator();
   1112   Node* node = NewNode(op, value);
   1113   Node* context =
   1114       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1115   NodeProperties::ReplaceContextInput(node, context);
   1116 }
   1117 
   1118 void BytecodeGraphBuilder::VisitStaCurrentContextSlot() {
   1119   const Operator* op =
   1120       javascript()->StoreContext(0, bytecode_iterator().GetIndexOperand(0));
   1121   Node* value = environment()->LookupAccumulator();
   1122   NewNode(op, value);
   1123 }
   1124 
   1125 void BytecodeGraphBuilder::BuildLdaLookupSlot(TypeofMode typeof_mode) {
   1126   PrepareEagerCheckpoint();
   1127   Node* name = jsgraph()->Constant(
   1128       handle(bytecode_iterator().GetConstantForIndexOperand(0), isolate()));
   1129   const Operator* op =
   1130       javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
   1131                                     ? Runtime::kLoadLookupSlot
   1132                                     : Runtime::kLoadLookupSlotInsideTypeof);
   1133   Node* value = NewNode(op, name);
   1134   environment()->BindAccumulator(value, Environment::kAttachFrameState);
   1135 }
   1136 
   1137 void BytecodeGraphBuilder::VisitLdaLookupSlot() {
   1138   BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF);
   1139 }
   1140 
   1141 void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() {
   1142   BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF);
   1143 }
   1144 
   1145 BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::CheckContextExtensions(
   1146     uint32_t depth) {
   1147   // Output environment where the context has an extension
   1148   Environment* slow_environment = nullptr;
   1149 
   1150   // We only need to check up to the last-but-one depth, because the an eval
   1151   // in the same scope as the variable itself has no way of shadowing it.
   1152   for (uint32_t d = 0; d < depth; d++) {
   1153     Node* extension_slot =
   1154         NewNode(javascript()->LoadContext(d, Context::EXTENSION_INDEX, false));
   1155 
   1156     Node* check_no_extension =
   1157         NewNode(simplified()->ReferenceEqual(), extension_slot,
   1158                 jsgraph()->TheHoleConstant());
   1159 
   1160     NewBranch(check_no_extension);
   1161 
   1162     {
   1163       SubEnvironment sub_environment(this);
   1164 
   1165       NewIfFalse();
   1166       // If there is an extension, merge into the slow path.
   1167       if (slow_environment == nullptr) {
   1168         slow_environment = environment();
   1169         NewMerge();
   1170       } else {
   1171         slow_environment->Merge(environment(),
   1172                                 bytecode_analysis()->GetInLivenessFor(
   1173                                     bytecode_iterator().current_offset()));
   1174       }
   1175     }
   1176 
   1177     NewIfTrue();
   1178     // Do nothing on if there is no extension, eventually falling through to
   1179     // the fast path.
   1180   }
   1181 
   1182   // The depth can be zero, in which case no slow-path checks are built, and
   1183   // the slow path environment can be null.
   1184   DCHECK(depth == 0 || slow_environment != nullptr);
   1185 
   1186   return slow_environment;
   1187 }
   1188 
   1189 void BytecodeGraphBuilder::BuildLdaLookupContextSlot(TypeofMode typeof_mode) {
   1190   uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2);
   1191 
   1192   // Check if any context in the depth has an extension.
   1193   Environment* slow_environment = CheckContextExtensions(depth);
   1194 
   1195   // Fast path, do a context load.
   1196   {
   1197     uint32_t slot_index = bytecode_iterator().GetIndexOperand(1);
   1198 
   1199     const Operator* op = javascript()->LoadContext(depth, slot_index, false);
   1200     environment()->BindAccumulator(NewNode(op));
   1201   }
   1202 
   1203   // Only build the slow path if there were any slow-path checks.
   1204   if (slow_environment != nullptr) {
   1205     // Add a merge to the fast environment.
   1206     NewMerge();
   1207     Environment* fast_environment = environment();
   1208 
   1209     // Slow path, do a runtime load lookup.
   1210     set_environment(slow_environment);
   1211     {
   1212       Node* name = jsgraph()->Constant(
   1213           handle(bytecode_iterator().GetConstantForIndexOperand(0), isolate()));
   1214 
   1215       const Operator* op =
   1216           javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
   1217                                         ? Runtime::kLoadLookupSlot
   1218                                         : Runtime::kLoadLookupSlotInsideTypeof);
   1219       Node* value = NewNode(op, name);
   1220       environment()->BindAccumulator(value, Environment::kAttachFrameState);
   1221     }
   1222 
   1223     fast_environment->Merge(environment(),
   1224                             bytecode_analysis()->GetOutLivenessFor(
   1225                                 bytecode_iterator().current_offset()));
   1226     set_environment(fast_environment);
   1227     mark_as_needing_eager_checkpoint(true);
   1228   }
   1229 }
   1230 
   1231 void BytecodeGraphBuilder::VisitLdaLookupContextSlot() {
   1232   BuildLdaLookupContextSlot(TypeofMode::NOT_INSIDE_TYPEOF);
   1233 }
   1234 
   1235 void BytecodeGraphBuilder::VisitLdaLookupContextSlotInsideTypeof() {
   1236   BuildLdaLookupContextSlot(TypeofMode::INSIDE_TYPEOF);
   1237 }
   1238 
   1239 void BytecodeGraphBuilder::BuildLdaLookupGlobalSlot(TypeofMode typeof_mode) {
   1240   uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2);
   1241 
   1242   // Check if any context in the depth has an extension.
   1243   Environment* slow_environment = CheckContextExtensions(depth);
   1244 
   1245   // Fast path, do a global load.
   1246   {
   1247     PrepareEagerCheckpoint();
   1248     Handle<Name> name(
   1249         Name::cast(bytecode_iterator().GetConstantForIndexOperand(0)),
   1250         isolate());
   1251     uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
   1252     Node* node = BuildLoadGlobal(name, feedback_slot_index, typeof_mode);
   1253     environment()->BindAccumulator(node, Environment::kAttachFrameState);
   1254   }
   1255 
   1256   // Only build the slow path if there were any slow-path checks.
   1257   if (slow_environment != nullptr) {
   1258     // Add a merge to the fast environment.
   1259     NewMerge();
   1260     Environment* fast_environment = environment();
   1261 
   1262     // Slow path, do a runtime load lookup.
   1263     set_environment(slow_environment);
   1264     {
   1265       Node* name = jsgraph()->Constant(
   1266           handle(bytecode_iterator().GetConstantForIndexOperand(0), isolate()));
   1267 
   1268       const Operator* op =
   1269           javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
   1270                                         ? Runtime::kLoadLookupSlot
   1271                                         : Runtime::kLoadLookupSlotInsideTypeof);
   1272       Node* value = NewNode(op, name);
   1273       environment()->BindAccumulator(value, Environment::kAttachFrameState);
   1274     }
   1275 
   1276     fast_environment->Merge(environment(),
   1277                             bytecode_analysis()->GetOutLivenessFor(
   1278                                 bytecode_iterator().current_offset()));
   1279     set_environment(fast_environment);
   1280     mark_as_needing_eager_checkpoint(true);
   1281   }
   1282 }
   1283 
   1284 void BytecodeGraphBuilder::VisitLdaLookupGlobalSlot() {
   1285   BuildLdaLookupGlobalSlot(TypeofMode::NOT_INSIDE_TYPEOF);
   1286 }
   1287 
   1288 void BytecodeGraphBuilder::VisitLdaLookupGlobalSlotInsideTypeof() {
   1289   BuildLdaLookupGlobalSlot(TypeofMode::INSIDE_TYPEOF);
   1290 }
   1291 
   1292 void BytecodeGraphBuilder::VisitStaLookupSlot() {
   1293   PrepareEagerCheckpoint();
   1294   Node* value = environment()->LookupAccumulator();
   1295   Node* name = jsgraph()->Constant(
   1296       handle(bytecode_iterator().GetConstantForIndexOperand(0), isolate()));
   1297   int bytecode_flags = bytecode_iterator().GetFlagOperand(1);
   1298   LanguageMode language_mode = static_cast<LanguageMode>(
   1299       interpreter::StoreLookupSlotFlags::LanguageModeBit::decode(
   1300           bytecode_flags));
   1301   LookupHoistingMode lookup_hoisting_mode = static_cast<LookupHoistingMode>(
   1302       interpreter::StoreLookupSlotFlags::LookupHoistingModeBit::decode(
   1303           bytecode_flags));
   1304   DCHECK_IMPLIES(lookup_hoisting_mode == LookupHoistingMode::kLegacySloppy,
   1305                  is_sloppy(language_mode));
   1306   const Operator* op = javascript()->CallRuntime(
   1307       is_strict(language_mode)
   1308           ? Runtime::kStoreLookupSlot_Strict
   1309           : lookup_hoisting_mode == LookupHoistingMode::kLegacySloppy
   1310                 ? Runtime::kStoreLookupSlot_SloppyHoisting
   1311                 : Runtime::kStoreLookupSlot_Sloppy);
   1312   Node* store = NewNode(op, name, value);
   1313   environment()->BindAccumulator(store, Environment::kAttachFrameState);
   1314 }
   1315 
   1316 void BytecodeGraphBuilder::VisitLdaNamedProperty() {
   1317   PrepareEagerCheckpoint();
   1318   Node* object =
   1319       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1320   Handle<Name> name(
   1321       Name::cast(bytecode_iterator().GetConstantForIndexOperand(1)), isolate());
   1322   VectorSlotPair feedback =
   1323       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
   1324   const Operator* op = javascript()->LoadNamed(name, feedback);
   1325 
   1326   JSTypeHintLowering::LoweringResult lowering =
   1327       TryBuildSimplifiedLoadNamed(op, object, feedback.slot());
   1328   if (lowering.IsExit()) return;
   1329 
   1330   Node* node = nullptr;
   1331   if (lowering.IsSideEffectFree()) {
   1332     node = lowering.value();
   1333   } else {
   1334     DCHECK(!lowering.Changed());
   1335     node = NewNode(op, object);
   1336   }
   1337   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   1338 }
   1339 
   1340 void BytecodeGraphBuilder::VisitLdaKeyedProperty() {
   1341   PrepareEagerCheckpoint();
   1342   Node* key = environment()->LookupAccumulator();
   1343   Node* object =
   1344       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1345   VectorSlotPair feedback =
   1346       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
   1347   const Operator* op = javascript()->LoadProperty(feedback);
   1348 
   1349   JSTypeHintLowering::LoweringResult lowering =
   1350       TryBuildSimplifiedLoadKeyed(op, object, key, feedback.slot());
   1351   if (lowering.IsExit()) return;
   1352 
   1353   Node* node = nullptr;
   1354   if (lowering.IsSideEffectFree()) {
   1355     node = lowering.value();
   1356   } else {
   1357     DCHECK(!lowering.Changed());
   1358     node = NewNode(op, object, key);
   1359   }
   1360   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   1361 }
   1362 
   1363 void BytecodeGraphBuilder::BuildNamedStore(StoreMode store_mode) {
   1364   PrepareEagerCheckpoint();
   1365   Node* value = environment()->LookupAccumulator();
   1366   Node* object =
   1367       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1368   Handle<Name> name(
   1369       Name::cast(bytecode_iterator().GetConstantForIndexOperand(1)), isolate());
   1370   VectorSlotPair feedback =
   1371       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
   1372 
   1373   const Operator* op;
   1374   if (store_mode == StoreMode::kOwn) {
   1375     DCHECK_EQ(FeedbackSlotKind::kStoreOwnNamed,
   1376               feedback.vector()->GetKind(feedback.slot()));
   1377     op = javascript()->StoreNamedOwn(name, feedback);
   1378   } else {
   1379     DCHECK_EQ(StoreMode::kNormal, store_mode);
   1380     LanguageMode language_mode =
   1381         feedback.vector()->GetLanguageMode(feedback.slot());
   1382     op = javascript()->StoreNamed(language_mode, name, feedback);
   1383   }
   1384 
   1385   JSTypeHintLowering::LoweringResult lowering =
   1386       TryBuildSimplifiedStoreNamed(op, object, value, feedback.slot());
   1387   if (lowering.IsExit()) return;
   1388 
   1389   Node* node = nullptr;
   1390   if (lowering.IsSideEffectFree()) {
   1391     node = lowering.value();
   1392   } else {
   1393     DCHECK(!lowering.Changed());
   1394     node = NewNode(op, object, value);
   1395   }
   1396   environment()->RecordAfterState(node, Environment::kAttachFrameState);
   1397 }
   1398 
   1399 void BytecodeGraphBuilder::VisitStaNamedProperty() {
   1400   BuildNamedStore(StoreMode::kNormal);
   1401 }
   1402 
   1403 void BytecodeGraphBuilder::VisitStaNamedOwnProperty() {
   1404   BuildNamedStore(StoreMode::kOwn);
   1405 }
   1406 
   1407 void BytecodeGraphBuilder::VisitStaKeyedProperty() {
   1408   PrepareEagerCheckpoint();
   1409   Node* value = environment()->LookupAccumulator();
   1410   Node* object =
   1411       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1412   Node* key =
   1413       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
   1414   VectorSlotPair feedback =
   1415       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
   1416   LanguageMode language_mode =
   1417       feedback.vector()->GetLanguageMode(feedback.slot());
   1418   const Operator* op = javascript()->StoreProperty(language_mode, feedback);
   1419 
   1420   JSTypeHintLowering::LoweringResult lowering =
   1421       TryBuildSimplifiedStoreKeyed(op, object, key, value, feedback.slot());
   1422   if (lowering.IsExit()) return;
   1423 
   1424   Node* node = nullptr;
   1425   if (lowering.IsSideEffectFree()) {
   1426     node = lowering.value();
   1427   } else {
   1428     DCHECK(!lowering.Changed());
   1429     node = NewNode(op, object, key, value);
   1430   }
   1431 
   1432   environment()->RecordAfterState(node, Environment::kAttachFrameState);
   1433 }
   1434 
   1435 void BytecodeGraphBuilder::VisitLdaModuleVariable() {
   1436   int32_t cell_index = bytecode_iterator().GetImmediateOperand(0);
   1437   uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1);
   1438   Node* module =
   1439       NewNode(javascript()->LoadContext(depth, Context::EXTENSION_INDEX, true));
   1440   Node* value = NewNode(javascript()->LoadModule(cell_index), module);
   1441   environment()->BindAccumulator(value);
   1442 }
   1443 
   1444 void BytecodeGraphBuilder::VisitStaModuleVariable() {
   1445   int32_t cell_index = bytecode_iterator().GetImmediateOperand(0);
   1446   uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1);
   1447   Node* module =
   1448       NewNode(javascript()->LoadContext(depth, Context::EXTENSION_INDEX, true));
   1449   Node* value = environment()->LookupAccumulator();
   1450   NewNode(javascript()->StoreModule(cell_index), module, value);
   1451 }
   1452 
   1453 void BytecodeGraphBuilder::VisitPushContext() {
   1454   Node* new_context = environment()->LookupAccumulator();
   1455   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0),
   1456                               environment()->Context());
   1457   environment()->SetContext(new_context);
   1458 }
   1459 
   1460 void BytecodeGraphBuilder::VisitPopContext() {
   1461   Node* context =
   1462       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1463   environment()->SetContext(context);
   1464 }
   1465 
   1466 void BytecodeGraphBuilder::VisitCreateClosure() {
   1467   Handle<SharedFunctionInfo> shared_info(
   1468       SharedFunctionInfo::cast(
   1469           bytecode_iterator().GetConstantForIndexOperand(0)),
   1470       isolate());
   1471   FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
   1472   FeedbackNexus nexus(feedback_vector(), slot);
   1473   PretenureFlag tenured =
   1474       interpreter::CreateClosureFlags::PretenuredBit::decode(
   1475           bytecode_iterator().GetFlagOperand(2))
   1476           ? TENURED
   1477           : NOT_TENURED;
   1478   const Operator* op = javascript()->CreateClosure(
   1479       shared_info, nexus.GetFeedbackCell(),
   1480       handle(jsgraph()->isolate()->builtins()->builtin(Builtins::kCompileLazy),
   1481              isolate()),
   1482       tenured);
   1483   Node* closure = NewNode(op);
   1484   environment()->BindAccumulator(closure);
   1485 }
   1486 
   1487 void BytecodeGraphBuilder::VisitCreateBlockContext() {
   1488   Handle<ScopeInfo> scope_info(
   1489       ScopeInfo::cast(bytecode_iterator().GetConstantForIndexOperand(0)),
   1490       isolate());
   1491 
   1492   const Operator* op = javascript()->CreateBlockContext(scope_info);
   1493   Node* context = NewNode(op);
   1494   environment()->BindAccumulator(context);
   1495 }
   1496 
   1497 void BytecodeGraphBuilder::VisitCreateFunctionContext() {
   1498   Handle<ScopeInfo> scope_info(
   1499       ScopeInfo::cast(bytecode_iterator().GetConstantForIndexOperand(0)),
   1500       isolate());
   1501   uint32_t slots = bytecode_iterator().GetUnsignedImmediateOperand(1);
   1502   const Operator* op =
   1503       javascript()->CreateFunctionContext(scope_info, slots, FUNCTION_SCOPE);
   1504   Node* context = NewNode(op);
   1505   environment()->BindAccumulator(context);
   1506 }
   1507 
   1508 void BytecodeGraphBuilder::VisitCreateEvalContext() {
   1509   Handle<ScopeInfo> scope_info(
   1510       ScopeInfo::cast(bytecode_iterator().GetConstantForIndexOperand(0)),
   1511       isolate());
   1512   uint32_t slots = bytecode_iterator().GetUnsignedImmediateOperand(1);
   1513   const Operator* op =
   1514       javascript()->CreateFunctionContext(scope_info, slots, EVAL_SCOPE);
   1515   Node* context = NewNode(op);
   1516   environment()->BindAccumulator(context);
   1517 }
   1518 
   1519 void BytecodeGraphBuilder::VisitCreateCatchContext() {
   1520   interpreter::Register reg = bytecode_iterator().GetRegisterOperand(0);
   1521   Node* exception = environment()->LookupRegister(reg);
   1522   Handle<ScopeInfo> scope_info(
   1523       ScopeInfo::cast(bytecode_iterator().GetConstantForIndexOperand(1)),
   1524       isolate());
   1525 
   1526   const Operator* op = javascript()->CreateCatchContext(scope_info);
   1527   Node* context = NewNode(op, exception);
   1528   environment()->BindAccumulator(context);
   1529 }
   1530 
   1531 void BytecodeGraphBuilder::VisitCreateWithContext() {
   1532   Node* object =
   1533       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1534   Handle<ScopeInfo> scope_info(
   1535       ScopeInfo::cast(bytecode_iterator().GetConstantForIndexOperand(1)),
   1536       isolate());
   1537 
   1538   const Operator* op = javascript()->CreateWithContext(scope_info);
   1539   Node* context = NewNode(op, object);
   1540   environment()->BindAccumulator(context);
   1541 }
   1542 
   1543 void BytecodeGraphBuilder::BuildCreateArguments(CreateArgumentsType type) {
   1544   const Operator* op = javascript()->CreateArguments(type);
   1545   Node* object = NewNode(op, GetFunctionClosure());
   1546   environment()->BindAccumulator(object, Environment::kAttachFrameState);
   1547 }
   1548 
   1549 void BytecodeGraphBuilder::VisitCreateMappedArguments() {
   1550   BuildCreateArguments(CreateArgumentsType::kMappedArguments);
   1551 }
   1552 
   1553 void BytecodeGraphBuilder::VisitCreateUnmappedArguments() {
   1554   BuildCreateArguments(CreateArgumentsType::kUnmappedArguments);
   1555 }
   1556 
   1557 void BytecodeGraphBuilder::VisitCreateRestParameter() {
   1558   BuildCreateArguments(CreateArgumentsType::kRestParameter);
   1559 }
   1560 
   1561 void BytecodeGraphBuilder::VisitCreateRegExpLiteral() {
   1562   Handle<String> constant_pattern(
   1563       String::cast(bytecode_iterator().GetConstantForIndexOperand(0)),
   1564       isolate());
   1565   int const slot_id = bytecode_iterator().GetIndexOperand(1);
   1566   VectorSlotPair pair = CreateVectorSlotPair(slot_id);
   1567   int literal_flags = bytecode_iterator().GetFlagOperand(2);
   1568   Node* literal = NewNode(
   1569       javascript()->CreateLiteralRegExp(constant_pattern, pair, literal_flags));
   1570   environment()->BindAccumulator(literal, Environment::kAttachFrameState);
   1571 }
   1572 
   1573 void BytecodeGraphBuilder::VisitCreateArrayLiteral() {
   1574   Handle<ArrayBoilerplateDescription> array_boilerplate_description(
   1575       ArrayBoilerplateDescription::cast(
   1576           bytecode_iterator().GetConstantForIndexOperand(0)),
   1577       isolate());
   1578   int const slot_id = bytecode_iterator().GetIndexOperand(1);
   1579   VectorSlotPair pair = CreateVectorSlotPair(slot_id);
   1580   int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
   1581   int literal_flags =
   1582       interpreter::CreateArrayLiteralFlags::FlagsBits::decode(bytecode_flags);
   1583   // Disable allocation site mementos. Only unoptimized code will collect
   1584   // feedback about allocation site. Once the code is optimized we expect the
   1585   // data to converge. So, we disable allocation site mementos in optimized
   1586   // code. We can revisit this when we have data to the contrary.
   1587   literal_flags |= ArrayLiteral::kDisableMementos;
   1588   // TODO(mstarzinger): Thread through number of elements. The below number is
   1589   // only an estimate and does not match {ArrayLiteral::values::length}.
   1590   int number_of_elements =
   1591       array_boilerplate_description->constant_elements()->length();
   1592   Node* literal = NewNode(javascript()->CreateLiteralArray(
   1593       array_boilerplate_description, pair, literal_flags, number_of_elements));
   1594   environment()->BindAccumulator(literal, Environment::kAttachFrameState);
   1595 }
   1596 
   1597 void BytecodeGraphBuilder::VisitCreateEmptyArrayLiteral() {
   1598   int const slot_id = bytecode_iterator().GetIndexOperand(0);
   1599   VectorSlotPair pair = CreateVectorSlotPair(slot_id);
   1600   Node* literal = NewNode(javascript()->CreateEmptyLiteralArray(pair));
   1601   environment()->BindAccumulator(literal);
   1602 }
   1603 
   1604 void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
   1605   Handle<ObjectBoilerplateDescription> constant_properties(
   1606       ObjectBoilerplateDescription::cast(
   1607           bytecode_iterator().GetConstantForIndexOperand(0)),
   1608       isolate());
   1609   int const slot_id = bytecode_iterator().GetIndexOperand(1);
   1610   VectorSlotPair pair = CreateVectorSlotPair(slot_id);
   1611   int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
   1612   int literal_flags =
   1613       interpreter::CreateObjectLiteralFlags::FlagsBits::decode(bytecode_flags);
   1614   // TODO(mstarzinger): Thread through number of properties. The below number is
   1615   // only an estimate and does not match {ObjectLiteral::properties_count}.
   1616   int number_of_properties = constant_properties->size();
   1617   Node* literal = NewNode(javascript()->CreateLiteralObject(
   1618       constant_properties, pair, literal_flags, number_of_properties));
   1619   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3),
   1620                               literal, Environment::kAttachFrameState);
   1621 }
   1622 
   1623 void BytecodeGraphBuilder::VisitCreateEmptyObjectLiteral() {
   1624   Node* literal =
   1625       NewNode(javascript()->CreateEmptyLiteralObject(), GetFunctionClosure());
   1626   environment()->BindAccumulator(literal);
   1627 }
   1628 
   1629 void BytecodeGraphBuilder::VisitCloneObject() {
   1630   PrepareEagerCheckpoint();
   1631   Node* source =
   1632       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1633   int flags = bytecode_iterator().GetFlagOperand(1);
   1634   int slot = bytecode_iterator().GetIndexOperand(2);
   1635   const Operator* op =
   1636       javascript()->CloneObject(CreateVectorSlotPair(slot), flags);
   1637   Node* value = NewNode(op, source);
   1638   environment()->BindAccumulator(value, Environment::kAttachFrameState);
   1639 }
   1640 
   1641 void BytecodeGraphBuilder::VisitGetTemplateObject() {
   1642   Handle<TemplateObjectDescription> description(
   1643       TemplateObjectDescription::cast(
   1644           bytecode_iterator().GetConstantForIndexOperand(0)),
   1645       isolate());
   1646   FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
   1647   FeedbackNexus nexus(feedback_vector(), slot);
   1648 
   1649   Handle<JSArray> cached_value;
   1650   if (nexus.GetFeedback() == MaybeObject::FromSmi(Smi::kZero)) {
   1651     // It's not observable when the template object is created, so we
   1652     // can just create it eagerly during graph building and bake in
   1653     // the JSArray constant here.
   1654     cached_value =
   1655         TemplateObjectDescription::CreateTemplateObject(isolate(), description);
   1656     nexus.vector()->Set(slot, *cached_value);
   1657   } else {
   1658     cached_value = handle(
   1659         JSArray::cast(nexus.GetFeedback()->ToStrongHeapObject()), isolate());
   1660   }
   1661 
   1662   Node* template_object = jsgraph()->HeapConstant(cached_value);
   1663   environment()->BindAccumulator(template_object);
   1664 }
   1665 
   1666 Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegisters(
   1667     Node* callee, Node* receiver, interpreter::Register first_arg,
   1668     int arg_count) {
   1669   // The arity of the Call node -- includes the callee, receiver and function
   1670   // arguments.
   1671   int arity = 2 + arg_count;
   1672 
   1673   Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
   1674 
   1675   all[0] = callee;
   1676   all[1] = receiver;
   1677 
   1678   // The function arguments are in consecutive registers.
   1679   int arg_base = first_arg.index();
   1680   for (int i = 0; i < arg_count; ++i) {
   1681     all[2 + i] =
   1682         environment()->LookupRegister(interpreter::Register(arg_base + i));
   1683   }
   1684 
   1685   return all;
   1686 }
   1687 
   1688 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
   1689                                                  Node* const* args,
   1690                                                  int arg_count) {
   1691   return MakeNode(call_op, arg_count, args, false);
   1692 }
   1693 
   1694 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
   1695                                                  Node* callee,
   1696                                                  interpreter::Register receiver,
   1697                                                  size_t reg_count) {
   1698   Node* receiver_node = environment()->LookupRegister(receiver);
   1699   // The receiver is followed by the arguments in the consecutive registers.
   1700   DCHECK_GE(reg_count, 1);
   1701   interpreter::Register first_arg = interpreter::Register(receiver.index() + 1);
   1702   int arg_count = static_cast<int>(reg_count) - 1;
   1703 
   1704   Node* const* call_args = GetCallArgumentsFromRegisters(callee, receiver_node,
   1705                                                          first_arg, arg_count);
   1706   return ProcessCallArguments(call_op, call_args, 2 + arg_count);
   1707 }
   1708 
   1709 void BytecodeGraphBuilder::BuildCall(ConvertReceiverMode receiver_mode,
   1710                                      Node* const* args, size_t arg_count,
   1711                                      int slot_id) {
   1712   DCHECK_EQ(interpreter::Bytecodes::GetReceiverMode(
   1713                 bytecode_iterator().current_bytecode()),
   1714             receiver_mode);
   1715   PrepareEagerCheckpoint();
   1716 
   1717   VectorSlotPair feedback = CreateVectorSlotPair(slot_id);
   1718 
   1719   CallFrequency frequency = ComputeCallFrequency(slot_id);
   1720   const Operator* op =
   1721       javascript()->Call(arg_count, frequency, feedback, receiver_mode,
   1722                          GetSpeculationMode(slot_id));
   1723   JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedCall(
   1724       op, args, static_cast<int>(arg_count), feedback.slot());
   1725   if (lowering.IsExit()) return;
   1726 
   1727   Node* node = nullptr;
   1728   if (lowering.IsSideEffectFree()) {
   1729     node = lowering.value();
   1730   } else {
   1731     DCHECK(!lowering.Changed());
   1732     node = ProcessCallArguments(op, args, static_cast<int>(arg_count));
   1733   }
   1734   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   1735 }
   1736 
   1737 Node* const* BytecodeGraphBuilder::ProcessCallVarArgs(
   1738     ConvertReceiverMode receiver_mode, Node* callee,
   1739     interpreter::Register first_reg, int arg_count) {
   1740   DCHECK_GE(arg_count, 0);
   1741   Node* receiver_node;
   1742   interpreter::Register first_arg;
   1743 
   1744   if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) {
   1745     // The receiver is implicit (and undefined), the arguments are in
   1746     // consecutive registers.
   1747     receiver_node = jsgraph()->UndefinedConstant();
   1748     first_arg = first_reg;
   1749   } else {
   1750     // The receiver is the first register, followed by the arguments in the
   1751     // consecutive registers.
   1752     receiver_node = environment()->LookupRegister(first_reg);
   1753     first_arg = interpreter::Register(first_reg.index() + 1);
   1754   }
   1755 
   1756   Node* const* call_args = GetCallArgumentsFromRegisters(callee, receiver_node,
   1757                                                          first_arg, arg_count);
   1758   return call_args;
   1759 }
   1760 
   1761 void BytecodeGraphBuilder::BuildCallVarArgs(ConvertReceiverMode receiver_mode) {
   1762   DCHECK_EQ(interpreter::Bytecodes::GetReceiverMode(
   1763                 bytecode_iterator().current_bytecode()),
   1764             receiver_mode);
   1765   Node* callee =
   1766       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1767   interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
   1768   size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
   1769   int const slot_id = bytecode_iterator().GetIndexOperand(3);
   1770 
   1771   int arg_count = receiver_mode == ConvertReceiverMode::kNullOrUndefined
   1772                       ? static_cast<int>(reg_count)
   1773                       : static_cast<int>(reg_count) - 1;
   1774   Node* const* call_args =
   1775       ProcessCallVarArgs(receiver_mode, callee, first_reg, arg_count);
   1776   BuildCall(receiver_mode, call_args, static_cast<size_t>(2 + arg_count),
   1777             slot_id);
   1778 }
   1779 
   1780 void BytecodeGraphBuilder::VisitCallAnyReceiver() {
   1781   BuildCallVarArgs(ConvertReceiverMode::kAny);
   1782 }
   1783 
   1784 void BytecodeGraphBuilder::VisitCallProperty() {
   1785   BuildCallVarArgs(ConvertReceiverMode::kNotNullOrUndefined);
   1786 }
   1787 
   1788 void BytecodeGraphBuilder::VisitCallProperty0() {
   1789   Node* callee =
   1790       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1791   Node* receiver =
   1792       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
   1793   int const slot_id = bytecode_iterator().GetIndexOperand(2);
   1794   BuildCall(ConvertReceiverMode::kNotNullOrUndefined, {callee, receiver},
   1795             slot_id);
   1796 }
   1797 
   1798 void BytecodeGraphBuilder::VisitCallProperty1() {
   1799   Node* callee =
   1800       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1801   Node* receiver =
   1802       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
   1803   Node* arg0 =
   1804       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
   1805   int const slot_id = bytecode_iterator().GetIndexOperand(3);
   1806   BuildCall(ConvertReceiverMode::kNotNullOrUndefined, {callee, receiver, arg0},
   1807             slot_id);
   1808 }
   1809 
   1810 void BytecodeGraphBuilder::VisitCallProperty2() {
   1811   Node* callee =
   1812       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1813   Node* receiver =
   1814       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
   1815   Node* arg0 =
   1816       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
   1817   Node* arg1 =
   1818       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3));
   1819   int const slot_id = bytecode_iterator().GetIndexOperand(4);
   1820   BuildCall(ConvertReceiverMode::kNotNullOrUndefined,
   1821             {callee, receiver, arg0, arg1}, slot_id);
   1822 }
   1823 
   1824 void BytecodeGraphBuilder::VisitCallUndefinedReceiver() {
   1825   BuildCallVarArgs(ConvertReceiverMode::kNullOrUndefined);
   1826 }
   1827 
   1828 void BytecodeGraphBuilder::VisitCallUndefinedReceiver0() {
   1829   Node* callee =
   1830       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1831   Node* receiver = jsgraph()->UndefinedConstant();
   1832   int const slot_id = bytecode_iterator().GetIndexOperand(1);
   1833   BuildCall(ConvertReceiverMode::kNullOrUndefined, {callee, receiver}, slot_id);
   1834 }
   1835 
   1836 void BytecodeGraphBuilder::VisitCallUndefinedReceiver1() {
   1837   Node* callee =
   1838       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1839   Node* receiver = jsgraph()->UndefinedConstant();
   1840   Node* arg0 =
   1841       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
   1842   int const slot_id = bytecode_iterator().GetIndexOperand(2);
   1843   BuildCall(ConvertReceiverMode::kNullOrUndefined, {callee, receiver, arg0},
   1844             slot_id);
   1845 }
   1846 
   1847 void BytecodeGraphBuilder::VisitCallUndefinedReceiver2() {
   1848   Node* callee =
   1849       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1850   Node* receiver = jsgraph()->UndefinedConstant();
   1851   Node* arg0 =
   1852       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
   1853   Node* arg1 =
   1854       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
   1855   int const slot_id = bytecode_iterator().GetIndexOperand(3);
   1856   BuildCall(ConvertReceiverMode::kNullOrUndefined,
   1857             {callee, receiver, arg0, arg1}, slot_id);
   1858 }
   1859 
   1860 void BytecodeGraphBuilder::VisitCallWithSpread() {
   1861   PrepareEagerCheckpoint();
   1862   Node* callee =
   1863       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1864   interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
   1865   Node* receiver_node = environment()->LookupRegister(receiver);
   1866   size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
   1867   interpreter::Register first_arg = interpreter::Register(receiver.index() + 1);
   1868   int arg_count = static_cast<int>(reg_count) - 1;
   1869   Node* const* args = GetCallArgumentsFromRegisters(callee, receiver_node,
   1870                                                     first_arg, arg_count);
   1871   int const slot_id = bytecode_iterator().GetIndexOperand(3);
   1872   VectorSlotPair feedback = CreateVectorSlotPair(slot_id);
   1873 
   1874   CallFrequency frequency = ComputeCallFrequency(slot_id);
   1875   const Operator* op = javascript()->CallWithSpread(
   1876       static_cast<int>(reg_count + 1), frequency, feedback);
   1877 
   1878   JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedCall(
   1879       op, args, static_cast<int>(arg_count), feedback.slot());
   1880   if (lowering.IsExit()) return;
   1881 
   1882   Node* node = nullptr;
   1883   if (lowering.IsSideEffectFree()) {
   1884     node = lowering.value();
   1885   } else {
   1886     DCHECK(!lowering.Changed());
   1887     node = ProcessCallArguments(op, args, 2 + arg_count);
   1888   }
   1889   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   1890 }
   1891 
   1892 void BytecodeGraphBuilder::VisitCallJSRuntime() {
   1893   PrepareEagerCheckpoint();
   1894   Node* callee = BuildLoadNativeContextField(
   1895       bytecode_iterator().GetNativeContextIndexOperand(0));
   1896   interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
   1897   size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
   1898   int arg_count = static_cast<int>(reg_count);
   1899 
   1900   const Operator* call = javascript()->Call(2 + arg_count);
   1901   Node* const* call_args = ProcessCallVarArgs(
   1902       ConvertReceiverMode::kNullOrUndefined, callee, first_reg, arg_count);
   1903   Node* value = ProcessCallArguments(call, call_args, 2 + arg_count);
   1904   environment()->BindAccumulator(value, Environment::kAttachFrameState);
   1905 }
   1906 
   1907 Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
   1908     const Operator* call_runtime_op, interpreter::Register receiver,
   1909     size_t reg_count) {
   1910   int arg_count = static_cast<int>(reg_count);
   1911   // arity is args.
   1912   int arity = arg_count;
   1913   Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
   1914   int first_arg_index = receiver.index();
   1915   for (int i = 0; i < static_cast<int>(reg_count); ++i) {
   1916     all[i] = environment()->LookupRegister(
   1917         interpreter::Register(first_arg_index + i));
   1918   }
   1919   Node* value = MakeNode(call_runtime_op, arity, all, false);
   1920   return value;
   1921 }
   1922 
   1923 void BytecodeGraphBuilder::VisitCallRuntime() {
   1924   PrepareEagerCheckpoint();
   1925   Runtime::FunctionId function_id = bytecode_iterator().GetRuntimeIdOperand(0);
   1926   interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
   1927   size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
   1928 
   1929   // Create node to perform the runtime call.
   1930   const Operator* call = javascript()->CallRuntime(function_id, reg_count);
   1931   Node* value = ProcessCallRuntimeArguments(call, receiver, reg_count);
   1932   environment()->BindAccumulator(value, Environment::kAttachFrameState);
   1933 
   1934   // Connect to the end if {function_id} is non-returning.
   1935   if (Runtime::IsNonReturning(function_id)) {
   1936     // TODO(7099): Investigate if we need LoopExit node here.
   1937     Node* control = NewNode(common()->Throw());
   1938     MergeControlToLeaveFunction(control);
   1939   }
   1940 }
   1941 
   1942 void BytecodeGraphBuilder::VisitCallRuntimeForPair() {
   1943   PrepareEagerCheckpoint();
   1944   Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
   1945   interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
   1946   size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
   1947   interpreter::Register first_return =
   1948       bytecode_iterator().GetRegisterOperand(3);
   1949 
   1950   // Create node to perform the runtime call.
   1951   const Operator* call = javascript()->CallRuntime(functionId, reg_count);
   1952   Node* return_pair = ProcessCallRuntimeArguments(call, receiver, reg_count);
   1953   environment()->BindRegistersToProjections(first_return, return_pair,
   1954                                             Environment::kAttachFrameState);
   1955 }
   1956 
   1957 Node* const* BytecodeGraphBuilder::GetConstructArgumentsFromRegister(
   1958     Node* target, Node* new_target, interpreter::Register first_arg,
   1959     int arg_count) {
   1960   // arity is args + callee and new target.
   1961   int arity = arg_count + 2;
   1962   Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
   1963   all[0] = target;
   1964   int first_arg_index = first_arg.index();
   1965   for (int i = 0; i < arg_count; ++i) {
   1966     all[1 + i] = environment()->LookupRegister(
   1967         interpreter::Register(first_arg_index + i));
   1968   }
   1969   all[arity - 1] = new_target;
   1970   return all;
   1971 }
   1972 
   1973 Node* BytecodeGraphBuilder::ProcessConstructArguments(const Operator* op,
   1974                                                       Node* const* args,
   1975                                                       int arg_count) {
   1976   return MakeNode(op, arg_count, args, false);
   1977 }
   1978 
   1979 void BytecodeGraphBuilder::VisitConstruct() {
   1980   PrepareEagerCheckpoint();
   1981   interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
   1982   interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
   1983   size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
   1984   int const slot_id = bytecode_iterator().GetIndexOperand(3);
   1985   VectorSlotPair feedback = CreateVectorSlotPair(slot_id);
   1986 
   1987   Node* new_target = environment()->LookupAccumulator();
   1988   Node* callee = environment()->LookupRegister(callee_reg);
   1989 
   1990   CallFrequency frequency = ComputeCallFrequency(slot_id);
   1991   const Operator* op = javascript()->Construct(
   1992       static_cast<uint32_t>(reg_count + 2), frequency, feedback);
   1993   int arg_count = static_cast<int>(reg_count);
   1994   Node* const* args = GetConstructArgumentsFromRegister(callee, new_target,
   1995                                                         first_reg, arg_count);
   1996   JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedConstruct(
   1997       op, args, static_cast<int>(arg_count), feedback.slot());
   1998   if (lowering.IsExit()) return;
   1999 
   2000   Node* node = nullptr;
   2001   if (lowering.IsSideEffectFree()) {
   2002     node = lowering.value();
   2003   } else {
   2004     DCHECK(!lowering.Changed());
   2005     node = ProcessConstructArguments(op, args, 2 + arg_count);
   2006   }
   2007   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   2008 }
   2009 
   2010 void BytecodeGraphBuilder::VisitConstructWithSpread() {
   2011   PrepareEagerCheckpoint();
   2012   interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
   2013   interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
   2014   size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
   2015   int const slot_id = bytecode_iterator().GetIndexOperand(3);
   2016   VectorSlotPair feedback = CreateVectorSlotPair(slot_id);
   2017 
   2018   Node* new_target = environment()->LookupAccumulator();
   2019   Node* callee = environment()->LookupRegister(callee_reg);
   2020 
   2021   CallFrequency frequency = ComputeCallFrequency(slot_id);
   2022   const Operator* op = javascript()->ConstructWithSpread(
   2023       static_cast<uint32_t>(reg_count + 2), frequency, feedback);
   2024   int arg_count = static_cast<int>(reg_count);
   2025   Node* const* args = GetConstructArgumentsFromRegister(callee, new_target,
   2026                                                         first_reg, arg_count);
   2027   JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedConstruct(
   2028       op, args, static_cast<int>(arg_count), feedback.slot());
   2029   if (lowering.IsExit()) return;
   2030 
   2031   Node* node = nullptr;
   2032   if (lowering.IsSideEffectFree()) {
   2033     node = lowering.value();
   2034   } else {
   2035     DCHECK(!lowering.Changed());
   2036     node = ProcessConstructArguments(op, args, 2 + arg_count);
   2037   }
   2038   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   2039 }
   2040 
   2041 void BytecodeGraphBuilder::VisitInvokeIntrinsic() {
   2042   PrepareEagerCheckpoint();
   2043   Runtime::FunctionId functionId = bytecode_iterator().GetIntrinsicIdOperand(0);
   2044   interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
   2045   size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
   2046 
   2047   // Create node to perform the runtime call. Turbofan will take care of the
   2048   // lowering.
   2049   const Operator* call = javascript()->CallRuntime(functionId, reg_count);
   2050   Node* value = ProcessCallRuntimeArguments(call, receiver, reg_count);
   2051   environment()->BindAccumulator(value, Environment::kAttachFrameState);
   2052 }
   2053 
   2054 void BytecodeGraphBuilder::VisitThrow() {
   2055   BuildLoopExitsForFunctionExit(bytecode_analysis()->GetInLivenessFor(
   2056       bytecode_iterator().current_offset()));
   2057   Node* value = environment()->LookupAccumulator();
   2058   Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value);
   2059   environment()->BindAccumulator(call, Environment::kAttachFrameState);
   2060   Node* control = NewNode(common()->Throw());
   2061   MergeControlToLeaveFunction(control);
   2062 }
   2063 
   2064 void BytecodeGraphBuilder::VisitAbort() {
   2065   BuildLoopExitsForFunctionExit(bytecode_analysis()->GetInLivenessFor(
   2066       bytecode_iterator().current_offset()));
   2067   AbortReason reason =
   2068       static_cast<AbortReason>(bytecode_iterator().GetIndexOperand(0));
   2069   NewNode(simplified()->RuntimeAbort(reason));
   2070   Node* control = NewNode(common()->Throw());
   2071   MergeControlToLeaveFunction(control);
   2072 }
   2073 
   2074 void BytecodeGraphBuilder::VisitReThrow() {
   2075   BuildLoopExitsForFunctionExit(bytecode_analysis()->GetInLivenessFor(
   2076       bytecode_iterator().current_offset()));
   2077   Node* value = environment()->LookupAccumulator();
   2078   NewNode(javascript()->CallRuntime(Runtime::kReThrow), value);
   2079   Node* control = NewNode(common()->Throw());
   2080   MergeControlToLeaveFunction(control);
   2081 }
   2082 
   2083 void BytecodeGraphBuilder::BuildHoleCheckAndThrow(
   2084     Node* condition, Runtime::FunctionId runtime_id, Node* name) {
   2085   Node* accumulator = environment()->LookupAccumulator();
   2086   NewBranch(condition, BranchHint::kFalse);
   2087   {
   2088     SubEnvironment sub_environment(this);
   2089 
   2090     NewIfTrue();
   2091     BuildLoopExitsForFunctionExit(bytecode_analysis()->GetInLivenessFor(
   2092         bytecode_iterator().current_offset()));
   2093     Node* node;
   2094     const Operator* op = javascript()->CallRuntime(runtime_id);
   2095     if (runtime_id == Runtime::kThrowReferenceError) {
   2096       DCHECK_NOT_NULL(name);
   2097       node = NewNode(op, name);
   2098     } else {
   2099       DCHECK(runtime_id == Runtime::kThrowSuperAlreadyCalledError ||
   2100              runtime_id == Runtime::kThrowSuperNotCalled);
   2101       node = NewNode(op);
   2102     }
   2103     environment()->RecordAfterState(node, Environment::kAttachFrameState);
   2104     Node* control = NewNode(common()->Throw());
   2105     MergeControlToLeaveFunction(control);
   2106   }
   2107   NewIfFalse();
   2108   environment()->BindAccumulator(accumulator);
   2109 }
   2110 
   2111 void BytecodeGraphBuilder::VisitThrowReferenceErrorIfHole() {
   2112   Node* accumulator = environment()->LookupAccumulator();
   2113   Node* check_for_hole = NewNode(simplified()->ReferenceEqual(), accumulator,
   2114                                  jsgraph()->TheHoleConstant());
   2115   Node* name = jsgraph()->Constant(
   2116       handle(bytecode_iterator().GetConstantForIndexOperand(0), isolate()));
   2117   BuildHoleCheckAndThrow(check_for_hole, Runtime::kThrowReferenceError, name);
   2118 }
   2119 
   2120 void BytecodeGraphBuilder::VisitThrowSuperNotCalledIfHole() {
   2121   Node* accumulator = environment()->LookupAccumulator();
   2122   Node* check_for_hole = NewNode(simplified()->ReferenceEqual(), accumulator,
   2123                                  jsgraph()->TheHoleConstant());
   2124   BuildHoleCheckAndThrow(check_for_hole, Runtime::kThrowSuperNotCalled);
   2125 }
   2126 
   2127 void BytecodeGraphBuilder::VisitThrowSuperAlreadyCalledIfNotHole() {
   2128   Node* accumulator = environment()->LookupAccumulator();
   2129   Node* check_for_hole = NewNode(simplified()->ReferenceEqual(), accumulator,
   2130                                  jsgraph()->TheHoleConstant());
   2131   Node* check_for_not_hole =
   2132       NewNode(simplified()->BooleanNot(), check_for_hole);
   2133   BuildHoleCheckAndThrow(check_for_not_hole,
   2134                          Runtime::kThrowSuperAlreadyCalledError);
   2135 }
   2136 
   2137 void BytecodeGraphBuilder::BuildUnaryOp(const Operator* op) {
   2138   PrepareEagerCheckpoint();
   2139   Node* operand = environment()->LookupAccumulator();
   2140 
   2141   FeedbackSlot slot =
   2142       bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex);
   2143   JSTypeHintLowering::LoweringResult lowering =
   2144       TryBuildSimplifiedUnaryOp(op, operand, slot);
   2145   if (lowering.IsExit()) return;
   2146 
   2147   Node* node = nullptr;
   2148   if (lowering.IsSideEffectFree()) {
   2149     node = lowering.value();
   2150   } else {
   2151     DCHECK(!lowering.Changed());
   2152     node = NewNode(op, operand);
   2153   }
   2154 
   2155   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   2156 }
   2157 
   2158 void BytecodeGraphBuilder::BuildBinaryOp(const Operator* op) {
   2159   PrepareEagerCheckpoint();
   2160   Node* left =
   2161       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   2162   Node* right = environment()->LookupAccumulator();
   2163 
   2164   FeedbackSlot slot =
   2165       bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex);
   2166   JSTypeHintLowering::LoweringResult lowering =
   2167       TryBuildSimplifiedBinaryOp(op, left, right, slot);
   2168   if (lowering.IsExit()) return;
   2169 
   2170   Node* node = nullptr;
   2171   if (lowering.IsSideEffectFree()) {
   2172     node = lowering.value();
   2173   } else {
   2174     DCHECK(!lowering.Changed());
   2175     node = NewNode(op, left, right);
   2176   }
   2177 
   2178   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   2179 }
   2180 
   2181 // Helper function to create binary operation hint from the recorded type
   2182 // feedback.
   2183 BinaryOperationHint BytecodeGraphBuilder::GetBinaryOperationHint(
   2184     int operand_index) {
   2185   FeedbackSlot slot = bytecode_iterator().GetSlotOperand(operand_index);
   2186   FeedbackNexus nexus(feedback_vector(), slot);
   2187   return nexus.GetBinaryOperationFeedback();
   2188 }
   2189 
   2190 // Helper function to create compare operation hint from the recorded type
   2191 // feedback.
   2192 CompareOperationHint BytecodeGraphBuilder::GetCompareOperationHint() {
   2193   FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
   2194   FeedbackNexus nexus(feedback_vector(), slot);
   2195   return nexus.GetCompareOperationFeedback();
   2196 }
   2197 
   2198 // Helper function to create for-in mode from the recorded type feedback.
   2199 ForInMode BytecodeGraphBuilder::GetForInMode(int operand_index) {
   2200   FeedbackSlot slot = bytecode_iterator().GetSlotOperand(operand_index);
   2201   FeedbackNexus nexus(feedback_vector(), slot);
   2202   switch (nexus.GetForInFeedback()) {
   2203     case ForInHint::kNone:
   2204     case ForInHint::kEnumCacheKeysAndIndices:
   2205       return ForInMode::kUseEnumCacheKeysAndIndices;
   2206     case ForInHint::kEnumCacheKeys:
   2207       return ForInMode::kUseEnumCacheKeys;
   2208     case ForInHint::kAny:
   2209       return ForInMode::kGeneric;
   2210   }
   2211   UNREACHABLE();
   2212 }
   2213 
   2214 CallFrequency BytecodeGraphBuilder::ComputeCallFrequency(int slot_id) const {
   2215   if (invocation_frequency_.IsUnknown()) return CallFrequency();
   2216   FeedbackNexus nexus(feedback_vector(), FeedbackVector::ToSlot(slot_id));
   2217   return CallFrequency(nexus.ComputeCallFrequency() *
   2218                        invocation_frequency_.value());
   2219 }
   2220 
   2221 SpeculationMode BytecodeGraphBuilder::GetSpeculationMode(int slot_id) const {
   2222   FeedbackNexus nexus(feedback_vector(), FeedbackVector::ToSlot(slot_id));
   2223   return nexus.GetSpeculationMode();
   2224 }
   2225 
   2226 void BytecodeGraphBuilder::VisitBitwiseNot() {
   2227   BuildUnaryOp(javascript()->BitwiseNot());
   2228 }
   2229 
   2230 void BytecodeGraphBuilder::VisitDec() {
   2231   BuildUnaryOp(javascript()->Decrement());
   2232 }
   2233 
   2234 void BytecodeGraphBuilder::VisitInc() {
   2235   BuildUnaryOp(javascript()->Increment());
   2236 }
   2237 
   2238 void BytecodeGraphBuilder::VisitNegate() {
   2239   BuildUnaryOp(javascript()->Negate());
   2240 }
   2241 
   2242 void BytecodeGraphBuilder::VisitAdd() {
   2243   BuildBinaryOp(
   2244       javascript()->Add(GetBinaryOperationHint(kBinaryOperationHintIndex)));
   2245 }
   2246 
   2247 void BytecodeGraphBuilder::VisitSub() {
   2248   BuildBinaryOp(javascript()->Subtract());
   2249 }
   2250 
   2251 void BytecodeGraphBuilder::VisitMul() {
   2252   BuildBinaryOp(javascript()->Multiply());
   2253 }
   2254 
   2255 void BytecodeGraphBuilder::VisitDiv() { BuildBinaryOp(javascript()->Divide()); }
   2256 
   2257 void BytecodeGraphBuilder::VisitMod() {
   2258   BuildBinaryOp(javascript()->Modulus());
   2259 }
   2260 
   2261 void BytecodeGraphBuilder::VisitExp() {
   2262   BuildBinaryOp(javascript()->Exponentiate());
   2263 }
   2264 
   2265 void BytecodeGraphBuilder::VisitBitwiseOr() {
   2266   BuildBinaryOp(javascript()->BitwiseOr());
   2267 }
   2268 
   2269 void BytecodeGraphBuilder::VisitBitwiseXor() {
   2270   BuildBinaryOp(javascript()->BitwiseXor());
   2271 }
   2272 
   2273 void BytecodeGraphBuilder::VisitBitwiseAnd() {
   2274   BuildBinaryOp(javascript()->BitwiseAnd());
   2275 }
   2276 
   2277 void BytecodeGraphBuilder::VisitShiftLeft() {
   2278   BuildBinaryOp(javascript()->ShiftLeft());
   2279 }
   2280 
   2281 void BytecodeGraphBuilder::VisitShiftRight() {
   2282   BuildBinaryOp(javascript()->ShiftRight());
   2283 }
   2284 
   2285 void BytecodeGraphBuilder::VisitShiftRightLogical() {
   2286   BuildBinaryOp(javascript()->ShiftRightLogical());
   2287 }
   2288 
   2289 void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(const Operator* op) {
   2290   PrepareEagerCheckpoint();
   2291   Node* left = environment()->LookupAccumulator();
   2292   Node* right = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
   2293 
   2294   FeedbackSlot slot =
   2295       bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex);
   2296   JSTypeHintLowering::LoweringResult lowering =
   2297       TryBuildSimplifiedBinaryOp(op, left, right, slot);
   2298   if (lowering.IsExit()) return;
   2299 
   2300   Node* node = nullptr;
   2301   if (lowering.IsSideEffectFree()) {
   2302     node = lowering.value();
   2303   } else {
   2304     DCHECK(!lowering.Changed());
   2305     node = NewNode(op, left, right);
   2306   }
   2307   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   2308 }
   2309 
   2310 void BytecodeGraphBuilder::VisitAddSmi() {
   2311   BuildBinaryOpWithImmediate(
   2312       javascript()->Add(GetBinaryOperationHint(kBinaryOperationSmiHintIndex)));
   2313 }
   2314 
   2315 void BytecodeGraphBuilder::VisitSubSmi() {
   2316   BuildBinaryOpWithImmediate(javascript()->Subtract());
   2317 }
   2318 
   2319 void BytecodeGraphBuilder::VisitMulSmi() {
   2320   BuildBinaryOpWithImmediate(javascript()->Multiply());
   2321 }
   2322 
   2323 void BytecodeGraphBuilder::VisitDivSmi() {
   2324   BuildBinaryOpWithImmediate(javascript()->Divide());
   2325 }
   2326 
   2327 void BytecodeGraphBuilder::VisitModSmi() {
   2328   BuildBinaryOpWithImmediate(javascript()->Modulus());
   2329 }
   2330 
   2331 void BytecodeGraphBuilder::VisitExpSmi() {
   2332   BuildBinaryOpWithImmediate(javascript()->Exponentiate());
   2333 }
   2334 
   2335 void BytecodeGraphBuilder::VisitBitwiseOrSmi() {
   2336   BuildBinaryOpWithImmediate(javascript()->BitwiseOr());
   2337 }
   2338 
   2339 void BytecodeGraphBuilder::VisitBitwiseXorSmi() {
   2340   BuildBinaryOpWithImmediate(javascript()->BitwiseXor());
   2341 }
   2342 
   2343 void BytecodeGraphBuilder::VisitBitwiseAndSmi() {
   2344   BuildBinaryOpWithImmediate(javascript()->BitwiseAnd());
   2345 }
   2346 
   2347 void BytecodeGraphBuilder::VisitShiftLeftSmi() {
   2348   BuildBinaryOpWithImmediate(javascript()->ShiftLeft());
   2349 }
   2350 
   2351 void BytecodeGraphBuilder::VisitShiftRightSmi() {
   2352   BuildBinaryOpWithImmediate(javascript()->ShiftRight());
   2353 }
   2354 
   2355 void BytecodeGraphBuilder::VisitShiftRightLogicalSmi() {
   2356   BuildBinaryOpWithImmediate(javascript()->ShiftRightLogical());
   2357 }
   2358 
   2359 void BytecodeGraphBuilder::VisitLogicalNot() {
   2360   Node* value = environment()->LookupAccumulator();
   2361   Node* node = NewNode(simplified()->BooleanNot(), value);
   2362   environment()->BindAccumulator(node);
   2363 }
   2364 
   2365 void BytecodeGraphBuilder::VisitToBooleanLogicalNot() {
   2366   Node* value =
   2367       NewNode(simplified()->ToBoolean(), environment()->LookupAccumulator());
   2368   Node* node = NewNode(simplified()->BooleanNot(), value);
   2369   environment()->BindAccumulator(node);
   2370 }
   2371 
   2372 void BytecodeGraphBuilder::VisitTypeOf() {
   2373   Node* node =
   2374       NewNode(simplified()->TypeOf(), environment()->LookupAccumulator());
   2375   environment()->BindAccumulator(node);
   2376 }
   2377 
   2378 void BytecodeGraphBuilder::BuildDelete(LanguageMode language_mode) {
   2379   PrepareEagerCheckpoint();
   2380   Node* key = environment()->LookupAccumulator();
   2381   Node* object =
   2382       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   2383   Node* mode = jsgraph()->Constant(static_cast<int32_t>(language_mode));
   2384   Node* node = NewNode(javascript()->DeleteProperty(), object, key, mode);
   2385   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   2386 }
   2387 
   2388 void BytecodeGraphBuilder::VisitDeletePropertyStrict() {
   2389   BuildDelete(LanguageMode::kStrict);
   2390 }
   2391 
   2392 void BytecodeGraphBuilder::VisitDeletePropertySloppy() {
   2393   BuildDelete(LanguageMode::kSloppy);
   2394 }
   2395 
   2396 void BytecodeGraphBuilder::VisitGetSuperConstructor() {
   2397   Node* node = NewNode(javascript()->GetSuperConstructor(),
   2398                        environment()->LookupAccumulator());
   2399   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), node,
   2400                               Environment::kAttachFrameState);
   2401 }
   2402 
   2403 void BytecodeGraphBuilder::BuildCompareOp(const Operator* op) {
   2404   PrepareEagerCheckpoint();
   2405   Node* left =
   2406       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   2407   Node* right = environment()->LookupAccumulator();
   2408 
   2409   FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
   2410   JSTypeHintLowering::LoweringResult lowering =
   2411       TryBuildSimplifiedBinaryOp(op, left, right, slot);
   2412   if (lowering.IsExit()) return;
   2413 
   2414   Node* node = nullptr;
   2415   if (lowering.IsSideEffectFree()) {
   2416     node = lowering.value();
   2417   } else {
   2418     DCHECK(!lowering.Changed());
   2419     node = NewNode(op, left, right);
   2420   }
   2421   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   2422 }
   2423 
   2424 void BytecodeGraphBuilder::VisitTestEqual() {
   2425   BuildCompareOp(javascript()->Equal(GetCompareOperationHint()));
   2426 }
   2427 
   2428 void BytecodeGraphBuilder::VisitTestEqualStrict() {
   2429   BuildCompareOp(javascript()->StrictEqual(GetCompareOperationHint()));
   2430 }
   2431 
   2432 void BytecodeGraphBuilder::VisitTestLessThan() {
   2433   BuildCompareOp(javascript()->LessThan(GetCompareOperationHint()));
   2434 }
   2435 
   2436 void BytecodeGraphBuilder::VisitTestGreaterThan() {
   2437   BuildCompareOp(javascript()->GreaterThan(GetCompareOperationHint()));
   2438 }
   2439 
   2440 void BytecodeGraphBuilder::VisitTestLessThanOrEqual() {
   2441   BuildCompareOp(javascript()->LessThanOrEqual(GetCompareOperationHint()));
   2442 }
   2443 
   2444 void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual() {
   2445   BuildCompareOp(javascript()->GreaterThanOrEqual(GetCompareOperationHint()));
   2446 }
   2447 
   2448 void BytecodeGraphBuilder::VisitTestReferenceEqual() {
   2449   Node* left =
   2450       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   2451   Node* right = environment()->LookupAccumulator();
   2452   Node* result = NewNode(simplified()->ReferenceEqual(), left, right);
   2453   environment()->BindAccumulator(result);
   2454 }
   2455 
   2456 void BytecodeGraphBuilder::VisitTestIn() {
   2457   PrepareEagerCheckpoint();
   2458   Node* object = environment()->LookupAccumulator();
   2459   Node* key =
   2460       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   2461   Node* node = NewNode(javascript()->HasProperty(), object, key);
   2462   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   2463 }
   2464 
   2465 void BytecodeGraphBuilder::VisitTestInstanceOf() {
   2466   int const slot_index = bytecode_iterator().GetIndexOperand(1);
   2467   BuildCompareOp(javascript()->InstanceOf(CreateVectorSlotPair(slot_index)));
   2468 }
   2469 
   2470 void BytecodeGraphBuilder::VisitTestUndetectable() {
   2471   Node* object = environment()->LookupAccumulator();
   2472   Node* node = NewNode(jsgraph()->simplified()->ObjectIsUndetectable(), object);
   2473   environment()->BindAccumulator(node);
   2474 }
   2475 
   2476 void BytecodeGraphBuilder::VisitTestNull() {
   2477   Node* object = environment()->LookupAccumulator();
   2478   Node* result = NewNode(simplified()->ReferenceEqual(), object,
   2479                          jsgraph()->NullConstant());
   2480   environment()->BindAccumulator(result);
   2481 }
   2482 
   2483 void BytecodeGraphBuilder::VisitTestUndefined() {
   2484   Node* object = environment()->LookupAccumulator();
   2485   Node* result = NewNode(simplified()->ReferenceEqual(), object,
   2486                          jsgraph()->UndefinedConstant());
   2487   environment()->BindAccumulator(result);
   2488 }
   2489 
   2490 void BytecodeGraphBuilder::VisitTestTypeOf() {
   2491   Node* object = environment()->LookupAccumulator();
   2492   auto literal_flag = interpreter::TestTypeOfFlags::Decode(
   2493       bytecode_iterator().GetFlagOperand(0));
   2494   Node* result;
   2495   switch (literal_flag) {
   2496     case interpreter::TestTypeOfFlags::LiteralFlag::kNumber:
   2497       result = NewNode(simplified()->ObjectIsNumber(), object);
   2498       break;
   2499     case interpreter::TestTypeOfFlags::LiteralFlag::kString:
   2500       result = NewNode(simplified()->ObjectIsString(), object);
   2501       break;
   2502     case interpreter::TestTypeOfFlags::LiteralFlag::kSymbol:
   2503       result = NewNode(simplified()->ObjectIsSymbol(), object);
   2504       break;
   2505     case interpreter::TestTypeOfFlags::LiteralFlag::kBigInt:
   2506       result = NewNode(simplified()->ObjectIsBigInt(), object);
   2507       break;
   2508     case interpreter::TestTypeOfFlags::LiteralFlag::kBoolean:
   2509       result = NewNode(common()->Select(MachineRepresentation::kTagged),
   2510                        NewNode(simplified()->ReferenceEqual(), object,
   2511                                jsgraph()->TrueConstant()),
   2512                        jsgraph()->TrueConstant(),
   2513                        NewNode(simplified()->ReferenceEqual(), object,
   2514                                jsgraph()->FalseConstant()));
   2515       break;
   2516     case interpreter::TestTypeOfFlags::LiteralFlag::kUndefined:
   2517       result = graph()->NewNode(
   2518           common()->Select(MachineRepresentation::kTagged),
   2519           graph()->NewNode(simplified()->ReferenceEqual(), object,
   2520                            jsgraph()->NullConstant()),
   2521           jsgraph()->FalseConstant(),
   2522           graph()->NewNode(simplified()->ObjectIsUndetectable(), object));
   2523       break;
   2524     case interpreter::TestTypeOfFlags::LiteralFlag::kFunction:
   2525       result =
   2526           graph()->NewNode(simplified()->ObjectIsDetectableCallable(), object);
   2527       break;
   2528     case interpreter::TestTypeOfFlags::LiteralFlag::kObject:
   2529       result = graph()->NewNode(
   2530           common()->Select(MachineRepresentation::kTagged),
   2531           graph()->NewNode(simplified()->ObjectIsNonCallable(), object),
   2532           jsgraph()->TrueConstant(),
   2533           graph()->NewNode(simplified()->ReferenceEqual(), object,
   2534                            jsgraph()->NullConstant()));
   2535       break;
   2536     case interpreter::TestTypeOfFlags::LiteralFlag::kOther:
   2537       UNREACHABLE();  // Should never be emitted.
   2538       break;
   2539   }
   2540   environment()->BindAccumulator(result);
   2541 }
   2542 
   2543 void BytecodeGraphBuilder::BuildCastOperator(const Operator* js_op) {
   2544   Node* value = NewNode(js_op, environment()->LookupAccumulator());
   2545   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value,
   2546                               Environment::kAttachFrameState);
   2547 }
   2548 
   2549 void BytecodeGraphBuilder::VisitToName() {
   2550   BuildCastOperator(javascript()->ToName());
   2551 }
   2552 
   2553 void BytecodeGraphBuilder::VisitToObject() {
   2554   BuildCastOperator(javascript()->ToObject());
   2555 }
   2556 
   2557 void BytecodeGraphBuilder::VisitToString() {
   2558   Node* value =
   2559       NewNode(javascript()->ToString(), environment()->LookupAccumulator());
   2560   environment()->BindAccumulator(value, Environment::kAttachFrameState);
   2561 }
   2562 
   2563 void BytecodeGraphBuilder::VisitToNumber() {
   2564   PrepareEagerCheckpoint();
   2565   Node* object = environment()->LookupAccumulator();
   2566 
   2567   FeedbackSlot slot = bytecode_iterator().GetSlotOperand(0);
   2568   JSTypeHintLowering::LoweringResult lowering =
   2569       TryBuildSimplifiedToNumber(object, slot);
   2570 
   2571   Node* node = nullptr;
   2572   if (lowering.IsSideEffectFree()) {
   2573     node = lowering.value();
   2574   } else {
   2575     DCHECK(!lowering.Changed());
   2576     node = NewNode(javascript()->ToNumber(), object);
   2577   }
   2578 
   2579   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   2580 }
   2581 
   2582 void BytecodeGraphBuilder::VisitToNumeric() {
   2583   PrepareEagerCheckpoint();
   2584   Node* object = environment()->LookupAccumulator();
   2585 
   2586   // If we have some kind of Number feedback, we do the same lowering as for
   2587   // ToNumber.
   2588   FeedbackSlot slot = bytecode_iterator().GetSlotOperand(0);
   2589   JSTypeHintLowering::LoweringResult lowering =
   2590       TryBuildSimplifiedToNumber(object, slot);
   2591 
   2592   Node* node = nullptr;
   2593   if (lowering.IsSideEffectFree()) {
   2594     node = lowering.value();
   2595   } else {
   2596     DCHECK(!lowering.Changed());
   2597     node = NewNode(javascript()->ToNumeric(), object);
   2598   }
   2599 
   2600   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   2601 }
   2602 
   2603 void BytecodeGraphBuilder::VisitJump() { BuildJump(); }
   2604 
   2605 void BytecodeGraphBuilder::VisitJumpConstant() { BuildJump(); }
   2606 
   2607 void BytecodeGraphBuilder::VisitJumpIfTrue() { BuildJumpIfTrue(); }
   2608 
   2609 void BytecodeGraphBuilder::VisitJumpIfTrueConstant() { BuildJumpIfTrue(); }
   2610 
   2611 void BytecodeGraphBuilder::VisitJumpIfFalse() { BuildJumpIfFalse(); }
   2612 
   2613 void BytecodeGraphBuilder::VisitJumpIfFalseConstant() { BuildJumpIfFalse(); }
   2614 
   2615 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue() {
   2616   BuildJumpIfToBooleanTrue();
   2617 }
   2618 
   2619 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant() {
   2620   BuildJumpIfToBooleanTrue();
   2621 }
   2622 
   2623 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse() {
   2624   BuildJumpIfToBooleanFalse();
   2625 }
   2626 
   2627 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant() {
   2628   BuildJumpIfToBooleanFalse();
   2629 }
   2630 
   2631 void BytecodeGraphBuilder::VisitJumpIfJSReceiver() { BuildJumpIfJSReceiver(); }
   2632 
   2633 void BytecodeGraphBuilder::VisitJumpIfJSReceiverConstant() {
   2634   BuildJumpIfJSReceiver();
   2635 }
   2636 
   2637 void BytecodeGraphBuilder::VisitJumpIfNull() {
   2638   BuildJumpIfEqual(jsgraph()->NullConstant());
   2639 }
   2640 
   2641 void BytecodeGraphBuilder::VisitJumpIfNullConstant() {
   2642   BuildJumpIfEqual(jsgraph()->NullConstant());
   2643 }
   2644 
   2645 void BytecodeGraphBuilder::VisitJumpIfNotNull() {
   2646   BuildJumpIfNotEqual(jsgraph()->NullConstant());
   2647 }
   2648 
   2649 void BytecodeGraphBuilder::VisitJumpIfNotNullConstant() {
   2650   BuildJumpIfNotEqual(jsgraph()->NullConstant());
   2651 }
   2652 
   2653 void BytecodeGraphBuilder::VisitJumpIfUndefined() {
   2654   BuildJumpIfEqual(jsgraph()->UndefinedConstant());
   2655 }
   2656 
   2657 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant() {
   2658   BuildJumpIfEqual(jsgraph()->UndefinedConstant());
   2659 }
   2660 
   2661 void BytecodeGraphBuilder::VisitJumpIfNotUndefined() {
   2662   BuildJumpIfNotEqual(jsgraph()->UndefinedConstant());
   2663 }
   2664 
   2665 void BytecodeGraphBuilder::VisitJumpIfNotUndefinedConstant() {
   2666   BuildJumpIfNotEqual(jsgraph()->UndefinedConstant());
   2667 }
   2668 
   2669 void BytecodeGraphBuilder::VisitJumpLoop() { BuildJump(); }
   2670 
   2671 void BytecodeGraphBuilder::BuildSwitchOnSmi(Node* condition) {
   2672   interpreter::JumpTableTargetOffsets offsets =
   2673       bytecode_iterator().GetJumpTableTargetOffsets();
   2674 
   2675   NewSwitch(condition, offsets.size() + 1);
   2676   for (const auto& entry : offsets) {
   2677     SubEnvironment sub_environment(this);
   2678     NewIfValue(entry.case_value);
   2679     MergeIntoSuccessorEnvironment(entry.target_offset);
   2680   }
   2681   NewIfDefault();
   2682 }
   2683 
   2684 void BytecodeGraphBuilder::VisitSwitchOnSmiNoFeedback() {
   2685   PrepareEagerCheckpoint();
   2686 
   2687   Node* acc = environment()->LookupAccumulator();
   2688   Node* acc_smi = NewNode(simplified()->CheckSmi(VectorSlotPair()), acc);
   2689   BuildSwitchOnSmi(acc_smi);
   2690 }
   2691 
   2692 void BytecodeGraphBuilder::VisitStackCheck() {
   2693   PrepareEagerCheckpoint();
   2694   Node* node = NewNode(javascript()->StackCheck());
   2695   environment()->RecordAfterState(node, Environment::kAttachFrameState);
   2696 }
   2697 
   2698 void BytecodeGraphBuilder::VisitSetPendingMessage() {
   2699   Node* previous_message = NewNode(javascript()->LoadMessage());
   2700   NewNode(javascript()->StoreMessage(), environment()->LookupAccumulator());
   2701   environment()->BindAccumulator(previous_message);
   2702 }
   2703 
   2704 void BytecodeGraphBuilder::BuildReturn(const BytecodeLivenessState* liveness) {
   2705   BuildLoopExitsForFunctionExit(liveness);
   2706   Node* pop_node = jsgraph()->ZeroConstant();
   2707   Node* control =
   2708       NewNode(common()->Return(), pop_node, environment()->LookupAccumulator());
   2709   MergeControlToLeaveFunction(control);
   2710 }
   2711 
   2712 void BytecodeGraphBuilder::VisitReturn() {
   2713   BuildReturn(bytecode_analysis()->GetInLivenessFor(
   2714       bytecode_iterator().current_offset()));
   2715 }
   2716 
   2717 void BytecodeGraphBuilder::VisitDebugger() {
   2718   PrepareEagerCheckpoint();
   2719   Node* call = NewNode(javascript()->Debugger());
   2720   environment()->RecordAfterState(call, Environment::kAttachFrameState);
   2721 }
   2722 
   2723 // We cannot create a graph from the debugger copy of the bytecode array.
   2724 #define DEBUG_BREAK(Name, ...) \
   2725   void BytecodeGraphBuilder::Visit##Name() { UNREACHABLE(); }
   2726 DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK);
   2727 #undef DEBUG_BREAK
   2728 
   2729 void BytecodeGraphBuilder::VisitIncBlockCounter() {
   2730   Node* closure = GetFunctionClosure();
   2731   Node* coverage_array_slot =
   2732       jsgraph()->Constant(bytecode_iterator().GetIndexOperand(0));
   2733 
   2734   const Operator* op = javascript()->CallRuntime(Runtime::kIncBlockCounter);
   2735 
   2736   NewNode(op, closure, coverage_array_slot);
   2737 }
   2738 
   2739 void BytecodeGraphBuilder::VisitForInEnumerate() {
   2740   Node* receiver =
   2741       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   2742   Node* enumerator = NewNode(javascript()->ForInEnumerate(), receiver);
   2743   environment()->BindAccumulator(enumerator, Environment::kAttachFrameState);
   2744 }
   2745 
   2746 void BytecodeGraphBuilder::VisitForInPrepare() {
   2747   PrepareEagerCheckpoint();
   2748   Node* enumerator = environment()->LookupAccumulator();
   2749 
   2750   FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
   2751   JSTypeHintLowering::LoweringResult lowering =
   2752       TryBuildSimplifiedForInPrepare(enumerator, slot);
   2753   if (lowering.IsExit()) return;
   2754   DCHECK(!lowering.Changed());
   2755   Node* node = NewNode(javascript()->ForInPrepare(GetForInMode(1)), enumerator);
   2756   environment()->BindRegistersToProjections(
   2757       bytecode_iterator().GetRegisterOperand(0), node);
   2758 }
   2759 
   2760 void BytecodeGraphBuilder::VisitForInContinue() {
   2761   PrepareEagerCheckpoint();
   2762   Node* index =
   2763       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   2764   Node* cache_length =
   2765       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
   2766   Node* exit_cond = NewNode(simplified()->SpeculativeNumberLessThan(
   2767                                 NumberOperationHint::kSignedSmall),
   2768                             index, cache_length);
   2769   environment()->BindAccumulator(exit_cond);
   2770 }
   2771 
   2772 void BytecodeGraphBuilder::VisitForInNext() {
   2773   PrepareEagerCheckpoint();
   2774   Node* receiver =
   2775       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   2776   Node* index =
   2777       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
   2778   int catch_reg_pair_index = bytecode_iterator().GetRegisterOperand(2).index();
   2779   Node* cache_type = environment()->LookupRegister(
   2780       interpreter::Register(catch_reg_pair_index));
   2781   Node* cache_array = environment()->LookupRegister(
   2782       interpreter::Register(catch_reg_pair_index + 1));
   2783 
   2784   // We need to rename the {index} here, as in case of OSR we loose the
   2785   // information that the {index} is always a valid unsigned Smi value.
   2786   index = graph()->NewNode(common()->TypeGuard(Type::UnsignedSmall()), index,
   2787                            environment()->GetEffectDependency(),
   2788                            environment()->GetControlDependency());
   2789   environment()->UpdateEffectDependency(index);
   2790 
   2791   FeedbackSlot slot = bytecode_iterator().GetSlotOperand(3);
   2792   JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedForInNext(
   2793       receiver, cache_array, cache_type, index, slot);
   2794   if (lowering.IsExit()) return;
   2795 
   2796   DCHECK(!lowering.Changed());
   2797   Node* node = NewNode(javascript()->ForInNext(GetForInMode(3)), receiver,
   2798                        cache_array, cache_type, index);
   2799   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   2800 }
   2801 
   2802 void BytecodeGraphBuilder::VisitForInStep() {
   2803   PrepareEagerCheckpoint();
   2804   Node* index =
   2805       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   2806   index = NewNode(simplified()->SpeculativeSafeIntegerAdd(
   2807                       NumberOperationHint::kSignedSmall),
   2808                   index, jsgraph()->OneConstant());
   2809   environment()->BindAccumulator(index, Environment::kAttachFrameState);
   2810 }
   2811 
   2812 void BytecodeGraphBuilder::VisitSuspendGenerator() {
   2813   Node* generator = environment()->LookupRegister(
   2814       bytecode_iterator().GetRegisterOperand(0));
   2815   interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
   2816   // We assume we are storing a range starting from index 0.
   2817   CHECK_EQ(0, first_reg.index());
   2818   int register_count =
   2819       static_cast<int>(bytecode_iterator().GetRegisterCountOperand(2));
   2820   int parameter_count_without_receiver =
   2821       bytecode_array()->parameter_count() - 1;
   2822 
   2823   Node* suspend_id = jsgraph()->SmiConstant(
   2824       bytecode_iterator().GetUnsignedImmediateOperand(3));
   2825 
   2826   // The offsets used by the bytecode iterator are relative to a different base
   2827   // than what is used in the interpreter, hence the addition.
   2828   Node* offset =
   2829       jsgraph()->Constant(bytecode_iterator().current_offset() +
   2830                           (BytecodeArray::kHeaderSize - kHeapObjectTag));
   2831 
   2832   const BytecodeLivenessState* liveness = bytecode_analysis()->GetInLivenessFor(
   2833       bytecode_iterator().current_offset());
   2834 
   2835   // Maybe overallocate the value list since we don't know how many registers
   2836   // are live.
   2837   // TODO(leszeks): We could get this count from liveness rather than the
   2838   // register list.
   2839   int value_input_count = 3 + parameter_count_without_receiver + register_count;
   2840 
   2841   Node** value_inputs = local_zone()->NewArray<Node*>(value_input_count);
   2842   value_inputs[0] = generator;
   2843   value_inputs[1] = suspend_id;
   2844   value_inputs[2] = offset;
   2845 
   2846   int count_written = 0;
   2847   // Store the parameters.
   2848   for (int i = 0; i < parameter_count_without_receiver; i++) {
   2849     value_inputs[3 + count_written++] =
   2850         environment()->LookupRegister(interpreter::Register::FromParameterIndex(
   2851             i, parameter_count_without_receiver));
   2852   }
   2853 
   2854   // Store the registers.
   2855   for (int i = 0; i < register_count; ++i) {
   2856     if (liveness == nullptr || liveness->RegisterIsLive(i)) {
   2857       int index_in_parameters_and_registers =
   2858           parameter_count_without_receiver + i;
   2859       while (count_written < index_in_parameters_and_registers) {
   2860         value_inputs[3 + count_written++] = jsgraph()->OptimizedOutConstant();
   2861       }
   2862       value_inputs[3 + count_written++] =
   2863           environment()->LookupRegister(interpreter::Register(i));
   2864       DCHECK_EQ(count_written, index_in_parameters_and_registers + 1);
   2865     }
   2866   }
   2867 
   2868   // Use the actual written count rather than the register count to create the
   2869   // node.
   2870   MakeNode(javascript()->GeneratorStore(count_written), 3 + count_written,
   2871            value_inputs, false);
   2872 
   2873   // TODO(leszeks): This over-approximates the liveness at exit, only the
   2874   // accumulator should be live by this point.
   2875   BuildReturn(bytecode_analysis()->GetInLivenessFor(
   2876       bytecode_iterator().current_offset()));
   2877 }
   2878 
   2879 void BytecodeGraphBuilder::BuildSwitchOnGeneratorState(
   2880     const ZoneVector<ResumeJumpTarget>& resume_jump_targets,
   2881     bool allow_fallthrough_on_executing) {
   2882   Node* generator_state = environment()->LookupGeneratorState();
   2883 
   2884   int extra_cases = allow_fallthrough_on_executing ? 2 : 1;
   2885   NewSwitch(generator_state,
   2886             static_cast<int>(resume_jump_targets.size() + extra_cases));
   2887   for (const ResumeJumpTarget& target : resume_jump_targets) {
   2888     SubEnvironment sub_environment(this);
   2889     NewIfValue(target.suspend_id());
   2890     if (target.is_leaf()) {
   2891       // Mark that we are resuming executing.
   2892       environment()->BindGeneratorState(
   2893           jsgraph()->SmiConstant(JSGeneratorObject::kGeneratorExecuting));
   2894     }
   2895     // Jump to the target offset, whether it's a loop header or the resume.
   2896     MergeIntoSuccessorEnvironment(target.target_offset());
   2897   }
   2898 
   2899   {
   2900     SubEnvironment sub_environment(this);
   2901     // We should never hit the default case (assuming generator state cannot be
   2902     // corrupted), so abort if we do.
   2903     // TODO(leszeks): Maybe only check this in debug mode, and otherwise use
   2904     // the default to represent one of the cases above/fallthrough below?
   2905     NewIfDefault();
   2906     NewNode(simplified()->RuntimeAbort(AbortReason::kInvalidJumpTableIndex));
   2907     // TODO(7099): Investigate if we need LoopExit here.
   2908     Node* control = NewNode(common()->Throw());
   2909     MergeControlToLeaveFunction(control);
   2910   }
   2911 
   2912   if (allow_fallthrough_on_executing) {
   2913     // If we are executing (rather than resuming), and we allow it, just fall
   2914     // through to the actual loop body.
   2915     NewIfValue(JSGeneratorObject::kGeneratorExecuting);
   2916   } else {
   2917     // Otherwise, this environment is dead.
   2918     set_environment(nullptr);
   2919   }
   2920 }
   2921 
   2922 void BytecodeGraphBuilder::VisitSwitchOnGeneratorState() {
   2923   Node* generator =
   2924       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   2925 
   2926   Node* generator_is_undefined =
   2927       NewNode(simplified()->ReferenceEqual(), generator,
   2928               jsgraph()->UndefinedConstant());
   2929 
   2930   NewBranch(generator_is_undefined);
   2931   {
   2932     SubEnvironment resume_env(this);
   2933     NewIfFalse();
   2934 
   2935     Node* generator_state =
   2936         NewNode(javascript()->GeneratorRestoreContinuation(), generator);
   2937     environment()->BindGeneratorState(generator_state);
   2938 
   2939     Node* generator_context =
   2940         NewNode(javascript()->GeneratorRestoreContext(), generator);
   2941     environment()->SetContext(generator_context);
   2942 
   2943     BuildSwitchOnGeneratorState(bytecode_analysis()->resume_jump_targets(),
   2944                                 false);
   2945   }
   2946 
   2947   // Fallthrough for the first-call case.
   2948   NewIfTrue();
   2949 }
   2950 
   2951 void BytecodeGraphBuilder::VisitResumeGenerator() {
   2952   Node* generator =
   2953       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   2954   interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
   2955   // We assume we are restoring registers starting fromm index 0.
   2956   CHECK_EQ(0, first_reg.index());
   2957 
   2958   const BytecodeLivenessState* liveness =
   2959       bytecode_analysis()->GetOutLivenessFor(
   2960           bytecode_iterator().current_offset());
   2961 
   2962   int parameter_count_without_receiver =
   2963       bytecode_array()->parameter_count() - 1;
   2964 
   2965   // Mapping between registers and array indices must match that used in
   2966   // InterpreterAssembler::ExportParametersAndRegisterFile.
   2967   for (int i = 0; i < environment()->register_count(); ++i) {
   2968     if (liveness == nullptr || liveness->RegisterIsLive(i)) {
   2969       Node* value = NewNode(javascript()->GeneratorRestoreRegister(
   2970                                 parameter_count_without_receiver + i),
   2971                             generator);
   2972       environment()->BindRegister(interpreter::Register(i), value);
   2973     }
   2974   }
   2975 
   2976   // Update the accumulator with the generator's input_or_debug_pos.
   2977   Node* input_or_debug_pos =
   2978       NewNode(javascript()->GeneratorRestoreInputOrDebugPos(), generator);
   2979   environment()->BindAccumulator(input_or_debug_pos);
   2980 }
   2981 
   2982 void BytecodeGraphBuilder::VisitWide() {
   2983   // Consumed by the BytecodeArrayIterator.
   2984   UNREACHABLE();
   2985 }
   2986 
   2987 void BytecodeGraphBuilder::VisitExtraWide() {
   2988   // Consumed by the BytecodeArrayIterator.
   2989   UNREACHABLE();
   2990 }
   2991 
   2992 void BytecodeGraphBuilder::VisitIllegal() {
   2993   // Not emitted in valid bytecode.
   2994   UNREACHABLE();
   2995 }
   2996 
   2997 void BytecodeGraphBuilder::SwitchToMergeEnvironment(int current_offset) {
   2998   auto it = merge_environments_.find(current_offset);
   2999   if (it != merge_environments_.end()) {
   3000     mark_as_needing_eager_checkpoint(true);
   3001     if (environment() != nullptr) {
   3002       it->second->Merge(environment(),
   3003                         bytecode_analysis()->GetInLivenessFor(current_offset));
   3004     }
   3005     set_environment(it->second);
   3006   }
   3007 }
   3008 
   3009 void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) {
   3010   if (bytecode_analysis()->IsLoopHeader(current_offset)) {
   3011     mark_as_needing_eager_checkpoint(true);
   3012     const LoopInfo& loop_info =
   3013         bytecode_analysis()->GetLoopInfoFor(current_offset);
   3014     const BytecodeLivenessState* liveness =
   3015         bytecode_analysis()->GetInLivenessFor(current_offset);
   3016 
   3017     const auto& resume_jump_targets = loop_info.resume_jump_targets();
   3018     bool generate_suspend_switch = !resume_jump_targets.empty();
   3019 
   3020     // Add loop header.
   3021     environment()->PrepareForLoop(loop_info.assignments(), liveness);
   3022 
   3023     // Store a copy of the environment so we can connect merged back edge inputs
   3024     // to the loop header.
   3025     merge_environments_[current_offset] = environment()->Copy();
   3026 
   3027     // If this loop contains resumes, create a new switch just after the loop
   3028     // for those resumes.
   3029     if (generate_suspend_switch) {
   3030       BuildSwitchOnGeneratorState(loop_info.resume_jump_targets(), true);
   3031 
   3032       // TODO(leszeks): At this point we know we are executing rather than
   3033       // resuming, so we should be able to prune off the phis in the environment
   3034       // related to the resume path.
   3035 
   3036       // Set the generator state to a known constant.
   3037       environment()->BindGeneratorState(
   3038           jsgraph()->SmiConstant(JSGeneratorObject::kGeneratorExecuting));
   3039     }
   3040   }
   3041 }
   3042 
   3043 void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(int target_offset) {
   3044   BuildLoopExitsForBranch(target_offset);
   3045   Environment*& merge_environment = merge_environments_[target_offset];
   3046 
   3047   if (merge_environment == nullptr) {
   3048     // Append merge nodes to the environment. We may merge here with another
   3049     // environment. So add a place holder for merge nodes. We may add redundant
   3050     // but will be eliminated in a later pass.
   3051     // TODO(mstarzinger): Be smarter about this!
   3052     NewMerge();
   3053     merge_environment = environment();
   3054   } else {
   3055     // Merge any values which are live coming into the successor.
   3056     merge_environment->Merge(
   3057         environment(), bytecode_analysis()->GetInLivenessFor(target_offset));
   3058   }
   3059   set_environment(nullptr);
   3060 }
   3061 
   3062 void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
   3063   exit_controls_.push_back(exit);
   3064   set_environment(nullptr);
   3065 }
   3066 
   3067 void BytecodeGraphBuilder::BuildLoopExitsForBranch(int target_offset) {
   3068   int origin_offset = bytecode_iterator().current_offset();
   3069   // Only build loop exits for forward edges.
   3070   if (target_offset > origin_offset) {
   3071     BuildLoopExitsUntilLoop(
   3072         bytecode_analysis()->GetLoopOffsetFor(target_offset),
   3073         bytecode_analysis()->GetInLivenessFor(target_offset));
   3074   }
   3075 }
   3076 
   3077 void BytecodeGraphBuilder::BuildLoopExitsUntilLoop(
   3078     int loop_offset, const BytecodeLivenessState* liveness) {
   3079   int origin_offset = bytecode_iterator().current_offset();
   3080   int current_loop = bytecode_analysis()->GetLoopOffsetFor(origin_offset);
   3081   // The limit_offset is the stop offset for building loop exists, used for OSR.
   3082   // It prevents the creations of loopexits for loops which do not exist.
   3083   loop_offset = std::max(loop_offset, currently_peeled_loop_offset_);
   3084 
   3085   while (loop_offset < current_loop) {
   3086     Node* loop_node = merge_environments_[current_loop]->GetControlDependency();
   3087     const LoopInfo& loop_info =
   3088         bytecode_analysis()->GetLoopInfoFor(current_loop);
   3089     environment()->PrepareForLoopExit(loop_node, loop_info.assignments(),
   3090                                       liveness);
   3091     current_loop = loop_info.parent_offset();
   3092   }
   3093 }
   3094 
   3095 void BytecodeGraphBuilder::BuildLoopExitsForFunctionExit(
   3096     const BytecodeLivenessState* liveness) {
   3097   BuildLoopExitsUntilLoop(-1, liveness);
   3098 }
   3099 
   3100 void BytecodeGraphBuilder::BuildJump() {
   3101   MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
   3102 }
   3103 
   3104 void BytecodeGraphBuilder::BuildJumpIf(Node* condition) {
   3105   NewBranch(condition, BranchHint::kNone, IsSafetyCheck::kNoSafetyCheck);
   3106   {
   3107     SubEnvironment sub_environment(this);
   3108     NewIfTrue();
   3109     MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
   3110   }
   3111   NewIfFalse();
   3112 }
   3113 
   3114 void BytecodeGraphBuilder::BuildJumpIfNot(Node* condition) {
   3115   NewBranch(condition, BranchHint::kNone, IsSafetyCheck::kNoSafetyCheck);
   3116   {
   3117     SubEnvironment sub_environment(this);
   3118     NewIfFalse();
   3119     MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
   3120   }
   3121   NewIfTrue();
   3122 }
   3123 
   3124 void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
   3125   Node* accumulator = environment()->LookupAccumulator();
   3126   Node* condition =
   3127       NewNode(simplified()->ReferenceEqual(), accumulator, comperand);
   3128   BuildJumpIf(condition);
   3129 }
   3130 
   3131 void BytecodeGraphBuilder::BuildJumpIfNotEqual(Node* comperand) {
   3132   Node* accumulator = environment()->LookupAccumulator();
   3133   Node* condition =
   3134       NewNode(simplified()->ReferenceEqual(), accumulator, comperand);
   3135   BuildJumpIfNot(condition);
   3136 }
   3137 
   3138 void BytecodeGraphBuilder::BuildJumpIfFalse() {
   3139   NewBranch(environment()->LookupAccumulator(), BranchHint::kNone,
   3140             IsSafetyCheck::kNoSafetyCheck);
   3141   {
   3142     SubEnvironment sub_environment(this);
   3143     NewIfFalse();
   3144     environment()->BindAccumulator(jsgraph()->FalseConstant());
   3145     MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
   3146   }
   3147   NewIfTrue();
   3148   environment()->BindAccumulator(jsgraph()->TrueConstant());
   3149 }
   3150 
   3151 void BytecodeGraphBuilder::BuildJumpIfTrue() {
   3152   NewBranch(environment()->LookupAccumulator(), BranchHint::kNone,
   3153             IsSafetyCheck::kNoSafetyCheck);
   3154   {
   3155     SubEnvironment sub_environment(this);
   3156     NewIfTrue();
   3157     environment()->BindAccumulator(jsgraph()->TrueConstant());
   3158     MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
   3159   }
   3160   NewIfFalse();
   3161   environment()->BindAccumulator(jsgraph()->FalseConstant());
   3162 }
   3163 
   3164 void BytecodeGraphBuilder::BuildJumpIfToBooleanTrue() {
   3165   Node* accumulator = environment()->LookupAccumulator();
   3166   Node* condition = NewNode(simplified()->ToBoolean(), accumulator);
   3167   BuildJumpIf(condition);
   3168 }
   3169 
   3170 void BytecodeGraphBuilder::BuildJumpIfToBooleanFalse() {
   3171   Node* accumulator = environment()->LookupAccumulator();
   3172   Node* condition = NewNode(simplified()->ToBoolean(), accumulator);
   3173   BuildJumpIfNot(condition);
   3174 }
   3175 
   3176 void BytecodeGraphBuilder::BuildJumpIfNotHole() {
   3177   Node* accumulator = environment()->LookupAccumulator();
   3178   Node* condition = NewNode(simplified()->ReferenceEqual(), accumulator,
   3179                             jsgraph()->TheHoleConstant());
   3180   BuildJumpIfNot(condition);
   3181 }
   3182 
   3183 void BytecodeGraphBuilder::BuildJumpIfJSReceiver() {
   3184   Node* accumulator = environment()->LookupAccumulator();
   3185   Node* condition = NewNode(simplified()->ObjectIsReceiver(), accumulator);
   3186   BuildJumpIf(condition);
   3187 }
   3188 
   3189 JSTypeHintLowering::LoweringResult
   3190 BytecodeGraphBuilder::TryBuildSimplifiedUnaryOp(const Operator* op,
   3191                                                 Node* operand,
   3192                                                 FeedbackSlot slot) {
   3193   Node* effect = environment()->GetEffectDependency();
   3194   Node* control = environment()->GetControlDependency();
   3195   JSTypeHintLowering::LoweringResult result =
   3196       type_hint_lowering().ReduceUnaryOperation(op, operand, effect, control,
   3197                                                 slot);
   3198   ApplyEarlyReduction(result);
   3199   return result;
   3200 }
   3201 
   3202 JSTypeHintLowering::LoweringResult
   3203 BytecodeGraphBuilder::TryBuildSimplifiedBinaryOp(const Operator* op, Node* left,
   3204                                                  Node* right,
   3205                                                  FeedbackSlot slot) {
   3206   Node* effect = environment()->GetEffectDependency();
   3207   Node* control = environment()->GetControlDependency();
   3208   JSTypeHintLowering::LoweringResult result =
   3209       type_hint_lowering().ReduceBinaryOperation(op, left, right, effect,
   3210                                                  control, slot);
   3211   ApplyEarlyReduction(result);
   3212   return result;
   3213 }
   3214 
   3215 JSTypeHintLowering::LoweringResult
   3216 BytecodeGraphBuilder::TryBuildSimplifiedForInNext(Node* receiver,
   3217                                                   Node* cache_array,
   3218                                                   Node* cache_type, Node* index,
   3219                                                   FeedbackSlot slot) {
   3220   Node* effect = environment()->GetEffectDependency();
   3221   Node* control = environment()->GetControlDependency();
   3222   JSTypeHintLowering::LoweringResult result =
   3223       type_hint_lowering().ReduceForInNextOperation(
   3224           receiver, cache_array, cache_type, index, effect, control, slot);
   3225   ApplyEarlyReduction(result);
   3226   return result;
   3227 }
   3228 
   3229 JSTypeHintLowering::LoweringResult
   3230 BytecodeGraphBuilder::TryBuildSimplifiedForInPrepare(Node* enumerator,
   3231                                                      FeedbackSlot slot) {
   3232   Node* effect = environment()->GetEffectDependency();
   3233   Node* control = environment()->GetControlDependency();
   3234   JSTypeHintLowering::LoweringResult result =
   3235       type_hint_lowering().ReduceForInPrepareOperation(enumerator, effect,
   3236                                                        control, slot);
   3237   ApplyEarlyReduction(result);
   3238   return result;
   3239 }
   3240 
   3241 JSTypeHintLowering::LoweringResult
   3242 BytecodeGraphBuilder::TryBuildSimplifiedToNumber(Node* value,
   3243                                                  FeedbackSlot slot) {
   3244   Node* effect = environment()->GetEffectDependency();
   3245   Node* control = environment()->GetControlDependency();
   3246   JSTypeHintLowering::LoweringResult result =
   3247       type_hint_lowering().ReduceToNumberOperation(value, effect, control,
   3248                                                    slot);
   3249   ApplyEarlyReduction(result);
   3250   return result;
   3251 }
   3252 
   3253 JSTypeHintLowering::LoweringResult BytecodeGraphBuilder::TryBuildSimplifiedCall(
   3254     const Operator* op, Node* const* args, int arg_count, FeedbackSlot slot) {
   3255   Node* effect = environment()->GetEffectDependency();
   3256   Node* control = environment()->GetControlDependency();
   3257   JSTypeHintLowering::LoweringResult result =
   3258       type_hint_lowering().ReduceCallOperation(op, args, arg_count, effect,
   3259                                                control, slot);
   3260   ApplyEarlyReduction(result);
   3261   return result;
   3262 }
   3263 
   3264 JSTypeHintLowering::LoweringResult
   3265 BytecodeGraphBuilder::TryBuildSimplifiedConstruct(const Operator* op,
   3266                                                   Node* const* args,
   3267                                                   int arg_count,
   3268                                                   FeedbackSlot slot) {
   3269   Node* effect = environment()->GetEffectDependency();
   3270   Node* control = environment()->GetControlDependency();
   3271   JSTypeHintLowering::LoweringResult result =
   3272       type_hint_lowering().ReduceConstructOperation(op, args, arg_count, effect,
   3273                                                     control, slot);
   3274   ApplyEarlyReduction(result);
   3275   return result;
   3276 }
   3277 
   3278 JSTypeHintLowering::LoweringResult
   3279 BytecodeGraphBuilder::TryBuildSimplifiedLoadNamed(const Operator* op,
   3280                                                   Node* receiver,
   3281                                                   FeedbackSlot slot) {
   3282   Node* effect = environment()->GetEffectDependency();
   3283   Node* control = environment()->GetControlDependency();
   3284   JSTypeHintLowering::LoweringResult early_reduction =
   3285       type_hint_lowering().ReduceLoadNamedOperation(op, receiver, effect,
   3286                                                     control, slot);
   3287   ApplyEarlyReduction(early_reduction);
   3288   return early_reduction;
   3289 }
   3290 
   3291 JSTypeHintLowering::LoweringResult
   3292 BytecodeGraphBuilder::TryBuildSimplifiedLoadKeyed(const Operator* op,
   3293                                                   Node* receiver, Node* key,
   3294                                                   FeedbackSlot slot) {
   3295   Node* effect = environment()->GetEffectDependency();
   3296   Node* control = environment()->GetControlDependency();
   3297   JSTypeHintLowering::LoweringResult result =
   3298       type_hint_lowering().ReduceLoadKeyedOperation(op, receiver, key, effect,
   3299                                                     control, slot);
   3300   ApplyEarlyReduction(result);
   3301   return result;
   3302 }
   3303 
   3304 JSTypeHintLowering::LoweringResult
   3305 BytecodeGraphBuilder::TryBuildSimplifiedStoreNamed(const Operator* op,
   3306                                                    Node* receiver, Node* value,
   3307                                                    FeedbackSlot slot) {
   3308   Node* effect = environment()->GetEffectDependency();
   3309   Node* control = environment()->GetControlDependency();
   3310   JSTypeHintLowering::LoweringResult result =
   3311       type_hint_lowering().ReduceStoreNamedOperation(op, receiver, value,
   3312                                                      effect, control, slot);
   3313   ApplyEarlyReduction(result);
   3314   return result;
   3315 }
   3316 
   3317 JSTypeHintLowering::LoweringResult
   3318 BytecodeGraphBuilder::TryBuildSimplifiedStoreKeyed(const Operator* op,
   3319                                                    Node* receiver, Node* key,
   3320                                                    Node* value,
   3321                                                    FeedbackSlot slot) {
   3322   Node* effect = environment()->GetEffectDependency();
   3323   Node* control = environment()->GetControlDependency();
   3324   JSTypeHintLowering::LoweringResult result =
   3325       type_hint_lowering().ReduceStoreKeyedOperation(op, receiver, key, value,
   3326                                                      effect, control, slot);
   3327   ApplyEarlyReduction(result);
   3328   return result;
   3329 }
   3330 
   3331 void BytecodeGraphBuilder::ApplyEarlyReduction(
   3332     JSTypeHintLowering::LoweringResult reduction) {
   3333   if (reduction.IsExit()) {
   3334     MergeControlToLeaveFunction(reduction.control());
   3335   } else if (reduction.IsSideEffectFree()) {
   3336     environment()->UpdateEffectDependency(reduction.effect());
   3337     environment()->UpdateControlDependency(reduction.control());
   3338   } else {
   3339     DCHECK(!reduction.Changed());
   3340     // At the moment, we assume side-effect free reduction. To support
   3341     // side-effects, we would have to invalidate the eager checkpoint,
   3342     // so that deoptimization does not repeat the side effect.
   3343   }
   3344 }
   3345 
   3346 Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) {
   3347   if (size > input_buffer_size_) {
   3348     size = size + kInputBufferSizeIncrement + input_buffer_size_;
   3349     input_buffer_ = local_zone()->NewArray<Node*>(size);
   3350     input_buffer_size_ = size;
   3351   }
   3352   return input_buffer_;
   3353 }
   3354 
   3355 void BytecodeGraphBuilder::ExitThenEnterExceptionHandlers(int current_offset) {
   3356   HandlerTable table(*bytecode_array());
   3357 
   3358   // Potentially exit exception handlers.
   3359   while (!exception_handlers_.empty()) {
   3360     int current_end = exception_handlers_.top().end_offset_;
   3361     if (current_offset < current_end) break;  // Still covered by range.
   3362     exception_handlers_.pop();
   3363   }
   3364 
   3365   // Potentially enter exception handlers.
   3366   int num_entries = table.NumberOfRangeEntries();
   3367   while (current_exception_handler_ < num_entries) {
   3368     int next_start = table.GetRangeStart(current_exception_handler_);
   3369     if (current_offset < next_start) break;  // Not yet covered by range.
   3370     int next_end = table.GetRangeEnd(current_exception_handler_);
   3371     int next_handler = table.GetRangeHandler(current_exception_handler_);
   3372     int context_register = table.GetRangeData(current_exception_handler_);
   3373     exception_handlers_.push(
   3374         {next_start, next_end, next_handler, context_register});
   3375     current_exception_handler_++;
   3376   }
   3377 }
   3378 
   3379 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
   3380                                      Node* const* value_inputs,
   3381                                      bool incomplete) {
   3382   DCHECK_EQ(op->ValueInputCount(), value_input_count);
   3383 
   3384   bool has_context = OperatorProperties::HasContextInput(op);
   3385   bool has_frame_state = OperatorProperties::HasFrameStateInput(op);
   3386   bool has_control = op->ControlInputCount() == 1;
   3387   bool has_effect = op->EffectInputCount() == 1;
   3388 
   3389   DCHECK_LT(op->ControlInputCount(), 2);
   3390   DCHECK_LT(op->EffectInputCount(), 2);
   3391 
   3392   Node* result = nullptr;
   3393   if (!has_context && !has_frame_state && !has_control && !has_effect) {
   3394     result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
   3395   } else {
   3396     bool inside_handler = !exception_handlers_.empty();
   3397     int input_count_with_deps = value_input_count;
   3398     if (has_context) ++input_count_with_deps;
   3399     if (has_frame_state) ++input_count_with_deps;
   3400     if (has_control) ++input_count_with_deps;
   3401     if (has_effect) ++input_count_with_deps;
   3402     Node** buffer = EnsureInputBufferSize(input_count_with_deps);
   3403     memcpy(buffer, value_inputs, kPointerSize * value_input_count);
   3404     Node** current_input = buffer + value_input_count;
   3405     if (has_context) {
   3406       *current_input++ = environment()->Context();
   3407     }
   3408     if (has_frame_state) {
   3409       // The frame state will be inserted later. Here we misuse the {Dead} node
   3410       // as a sentinel to be later overwritten with the real frame state by the
   3411       // calls to {PrepareFrameState} within individual visitor methods.
   3412       *current_input++ = jsgraph()->Dead();
   3413     }
   3414     if (has_effect) {
   3415       *current_input++ = environment()->GetEffectDependency();
   3416     }
   3417     if (has_control) {
   3418       *current_input++ = environment()->GetControlDependency();
   3419     }
   3420     result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
   3421     // Update the current control dependency for control-producing nodes.
   3422     if (result->op()->ControlOutputCount() > 0) {
   3423       environment()->UpdateControlDependency(result);
   3424     }
   3425     // Update the current effect dependency for effect-producing nodes.
   3426     if (result->op()->EffectOutputCount() > 0) {
   3427       environment()->UpdateEffectDependency(result);
   3428     }
   3429     // Add implicit exception continuation for throwing nodes.
   3430     if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
   3431       int handler_offset = exception_handlers_.top().handler_offset_;
   3432       int context_index = exception_handlers_.top().context_register_;
   3433       interpreter::Register context_register(context_index);
   3434       Environment* success_env = environment()->Copy();
   3435       const Operator* op = common()->IfException();
   3436       Node* effect = environment()->GetEffectDependency();
   3437       Node* on_exception = graph()->NewNode(op, effect, result);
   3438       Node* context = environment()->LookupRegister(context_register);
   3439       environment()->UpdateControlDependency(on_exception);
   3440       environment()->UpdateEffectDependency(on_exception);
   3441       environment()->BindAccumulator(on_exception);
   3442       environment()->SetContext(context);
   3443       MergeIntoSuccessorEnvironment(handler_offset);
   3444       set_environment(success_env);
   3445     }
   3446     // Add implicit success continuation for throwing nodes.
   3447     if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
   3448       const Operator* if_success = common()->IfSuccess();
   3449       Node* on_success = graph()->NewNode(if_success, result);
   3450       environment()->UpdateControlDependency(on_success);
   3451     }
   3452     // Ensure checkpoints are created after operations with side-effects.
   3453     if (has_effect && !result->op()->HasProperty(Operator::kNoWrite)) {
   3454       mark_as_needing_eager_checkpoint(true);
   3455     }
   3456   }
   3457 
   3458   return result;
   3459 }
   3460 
   3461 
   3462 Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) {
   3463   const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
   3464   Node** buffer = EnsureInputBufferSize(count + 1);
   3465   MemsetPointer(buffer, input, count);
   3466   buffer[count] = control;
   3467   return graph()->NewNode(phi_op, count + 1, buffer, true);
   3468 }
   3469 
   3470 Node* BytecodeGraphBuilder::NewEffectPhi(int count, Node* input,
   3471                                          Node* control) {
   3472   const Operator* phi_op = common()->EffectPhi(count);
   3473   Node** buffer = EnsureInputBufferSize(count + 1);
   3474   MemsetPointer(buffer, input, count);
   3475   buffer[count] = control;
   3476   return graph()->NewNode(phi_op, count + 1, buffer, true);
   3477 }
   3478 
   3479 
   3480 Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) {
   3481   int inputs = control->op()->ControlInputCount() + 1;
   3482   if (control->opcode() == IrOpcode::kLoop) {
   3483     // Control node for loop exists, add input.
   3484     const Operator* op = common()->Loop(inputs);
   3485     control->AppendInput(graph_zone(), other);
   3486     NodeProperties::ChangeOp(control, op);
   3487   } else if (control->opcode() == IrOpcode::kMerge) {
   3488     // Control node for merge exists, add input.
   3489     const Operator* op = common()->Merge(inputs);
   3490     control->AppendInput(graph_zone(), other);
   3491     NodeProperties::ChangeOp(control, op);
   3492   } else {
   3493     // Control node is a singleton, introduce a merge.
   3494     const Operator* op = common()->Merge(inputs);
   3495     Node* merge_inputs[] = {control, other};
   3496     control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true);
   3497   }
   3498   return control;
   3499 }
   3500 
   3501 Node* BytecodeGraphBuilder::MergeEffect(Node* value, Node* other,
   3502                                         Node* control) {
   3503   int inputs = control->op()->ControlInputCount();
   3504   if (value->opcode() == IrOpcode::kEffectPhi &&
   3505       NodeProperties::GetControlInput(value) == control) {
   3506     // Phi already exists, add input.
   3507     value->InsertInput(graph_zone(), inputs - 1, other);
   3508     NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
   3509   } else if (value != other) {
   3510     // Phi does not exist yet, introduce one.
   3511     value = NewEffectPhi(inputs, value, control);
   3512     value->ReplaceInput(inputs - 1, other);
   3513   }
   3514   return value;
   3515 }
   3516 
   3517 Node* BytecodeGraphBuilder::MergeValue(Node* value, Node* other,
   3518                                        Node* control) {
   3519   int inputs = control->op()->ControlInputCount();
   3520   if (value->opcode() == IrOpcode::kPhi &&
   3521       NodeProperties::GetControlInput(value) == control) {
   3522     // Phi already exists, add input.
   3523     value->InsertInput(graph_zone(), inputs - 1, other);
   3524     NodeProperties::ChangeOp(
   3525         value, common()->Phi(MachineRepresentation::kTagged, inputs));
   3526   } else if (value != other) {
   3527     // Phi does not exist yet, introduce one.
   3528     value = NewPhi(inputs, value, control);
   3529     value->ReplaceInput(inputs - 1, other);
   3530   }
   3531   return value;
   3532 }
   3533 
   3534 void BytecodeGraphBuilder::UpdateSourcePosition(SourcePositionTableIterator* it,
   3535                                                 int offset) {
   3536   if (it->done()) return;
   3537   if (it->code_offset() == offset) {
   3538     source_positions_->SetCurrentPosition(SourcePosition(
   3539         it->source_position().ScriptOffset(), start_position_.InliningId()));
   3540     it->Advance();
   3541   } else {
   3542     DCHECK_GT(it->code_offset(), offset);
   3543   }
   3544 }
   3545 
   3546 }  // namespace compiler
   3547 }  // namespace internal
   3548 }  // namespace v8
   3549