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/compilation-info.h"
     10 #include "src/compiler/bytecode-branch-analysis.h"
     11 #include "src/compiler/compiler-source-position-table.h"
     12 #include "src/compiler/linkage.h"
     13 #include "src/compiler/operator-properties.h"
     14 #include "src/interpreter/bytecodes.h"
     15 #include "src/objects-inl.h"
     16 
     17 namespace v8 {
     18 namespace internal {
     19 namespace compiler {
     20 
     21 // The abstract execution environment simulates the content of the interpreter
     22 // register file. The environment performs SSA-renaming of all tracked nodes at
     23 // split and merge points in the control flow.
     24 class BytecodeGraphBuilder::Environment : public ZoneObject {
     25  public:
     26   Environment(BytecodeGraphBuilder* builder, int register_count,
     27               int parameter_count, Node* control_dependency, Node* context);
     28 
     29   // Specifies whether environment binding methods should attach frame state
     30   // inputs to nodes representing the value being bound. This is done because
     31   // the {OutputFrameStateCombine} is closely related to the binding method.
     32   enum FrameStateAttachmentMode { kAttachFrameState, kDontAttachFrameState };
     33 
     34   int parameter_count() const { return parameter_count_; }
     35   int register_count() const { return register_count_; }
     36 
     37   Node* LookupAccumulator() const;
     38   Node* LookupRegister(interpreter::Register the_register) const;
     39   void MarkAllRegistersLive();
     40 
     41   void BindAccumulator(Node* node,
     42                        FrameStateAttachmentMode mode = kDontAttachFrameState);
     43   void BindRegister(interpreter::Register the_register, Node* node,
     44                     FrameStateAttachmentMode mode = kDontAttachFrameState);
     45   void BindRegistersToProjections(
     46       interpreter::Register first_reg, Node* node,
     47       FrameStateAttachmentMode mode = kDontAttachFrameState);
     48   void RecordAfterState(Node* node,
     49                         FrameStateAttachmentMode mode = kDontAttachFrameState);
     50 
     51   // Effect dependency tracked by this environment.
     52   Node* GetEffectDependency() { return effect_dependency_; }
     53   void UpdateEffectDependency(Node* dependency) {
     54     effect_dependency_ = dependency;
     55   }
     56 
     57   // Preserve a checkpoint of the environment for the IR graph. Any
     58   // further mutation of the environment will not affect checkpoints.
     59   Node* Checkpoint(BailoutId bytecode_offset, OutputFrameStateCombine combine,
     60                    bool owner_has_exception);
     61 
     62   // Control dependency tracked by this environment.
     63   Node* GetControlDependency() const { return control_dependency_; }
     64   void UpdateControlDependency(Node* dependency) {
     65     control_dependency_ = dependency;
     66   }
     67 
     68   Node* Context() const { return context_; }
     69   void SetContext(Node* new_context) { context_ = new_context; }
     70 
     71   Environment* CopyForConditional();
     72   Environment* CopyForLoop();
     73   Environment* CopyForOsrEntry();
     74   void Merge(Environment* other);
     75   void PrepareForOsrEntry();
     76 
     77   void PrepareForLoopExit(Node* loop);
     78 
     79  private:
     80   Environment(const Environment* copy, LivenessAnalyzerBlock* liveness_block);
     81   void PrepareForLoop();
     82 
     83   bool StateValuesRequireUpdate(Node** state_values, int offset, int count);
     84   void UpdateStateValues(Node** state_values, int offset, int count);
     85 
     86   int RegisterToValuesIndex(interpreter::Register the_register) const;
     87 
     88   bool IsLivenessBlockConsistent() const;
     89 
     90   Zone* zone() const { return builder_->local_zone(); }
     91   Graph* graph() const { return builder_->graph(); }
     92   CommonOperatorBuilder* common() const { return builder_->common(); }
     93   BytecodeGraphBuilder* builder() const { return builder_; }
     94   LivenessAnalyzerBlock* liveness_block() const { return liveness_block_; }
     95   const NodeVector* values() const { return &values_; }
     96   NodeVector* values() { return &values_; }
     97   int register_base() const { return register_base_; }
     98   int accumulator_base() const { return accumulator_base_; }
     99 
    100   BytecodeGraphBuilder* builder_;
    101   int register_count_;
    102   int parameter_count_;
    103   LivenessAnalyzerBlock* liveness_block_;
    104   Node* context_;
    105   Node* control_dependency_;
    106   Node* effect_dependency_;
    107   NodeVector values_;
    108   Node* parameters_state_values_;
    109   Node* registers_state_values_;
    110   Node* accumulator_state_values_;
    111   int register_base_;
    112   int accumulator_base_;
    113 };
    114 
    115 
    116 // Issues:
    117 // - Scopes - intimately tied to AST. Need to eval what is needed.
    118 // - Need to resolve closure parameter treatment.
    119 BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder,
    120                                                int register_count,
    121                                                int parameter_count,
    122                                                Node* control_dependency,
    123                                                Node* context)
    124     : builder_(builder),
    125       register_count_(register_count),
    126       parameter_count_(parameter_count),
    127       liveness_block_(builder->is_liveness_analysis_enabled_
    128                           ? builder_->liveness_analyzer()->NewBlock()
    129                           : nullptr),
    130       context_(context),
    131       control_dependency_(control_dependency),
    132       effect_dependency_(control_dependency),
    133       values_(builder->local_zone()),
    134       parameters_state_values_(nullptr),
    135       registers_state_values_(nullptr),
    136       accumulator_state_values_(nullptr) {
    137   // The layout of values_ is:
    138   //
    139   // [receiver] [parameters] [registers] [accumulator]
    140   //
    141   // parameter[0] is the receiver (this), parameters 1..N are the
    142   // parameters supplied to the method (arg0..argN-1). The accumulator
    143   // is stored separately.
    144 
    145   // Parameters including the receiver
    146   for (int i = 0; i < parameter_count; i++) {
    147     const char* debug_name = (i == 0) ? "%this" : nullptr;
    148     const Operator* op = common()->Parameter(i, debug_name);
    149     Node* parameter = builder->graph()->NewNode(op, graph()->start());
    150     values()->push_back(parameter);
    151   }
    152 
    153   // Registers
    154   register_base_ = static_cast<int>(values()->size());
    155   Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
    156   values()->insert(values()->end(), register_count, undefined_constant);
    157 
    158   // Accumulator
    159   accumulator_base_ = static_cast<int>(values()->size());
    160   values()->push_back(undefined_constant);
    161 }
    162 
    163 BytecodeGraphBuilder::Environment::Environment(
    164     const BytecodeGraphBuilder::Environment* other,
    165     LivenessAnalyzerBlock* liveness_block)
    166     : builder_(other->builder_),
    167       register_count_(other->register_count_),
    168       parameter_count_(other->parameter_count_),
    169       liveness_block_(liveness_block),
    170       context_(other->context_),
    171       control_dependency_(other->control_dependency_),
    172       effect_dependency_(other->effect_dependency_),
    173       values_(other->zone()),
    174       parameters_state_values_(nullptr),
    175       registers_state_values_(nullptr),
    176       accumulator_state_values_(nullptr),
    177       register_base_(other->register_base_),
    178       accumulator_base_(other->accumulator_base_) {
    179   values_ = other->values_;
    180 }
    181 
    182 
    183 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex(
    184     interpreter::Register the_register) const {
    185   if (the_register.is_parameter()) {
    186     return the_register.ToParameterIndex(parameter_count());
    187   } else {
    188     return the_register.index() + register_base();
    189   }
    190 }
    191 
    192 bool BytecodeGraphBuilder::Environment::IsLivenessBlockConsistent() const {
    193   return !builder_->IsLivenessAnalysisEnabled() ==
    194          (liveness_block() == nullptr);
    195 }
    196 
    197 Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const {
    198   DCHECK(IsLivenessBlockConsistent());
    199   if (liveness_block() != nullptr) {
    200     liveness_block()->LookupAccumulator();
    201   }
    202   return values()->at(accumulator_base_);
    203 }
    204 
    205 
    206 Node* BytecodeGraphBuilder::Environment::LookupRegister(
    207     interpreter::Register the_register) const {
    208   if (the_register.is_current_context()) {
    209     return Context();
    210   } else if (the_register.is_function_closure()) {
    211     return builder()->GetFunctionClosure();
    212   } else if (the_register.is_new_target()) {
    213     return builder()->GetNewTarget();
    214   } else {
    215     int values_index = RegisterToValuesIndex(the_register);
    216     if (liveness_block() != nullptr && !the_register.is_parameter()) {
    217       DCHECK(IsLivenessBlockConsistent());
    218       liveness_block()->Lookup(the_register.index());
    219     }
    220     return values()->at(values_index);
    221   }
    222 }
    223 
    224 void BytecodeGraphBuilder::Environment::MarkAllRegistersLive() {
    225   DCHECK(IsLivenessBlockConsistent());
    226   if (liveness_block() != nullptr) {
    227     for (int i = 0; i < register_count(); ++i) {
    228       liveness_block()->Lookup(i);
    229     }
    230   }
    231 }
    232 
    233 void BytecodeGraphBuilder::Environment::BindAccumulator(
    234     Node* node, FrameStateAttachmentMode mode) {
    235   if (mode == FrameStateAttachmentMode::kAttachFrameState) {
    236     builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(0));
    237   }
    238   DCHECK(IsLivenessBlockConsistent());
    239   if (liveness_block() != nullptr) {
    240     liveness_block()->BindAccumulator();
    241   }
    242   values()->at(accumulator_base_) = node;
    243 }
    244 
    245 void BytecodeGraphBuilder::Environment::BindRegister(
    246     interpreter::Register the_register, Node* node,
    247     FrameStateAttachmentMode mode) {
    248   int values_index = RegisterToValuesIndex(the_register);
    249   if (mode == FrameStateAttachmentMode::kAttachFrameState) {
    250     builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(
    251                                            accumulator_base_ - values_index));
    252   }
    253   values()->at(values_index) = node;
    254   if (liveness_block() != nullptr && !the_register.is_parameter()) {
    255     DCHECK(IsLivenessBlockConsistent());
    256     liveness_block()->Bind(the_register.index());
    257   }
    258 }
    259 
    260 void BytecodeGraphBuilder::Environment::BindRegistersToProjections(
    261     interpreter::Register first_reg, Node* node,
    262     FrameStateAttachmentMode mode) {
    263   int values_index = RegisterToValuesIndex(first_reg);
    264   if (mode == FrameStateAttachmentMode::kAttachFrameState) {
    265     builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(
    266                                            accumulator_base_ - values_index));
    267   }
    268   for (int i = 0; i < node->op()->ValueOutputCount(); i++) {
    269     values()->at(values_index + i) =
    270         builder()->NewNode(common()->Projection(i), node);
    271   }
    272 }
    273 
    274 void BytecodeGraphBuilder::Environment::RecordAfterState(
    275     Node* node, FrameStateAttachmentMode mode) {
    276   if (mode == FrameStateAttachmentMode::kAttachFrameState) {
    277     builder()->PrepareFrameState(node, OutputFrameStateCombine::Ignore());
    278   }
    279 }
    280 
    281 
    282 BytecodeGraphBuilder::Environment*
    283 BytecodeGraphBuilder::Environment::CopyForLoop() {
    284   PrepareForLoop();
    285   if (liveness_block() != nullptr) {
    286     // Finish the current block before copying.
    287     liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block());
    288   }
    289   return new (zone()) Environment(this, liveness_block());
    290 }
    291 
    292 BytecodeGraphBuilder::Environment*
    293 BytecodeGraphBuilder::Environment::CopyForOsrEntry() {
    294   return new (zone())
    295       Environment(this, builder_->liveness_analyzer()->NewBlock());
    296 }
    297 
    298 BytecodeGraphBuilder::Environment*
    299 BytecodeGraphBuilder::Environment::CopyForConditional() {
    300   LivenessAnalyzerBlock* copy_liveness_block = nullptr;
    301   if (liveness_block() != nullptr) {
    302     copy_liveness_block =
    303         builder_->liveness_analyzer()->NewBlock(liveness_block());
    304     liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block());
    305   }
    306   return new (zone()) Environment(this, copy_liveness_block);
    307 }
    308 
    309 
    310 void BytecodeGraphBuilder::Environment::Merge(
    311     BytecodeGraphBuilder::Environment* other) {
    312   if (builder_->is_liveness_analysis_enabled_) {
    313     if (GetControlDependency()->opcode() != IrOpcode::kLoop) {
    314       liveness_block_ =
    315           builder()->liveness_analyzer()->NewBlock(liveness_block());
    316     }
    317     liveness_block()->AddPredecessor(other->liveness_block());
    318   }
    319 
    320   // Create a merge of the control dependencies of both environments and update
    321   // the current environment's control dependency accordingly.
    322   Node* control = builder()->MergeControl(GetControlDependency(),
    323                                           other->GetControlDependency());
    324   UpdateControlDependency(control);
    325 
    326   // Create a merge of the effect dependencies of both environments and update
    327   // the current environment's effect dependency accordingly.
    328   Node* effect = builder()->MergeEffect(GetEffectDependency(),
    329                                         other->GetEffectDependency(), control);
    330   UpdateEffectDependency(effect);
    331 
    332   // Introduce Phi nodes for values that have differing input at merge points,
    333   // potentially extending an existing Phi node if possible.
    334   context_ = builder()->MergeValue(context_, other->context_, control);
    335   for (size_t i = 0; i < values_.size(); i++) {
    336     values_[i] = builder()->MergeValue(values_[i], other->values_[i], control);
    337   }
    338 }
    339 
    340 
    341 void BytecodeGraphBuilder::Environment::PrepareForLoop() {
    342   // Create a control node for the loop header.
    343   Node* control = builder()->NewLoop();
    344 
    345   // Create a Phi for external effects.
    346   Node* effect = builder()->NewEffectPhi(1, GetEffectDependency(), control);
    347   UpdateEffectDependency(effect);
    348 
    349   // Assume everything in the loop is updated.
    350   context_ = builder()->NewPhi(1, context_, control);
    351   int size = static_cast<int>(values()->size());
    352   for (int i = 0; i < size; i++) {
    353     values()->at(i) = builder()->NewPhi(1, values()->at(i), control);
    354   }
    355 
    356   // Connect to the loop end.
    357   Node* terminate = builder()->graph()->NewNode(
    358       builder()->common()->Terminate(), effect, control);
    359   builder()->exit_controls_.push_back(terminate);
    360 }
    361 
    362 void BytecodeGraphBuilder::Environment::PrepareForOsrEntry() {
    363   DCHECK_EQ(IrOpcode::kLoop, GetControlDependency()->opcode());
    364   DCHECK_EQ(1, GetControlDependency()->InputCount());
    365 
    366   Node* start = graph()->start();
    367 
    368   // Create a control node for the OSR entry point and update the current
    369   // environment's dependencies accordingly.
    370   Node* entry = graph()->NewNode(common()->OsrLoopEntry(), start, start);
    371   UpdateControlDependency(entry);
    372   UpdateEffectDependency(entry);
    373 
    374   // Create OSR values for each environment value.
    375   SetContext(graph()->NewNode(
    376       common()->OsrValue(Linkage::kOsrContextSpillSlotIndex), entry));
    377   int size = static_cast<int>(values()->size());
    378   for (int i = 0; i < size; i++) {
    379     int idx = i;  // Indexing scheme follows {StandardFrame}, adapt accordingly.
    380     if (i >= register_base()) idx += InterpreterFrameConstants::kExtraSlotCount;
    381     if (i >= accumulator_base()) idx = Linkage::kOsrAccumulatorRegisterIndex;
    382     values()->at(i) = graph()->NewNode(common()->OsrValue(idx), entry);
    383   }
    384 
    385   BailoutId loop_id(builder_->bytecode_iterator().current_offset());
    386   Node* frame_state =
    387       Checkpoint(loop_id, OutputFrameStateCombine::Ignore(), false);
    388   Node* checkpoint =
    389       graph()->NewNode(common()->Checkpoint(), frame_state, entry, entry);
    390   UpdateEffectDependency(checkpoint);
    391 
    392   // Create the OSR guard nodes.
    393   const Operator* guard_op = common()->OsrGuard(OsrGuardType::kUninitialized);
    394   Node* effect = checkpoint;
    395   for (int i = 0; i < size; i++) {
    396     values()->at(i) = effect =
    397         graph()->NewNode(guard_op, values()->at(i), effect, entry);
    398   }
    399   Node* context = effect = graph()->NewNode(guard_op, Context(), effect, entry);
    400   SetContext(context);
    401   UpdateEffectDependency(effect);
    402 }
    403 
    404 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate(
    405     Node** state_values, int offset, int count) {
    406   if (*state_values == nullptr) {
    407     return true;
    408   }
    409   DCHECK_EQ((*state_values)->InputCount(), count);
    410   DCHECK_LE(static_cast<size_t>(offset + count), values()->size());
    411   Node** env_values = (count == 0) ? nullptr : &values()->at(offset);
    412   for (int i = 0; i < count; i++) {
    413     if ((*state_values)->InputAt(i) != env_values[i]) {
    414       return true;
    415     }
    416   }
    417   return false;
    418 }
    419 
    420 void BytecodeGraphBuilder::Environment::PrepareForLoopExit(Node* loop) {
    421   DCHECK_EQ(loop->opcode(), IrOpcode::kLoop);
    422 
    423   Node* control = GetControlDependency();
    424 
    425   // Create the loop exit node.
    426   Node* loop_exit = graph()->NewNode(common()->LoopExit(), control, loop);
    427   UpdateControlDependency(loop_exit);
    428 
    429   // Rename the effect.
    430   Node* effect_rename = graph()->NewNode(common()->LoopExitEffect(),
    431                                          GetEffectDependency(), loop_exit);
    432   UpdateEffectDependency(effect_rename);
    433 
    434   // TODO(jarin) We should also rename context here. However, uncoditional
    435   // renaming confuses global object and native context specialization.
    436   // We should only rename if the context is assigned in the loop.
    437 
    438   // Rename the environmnent values.
    439   for (size_t i = 0; i < values_.size(); i++) {
    440     Node* rename =
    441         graph()->NewNode(common()->LoopExitValue(), values_[i], loop_exit);
    442     values_[i] = rename;
    443   }
    444 }
    445 
    446 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values,
    447                                                           int offset,
    448                                                           int count) {
    449   if (StateValuesRequireUpdate(state_values, offset, count)) {
    450     const Operator* op = common()->StateValues(count);
    451     (*state_values) = graph()->NewNode(op, count, &values()->at(offset));
    452   }
    453 }
    454 
    455 Node* BytecodeGraphBuilder::Environment::Checkpoint(
    456     BailoutId bailout_id, OutputFrameStateCombine combine,
    457     bool owner_has_exception) {
    458   UpdateStateValues(&parameters_state_values_, 0, parameter_count());
    459   UpdateStateValues(&registers_state_values_, register_base(),
    460                     register_count());
    461   UpdateStateValues(&accumulator_state_values_, accumulator_base(), 1);
    462 
    463   const Operator* op = common()->FrameState(
    464       bailout_id, combine, builder()->frame_state_function_info());
    465   Node* result = graph()->NewNode(
    466       op, parameters_state_values_, registers_state_values_,
    467       accumulator_state_values_, Context(), builder()->GetFunctionClosure(),
    468       builder()->graph()->start());
    469 
    470   if (liveness_block() != nullptr) {
    471     // If the owning node has an exception, register the checkpoint to the
    472     // predecessor so that the checkpoint is used for both the normal and the
    473     // exceptional paths. Yes, this is a terrible hack and we might want
    474     // to use an explicit frame state for the exceptional path.
    475     if (owner_has_exception) {
    476       liveness_block()->GetPredecessor()->Checkpoint(result);
    477     } else {
    478       liveness_block()->Checkpoint(result);
    479     }
    480   }
    481 
    482   return result;
    483 }
    484 
    485 BytecodeGraphBuilder::BytecodeGraphBuilder(
    486     Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph,
    487     float invocation_frequency, SourcePositionTable* source_positions,
    488     int inlining_id)
    489     : local_zone_(local_zone),
    490       jsgraph_(jsgraph),
    491       invocation_frequency_(invocation_frequency),
    492       bytecode_array_(handle(info->shared_info()->bytecode_array())),
    493       exception_handler_table_(
    494           handle(HandlerTable::cast(bytecode_array()->handler_table()))),
    495       feedback_vector_(handle(info->closure()->feedback_vector())),
    496       frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
    497           FrameStateType::kInterpretedFunction,
    498           bytecode_array()->parameter_count(),
    499           bytecode_array()->register_count(), info->shared_info())),
    500       osr_ast_id_(info->osr_ast_id()),
    501       merge_environments_(local_zone),
    502       exception_handlers_(local_zone),
    503       current_exception_handler_(0),
    504       input_buffer_size_(0),
    505       input_buffer_(nullptr),
    506       exit_controls_(local_zone),
    507       is_liveness_analysis_enabled_(FLAG_analyze_environment_liveness &&
    508                                     info->is_deoptimization_enabled()),
    509       state_values_cache_(jsgraph),
    510       liveness_analyzer_(
    511           static_cast<size_t>(bytecode_array()->register_count()), true,
    512           local_zone),
    513       source_positions_(source_positions),
    514       start_position_(info->shared_info()->start_position(), inlining_id) {}
    515 
    516 Node* BytecodeGraphBuilder::GetNewTarget() {
    517   if (!new_target_.is_set()) {
    518     int params = bytecode_array()->parameter_count();
    519     int index = Linkage::GetJSCallNewTargetParamIndex(params);
    520     const Operator* op = common()->Parameter(index, "%new.target");
    521     Node* node = NewNode(op, graph()->start());
    522     new_target_.set(node);
    523   }
    524   return new_target_.get();
    525 }
    526 
    527 
    528 Node* BytecodeGraphBuilder::GetFunctionContext() {
    529   if (!function_context_.is_set()) {
    530     int params = bytecode_array()->parameter_count();
    531     int index = Linkage::GetJSCallContextParamIndex(params);
    532     const Operator* op = common()->Parameter(index, "%context");
    533     Node* node = NewNode(op, graph()->start());
    534     function_context_.set(node);
    535   }
    536   return function_context_.get();
    537 }
    538 
    539 
    540 Node* BytecodeGraphBuilder::GetFunctionClosure() {
    541   if (!function_closure_.is_set()) {
    542     int index = Linkage::kJSCallClosureParamIndex;
    543     const Operator* op = common()->Parameter(index, "%closure");
    544     Node* node = NewNode(op, graph()->start());
    545     function_closure_.set(node);
    546   }
    547   return function_closure_.get();
    548 }
    549 
    550 
    551 Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) {
    552   const Operator* op =
    553       javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true);
    554   Node* native_context = NewNode(op, environment()->Context());
    555   return NewNode(javascript()->LoadContext(0, index, true), native_context);
    556 }
    557 
    558 
    559 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) {
    560   FeedbackVectorSlot slot;
    561   if (slot_id >= TypeFeedbackVector::kReservedIndexCount) {
    562     slot = feedback_vector()->ToSlot(slot_id);
    563   }
    564   return VectorSlotPair(feedback_vector(), slot);
    565 }
    566 
    567 bool BytecodeGraphBuilder::CreateGraph(bool stack_check) {
    568   SourcePositionTable::Scope pos_scope(source_positions_, start_position_);
    569 
    570   // Set up the basic structure of the graph. Outputs for {Start} are the formal
    571   // parameters (including the receiver) plus new target, number of arguments,
    572   // context and closure.
    573   int actual_parameter_count = bytecode_array()->parameter_count() + 4;
    574   graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count)));
    575 
    576   Environment env(this, bytecode_array()->register_count(),
    577                   bytecode_array()->parameter_count(), graph()->start(),
    578                   GetFunctionContext());
    579   set_environment(&env);
    580 
    581   VisitBytecodes(stack_check);
    582 
    583   // Finish the basic structure of the graph.
    584   DCHECK_NE(0u, exit_controls_.size());
    585   int const input_count = static_cast<int>(exit_controls_.size());
    586   Node** const inputs = &exit_controls_.front();
    587   Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs);
    588   graph()->SetEnd(end);
    589 
    590   ClearNonLiveSlotsInFrameStates();
    591 
    592   return true;
    593 }
    594 
    595 void BytecodeGraphBuilder::PrepareEagerCheckpoint() {
    596   if (environment()->GetEffectDependency()->opcode() != IrOpcode::kCheckpoint) {
    597     // Create an explicit checkpoint node for before the operation. This only
    598     // needs to happen if we aren't effect-dominated by a {Checkpoint} already.
    599     Node* node = NewNode(common()->Checkpoint());
    600     DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
    601     DCHECK_EQ(IrOpcode::kDead,
    602               NodeProperties::GetFrameStateInput(node)->opcode());
    603     BailoutId bailout_id(bytecode_iterator().current_offset());
    604     Node* frame_state_before = environment()->Checkpoint(
    605         bailout_id, OutputFrameStateCombine::Ignore(), false);
    606     NodeProperties::ReplaceFrameStateInput(node, frame_state_before);
    607   }
    608 }
    609 
    610 void BytecodeGraphBuilder::PrepareFrameState(Node* node,
    611                                              OutputFrameStateCombine combine) {
    612   if (OperatorProperties::HasFrameStateInput(node->op())) {
    613     // Add the frame state for after the operation. The node in question has
    614     // already been created and had a {Dead} frame state input up until now.
    615     DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
    616     DCHECK_EQ(IrOpcode::kDead,
    617               NodeProperties::GetFrameStateInput(node)->opcode());
    618     BailoutId bailout_id(bytecode_iterator().current_offset());
    619     bool has_exception = NodeProperties::IsExceptionalCall(node);
    620     Node* frame_state_after =
    621         environment()->Checkpoint(bailout_id, combine, has_exception);
    622     NodeProperties::ReplaceFrameStateInput(node, frame_state_after);
    623   }
    624 }
    625 
    626 void BytecodeGraphBuilder::ClearNonLiveSlotsInFrameStates() {
    627   if (!IsLivenessAnalysisEnabled()) {
    628     return;
    629   }
    630   NonLiveFrameStateSlotReplacer replacer(
    631       &state_values_cache_, jsgraph()->OptimizedOutConstant(),
    632       liveness_analyzer()->local_count(), true, local_zone());
    633   liveness_analyzer()->Run(&replacer);
    634   if (FLAG_trace_environment_liveness) {
    635     OFStream os(stdout);
    636     liveness_analyzer()->Print(os);
    637   }
    638 }
    639 
    640 void BytecodeGraphBuilder::VisitBytecodes(bool stack_check) {
    641   BytecodeBranchAnalysis analysis(bytecode_array(), local_zone());
    642   BytecodeLoopAnalysis loop_analysis(bytecode_array(), &analysis, local_zone());
    643   analysis.Analyze();
    644   loop_analysis.Analyze();
    645   set_branch_analysis(&analysis);
    646   set_loop_analysis(&loop_analysis);
    647 
    648   interpreter::BytecodeArrayIterator iterator(bytecode_array());
    649   set_bytecode_iterator(&iterator);
    650   SourcePositionTableIterator source_position_iterator(
    651       bytecode_array()->source_position_table());
    652 
    653   BuildOSRNormalEntryPoint();
    654   for (; !iterator.done(); iterator.Advance()) {
    655     int current_offset = iterator.current_offset();
    656     UpdateCurrentSourcePosition(&source_position_iterator, current_offset);
    657     EnterAndExitExceptionHandlers(current_offset);
    658     SwitchToMergeEnvironment(current_offset);
    659     if (environment() != nullptr) {
    660       BuildLoopHeaderEnvironment(current_offset);
    661       BuildOSRLoopEntryPoint(current_offset);
    662 
    663       // Skip the first stack check if stack_check is false
    664       if (!stack_check &&
    665           iterator.current_bytecode() == interpreter::Bytecode::kStackCheck) {
    666         stack_check = true;
    667         continue;
    668       }
    669 
    670       switch (iterator.current_bytecode()) {
    671 #define BYTECODE_CASE(name, ...)       \
    672   case interpreter::Bytecode::k##name: \
    673     Visit##name();                     \
    674     break;
    675         BYTECODE_LIST(BYTECODE_CASE)
    676 #undef BYTECODE_CODE
    677       }
    678     }
    679   }
    680 
    681   set_branch_analysis(nullptr);
    682   set_bytecode_iterator(nullptr);
    683   DCHECK(exception_handlers_.empty());
    684 }
    685 
    686 void BytecodeGraphBuilder::VisitLdaZero() {
    687   Node* node = jsgraph()->ZeroConstant();
    688   environment()->BindAccumulator(node);
    689 }
    690 
    691 void BytecodeGraphBuilder::VisitLdaSmi() {
    692   Node* node = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
    693   environment()->BindAccumulator(node);
    694 }
    695 
    696 void BytecodeGraphBuilder::VisitLdaConstant() {
    697   Node* node =
    698       jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
    699   environment()->BindAccumulator(node);
    700 }
    701 
    702 void BytecodeGraphBuilder::VisitLdaUndefined() {
    703   Node* node = jsgraph()->UndefinedConstant();
    704   environment()->BindAccumulator(node);
    705 }
    706 
    707 void BytecodeGraphBuilder::VisitLdaNull() {
    708   Node* node = jsgraph()->NullConstant();
    709   environment()->BindAccumulator(node);
    710 }
    711 
    712 void BytecodeGraphBuilder::VisitLdaTheHole() {
    713   Node* node = jsgraph()->TheHoleConstant();
    714   environment()->BindAccumulator(node);
    715 }
    716 
    717 void BytecodeGraphBuilder::VisitLdaTrue() {
    718   Node* node = jsgraph()->TrueConstant();
    719   environment()->BindAccumulator(node);
    720 }
    721 
    722 void BytecodeGraphBuilder::VisitLdaFalse() {
    723   Node* node = jsgraph()->FalseConstant();
    724   environment()->BindAccumulator(node);
    725 }
    726 
    727 void BytecodeGraphBuilder::VisitLdar() {
    728   Node* value =
    729       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
    730   environment()->BindAccumulator(value);
    731 }
    732 
    733 void BytecodeGraphBuilder::VisitStar() {
    734   Node* value = environment()->LookupAccumulator();
    735   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value);
    736 }
    737 
    738 void BytecodeGraphBuilder::VisitMov() {
    739   Node* value =
    740       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
    741   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), value);
    742 }
    743 
    744 Node* BytecodeGraphBuilder::BuildLoadGlobal(uint32_t feedback_slot_index,
    745                                             TypeofMode typeof_mode) {
    746   VectorSlotPair feedback = CreateVectorSlotPair(feedback_slot_index);
    747   DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC,
    748             feedback_vector()->GetKind(feedback.slot()));
    749   Handle<Name> name(feedback_vector()->GetName(feedback.slot()));
    750   const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
    751   return NewNode(op, GetFunctionClosure());
    752 }
    753 
    754 void BytecodeGraphBuilder::VisitLdaGlobal() {
    755   PrepareEagerCheckpoint();
    756   Node* node = BuildLoadGlobal(bytecode_iterator().GetIndexOperand(0),
    757                                TypeofMode::NOT_INSIDE_TYPEOF);
    758   environment()->BindAccumulator(node, Environment::kAttachFrameState);
    759 }
    760 
    761 void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() {
    762   PrepareEagerCheckpoint();
    763   Node* node = BuildLoadGlobal(bytecode_iterator().GetIndexOperand(0),
    764                                TypeofMode::INSIDE_TYPEOF);
    765   environment()->BindAccumulator(node, Environment::kAttachFrameState);
    766 }
    767 
    768 void BytecodeGraphBuilder::BuildStoreGlobal(LanguageMode language_mode) {
    769   PrepareEagerCheckpoint();
    770   Handle<Name> name =
    771       Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
    772   VectorSlotPair feedback =
    773       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
    774   Node* value = environment()->LookupAccumulator();
    775 
    776   const Operator* op = javascript()->StoreGlobal(language_mode, name, feedback);
    777   Node* node = NewNode(op, value, GetFunctionClosure());
    778   environment()->RecordAfterState(node, Environment::kAttachFrameState);
    779 }
    780 
    781 void BytecodeGraphBuilder::VisitStaGlobalSloppy() {
    782   BuildStoreGlobal(LanguageMode::SLOPPY);
    783 }
    784 
    785 void BytecodeGraphBuilder::VisitStaGlobalStrict() {
    786   BuildStoreGlobal(LanguageMode::STRICT);
    787 }
    788 
    789 void BytecodeGraphBuilder::VisitLdaContextSlot() {
    790   // TODO(mythria): immutable flag is also set to false. This information is not
    791   // available in bytecode array. update this code when the implementation
    792   // changes.
    793   const Operator* op = javascript()->LoadContext(
    794       bytecode_iterator().GetUnsignedImmediateOperand(2),
    795       bytecode_iterator().GetIndexOperand(1), false);
    796   Node* context =
    797       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
    798   Node* node = NewNode(op, context);
    799   environment()->BindAccumulator(node);
    800 }
    801 
    802 void BytecodeGraphBuilder::VisitLdaCurrentContextSlot() {
    803   // TODO(mythria): immutable flag is also set to false. This information is not
    804   // available in bytecode array. update this code when the implementation
    805   // changes.
    806   const Operator* op = javascript()->LoadContext(
    807       0, bytecode_iterator().GetIndexOperand(0), false);
    808   Node* context = environment()->Context();
    809   Node* node = NewNode(op, context);
    810   environment()->BindAccumulator(node);
    811 }
    812 
    813 void BytecodeGraphBuilder::VisitStaContextSlot() {
    814   const Operator* op = javascript()->StoreContext(
    815       bytecode_iterator().GetUnsignedImmediateOperand(2),
    816       bytecode_iterator().GetIndexOperand(1));
    817   Node* context =
    818       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
    819   Node* value = environment()->LookupAccumulator();
    820   NewNode(op, context, value);
    821 }
    822 
    823 void BytecodeGraphBuilder::VisitStaCurrentContextSlot() {
    824   const Operator* op =
    825       javascript()->StoreContext(0, bytecode_iterator().GetIndexOperand(0));
    826   Node* context = environment()->Context();
    827   Node* value = environment()->LookupAccumulator();
    828   NewNode(op, context, value);
    829 }
    830 
    831 void BytecodeGraphBuilder::BuildLdaLookupSlot(TypeofMode typeof_mode) {
    832   PrepareEagerCheckpoint();
    833   Node* name =
    834       jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
    835   const Operator* op =
    836       javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
    837                                     ? Runtime::kLoadLookupSlot
    838                                     : Runtime::kLoadLookupSlotInsideTypeof);
    839   Node* value = NewNode(op, name);
    840   environment()->BindAccumulator(value, Environment::kAttachFrameState);
    841 }
    842 
    843 void BytecodeGraphBuilder::VisitLdaLookupSlot() {
    844   BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF);
    845 }
    846 
    847 void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() {
    848   BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF);
    849 }
    850 
    851 BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::CheckContextExtensions(
    852     uint32_t depth) {
    853   // Output environment where the context has an extension
    854   Environment* slow_environment = nullptr;
    855 
    856   // We only need to check up to the last-but-one depth, because the an eval in
    857   // the same scope as the variable itself has no way of shadowing it.
    858   for (uint32_t d = 0; d < depth; d++) {
    859     Node* extension_slot =
    860         NewNode(javascript()->LoadContext(d, Context::EXTENSION_INDEX, false),
    861                 environment()->Context());
    862 
    863     Node* check_no_extension =
    864         NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
    865                 extension_slot, jsgraph()->TheHoleConstant());
    866 
    867     NewBranch(check_no_extension);
    868     Environment* true_environment = environment()->CopyForConditional();
    869 
    870     {
    871       NewIfFalse();
    872       // If there is an extension, merge into the slow path.
    873       if (slow_environment == nullptr) {
    874         slow_environment = environment();
    875         NewMerge();
    876       } else {
    877         slow_environment->Merge(environment());
    878       }
    879     }
    880 
    881     {
    882       set_environment(true_environment);
    883       NewIfTrue();
    884       // Do nothing on if there is no extension, eventually falling through to
    885       // the fast path.
    886     }
    887   }
    888 
    889   // The depth can be zero, in which case no slow-path checks are built, and the
    890   // slow path environment can be null.
    891   DCHECK(depth == 0 || slow_environment != nullptr);
    892 
    893   return slow_environment;
    894 }
    895 
    896 void BytecodeGraphBuilder::BuildLdaLookupContextSlot(TypeofMode typeof_mode) {
    897   uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2);
    898 
    899   // Check if any context in the depth has an extension.
    900   Environment* slow_environment = CheckContextExtensions(depth);
    901 
    902   // Fast path, do a context load.
    903   {
    904     uint32_t slot_index = bytecode_iterator().GetIndexOperand(1);
    905 
    906     const Operator* op = javascript()->LoadContext(depth, slot_index, false);
    907     Node* context = environment()->Context();
    908     environment()->BindAccumulator(NewNode(op, context));
    909   }
    910 
    911   // Only build the slow path if there were any slow-path checks.
    912   if (slow_environment != nullptr) {
    913     // Add a merge to the fast environment.
    914     NewMerge();
    915     Environment* fast_environment = environment();
    916 
    917     // Slow path, do a runtime load lookup.
    918     set_environment(slow_environment);
    919     {
    920       Node* name = jsgraph()->Constant(
    921           bytecode_iterator().GetConstantForIndexOperand(0));
    922 
    923       const Operator* op =
    924           javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
    925                                         ? Runtime::kLoadLookupSlot
    926                                         : Runtime::kLoadLookupSlotInsideTypeof);
    927       Node* value = NewNode(op, name);
    928       environment()->BindAccumulator(value, Environment::kAttachFrameState);
    929     }
    930 
    931     fast_environment->Merge(environment());
    932     set_environment(fast_environment);
    933   }
    934 }
    935 
    936 void BytecodeGraphBuilder::VisitLdaLookupContextSlot() {
    937   BuildLdaLookupContextSlot(TypeofMode::NOT_INSIDE_TYPEOF);
    938 }
    939 
    940 void BytecodeGraphBuilder::VisitLdaLookupContextSlotInsideTypeof() {
    941   BuildLdaLookupContextSlot(TypeofMode::INSIDE_TYPEOF);
    942 }
    943 
    944 void BytecodeGraphBuilder::BuildLdaLookupGlobalSlot(TypeofMode typeof_mode) {
    945   uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2);
    946 
    947   // Check if any context in the depth has an extension.
    948   Environment* slow_environment = CheckContextExtensions(depth);
    949 
    950   // Fast path, do a global load.
    951   {
    952     PrepareEagerCheckpoint();
    953     Node* node =
    954         BuildLoadGlobal(bytecode_iterator().GetIndexOperand(1), typeof_mode);
    955     environment()->BindAccumulator(node, Environment::kAttachFrameState);
    956   }
    957 
    958   // Only build the slow path if there were any slow-path checks.
    959   if (slow_environment != nullptr) {
    960     // Add a merge to the fast environment.
    961     NewMerge();
    962     Environment* fast_environment = environment();
    963 
    964     // Slow path, do a runtime load lookup.
    965     set_environment(slow_environment);
    966     {
    967       Node* name = jsgraph()->Constant(
    968           bytecode_iterator().GetConstantForIndexOperand(0));
    969 
    970       const Operator* op =
    971           javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
    972                                         ? Runtime::kLoadLookupSlot
    973                                         : Runtime::kLoadLookupSlotInsideTypeof);
    974       Node* value = NewNode(op, name);
    975       environment()->BindAccumulator(value, Environment::kAttachFrameState);
    976     }
    977 
    978     fast_environment->Merge(environment());
    979     set_environment(fast_environment);
    980   }
    981 }
    982 
    983 void BytecodeGraphBuilder::VisitLdaLookupGlobalSlot() {
    984   BuildLdaLookupGlobalSlot(TypeofMode::NOT_INSIDE_TYPEOF);
    985 }
    986 
    987 void BytecodeGraphBuilder::VisitLdaLookupGlobalSlotInsideTypeof() {
    988   BuildLdaLookupGlobalSlot(TypeofMode::INSIDE_TYPEOF);
    989 }
    990 
    991 void BytecodeGraphBuilder::BuildStaLookupSlot(LanguageMode language_mode) {
    992   PrepareEagerCheckpoint();
    993   Node* value = environment()->LookupAccumulator();
    994   Node* name =
    995       jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
    996   const Operator* op = javascript()->CallRuntime(
    997       is_strict(language_mode) ? Runtime::kStoreLookupSlot_Strict
    998                                : Runtime::kStoreLookupSlot_Sloppy);
    999   Node* store = NewNode(op, name, value);
   1000   environment()->BindAccumulator(store, Environment::kAttachFrameState);
   1001 }
   1002 
   1003 void BytecodeGraphBuilder::VisitStaLookupSlotSloppy() {
   1004   BuildStaLookupSlot(LanguageMode::SLOPPY);
   1005 }
   1006 
   1007 void BytecodeGraphBuilder::VisitStaLookupSlotStrict() {
   1008   BuildStaLookupSlot(LanguageMode::STRICT);
   1009 }
   1010 
   1011 void BytecodeGraphBuilder::VisitLdaNamedProperty() {
   1012   PrepareEagerCheckpoint();
   1013   Node* object =
   1014       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1015   Handle<Name> name =
   1016       Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(1));
   1017   VectorSlotPair feedback =
   1018       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
   1019 
   1020   const Operator* op = javascript()->LoadNamed(name, feedback);
   1021   Node* node = NewNode(op, object, GetFunctionClosure());
   1022   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   1023 }
   1024 
   1025 void BytecodeGraphBuilder::VisitLdaKeyedProperty() {
   1026   PrepareEagerCheckpoint();
   1027   Node* key = environment()->LookupAccumulator();
   1028   Node* object =
   1029       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1030   VectorSlotPair feedback =
   1031       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
   1032 
   1033   const Operator* op = javascript()->LoadProperty(feedback);
   1034   Node* node = NewNode(op, object, key, GetFunctionClosure());
   1035   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   1036 }
   1037 
   1038 void BytecodeGraphBuilder::BuildNamedStore(LanguageMode language_mode) {
   1039   PrepareEagerCheckpoint();
   1040   Node* value = environment()->LookupAccumulator();
   1041   Node* object =
   1042       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1043   Handle<Name> name =
   1044       Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(1));
   1045   VectorSlotPair feedback =
   1046       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
   1047 
   1048   const Operator* op = javascript()->StoreNamed(language_mode, name, feedback);
   1049   Node* node = NewNode(op, object, value, GetFunctionClosure());
   1050   environment()->RecordAfterState(node, Environment::kAttachFrameState);
   1051 }
   1052 
   1053 void BytecodeGraphBuilder::VisitStaNamedPropertySloppy() {
   1054   BuildNamedStore(LanguageMode::SLOPPY);
   1055 }
   1056 
   1057 void BytecodeGraphBuilder::VisitStaNamedPropertyStrict() {
   1058   BuildNamedStore(LanguageMode::STRICT);
   1059 }
   1060 
   1061 void BytecodeGraphBuilder::BuildKeyedStore(LanguageMode language_mode) {
   1062   PrepareEagerCheckpoint();
   1063   Node* value = environment()->LookupAccumulator();
   1064   Node* object =
   1065       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1066   Node* key =
   1067       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
   1068   VectorSlotPair feedback =
   1069       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
   1070 
   1071   const Operator* op = javascript()->StoreProperty(language_mode, feedback);
   1072   Node* node = NewNode(op, object, key, value, GetFunctionClosure());
   1073   environment()->RecordAfterState(node, Environment::kAttachFrameState);
   1074 }
   1075 
   1076 void BytecodeGraphBuilder::VisitStaKeyedPropertySloppy() {
   1077   BuildKeyedStore(LanguageMode::SLOPPY);
   1078 }
   1079 
   1080 void BytecodeGraphBuilder::VisitStaKeyedPropertyStrict() {
   1081   BuildKeyedStore(LanguageMode::STRICT);
   1082 }
   1083 
   1084 void BytecodeGraphBuilder::VisitLdaModuleVariable() {
   1085   int32_t cell_index = bytecode_iterator().GetImmediateOperand(0);
   1086   uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1);
   1087   Node* module =
   1088       NewNode(javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false),
   1089               environment()->Context());
   1090   Node* value = NewNode(javascript()->LoadModule(cell_index), module);
   1091   environment()->BindAccumulator(value);
   1092 }
   1093 
   1094 void BytecodeGraphBuilder::VisitStaModuleVariable() {
   1095   int32_t cell_index = bytecode_iterator().GetImmediateOperand(0);
   1096   uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1);
   1097   Node* module =
   1098       NewNode(javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false),
   1099               environment()->Context());
   1100   Node* value = environment()->LookupAccumulator();
   1101   NewNode(javascript()->StoreModule(cell_index), module, value);
   1102 }
   1103 
   1104 void BytecodeGraphBuilder::VisitPushContext() {
   1105   Node* new_context = environment()->LookupAccumulator();
   1106   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0),
   1107                               environment()->Context());
   1108   environment()->SetContext(new_context);
   1109 }
   1110 
   1111 void BytecodeGraphBuilder::VisitPopContext() {
   1112   Node* context =
   1113       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1114   environment()->SetContext(context);
   1115 }
   1116 
   1117 void BytecodeGraphBuilder::VisitCreateClosure() {
   1118   Handle<SharedFunctionInfo> shared_info = Handle<SharedFunctionInfo>::cast(
   1119       bytecode_iterator().GetConstantForIndexOperand(0));
   1120   PretenureFlag tenured =
   1121       interpreter::CreateClosureFlags::PretenuredBit::decode(
   1122           bytecode_iterator().GetFlagOperand(1))
   1123           ? TENURED
   1124           : NOT_TENURED;
   1125   const Operator* op = javascript()->CreateClosure(shared_info, tenured);
   1126   Node* closure = NewNode(op);
   1127   environment()->BindAccumulator(closure);
   1128 }
   1129 
   1130 void BytecodeGraphBuilder::VisitCreateBlockContext() {
   1131   Handle<ScopeInfo> scope_info = Handle<ScopeInfo>::cast(
   1132       bytecode_iterator().GetConstantForIndexOperand(0));
   1133 
   1134   const Operator* op = javascript()->CreateBlockContext(scope_info);
   1135   Node* context = NewNode(op, environment()->LookupAccumulator());
   1136   environment()->BindAccumulator(context);
   1137 }
   1138 
   1139 void BytecodeGraphBuilder::VisitCreateFunctionContext() {
   1140   uint32_t slots = bytecode_iterator().GetUnsignedImmediateOperand(0);
   1141   const Operator* op = javascript()->CreateFunctionContext(slots);
   1142   Node* context = NewNode(op, GetFunctionClosure());
   1143   environment()->BindAccumulator(context);
   1144 }
   1145 
   1146 void BytecodeGraphBuilder::VisitCreateCatchContext() {
   1147   interpreter::Register reg = bytecode_iterator().GetRegisterOperand(0);
   1148   Node* exception = environment()->LookupRegister(reg);
   1149   Handle<String> name =
   1150       Handle<String>::cast(bytecode_iterator().GetConstantForIndexOperand(1));
   1151   Handle<ScopeInfo> scope_info = Handle<ScopeInfo>::cast(
   1152       bytecode_iterator().GetConstantForIndexOperand(2));
   1153   Node* closure = environment()->LookupAccumulator();
   1154 
   1155   const Operator* op = javascript()->CreateCatchContext(name, scope_info);
   1156   Node* context = NewNode(op, exception, closure);
   1157   environment()->BindAccumulator(context);
   1158 }
   1159 
   1160 void BytecodeGraphBuilder::VisitCreateWithContext() {
   1161   Node* object =
   1162       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1163   Handle<ScopeInfo> scope_info = Handle<ScopeInfo>::cast(
   1164       bytecode_iterator().GetConstantForIndexOperand(1));
   1165 
   1166   const Operator* op = javascript()->CreateWithContext(scope_info);
   1167   Node* context = NewNode(op, object, environment()->LookupAccumulator());
   1168   environment()->BindAccumulator(context);
   1169 }
   1170 
   1171 void BytecodeGraphBuilder::BuildCreateArguments(CreateArgumentsType type) {
   1172   const Operator* op = javascript()->CreateArguments(type);
   1173   Node* object = NewNode(op, GetFunctionClosure());
   1174   environment()->BindAccumulator(object, Environment::kAttachFrameState);
   1175 }
   1176 
   1177 void BytecodeGraphBuilder::VisitCreateMappedArguments() {
   1178   BuildCreateArguments(CreateArgumentsType::kMappedArguments);
   1179 }
   1180 
   1181 void BytecodeGraphBuilder::VisitCreateUnmappedArguments() {
   1182   BuildCreateArguments(CreateArgumentsType::kUnmappedArguments);
   1183 }
   1184 
   1185 void BytecodeGraphBuilder::VisitCreateRestParameter() {
   1186   BuildCreateArguments(CreateArgumentsType::kRestParameter);
   1187 }
   1188 
   1189 void BytecodeGraphBuilder::VisitCreateRegExpLiteral() {
   1190   Handle<String> constant_pattern =
   1191       Handle<String>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
   1192   int literal_index = bytecode_iterator().GetIndexOperand(1);
   1193   int literal_flags = bytecode_iterator().GetFlagOperand(2);
   1194   Node* literal = NewNode(javascript()->CreateLiteralRegExp(
   1195                               constant_pattern, literal_flags, literal_index),
   1196                           GetFunctionClosure());
   1197   environment()->BindAccumulator(literal, Environment::kAttachFrameState);
   1198 }
   1199 
   1200 void BytecodeGraphBuilder::VisitCreateArrayLiteral() {
   1201   Handle<FixedArray> constant_elements = Handle<FixedArray>::cast(
   1202       bytecode_iterator().GetConstantForIndexOperand(0));
   1203   int literal_index = bytecode_iterator().GetIndexOperand(1);
   1204   int literal_flags = bytecode_iterator().GetFlagOperand(2);
   1205   // Disable allocation site mementos. Only unoptimized code will collect
   1206   // feedback about allocation site. Once the code is optimized we expect the
   1207   // data to converge. So, we disable allocation site mementos in optimized
   1208   // code. We can revisit this when we have data to the contrary.
   1209   literal_flags |= ArrayLiteral::kDisableMementos;
   1210   int number_of_elements = constant_elements->length();
   1211   Node* literal = NewNode(
   1212       javascript()->CreateLiteralArray(constant_elements, literal_flags,
   1213                                        literal_index, number_of_elements),
   1214       GetFunctionClosure());
   1215   environment()->BindAccumulator(literal, Environment::kAttachFrameState);
   1216 }
   1217 
   1218 void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
   1219   PrepareEagerCheckpoint();
   1220   Handle<FixedArray> constant_properties = Handle<FixedArray>::cast(
   1221       bytecode_iterator().GetConstantForIndexOperand(0));
   1222   int literal_index = bytecode_iterator().GetIndexOperand(1);
   1223   int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
   1224   int literal_flags =
   1225       interpreter::CreateObjectLiteralFlags::FlagsBits::decode(bytecode_flags);
   1226   // TODO(mstarzinger): Thread through number of properties.
   1227   int number_of_properties = constant_properties->length() / 2;
   1228   Node* literal = NewNode(
   1229       javascript()->CreateLiteralObject(constant_properties, literal_flags,
   1230                                         literal_index, number_of_properties),
   1231       GetFunctionClosure());
   1232   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3),
   1233                               literal, Environment::kAttachFrameState);
   1234 }
   1235 
   1236 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
   1237                                                  Node* callee,
   1238                                                  interpreter::Register receiver,
   1239                                                  size_t arity) {
   1240   Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity));
   1241   all[0] = callee;
   1242   all[1] = environment()->LookupRegister(receiver);
   1243   int receiver_index = receiver.index();
   1244   for (int i = 2; i < static_cast<int>(arity); ++i) {
   1245     all[i] = environment()->LookupRegister(
   1246         interpreter::Register(receiver_index + i - 1));
   1247   }
   1248   Node* value = MakeNode(call_op, static_cast<int>(arity), all, false);
   1249   return value;
   1250 }
   1251 
   1252 void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode,
   1253                                      ConvertReceiverMode receiver_hint) {
   1254   PrepareEagerCheckpoint();
   1255 
   1256   Node* callee =
   1257       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1258   interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
   1259   size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
   1260 
   1261   // Slot index of 0 is used indicate no feedback slot is available. Assert
   1262   // the assumption that slot index 0 is never a valid feedback slot.
   1263   STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0);
   1264   int const slot_id = bytecode_iterator().GetIndexOperand(3);
   1265   VectorSlotPair feedback = CreateVectorSlotPair(slot_id);
   1266 
   1267   float const frequency = ComputeCallFrequency(slot_id);
   1268   const Operator* call = javascript()->CallFunction(
   1269       arg_count + 1, frequency, feedback, receiver_hint, tail_call_mode);
   1270   Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
   1271   environment()->BindAccumulator(value, Environment::kAttachFrameState);
   1272 }
   1273 
   1274 void BytecodeGraphBuilder::VisitCall() {
   1275   BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny);
   1276 }
   1277 
   1278 void BytecodeGraphBuilder::VisitCallProperty() {
   1279   BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined);
   1280 }
   1281 
   1282 void BytecodeGraphBuilder::VisitTailCall() {
   1283   TailCallMode tail_call_mode =
   1284       bytecode_array_->GetIsolate()->is_tail_call_elimination_enabled()
   1285           ? TailCallMode::kAllow
   1286           : TailCallMode::kDisallow;
   1287   BuildCall(tail_call_mode, ConvertReceiverMode::kAny);
   1288 }
   1289 
   1290 void BytecodeGraphBuilder::VisitCallJSRuntime() {
   1291   PrepareEagerCheckpoint();
   1292   Node* callee =
   1293       BuildLoadNativeContextField(bytecode_iterator().GetIndexOperand(0));
   1294   interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
   1295   size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
   1296 
   1297   // Create node to perform the JS runtime call.
   1298   const Operator* call = javascript()->CallFunction(arg_count + 1);
   1299   Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
   1300   environment()->BindAccumulator(value, Environment::kAttachFrameState);
   1301 }
   1302 
   1303 Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
   1304     const Operator* call_runtime_op, interpreter::Register first_arg,
   1305     size_t arity) {
   1306   Node** all = local_zone()->NewArray<Node*>(arity);
   1307   int first_arg_index = first_arg.index();
   1308   for (int i = 0; i < static_cast<int>(arity); ++i) {
   1309     all[i] = environment()->LookupRegister(
   1310         interpreter::Register(first_arg_index + i));
   1311   }
   1312   Node* value = MakeNode(call_runtime_op, static_cast<int>(arity), all, false);
   1313   return value;
   1314 }
   1315 
   1316 void BytecodeGraphBuilder::VisitCallRuntime() {
   1317   PrepareEagerCheckpoint();
   1318   Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
   1319   interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
   1320   size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
   1321 
   1322   // Create node to perform the runtime call.
   1323   const Operator* call = javascript()->CallRuntime(functionId, arg_count);
   1324   Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
   1325   environment()->BindAccumulator(value, Environment::kAttachFrameState);
   1326 }
   1327 
   1328 void BytecodeGraphBuilder::VisitCallRuntimeForPair() {
   1329   PrepareEagerCheckpoint();
   1330   Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
   1331   interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
   1332   size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
   1333   interpreter::Register first_return =
   1334       bytecode_iterator().GetRegisterOperand(3);
   1335 
   1336   // Create node to perform the runtime call.
   1337   const Operator* call = javascript()->CallRuntime(functionId, arg_count);
   1338   Node* return_pair = ProcessCallRuntimeArguments(call, first_arg, arg_count);
   1339   environment()->BindRegistersToProjections(first_return, return_pair,
   1340                                             Environment::kAttachFrameState);
   1341 }
   1342 
   1343 void BytecodeGraphBuilder::VisitInvokeIntrinsic() {
   1344   PrepareEagerCheckpoint();
   1345   Runtime::FunctionId functionId = bytecode_iterator().GetIntrinsicIdOperand(0);
   1346   interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
   1347   size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
   1348 
   1349   // Create node to perform the runtime call. Turbofan will take care of the
   1350   // lowering.
   1351   const Operator* call = javascript()->CallRuntime(functionId, arg_count);
   1352   Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
   1353   environment()->BindAccumulator(value, Environment::kAttachFrameState);
   1354 }
   1355 
   1356 Node* BytecodeGraphBuilder::ProcessCallNewArguments(
   1357     const Operator* call_new_op, Node* callee, Node* new_target,
   1358     interpreter::Register first_arg, size_t arity) {
   1359   Node** all = local_zone()->NewArray<Node*>(arity);
   1360   all[0] = callee;
   1361   int first_arg_index = first_arg.index();
   1362   for (int i = 1; i < static_cast<int>(arity) - 1; ++i) {
   1363     all[i] = environment()->LookupRegister(
   1364         interpreter::Register(first_arg_index + i - 1));
   1365   }
   1366   all[arity - 1] = new_target;
   1367   Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false);
   1368   return value;
   1369 }
   1370 
   1371 void BytecodeGraphBuilder::VisitNew() {
   1372   PrepareEagerCheckpoint();
   1373   interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
   1374   interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
   1375   size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
   1376   // Slot index of 0 is used indicate no feedback slot is available. Assert
   1377   // the assumption that slot index 0 is never a valid feedback slot.
   1378   STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0);
   1379   int const slot_id = bytecode_iterator().GetIndexOperand(3);
   1380   VectorSlotPair feedback = CreateVectorSlotPair(slot_id);
   1381 
   1382   Node* new_target = environment()->LookupAccumulator();
   1383   Node* callee = environment()->LookupRegister(callee_reg);
   1384 
   1385   float const frequency = ComputeCallFrequency(slot_id);
   1386   const Operator* call = javascript()->CallConstruct(
   1387       static_cast<int>(arg_count) + 2, frequency, feedback);
   1388   Node* value = ProcessCallNewArguments(call, callee, new_target, first_arg,
   1389                                         arg_count + 2);
   1390   environment()->BindAccumulator(value, Environment::kAttachFrameState);
   1391 }
   1392 
   1393 void BytecodeGraphBuilder::BuildThrow() {
   1394   PrepareEagerCheckpoint();
   1395   Node* value = environment()->LookupAccumulator();
   1396   Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value);
   1397   environment()->BindAccumulator(call, Environment::kAttachFrameState);
   1398 }
   1399 
   1400 void BytecodeGraphBuilder::VisitThrow() {
   1401   BuildLoopExitsForFunctionExit();
   1402   BuildThrow();
   1403   Node* call = environment()->LookupAccumulator();
   1404   Node* control = NewNode(common()->Throw(), call);
   1405   MergeControlToLeaveFunction(control);
   1406 }
   1407 
   1408 void BytecodeGraphBuilder::VisitReThrow() {
   1409   BuildLoopExitsForFunctionExit();
   1410   Node* value = environment()->LookupAccumulator();
   1411   Node* call = NewNode(javascript()->CallRuntime(Runtime::kReThrow), value);
   1412   Node* control = NewNode(common()->Throw(), call);
   1413   MergeControlToLeaveFunction(control);
   1414 }
   1415 
   1416 void BytecodeGraphBuilder::BuildBinaryOp(const Operator* js_op) {
   1417   PrepareEagerCheckpoint();
   1418   Node* left =
   1419       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1420   Node* right = environment()->LookupAccumulator();
   1421   Node* node = NewNode(js_op, left, right);
   1422   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   1423 }
   1424 
   1425 // Helper function to create binary operation hint from the recorded type
   1426 // feedback.
   1427 BinaryOperationHint BytecodeGraphBuilder::GetBinaryOperationHint(
   1428     int operand_index) {
   1429   FeedbackVectorSlot slot = feedback_vector()->ToSlot(
   1430       bytecode_iterator().GetIndexOperand(operand_index));
   1431   DCHECK_EQ(FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC,
   1432             feedback_vector()->GetKind(slot));
   1433   BinaryOpICNexus nexus(feedback_vector(), slot);
   1434   return nexus.GetBinaryOperationFeedback();
   1435 }
   1436 
   1437 // Helper function to create compare operation hint from the recorded type
   1438 // feedback.
   1439 CompareOperationHint BytecodeGraphBuilder::GetCompareOperationHint() {
   1440   int slot_index = bytecode_iterator().GetIndexOperand(1);
   1441   if (slot_index == 0) {
   1442     return CompareOperationHint::kAny;
   1443   }
   1444   FeedbackVectorSlot slot =
   1445       feedback_vector()->ToSlot(bytecode_iterator().GetIndexOperand(1));
   1446   DCHECK_EQ(FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC,
   1447             feedback_vector()->GetKind(slot));
   1448   CompareICNexus nexus(feedback_vector(), slot);
   1449   return nexus.GetCompareOperationFeedback();
   1450 }
   1451 
   1452 float BytecodeGraphBuilder::ComputeCallFrequency(int slot_id) const {
   1453   CallICNexus nexus(feedback_vector(), feedback_vector()->ToSlot(slot_id));
   1454   return nexus.ComputeCallFrequency() * invocation_frequency_;
   1455 }
   1456 
   1457 void BytecodeGraphBuilder::VisitAdd() {
   1458   BuildBinaryOp(
   1459       javascript()->Add(GetBinaryOperationHint(kBinaryOperationHintIndex)));
   1460 }
   1461 
   1462 void BytecodeGraphBuilder::VisitSub() {
   1463   BuildBinaryOp(javascript()->Subtract(
   1464       GetBinaryOperationHint(kBinaryOperationHintIndex)));
   1465 }
   1466 
   1467 void BytecodeGraphBuilder::VisitMul() {
   1468   BuildBinaryOp(javascript()->Multiply(
   1469       GetBinaryOperationHint(kBinaryOperationHintIndex)));
   1470 }
   1471 
   1472 void BytecodeGraphBuilder::VisitDiv() {
   1473   BuildBinaryOp(
   1474       javascript()->Divide(GetBinaryOperationHint(kBinaryOperationHintIndex)));
   1475 }
   1476 
   1477 void BytecodeGraphBuilder::VisitMod() {
   1478   BuildBinaryOp(
   1479       javascript()->Modulus(GetBinaryOperationHint(kBinaryOperationHintIndex)));
   1480 }
   1481 
   1482 void BytecodeGraphBuilder::VisitBitwiseOr() {
   1483   BuildBinaryOp(javascript()->BitwiseOr(
   1484       GetBinaryOperationHint(kBinaryOperationHintIndex)));
   1485 }
   1486 
   1487 void BytecodeGraphBuilder::VisitBitwiseXor() {
   1488   BuildBinaryOp(javascript()->BitwiseXor(
   1489       GetBinaryOperationHint(kBinaryOperationHintIndex)));
   1490 }
   1491 
   1492 void BytecodeGraphBuilder::VisitBitwiseAnd() {
   1493   BuildBinaryOp(javascript()->BitwiseAnd(
   1494       GetBinaryOperationHint(kBinaryOperationHintIndex)));
   1495 }
   1496 
   1497 void BytecodeGraphBuilder::VisitShiftLeft() {
   1498   BuildBinaryOp(javascript()->ShiftLeft(
   1499       GetBinaryOperationHint(kBinaryOperationHintIndex)));
   1500 }
   1501 
   1502 void BytecodeGraphBuilder::VisitShiftRight() {
   1503   BuildBinaryOp(javascript()->ShiftRight(
   1504       GetBinaryOperationHint(kBinaryOperationHintIndex)));
   1505 }
   1506 
   1507 void BytecodeGraphBuilder::VisitShiftRightLogical() {
   1508   BuildBinaryOp(javascript()->ShiftRightLogical(
   1509       GetBinaryOperationHint(kBinaryOperationHintIndex)));
   1510 }
   1511 
   1512 void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(const Operator* js_op) {
   1513   PrepareEagerCheckpoint();
   1514   Node* left =
   1515       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
   1516   Node* right = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
   1517   Node* node = NewNode(js_op, left, right);
   1518   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   1519 }
   1520 
   1521 void BytecodeGraphBuilder::VisitAddSmi() {
   1522   BuildBinaryOpWithImmediate(
   1523       javascript()->Add(GetBinaryOperationHint(kBinaryOperationSmiHintIndex)));
   1524 }
   1525 
   1526 void BytecodeGraphBuilder::VisitSubSmi() {
   1527   BuildBinaryOpWithImmediate(javascript()->Subtract(
   1528       GetBinaryOperationHint(kBinaryOperationSmiHintIndex)));
   1529 }
   1530 
   1531 void BytecodeGraphBuilder::VisitBitwiseOrSmi() {
   1532   BuildBinaryOpWithImmediate(javascript()->BitwiseOr(
   1533       GetBinaryOperationHint(kBinaryOperationSmiHintIndex)));
   1534 }
   1535 
   1536 void BytecodeGraphBuilder::VisitBitwiseAndSmi() {
   1537   BuildBinaryOpWithImmediate(javascript()->BitwiseAnd(
   1538       GetBinaryOperationHint(kBinaryOperationSmiHintIndex)));
   1539 }
   1540 
   1541 void BytecodeGraphBuilder::VisitShiftLeftSmi() {
   1542   BuildBinaryOpWithImmediate(javascript()->ShiftLeft(
   1543       GetBinaryOperationHint(kBinaryOperationSmiHintIndex)));
   1544 }
   1545 
   1546 void BytecodeGraphBuilder::VisitShiftRightSmi() {
   1547   BuildBinaryOpWithImmediate(javascript()->ShiftRight(
   1548       GetBinaryOperationHint(kBinaryOperationSmiHintIndex)));
   1549 }
   1550 
   1551 void BytecodeGraphBuilder::VisitInc() {
   1552   PrepareEagerCheckpoint();
   1553   // Note: Use subtract -1 here instead of add 1 to ensure we always convert to
   1554   // a number, not a string.
   1555   const Operator* js_op =
   1556       javascript()->Subtract(GetBinaryOperationHint(kCountOperationHintIndex));
   1557   Node* node = NewNode(js_op, environment()->LookupAccumulator(),
   1558                        jsgraph()->Constant(-1));
   1559   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   1560 }
   1561 
   1562 void BytecodeGraphBuilder::VisitDec() {
   1563   PrepareEagerCheckpoint();
   1564   const Operator* js_op =
   1565       javascript()->Subtract(GetBinaryOperationHint(kCountOperationHintIndex));
   1566   Node* node = NewNode(js_op, environment()->LookupAccumulator(),
   1567                        jsgraph()->OneConstant());
   1568   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   1569 }
   1570 
   1571 void BytecodeGraphBuilder::VisitLogicalNot() {
   1572   Node* value = environment()->LookupAccumulator();
   1573   Node* node = NewNode(common()->Select(MachineRepresentation::kTagged), value,
   1574                        jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
   1575   environment()->BindAccumulator(node);
   1576 }
   1577 
   1578 void BytecodeGraphBuilder::VisitToBooleanLogicalNot() {
   1579   Node* value = NewNode(javascript()->ToBoolean(ToBooleanHint::kAny),
   1580                         environment()->LookupAccumulator());
   1581   Node* node = NewNode(common()->Select(MachineRepresentation::kTagged), value,
   1582                        jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
   1583   environment()->BindAccumulator(node);
   1584 }
   1585 
   1586 void BytecodeGraphBuilder::VisitTypeOf() {
   1587   Node* node =
   1588       NewNode(javascript()->TypeOf(), environment()->LookupAccumulator());
   1589   environment()->BindAccumulator(node);
   1590 }
   1591 
   1592 void BytecodeGraphBuilder::BuildDelete(LanguageMode language_mode) {
   1593   PrepareEagerCheckpoint();
   1594   Node* key = environment()->LookupAccumulator();
   1595   Node* object =
   1596       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1597   Node* node =
   1598       NewNode(javascript()->DeleteProperty(language_mode), object, key);
   1599   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   1600 }
   1601 
   1602 void BytecodeGraphBuilder::VisitDeletePropertyStrict() {
   1603   BuildDelete(LanguageMode::STRICT);
   1604 }
   1605 
   1606 void BytecodeGraphBuilder::VisitDeletePropertySloppy() {
   1607   BuildDelete(LanguageMode::SLOPPY);
   1608 }
   1609 
   1610 void BytecodeGraphBuilder::BuildCompareOp(const Operator* js_op) {
   1611   PrepareEagerCheckpoint();
   1612   Node* left =
   1613       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1614   Node* right = environment()->LookupAccumulator();
   1615   Node* node = NewNode(js_op, left, right);
   1616   environment()->BindAccumulator(node, Environment::kAttachFrameState);
   1617 }
   1618 
   1619 void BytecodeGraphBuilder::VisitTestEqual() {
   1620   BuildCompareOp(javascript()->Equal(GetCompareOperationHint()));
   1621 }
   1622 
   1623 void BytecodeGraphBuilder::VisitTestNotEqual() {
   1624   BuildCompareOp(javascript()->NotEqual(GetCompareOperationHint()));
   1625 }
   1626 
   1627 void BytecodeGraphBuilder::VisitTestEqualStrict() {
   1628   BuildCompareOp(javascript()->StrictEqual(GetCompareOperationHint()));
   1629 }
   1630 
   1631 void BytecodeGraphBuilder::VisitTestLessThan() {
   1632   BuildCompareOp(javascript()->LessThan(GetCompareOperationHint()));
   1633 }
   1634 
   1635 void BytecodeGraphBuilder::VisitTestGreaterThan() {
   1636   BuildCompareOp(javascript()->GreaterThan(GetCompareOperationHint()));
   1637 }
   1638 
   1639 void BytecodeGraphBuilder::VisitTestLessThanOrEqual() {
   1640   BuildCompareOp(javascript()->LessThanOrEqual(GetCompareOperationHint()));
   1641 }
   1642 
   1643 void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual() {
   1644   BuildCompareOp(javascript()->GreaterThanOrEqual(GetCompareOperationHint()));
   1645 }
   1646 
   1647 void BytecodeGraphBuilder::VisitTestIn() {
   1648   BuildCompareOp(javascript()->HasProperty());
   1649 }
   1650 
   1651 void BytecodeGraphBuilder::VisitTestInstanceOf() {
   1652   BuildCompareOp(javascript()->InstanceOf());
   1653 }
   1654 
   1655 void BytecodeGraphBuilder::BuildCastOperator(const Operator* js_op) {
   1656   PrepareEagerCheckpoint();
   1657   Node* value = NewNode(js_op, environment()->LookupAccumulator());
   1658   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value,
   1659                               Environment::kAttachFrameState);
   1660 }
   1661 
   1662 void BytecodeGraphBuilder::VisitToName() {
   1663   BuildCastOperator(javascript()->ToName());
   1664 }
   1665 
   1666 void BytecodeGraphBuilder::VisitToObject() {
   1667   BuildCastOperator(javascript()->ToObject());
   1668 }
   1669 
   1670 void BytecodeGraphBuilder::VisitToNumber() {
   1671   BuildCastOperator(javascript()->ToNumber());
   1672 }
   1673 
   1674 void BytecodeGraphBuilder::VisitJump() { BuildJump(); }
   1675 
   1676 void BytecodeGraphBuilder::VisitJumpConstant() { BuildJump(); }
   1677 
   1678 void BytecodeGraphBuilder::VisitJumpIfTrue() { BuildJumpIfTrue(); }
   1679 
   1680 void BytecodeGraphBuilder::VisitJumpIfTrueConstant() { BuildJumpIfTrue(); }
   1681 
   1682 void BytecodeGraphBuilder::VisitJumpIfFalse() { BuildJumpIfFalse(); }
   1683 
   1684 void BytecodeGraphBuilder::VisitJumpIfFalseConstant() { BuildJumpIfFalse(); }
   1685 
   1686 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue() {
   1687   BuildJumpIfToBooleanTrue();
   1688 }
   1689 
   1690 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant() {
   1691   BuildJumpIfToBooleanTrue();
   1692 }
   1693 
   1694 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse() {
   1695   BuildJumpIfToBooleanFalse();
   1696 }
   1697 
   1698 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant() {
   1699   BuildJumpIfToBooleanFalse();
   1700 }
   1701 
   1702 void BytecodeGraphBuilder::VisitJumpIfNotHole() { BuildJumpIfNotHole(); }
   1703 
   1704 void BytecodeGraphBuilder::VisitJumpIfNotHoleConstant() {
   1705   BuildJumpIfNotHole();
   1706 }
   1707 
   1708 void BytecodeGraphBuilder::VisitJumpIfNull() {
   1709   BuildJumpIfEqual(jsgraph()->NullConstant());
   1710 }
   1711 
   1712 void BytecodeGraphBuilder::VisitJumpIfNullConstant() {
   1713   BuildJumpIfEqual(jsgraph()->NullConstant());
   1714 }
   1715 
   1716 void BytecodeGraphBuilder::VisitJumpIfUndefined() {
   1717   BuildJumpIfEqual(jsgraph()->UndefinedConstant());
   1718 }
   1719 
   1720 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant() {
   1721   BuildJumpIfEqual(jsgraph()->UndefinedConstant());
   1722 }
   1723 
   1724 void BytecodeGraphBuilder::VisitJumpLoop() { BuildJump(); }
   1725 
   1726 void BytecodeGraphBuilder::VisitStackCheck() {
   1727   PrepareEagerCheckpoint();
   1728   Node* node = NewNode(javascript()->StackCheck());
   1729   environment()->RecordAfterState(node, Environment::kAttachFrameState);
   1730 }
   1731 
   1732 void BytecodeGraphBuilder::VisitReturn() {
   1733   BuildLoopExitsForFunctionExit();
   1734   Node* pop_node = jsgraph()->ZeroConstant();
   1735   Node* control =
   1736       NewNode(common()->Return(), pop_node, environment()->LookupAccumulator());
   1737   MergeControlToLeaveFunction(control);
   1738 }
   1739 
   1740 void BytecodeGraphBuilder::VisitDebugger() {
   1741   PrepareEagerCheckpoint();
   1742   Node* call =
   1743       NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement));
   1744   environment()->BindAccumulator(call, Environment::kAttachFrameState);
   1745   environment()->MarkAllRegistersLive();
   1746 }
   1747 
   1748 // We cannot create a graph from the debugger copy of the bytecode array.
   1749 #define DEBUG_BREAK(Name, ...) \
   1750   void BytecodeGraphBuilder::Visit##Name() { UNREACHABLE(); }
   1751 DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK);
   1752 #undef DEBUG_BREAK
   1753 
   1754 void BytecodeGraphBuilder::BuildForInPrepare() {
   1755   PrepareEagerCheckpoint();
   1756   Node* receiver =
   1757       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1758   Node* prepare = NewNode(javascript()->ForInPrepare(), receiver);
   1759   environment()->BindRegistersToProjections(
   1760       bytecode_iterator().GetRegisterOperand(1), prepare,
   1761       Environment::kAttachFrameState);
   1762 }
   1763 
   1764 void BytecodeGraphBuilder::VisitForInPrepare() { BuildForInPrepare(); }
   1765 
   1766 void BytecodeGraphBuilder::VisitForInContinue() {
   1767   PrepareEagerCheckpoint();
   1768   Node* index =
   1769       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1770   Node* cache_length =
   1771       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
   1772   Node* exit_cond =
   1773       NewNode(javascript()->LessThan(CompareOperationHint::kSignedSmall), index,
   1774               cache_length);
   1775   environment()->BindAccumulator(exit_cond, Environment::kAttachFrameState);
   1776 }
   1777 
   1778 void BytecodeGraphBuilder::BuildForInNext() {
   1779   PrepareEagerCheckpoint();
   1780   Node* receiver =
   1781       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1782   Node* index =
   1783       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
   1784   int catch_reg_pair_index = bytecode_iterator().GetRegisterOperand(2).index();
   1785   Node* cache_type = environment()->LookupRegister(
   1786       interpreter::Register(catch_reg_pair_index));
   1787   Node* cache_array = environment()->LookupRegister(
   1788       interpreter::Register(catch_reg_pair_index + 1));
   1789 
   1790   Node* value = NewNode(javascript()->ForInNext(), receiver, cache_array,
   1791                         cache_type, index);
   1792   environment()->BindAccumulator(value, Environment::kAttachFrameState);
   1793 }
   1794 
   1795 void BytecodeGraphBuilder::VisitForInNext() { BuildForInNext(); }
   1796 
   1797 void BytecodeGraphBuilder::VisitForInStep() {
   1798   PrepareEagerCheckpoint();
   1799   Node* index =
   1800       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
   1801   index = NewNode(javascript()->Add(BinaryOperationHint::kSignedSmall), index,
   1802                   jsgraph()->OneConstant());
   1803   environment()->BindAccumulator(index, Environment::kAttachFrameState);
   1804 }
   1805 
   1806 void BytecodeGraphBuilder::VisitSuspendGenerator() {
   1807   Node* state = environment()->LookupAccumulator();
   1808   Node* generator = environment()->LookupRegister(
   1809       bytecode_iterator().GetRegisterOperand(0));
   1810   // The offsets used by the bytecode iterator are relative to a different base
   1811   // than what is used in the interpreter, hence the addition.
   1812   Node* offset =
   1813       jsgraph()->Constant(bytecode_iterator().current_offset() +
   1814                           (BytecodeArray::kHeaderSize - kHeapObjectTag));
   1815 
   1816   int register_count = environment()->register_count();
   1817   int value_input_count = 3 + register_count;
   1818 
   1819   Node** value_inputs = local_zone()->NewArray<Node*>(value_input_count);
   1820   value_inputs[0] = generator;
   1821   value_inputs[1] = state;
   1822   value_inputs[2] = offset;
   1823   for (int i = 0; i < register_count; ++i) {
   1824     value_inputs[3 + i] =
   1825         environment()->LookupRegister(interpreter::Register(i));
   1826   }
   1827 
   1828   MakeNode(javascript()->GeneratorStore(register_count), value_input_count,
   1829            value_inputs, false);
   1830 }
   1831 
   1832 void BytecodeGraphBuilder::VisitResumeGenerator() {
   1833   PrepareEagerCheckpoint();
   1834 
   1835   Node* generator = environment()->LookupRegister(
   1836       bytecode_iterator().GetRegisterOperand(0));
   1837 
   1838   // Bijection between registers and array indices must match that used in
   1839   // InterpreterAssembler::ExportRegisterFile.
   1840   for (int i = 0; i < environment()->register_count(); ++i) {
   1841     Node* value = NewNode(javascript()->GeneratorRestoreRegister(i), generator);
   1842     environment()->BindRegister(interpreter::Register(i), value);
   1843   }
   1844 
   1845   Node* state =
   1846       NewNode(javascript()->GeneratorRestoreContinuation(), generator);
   1847 
   1848   environment()->BindAccumulator(state, Environment::kAttachFrameState);
   1849 }
   1850 
   1851 void BytecodeGraphBuilder::VisitWide() {
   1852   // Consumed by the BytecodeArrayIterator.
   1853   UNREACHABLE();
   1854 }
   1855 
   1856 void BytecodeGraphBuilder::VisitExtraWide() {
   1857   // Consumed by the BytecodeArrayIterator.
   1858   UNREACHABLE();
   1859 }
   1860 
   1861 void BytecodeGraphBuilder::VisitIllegal() {
   1862   // Not emitted in valid bytecode.
   1863   UNREACHABLE();
   1864 }
   1865 
   1866 void BytecodeGraphBuilder::VisitNop() {}
   1867 
   1868 void BytecodeGraphBuilder::SwitchToMergeEnvironment(int current_offset) {
   1869   if (merge_environments_[current_offset] != nullptr) {
   1870     if (environment() != nullptr) {
   1871       merge_environments_[current_offset]->Merge(environment());
   1872     }
   1873     set_environment(merge_environments_[current_offset]);
   1874   }
   1875 }
   1876 
   1877 void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) {
   1878   if (branch_analysis()->backward_branches_target(current_offset)) {
   1879     // Add loop header and store a copy so we can connect merged back
   1880     // edge inputs to the loop header.
   1881     merge_environments_[current_offset] = environment()->CopyForLoop();
   1882   }
   1883 }
   1884 
   1885 void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(int target_offset) {
   1886   BuildLoopExitsForBranch(target_offset);
   1887   if (merge_environments_[target_offset] == nullptr) {
   1888     // Append merge nodes to the environment. We may merge here with another
   1889     // environment. So add a place holder for merge nodes. We may add redundant
   1890     // but will be eliminated in a later pass.
   1891     // TODO(mstarzinger): Be smarter about this!
   1892     NewMerge();
   1893     merge_environments_[target_offset] = environment();
   1894   } else {
   1895     merge_environments_[target_offset]->Merge(environment());
   1896   }
   1897   set_environment(nullptr);
   1898 }
   1899 
   1900 void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
   1901   exit_controls_.push_back(exit);
   1902   set_environment(nullptr);
   1903 }
   1904 
   1905 void BytecodeGraphBuilder::BuildOSRLoopEntryPoint(int current_offset) {
   1906   if (!osr_ast_id_.IsNone() && osr_ast_id_.ToInt() == current_offset) {
   1907     // For OSR add a special {OsrLoopEntry} node into the current loop header.
   1908     // It will be turned into a usable entry by the OSR deconstruction.
   1909     Environment* loop_env = merge_environments_[current_offset];
   1910     Environment* osr_env = loop_env->CopyForOsrEntry();
   1911     osr_env->PrepareForOsrEntry();
   1912     loop_env->Merge(osr_env);
   1913   }
   1914 }
   1915 
   1916 void BytecodeGraphBuilder::BuildOSRNormalEntryPoint() {
   1917   if (!osr_ast_id_.IsNone()) {
   1918     // For OSR add an {OsrNormalEntry} as the the top-level environment start.
   1919     // It will be replaced with {Dead} by the OSR deconstruction.
   1920     NewNode(common()->OsrNormalEntry());
   1921     // Note that the requested OSR entry point must be the target of a backward
   1922     // branch, otherwise there will not be a proper loop header available.
   1923     DCHECK(branch_analysis()->backward_branches_target(osr_ast_id_.ToInt()));
   1924   }
   1925 }
   1926 
   1927 void BytecodeGraphBuilder::BuildLoopExitsForBranch(int target_offset) {
   1928   int origin_offset = bytecode_iterator().current_offset();
   1929   // Only build loop exits for forward edges.
   1930   if (target_offset > origin_offset) {
   1931     BuildLoopExitsUntilLoop(loop_analysis()->GetLoopOffsetFor(target_offset));
   1932   }
   1933 }
   1934 
   1935 void BytecodeGraphBuilder::BuildLoopExitsUntilLoop(int loop_offset) {
   1936   int origin_offset = bytecode_iterator().current_offset();
   1937   int current_loop = loop_analysis()->GetLoopOffsetFor(origin_offset);
   1938   while (loop_offset < current_loop) {
   1939     Node* loop_node = merge_environments_[current_loop]->GetControlDependency();
   1940     environment()->PrepareForLoopExit(loop_node);
   1941     current_loop = loop_analysis()->GetParentLoopFor(current_loop);
   1942   }
   1943 }
   1944 
   1945 void BytecodeGraphBuilder::BuildLoopExitsForFunctionExit() {
   1946   BuildLoopExitsUntilLoop(-1);
   1947 }
   1948 
   1949 void BytecodeGraphBuilder::BuildJump() {
   1950   MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
   1951 }
   1952 
   1953 void BytecodeGraphBuilder::BuildJumpIf(Node* condition) {
   1954   NewBranch(condition);
   1955   Environment* if_false_environment = environment()->CopyForConditional();
   1956   NewIfTrue();
   1957   MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
   1958   set_environment(if_false_environment);
   1959   NewIfFalse();
   1960 }
   1961 
   1962 void BytecodeGraphBuilder::BuildJumpIfNot(Node* condition) {
   1963   NewBranch(condition);
   1964   Environment* if_true_environment = environment()->CopyForConditional();
   1965   NewIfFalse();
   1966   MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
   1967   set_environment(if_true_environment);
   1968   NewIfTrue();
   1969 }
   1970 
   1971 void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
   1972   Node* accumulator = environment()->LookupAccumulator();
   1973   Node* condition =
   1974       NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
   1975               accumulator, comperand);
   1976   BuildJumpIf(condition);
   1977 }
   1978 
   1979 void BytecodeGraphBuilder::BuildJumpIfFalse() {
   1980   BuildJumpIfNot(environment()->LookupAccumulator());
   1981 }
   1982 
   1983 void BytecodeGraphBuilder::BuildJumpIfTrue() {
   1984   BuildJumpIf(environment()->LookupAccumulator());
   1985 }
   1986 
   1987 void BytecodeGraphBuilder::BuildJumpIfToBooleanTrue() {
   1988   Node* accumulator = environment()->LookupAccumulator();
   1989   Node* condition =
   1990       NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
   1991   BuildJumpIf(condition);
   1992 }
   1993 
   1994 void BytecodeGraphBuilder::BuildJumpIfToBooleanFalse() {
   1995   Node* accumulator = environment()->LookupAccumulator();
   1996   Node* condition =
   1997       NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
   1998   BuildJumpIfNot(condition);
   1999 }
   2000 
   2001 void BytecodeGraphBuilder::BuildJumpIfNotHole() {
   2002   Node* accumulator = environment()->LookupAccumulator();
   2003   Node* condition =
   2004       NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
   2005               accumulator, jsgraph()->TheHoleConstant());
   2006   BuildJumpIfNot(condition);
   2007 }
   2008 
   2009 Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) {
   2010   if (size > input_buffer_size_) {
   2011     size = size + kInputBufferSizeIncrement + input_buffer_size_;
   2012     input_buffer_ = local_zone()->NewArray<Node*>(size);
   2013     input_buffer_size_ = size;
   2014   }
   2015   return input_buffer_;
   2016 }
   2017 
   2018 void BytecodeGraphBuilder::EnterAndExitExceptionHandlers(int current_offset) {
   2019   Handle<HandlerTable> table = exception_handler_table();
   2020   int num_entries = table->NumberOfRangeEntries();
   2021 
   2022   // Potentially exit exception handlers.
   2023   while (!exception_handlers_.empty()) {
   2024     int current_end = exception_handlers_.top().end_offset_;
   2025     if (current_offset < current_end) break;  // Still covered by range.
   2026     exception_handlers_.pop();
   2027   }
   2028 
   2029   // Potentially enter exception handlers.
   2030   while (current_exception_handler_ < num_entries) {
   2031     int next_start = table->GetRangeStart(current_exception_handler_);
   2032     if (current_offset < next_start) break;  // Not yet covered by range.
   2033     int next_end = table->GetRangeEnd(current_exception_handler_);
   2034     int next_handler = table->GetRangeHandler(current_exception_handler_);
   2035     int context_register = table->GetRangeData(current_exception_handler_);
   2036     exception_handlers_.push(
   2037         {next_start, next_end, next_handler, context_register});
   2038     current_exception_handler_++;
   2039   }
   2040 }
   2041 
   2042 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
   2043                                      Node** value_inputs, bool incomplete) {
   2044   DCHECK_EQ(op->ValueInputCount(), value_input_count);
   2045 
   2046   bool has_context = OperatorProperties::HasContextInput(op);
   2047   bool has_frame_state = OperatorProperties::HasFrameStateInput(op);
   2048   bool has_control = op->ControlInputCount() == 1;
   2049   bool has_effect = op->EffectInputCount() == 1;
   2050 
   2051   DCHECK_LT(op->ControlInputCount(), 2);
   2052   DCHECK_LT(op->EffectInputCount(), 2);
   2053 
   2054   Node* result = nullptr;
   2055   if (!has_context && !has_frame_state && !has_control && !has_effect) {
   2056     result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
   2057   } else {
   2058     bool inside_handler = !exception_handlers_.empty();
   2059     int input_count_with_deps = value_input_count;
   2060     if (has_context) ++input_count_with_deps;
   2061     if (has_frame_state) ++input_count_with_deps;
   2062     if (has_control) ++input_count_with_deps;
   2063     if (has_effect) ++input_count_with_deps;
   2064     Node** buffer = EnsureInputBufferSize(input_count_with_deps);
   2065     memcpy(buffer, value_inputs, kPointerSize * value_input_count);
   2066     Node** current_input = buffer + value_input_count;
   2067     if (has_context) {
   2068       *current_input++ = environment()->Context();
   2069     }
   2070     if (has_frame_state) {
   2071       // The frame state will be inserted later. Here we misuse the {Dead} node
   2072       // as a sentinel to be later overwritten with the real frame state by the
   2073       // calls to {PrepareFrameState} within individual visitor methods.
   2074       *current_input++ = jsgraph()->Dead();
   2075     }
   2076     if (has_effect) {
   2077       *current_input++ = environment()->GetEffectDependency();
   2078     }
   2079     if (has_control) {
   2080       *current_input++ = environment()->GetControlDependency();
   2081     }
   2082     result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
   2083     // Update the current control dependency for control-producing nodes.
   2084     if (NodeProperties::IsControl(result)) {
   2085       environment()->UpdateControlDependency(result);
   2086     }
   2087     // Update the current effect dependency for effect-producing nodes.
   2088     if (result->op()->EffectOutputCount() > 0) {
   2089       environment()->UpdateEffectDependency(result);
   2090     }
   2091     // Add implicit exception continuation for throwing nodes.
   2092     if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
   2093       int handler_offset = exception_handlers_.top().handler_offset_;
   2094       int context_index = exception_handlers_.top().context_register_;
   2095       interpreter::Register context_register(context_index);
   2096       Environment* success_env = environment()->CopyForConditional();
   2097       const Operator* op = common()->IfException();
   2098       Node* effect = environment()->GetEffectDependency();
   2099       Node* on_exception = graph()->NewNode(op, effect, result);
   2100       Node* context = environment()->LookupRegister(context_register);
   2101       environment()->UpdateControlDependency(on_exception);
   2102       environment()->UpdateEffectDependency(on_exception);
   2103       environment()->BindAccumulator(on_exception);
   2104       environment()->SetContext(context);
   2105       MergeIntoSuccessorEnvironment(handler_offset);
   2106       set_environment(success_env);
   2107     }
   2108     // Add implicit success continuation for throwing nodes.
   2109     if (!result->op()->HasProperty(Operator::kNoThrow)) {
   2110       const Operator* if_success = common()->IfSuccess();
   2111       Node* on_success = graph()->NewNode(if_success, result);
   2112       environment()->UpdateControlDependency(on_success);
   2113     }
   2114   }
   2115 
   2116   return result;
   2117 }
   2118 
   2119 
   2120 Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) {
   2121   const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
   2122   Node** buffer = EnsureInputBufferSize(count + 1);
   2123   MemsetPointer(buffer, input, count);
   2124   buffer[count] = control;
   2125   return graph()->NewNode(phi_op, count + 1, buffer, true);
   2126 }
   2127 
   2128 
   2129 Node* BytecodeGraphBuilder::NewEffectPhi(int count, Node* input,
   2130                                          Node* control) {
   2131   const Operator* phi_op = common()->EffectPhi(count);
   2132   Node** buffer = EnsureInputBufferSize(count + 1);
   2133   MemsetPointer(buffer, input, count);
   2134   buffer[count] = control;
   2135   return graph()->NewNode(phi_op, count + 1, buffer, true);
   2136 }
   2137 
   2138 
   2139 Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) {
   2140   int inputs = control->op()->ControlInputCount() + 1;
   2141   if (control->opcode() == IrOpcode::kLoop) {
   2142     // Control node for loop exists, add input.
   2143     const Operator* op = common()->Loop(inputs);
   2144     control->AppendInput(graph_zone(), other);
   2145     NodeProperties::ChangeOp(control, op);
   2146   } else if (control->opcode() == IrOpcode::kMerge) {
   2147     // Control node for merge exists, add input.
   2148     const Operator* op = common()->Merge(inputs);
   2149     control->AppendInput(graph_zone(), other);
   2150     NodeProperties::ChangeOp(control, op);
   2151   } else {
   2152     // Control node is a singleton, introduce a merge.
   2153     const Operator* op = common()->Merge(inputs);
   2154     Node* merge_inputs[] = {control, other};
   2155     control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true);
   2156   }
   2157   return control;
   2158 }
   2159 
   2160 
   2161 Node* BytecodeGraphBuilder::MergeEffect(Node* value, Node* other,
   2162                                         Node* control) {
   2163   int inputs = control->op()->ControlInputCount();
   2164   if (value->opcode() == IrOpcode::kEffectPhi &&
   2165       NodeProperties::GetControlInput(value) == control) {
   2166     // Phi already exists, add input.
   2167     value->InsertInput(graph_zone(), inputs - 1, other);
   2168     NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
   2169   } else if (value != other) {
   2170     // Phi does not exist yet, introduce one.
   2171     value = NewEffectPhi(inputs, value, control);
   2172     value->ReplaceInput(inputs - 1, other);
   2173   }
   2174   return value;
   2175 }
   2176 
   2177 
   2178 Node* BytecodeGraphBuilder::MergeValue(Node* value, Node* other,
   2179                                        Node* control) {
   2180   int inputs = control->op()->ControlInputCount();
   2181   if (value->opcode() == IrOpcode::kPhi &&
   2182       NodeProperties::GetControlInput(value) == control) {
   2183     // Phi already exists, add input.
   2184     value->InsertInput(graph_zone(), inputs - 1, other);
   2185     NodeProperties::ChangeOp(
   2186         value, common()->Phi(MachineRepresentation::kTagged, inputs));
   2187   } else if (value != other) {
   2188     // Phi does not exist yet, introduce one.
   2189     value = NewPhi(inputs, value, control);
   2190     value->ReplaceInput(inputs - 1, other);
   2191   }
   2192   return value;
   2193 }
   2194 
   2195 void BytecodeGraphBuilder::UpdateCurrentSourcePosition(
   2196     SourcePositionTableIterator* it, int offset) {
   2197   if (it->done()) return;
   2198 
   2199   if (it->code_offset() == offset) {
   2200     source_positions_->SetCurrentPosition(SourcePosition(
   2201         it->source_position().ScriptOffset(), start_position_.InliningId()));
   2202     it->Advance();
   2203   } else {
   2204     DCHECK_GT(it->code_offset(), offset);
   2205   }
   2206 }
   2207 
   2208 }  // namespace compiler
   2209 }  // namespace internal
   2210 }  // namespace v8
   2211