Home | History | Annotate | Download | only in compiler
      1 // Copyright 2014 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/ast-graph-builder.h"
      6 
      7 #include "src/ast/compile-time-value.h"
      8 #include "src/ast/scopes.h"
      9 #include "src/compilation-info.h"
     10 #include "src/compiler.h"
     11 #include "src/compiler/ast-loop-assignment-analyzer.h"
     12 #include "src/compiler/control-builders.h"
     13 #include "src/compiler/linkage.h"
     14 #include "src/compiler/liveness-analyzer.h"
     15 #include "src/compiler/machine-operator.h"
     16 #include "src/compiler/node-matchers.h"
     17 #include "src/compiler/node-properties.h"
     18 #include "src/compiler/operator-properties.h"
     19 #include "src/compiler/state-values-utils.h"
     20 #include "src/compiler/type-hint-analyzer.h"
     21 
     22 namespace v8 {
     23 namespace internal {
     24 namespace compiler {
     25 
     26 
     27 // Each expression in the AST is evaluated in a specific context. This context
     28 // decides how the evaluation result is passed up the visitor.
     29 class AstGraphBuilder::AstContext BASE_EMBEDDED {
     30  public:
     31   bool IsEffect() const { return kind_ == Expression::kEffect; }
     32   bool IsValue() const { return kind_ == Expression::kValue; }
     33   bool IsTest() const { return kind_ == Expression::kTest; }
     34 
     35   // Determines how to combine the frame state with the value
     36   // that is about to be plugged into this AstContext.
     37   OutputFrameStateCombine GetStateCombine() {
     38     return IsEffect() ? OutputFrameStateCombine::Ignore()
     39                       : OutputFrameStateCombine::Push();
     40   }
     41 
     42   // Plug a node into this expression context.  Call this function in tail
     43   // position in the Visit functions for expressions.
     44   virtual void ProduceValue(Expression* expr, Node* value) = 0;
     45 
     46   // Unplugs a node from this expression context.  Call this to retrieve the
     47   // result of another Visit function that already plugged the context.
     48   virtual Node* ConsumeValue() = 0;
     49 
     50   // Shortcut for "context->ProduceValue(context->ConsumeValue())".
     51   void ReplaceValue(Expression* expr) { ProduceValue(expr, ConsumeValue()); }
     52 
     53  protected:
     54   AstContext(AstGraphBuilder* owner, Expression::Context kind);
     55   virtual ~AstContext();
     56 
     57   AstGraphBuilder* owner() const { return owner_; }
     58   Environment* environment() const { return owner_->environment(); }
     59 
     60 // We want to be able to assert, in a context-specific way, that the stack
     61 // height makes sense when the context is filled.
     62 #ifdef DEBUG
     63   int original_height_;
     64 #endif
     65 
     66  private:
     67   Expression::Context kind_;
     68   AstGraphBuilder* owner_;
     69   AstContext* outer_;
     70 };
     71 
     72 
     73 // Context to evaluate expression for its side effects only.
     74 class AstGraphBuilder::AstEffectContext final : public AstContext {
     75  public:
     76   explicit AstEffectContext(AstGraphBuilder* owner)
     77       : AstContext(owner, Expression::kEffect) {}
     78   ~AstEffectContext() final;
     79   void ProduceValue(Expression* expr, Node* value) final;
     80   Node* ConsumeValue() final;
     81 };
     82 
     83 
     84 // Context to evaluate expression for its value (and side effects).
     85 class AstGraphBuilder::AstValueContext final : public AstContext {
     86  public:
     87   explicit AstValueContext(AstGraphBuilder* owner)
     88       : AstContext(owner, Expression::kValue) {}
     89   ~AstValueContext() final;
     90   void ProduceValue(Expression* expr, Node* value) final;
     91   Node* ConsumeValue() final;
     92 };
     93 
     94 
     95 // Context to evaluate expression for a condition value (and side effects).
     96 class AstGraphBuilder::AstTestContext final : public AstContext {
     97  public:
     98   AstTestContext(AstGraphBuilder* owner, TypeFeedbackId feedback_id)
     99       : AstContext(owner, Expression::kTest), feedback_id_(feedback_id) {}
    100   ~AstTestContext() final;
    101   void ProduceValue(Expression* expr, Node* value) final;
    102   Node* ConsumeValue() final;
    103 
    104  private:
    105   TypeFeedbackId const feedback_id_;
    106 };
    107 
    108 
    109 // Scoped class tracking context objects created by the visitor. Represents
    110 // mutations of the context chain within the function body and allows to
    111 // change the current {scope} and {context} during visitation.
    112 class AstGraphBuilder::ContextScope BASE_EMBEDDED {
    113  public:
    114   ContextScope(AstGraphBuilder* builder, Scope* scope, Node* context)
    115       : builder_(builder),
    116         outer_(builder->execution_context()),
    117         scope_(scope),
    118         depth_(builder_->environment()->context_chain_length()) {
    119     builder_->environment()->PushContext(context);  // Push.
    120     builder_->set_execution_context(this);
    121   }
    122 
    123   ~ContextScope() {
    124     builder_->set_execution_context(outer_);  // Pop.
    125     builder_->environment()->PopContext();
    126     CHECK_EQ(depth_, builder_->environment()->context_chain_length());
    127   }
    128 
    129   // Current scope during visitation.
    130   Scope* scope() const { return scope_; }
    131 
    132  private:
    133   AstGraphBuilder* builder_;
    134   ContextScope* outer_;
    135   Scope* scope_;
    136   int depth_;
    137 };
    138 
    139 
    140 // Scoped class tracking control statements entered by the visitor. There are
    141 // different types of statements participating in this stack to properly track
    142 // local as well as non-local control flow:
    143 //  - IterationStatement : Allows proper 'break' and 'continue' behavior.
    144 //  - BreakableStatement : Allows 'break' from block and switch statements.
    145 //  - TryCatchStatement  : Intercepts 'throw' and implicit exceptional edges.
    146 //  - TryFinallyStatement: Intercepts 'break', 'continue', 'throw' and 'return'.
    147 class AstGraphBuilder::ControlScope BASE_EMBEDDED {
    148  public:
    149   explicit ControlScope(AstGraphBuilder* builder)
    150       : builder_(builder),
    151         outer_(builder->execution_control()),
    152         context_length_(builder->environment()->context_chain_length()),
    153         stack_height_(builder->environment()->stack_height()) {
    154     builder_->set_execution_control(this);  // Push.
    155   }
    156 
    157   virtual ~ControlScope() {
    158     builder_->set_execution_control(outer_);  // Pop.
    159   }
    160 
    161   // Either 'break' or 'continue' to the target statement.
    162   void BreakTo(BreakableStatement* target);
    163   void ContinueTo(BreakableStatement* target);
    164 
    165   // Either 'return' or 'throw' the given value.
    166   void ReturnValue(Node* return_value);
    167   void ThrowValue(Node* exception_value);
    168 
    169   class DeferredCommands;
    170 
    171  protected:
    172   enum Command { CMD_BREAK, CMD_CONTINUE, CMD_RETURN, CMD_THROW };
    173 
    174   // Performs one of the above commands on this stack of control scopes. This
    175   // walks through the stack giving each scope a chance to execute or defer the
    176   // given command by overriding the {Execute} method appropriately. Note that
    177   // this also drops extra operands from the environment for each skipped scope.
    178   void PerformCommand(Command cmd, Statement* target, Node* value);
    179 
    180   // Interface to execute a given command in this scope. Returning {true} here
    181   // indicates successful execution whereas {false} requests to skip scope.
    182   virtual bool Execute(Command cmd, Statement* target, Node** value) {
    183     // For function-level control.
    184     switch (cmd) {
    185       case CMD_THROW:
    186         builder()->BuildThrow(*value);
    187         return true;
    188       case CMD_RETURN:
    189         builder()->BuildReturn(*value);
    190         return true;
    191       case CMD_BREAK:
    192       case CMD_CONTINUE:
    193         break;
    194     }
    195     return false;
    196   }
    197 
    198   Environment* environment() { return builder_->environment(); }
    199   AstGraphBuilder* builder() const { return builder_; }
    200   int context_length() const { return context_length_; }
    201   int stack_height() const { return stack_height_; }
    202 
    203  private:
    204   AstGraphBuilder* builder_;
    205   ControlScope* outer_;
    206   int context_length_;
    207   int stack_height_;
    208 };
    209 
    210 // Helper class for a try-finally control scope. It can record intercepted
    211 // control-flow commands that cause entry into a finally-block, and re-apply
    212 // them after again leaving that block. Special tokens are used to identify
    213 // paths going through the finally-block to dispatch after leaving the block.
    214 class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject {
    215  public:
    216   explicit DeferredCommands(AstGraphBuilder* owner)
    217       : owner_(owner),
    218         deferred_(owner->local_zone()),
    219         return_token_(nullptr),
    220         throw_token_(nullptr) {}
    221 
    222   // One recorded control-flow command.
    223   struct Entry {
    224     Command command;       // The command type being applied on this path.
    225     Statement* statement;  // The target statement for the command or {nullptr}.
    226     Node* token;           // A token identifying this particular path.
    227   };
    228 
    229   // Records a control-flow command while entering the finally-block. This also
    230   // generates a new dispatch token that identifies one particular path.
    231   Node* RecordCommand(Command cmd, Statement* stmt, Node* value) {
    232     Node* token = nullptr;
    233     switch (cmd) {
    234       case CMD_BREAK:
    235       case CMD_CONTINUE:
    236         token = NewPathToken(dispenser_.GetBreakContinueToken());
    237         break;
    238       case CMD_THROW:
    239         if (throw_token_) return throw_token_;
    240         token = NewPathToken(TokenDispenserForFinally::kThrowToken);
    241         throw_token_ = token;
    242         break;
    243       case CMD_RETURN:
    244         if (return_token_) return return_token_;
    245         token = NewPathToken(TokenDispenserForFinally::kReturnToken);
    246         return_token_ = token;
    247         break;
    248     }
    249     DCHECK_NOT_NULL(token);
    250     deferred_.push_back({cmd, stmt, token});
    251     return token;
    252   }
    253 
    254   // Returns the dispatch token to be used to identify the implicit fall-through
    255   // path at the end of a try-block into the corresponding finally-block.
    256   Node* GetFallThroughToken() { return NewPathTokenForImplicitFallThrough(); }
    257 
    258   // Applies all recorded control-flow commands after the finally-block again.
    259   // This generates a dynamic dispatch on the token from the entry point.
    260   void ApplyDeferredCommands(Node* token, Node* value) {
    261     SwitchBuilder dispatch(owner_, static_cast<int>(deferred_.size()));
    262     dispatch.BeginSwitch();
    263     for (size_t i = 0; i < deferred_.size(); ++i) {
    264       Node* condition = NewPathDispatchCondition(token, deferred_[i].token);
    265       dispatch.BeginLabel(static_cast<int>(i), condition);
    266       dispatch.EndLabel();
    267     }
    268     for (size_t i = 0; i < deferred_.size(); ++i) {
    269       dispatch.BeginCase(static_cast<int>(i));
    270       owner_->execution_control()->PerformCommand(
    271           deferred_[i].command, deferred_[i].statement, value);
    272       dispatch.EndCase();
    273     }
    274     dispatch.EndSwitch();
    275   }
    276 
    277  protected:
    278   Node* NewPathToken(int token_id) {
    279     return owner_->jsgraph()->Constant(token_id);
    280   }
    281   Node* NewPathTokenForImplicitFallThrough() {
    282     return NewPathToken(TokenDispenserForFinally::kFallThroughToken);
    283   }
    284   Node* NewPathDispatchCondition(Node* t1, Node* t2) {
    285     return owner_->NewNode(
    286         owner_->javascript()->StrictEqual(CompareOperationHint::kAny), t1, t2);
    287   }
    288 
    289  private:
    290   TokenDispenserForFinally dispenser_;
    291   AstGraphBuilder* owner_;
    292   ZoneVector<Entry> deferred_;
    293   Node* return_token_;
    294   Node* throw_token_;
    295 };
    296 
    297 
    298 // Control scope implementation for a BreakableStatement.
    299 class AstGraphBuilder::ControlScopeForBreakable : public ControlScope {
    300  public:
    301   ControlScopeForBreakable(AstGraphBuilder* owner, BreakableStatement* target,
    302                            ControlBuilder* control)
    303       : ControlScope(owner), target_(target), control_(control) {}
    304 
    305  protected:
    306   bool Execute(Command cmd, Statement* target, Node** value) override {
    307     if (target != target_) return false;  // We are not the command target.
    308     switch (cmd) {
    309       case CMD_BREAK:
    310         control_->Break();
    311         return true;
    312       case CMD_CONTINUE:
    313       case CMD_THROW:
    314       case CMD_RETURN:
    315         break;
    316     }
    317     return false;
    318   }
    319 
    320  private:
    321   BreakableStatement* target_;
    322   ControlBuilder* control_;
    323 };
    324 
    325 
    326 // Control scope implementation for an IterationStatement.
    327 class AstGraphBuilder::ControlScopeForIteration : public ControlScope {
    328  public:
    329   ControlScopeForIteration(AstGraphBuilder* owner, IterationStatement* target,
    330                            LoopBuilder* control)
    331       : ControlScope(owner), target_(target), control_(control) {}
    332 
    333  protected:
    334   bool Execute(Command cmd, Statement* target, Node** value) override {
    335     if (target != target_) {
    336       control_->ExitLoop(value);
    337       return false;
    338     }
    339     switch (cmd) {
    340       case CMD_BREAK:
    341         control_->Break();
    342         return true;
    343       case CMD_CONTINUE:
    344         control_->Continue();
    345         return true;
    346       case CMD_THROW:
    347       case CMD_RETURN:
    348         break;
    349     }
    350     return false;
    351   }
    352 
    353  private:
    354   BreakableStatement* target_;
    355   LoopBuilder* control_;
    356 };
    357 
    358 
    359 // Control scope implementation for a TryCatchStatement.
    360 class AstGraphBuilder::ControlScopeForCatch : public ControlScope {
    361  public:
    362   ControlScopeForCatch(AstGraphBuilder* owner, TryCatchStatement* stmt,
    363                        TryCatchBuilder* control)
    364       : ControlScope(owner), control_(control) {
    365     builder()->try_nesting_level_++;  // Increment nesting.
    366   }
    367   ~ControlScopeForCatch() {
    368     builder()->try_nesting_level_--;  // Decrement nesting.
    369   }
    370 
    371  protected:
    372   bool Execute(Command cmd, Statement* target, Node** value) override {
    373     switch (cmd) {
    374       case CMD_THROW:
    375         control_->Throw(*value);
    376         return true;
    377       case CMD_BREAK:
    378       case CMD_CONTINUE:
    379       case CMD_RETURN:
    380         break;
    381     }
    382     return false;
    383   }
    384 
    385  private:
    386   TryCatchBuilder* control_;
    387 };
    388 
    389 
    390 // Control scope implementation for a TryFinallyStatement.
    391 class AstGraphBuilder::ControlScopeForFinally : public ControlScope {
    392  public:
    393   ControlScopeForFinally(AstGraphBuilder* owner, TryFinallyStatement* stmt,
    394                          DeferredCommands* commands, TryFinallyBuilder* control)
    395       : ControlScope(owner), commands_(commands), control_(control) {
    396     builder()->try_nesting_level_++;  // Increment nesting.
    397   }
    398   ~ControlScopeForFinally() {
    399     builder()->try_nesting_level_--;  // Decrement nesting.
    400   }
    401 
    402  protected:
    403   bool Execute(Command cmd, Statement* target, Node** value) override {
    404     Node* token = commands_->RecordCommand(cmd, target, *value);
    405     control_->LeaveTry(token, *value);
    406     return true;
    407   }
    408 
    409  private:
    410   DeferredCommands* commands_;
    411   TryFinallyBuilder* control_;
    412 };
    413 
    414 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info,
    415                                  JSGraph* jsgraph, float invocation_frequency,
    416                                  LoopAssignmentAnalysis* loop,
    417                                  TypeHintAnalysis* type_hint_analysis)
    418     : isolate_(info->isolate()),
    419       local_zone_(local_zone),
    420       info_(info),
    421       jsgraph_(jsgraph),
    422       invocation_frequency_(invocation_frequency),
    423       environment_(nullptr),
    424       ast_context_(nullptr),
    425       globals_(0, local_zone),
    426       execution_control_(nullptr),
    427       execution_context_(nullptr),
    428       try_nesting_level_(0),
    429       input_buffer_size_(0),
    430       input_buffer_(nullptr),
    431       exit_controls_(local_zone),
    432       loop_assignment_analysis_(loop),
    433       type_hint_analysis_(type_hint_analysis),
    434       state_values_cache_(jsgraph),
    435       liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()),
    436                          false, local_zone),
    437       frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
    438           FrameStateType::kJavaScriptFunction, info->num_parameters() + 1,
    439           info->scope()->num_stack_slots(), info->shared_info())) {
    440   InitializeAstVisitor(info->isolate());
    441 }
    442 
    443 
    444 Node* AstGraphBuilder::GetFunctionClosureForContext() {
    445   DeclarationScope* closure_scope = current_scope()->GetClosureScope();
    446   if (closure_scope->is_script_scope() ||
    447       closure_scope->is_module_scope()) {
    448     // Contexts nested in the native context have a canonical empty function as
    449     // their closure, not the anonymous closure containing the global code.
    450     return BuildLoadNativeContextField(Context::CLOSURE_INDEX);
    451   } else if (closure_scope->is_eval_scope()) {
    452     // Contexts nested inside eval code have the same closure as the context
    453     // calling eval, not the anonymous closure containing the eval code.
    454     const Operator* op =
    455         javascript()->LoadContext(0, Context::CLOSURE_INDEX, false);
    456     return NewNode(op, current_context());
    457   } else {
    458     DCHECK(closure_scope->is_function_scope());
    459     return GetFunctionClosure();
    460   }
    461 }
    462 
    463 
    464 Node* AstGraphBuilder::GetFunctionClosure() {
    465   if (!function_closure_.is_set()) {
    466     int index = Linkage::kJSCallClosureParamIndex;
    467     const Operator* op = common()->Parameter(index, "%closure");
    468     Node* node = NewNode(op, graph()->start());
    469     function_closure_.set(node);
    470   }
    471   return function_closure_.get();
    472 }
    473 
    474 
    475 Node* AstGraphBuilder::GetFunctionContext() {
    476   if (!function_context_.is_set()) {
    477     int params = info()->num_parameters_including_this();
    478     int index = Linkage::GetJSCallContextParamIndex(params);
    479     const Operator* op = common()->Parameter(index, "%context");
    480     Node* node = NewNode(op, graph()->start());
    481     function_context_.set(node);
    482   }
    483   return function_context_.get();
    484 }
    485 
    486 
    487 Node* AstGraphBuilder::GetNewTarget() {
    488   if (!new_target_.is_set()) {
    489     int params = info()->num_parameters_including_this();
    490     int index = Linkage::GetJSCallNewTargetParamIndex(params);
    491     const Operator* op = common()->Parameter(index, "%new.target");
    492     Node* node = NewNode(op, graph()->start());
    493     new_target_.set(node);
    494   }
    495   return new_target_.get();
    496 }
    497 
    498 Node* AstGraphBuilder::GetEmptyFrameState() {
    499   if (!empty_frame_state_.is_set()) {
    500     const Operator* op = common()->FrameState(
    501         BailoutId::None(), OutputFrameStateCombine::Ignore(), nullptr);
    502     Node* node = graph()->NewNode(
    503         op, jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(),
    504         jsgraph()->EmptyStateValues(), jsgraph()->NoContextConstant(),
    505         jsgraph()->UndefinedConstant(), graph()->start());
    506     empty_frame_state_.set(node);
    507   }
    508   return empty_frame_state_.get();
    509 }
    510 
    511 bool AstGraphBuilder::CreateGraph(bool stack_check) {
    512   DeclarationScope* scope = info()->scope();
    513   DCHECK_NOT_NULL(graph());
    514 
    515   // Set up the basic structure of the graph. Outputs for {Start} are the formal
    516   // parameters (including the receiver) plus new target, number of arguments,
    517   // context and closure.
    518   int actual_parameter_count = info()->num_parameters_including_this() + 4;
    519   graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count)));
    520 
    521   // Initialize the top-level environment.
    522   Environment env(this, scope, graph()->start());
    523   set_environment(&env);
    524 
    525   if (info()->is_osr()) {
    526     // Use OSR normal entry as the start of the top-level environment.
    527     // It will be replaced with {Dead} after typing and optimizations.
    528     NewNode(common()->OsrNormalEntry());
    529   }
    530 
    531   // Initialize the incoming context.
    532   ContextScope incoming(this, scope, GetFunctionContext());
    533 
    534   // Initialize control scope.
    535   ControlScope control(this);
    536 
    537   // TODO(mstarzinger): For now we cannot assume that the {this} parameter is
    538   // not {the_hole}, because for derived classes {this} has a TDZ and the
    539   // JSConstructStubForDerived magically passes {the_hole} as a receiver.
    540   if (scope->has_this_declaration() && scope->receiver()->mode() == CONST) {
    541     env.RawParameterBind(0, jsgraph()->TheHoleConstant());
    542   }
    543 
    544   if (scope->NeedsContext()) {
    545     // Push a new inner context scope for the current activation.
    546     Node* inner_context = BuildLocalActivationContext(GetFunctionContext());
    547     ContextScope top_context(this, scope, inner_context);
    548     CreateGraphBody(stack_check);
    549   } else {
    550     // Simply use the outer function context in building the graph.
    551     CreateGraphBody(stack_check);
    552   }
    553 
    554   // Finish the basic structure of the graph.
    555   DCHECK_NE(0u, exit_controls_.size());
    556   int const input_count = static_cast<int>(exit_controls_.size());
    557   Node** const inputs = &exit_controls_.front();
    558   Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs);
    559   graph()->SetEnd(end);
    560 
    561   // Compute local variable liveness information and use it to relax
    562   // frame states.
    563   ClearNonLiveSlotsInFrameStates();
    564 
    565   // Failures indicated by stack overflow.
    566   return !HasStackOverflow();
    567 }
    568 
    569 
    570 void AstGraphBuilder::CreateGraphBody(bool stack_check) {
    571   DeclarationScope* scope = info()->scope();
    572 
    573   // Build the arguments object if it is used.
    574   BuildArgumentsObject(scope->arguments());
    575 
    576   // Build rest arguments array if it is used.
    577   Variable* rest_parameter = scope->rest_parameter();
    578   BuildRestArgumentsArray(rest_parameter);
    579 
    580   // Build assignment to {.this_function} variable if it is used.
    581   BuildThisFunctionVariable(scope->this_function_var());
    582 
    583   // Build assignment to {new.target} variable if it is used.
    584   BuildNewTargetVariable(scope->new_target_var());
    585 
    586   // Emit tracing call if requested to do so.
    587   if (FLAG_trace) {
    588     NewNode(javascript()->CallRuntime(Runtime::kTraceEnter));
    589   }
    590 
    591   // Visit declarations within the function scope.
    592   VisitDeclarations(scope->declarations());
    593 
    594   // Build a stack-check before the body.
    595   if (stack_check) {
    596     Node* node = NewNode(javascript()->StackCheck());
    597     PrepareFrameState(node, BailoutId::FunctionEntry());
    598   }
    599 
    600   // Visit statements in the function body.
    601   VisitStatements(info()->literal()->body());
    602 
    603   // Return 'undefined' in case we can fall off the end.
    604   BuildReturn(jsgraph()->UndefinedConstant());
    605 }
    606 
    607 
    608 void AstGraphBuilder::ClearNonLiveSlotsInFrameStates() {
    609   if (!FLAG_analyze_environment_liveness ||
    610       !info()->is_deoptimization_enabled()) {
    611     return;
    612   }
    613 
    614   NonLiveFrameStateSlotReplacer replacer(
    615       &state_values_cache_, jsgraph()->OptimizedOutConstant(),
    616       liveness_analyzer()->local_count(), false, local_zone());
    617   Variable* arguments = info()->scope()->arguments();
    618   if (arguments != nullptr && arguments->IsStackAllocated()) {
    619     replacer.MarkPermanentlyLive(arguments->index());
    620   }
    621   liveness_analyzer()->Run(&replacer);
    622   if (FLAG_trace_environment_liveness) {
    623     OFStream os(stdout);
    624     liveness_analyzer()->Print(os);
    625   }
    626 }
    627 
    628 
    629 // Gets the bailout id just before reading a variable proxy, but only for
    630 // unallocated variables.
    631 static BailoutId BeforeId(VariableProxy* proxy) {
    632   return proxy->var()->IsUnallocated() ? proxy->BeforeId() : BailoutId::None();
    633 }
    634 
    635 static const char* GetDebugParameterName(Zone* zone, DeclarationScope* scope,
    636                                          int index) {
    637 #if DEBUG
    638   const AstRawString* name = scope->parameter(index)->raw_name();
    639   if (name && name->length() > 0) {
    640     char* data = zone->NewArray<char>(name->length() + 1);
    641     data[name->length()] = 0;
    642     memcpy(data, name->raw_data(), name->length());
    643     return data;
    644   }
    645 #endif
    646   return nullptr;
    647 }
    648 
    649 AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder,
    650                                           DeclarationScope* scope,
    651                                           Node* control_dependency)
    652     : builder_(builder),
    653       parameters_count_(scope->num_parameters() + 1),
    654       locals_count_(scope->num_stack_slots()),
    655       liveness_block_(IsLivenessAnalysisEnabled()
    656                           ? builder_->liveness_analyzer()->NewBlock()
    657                           : nullptr),
    658       values_(builder_->local_zone()),
    659       contexts_(builder_->local_zone()),
    660       control_dependency_(control_dependency),
    661       effect_dependency_(control_dependency),
    662       parameters_node_(nullptr),
    663       locals_node_(nullptr),
    664       stack_node_(nullptr) {
    665   DCHECK_EQ(scope->num_parameters() + 1, parameters_count());
    666 
    667   // Bind the receiver variable.
    668   int param_num = 0;
    669   if (builder->info()->is_this_defined()) {
    670     const Operator* op = common()->Parameter(param_num++, "%this");
    671     Node* receiver = builder->graph()->NewNode(op, builder->graph()->start());
    672     values()->push_back(receiver);
    673   } else {
    674     values()->push_back(builder->jsgraph()->UndefinedConstant());
    675   }
    676 
    677   // Bind all parameter variables. The parameter indices are shifted by 1
    678   // (receiver is variable index -1 but {Parameter} node index 0 and located at
    679   // index 0 in the environment).
    680   for (int i = 0; i < scope->num_parameters(); ++i) {
    681     const char* debug_name = GetDebugParameterName(graph()->zone(), scope, i);
    682     const Operator* op = common()->Parameter(param_num++, debug_name);
    683     Node* parameter = builder->graph()->NewNode(op, builder->graph()->start());
    684     values()->push_back(parameter);
    685   }
    686 
    687   // Bind all local variables to undefined.
    688   Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
    689   values()->insert(values()->end(), locals_count(), undefined_constant);
    690 }
    691 
    692 
    693 AstGraphBuilder::Environment::Environment(AstGraphBuilder::Environment* copy,
    694                                           LivenessAnalyzerBlock* liveness_block)
    695     : builder_(copy->builder_),
    696       parameters_count_(copy->parameters_count_),
    697       locals_count_(copy->locals_count_),
    698       liveness_block_(liveness_block),
    699       values_(copy->zone()),
    700       contexts_(copy->zone()),
    701       control_dependency_(copy->control_dependency_),
    702       effect_dependency_(copy->effect_dependency_),
    703       parameters_node_(copy->parameters_node_),
    704       locals_node_(copy->locals_node_),
    705       stack_node_(copy->stack_node_) {
    706   const size_t kStackEstimate = 7;  // optimum from experimentation!
    707   values_.reserve(copy->values_.size() + kStackEstimate);
    708   values_.insert(values_.begin(), copy->values_.begin(), copy->values_.end());
    709   contexts_.reserve(copy->contexts_.size());
    710   contexts_.insert(contexts_.begin(), copy->contexts_.begin(),
    711                    copy->contexts_.end());
    712 }
    713 
    714 
    715 void AstGraphBuilder::Environment::Bind(Variable* variable, Node* node) {
    716   DCHECK(variable->IsStackAllocated());
    717   if (variable->IsParameter()) {
    718     // The parameter indices are shifted by 1 (receiver is variable
    719     // index -1 but located at index 0 in the environment).
    720     values()->at(variable->index() + 1) = node;
    721   } else {
    722     DCHECK(variable->IsStackLocal());
    723     values()->at(variable->index() + parameters_count_) = node;
    724     DCHECK(IsLivenessBlockConsistent());
    725     if (liveness_block() != nullptr) {
    726       liveness_block()->Bind(variable->index());
    727     }
    728   }
    729 }
    730 
    731 
    732 Node* AstGraphBuilder::Environment::Lookup(Variable* variable) {
    733   DCHECK(variable->IsStackAllocated());
    734   if (variable->IsParameter()) {
    735     // The parameter indices are shifted by 1 (receiver is variable
    736     // index -1 but located at index 0 in the environment).
    737     return values()->at(variable->index() + 1);
    738   } else {
    739     DCHECK(variable->IsStackLocal());
    740     DCHECK(IsLivenessBlockConsistent());
    741     if (liveness_block() != nullptr) {
    742       liveness_block()->Lookup(variable->index());
    743     }
    744     return values()->at(variable->index() + parameters_count_);
    745   }
    746 }
    747 
    748 
    749 void AstGraphBuilder::Environment::MarkAllLocalsLive() {
    750   DCHECK(IsLivenessBlockConsistent());
    751   if (liveness_block() != nullptr) {
    752     for (int i = 0; i < locals_count_; i++) {
    753       liveness_block()->Lookup(i);
    754     }
    755   }
    756 }
    757 
    758 
    759 void AstGraphBuilder::Environment::RawParameterBind(int index, Node* node) {
    760   DCHECK_LT(index, parameters_count());
    761   values()->at(index) = node;
    762 }
    763 
    764 
    765 Node* AstGraphBuilder::Environment::RawParameterLookup(int index) {
    766   DCHECK_LT(index, parameters_count());
    767   return values()->at(index);
    768 }
    769 
    770 
    771 AstGraphBuilder::Environment*
    772 AstGraphBuilder::Environment::CopyForConditional() {
    773   LivenessAnalyzerBlock* copy_liveness_block = nullptr;
    774   if (liveness_block() != nullptr) {
    775     copy_liveness_block =
    776         builder_->liveness_analyzer()->NewBlock(liveness_block());
    777     liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block());
    778   }
    779   return new (zone()) Environment(this, copy_liveness_block);
    780 }
    781 
    782 
    783 AstGraphBuilder::Environment*
    784 AstGraphBuilder::Environment::CopyAsUnreachable() {
    785   Environment* env = new (zone()) Environment(this, nullptr);
    786   env->MarkAsUnreachable();
    787   return env;
    788 }
    789 
    790 AstGraphBuilder::Environment* AstGraphBuilder::Environment::CopyForOsrEntry() {
    791   LivenessAnalyzerBlock* copy_block =
    792       liveness_block() == nullptr ? nullptr
    793                                   : builder_->liveness_analyzer()->NewBlock();
    794   return new (zone()) Environment(this, copy_block);
    795 }
    796 
    797 AstGraphBuilder::Environment*
    798 AstGraphBuilder::Environment::CopyAndShareLiveness() {
    799   if (liveness_block() != nullptr) {
    800     // Finish the current liveness block before copying.
    801     liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block());
    802   }
    803   Environment* env = new (zone()) Environment(this, liveness_block());
    804   return env;
    805 }
    806 
    807 
    808 AstGraphBuilder::Environment* AstGraphBuilder::Environment::CopyForLoop(
    809     BitVector* assigned, bool is_osr) {
    810   PrepareForLoop(assigned);
    811   Environment* loop = CopyAndShareLiveness();
    812   if (is_osr) {
    813     // Create and merge the OSR entry if necessary.
    814     Environment* osr_env = CopyForOsrEntry();
    815     osr_env->PrepareForOsrEntry();
    816     loop->Merge(osr_env);
    817   }
    818   return loop;
    819 }
    820 
    821 
    822 void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values,
    823                                                      int offset, int count) {
    824   bool should_update = false;
    825   Node** env_values = (count == 0) ? nullptr : &values()->at(offset);
    826   if (*state_values == nullptr || (*state_values)->InputCount() != count) {
    827     should_update = true;
    828   } else {
    829     DCHECK(static_cast<size_t>(offset + count) <= values()->size());
    830     for (int i = 0; i < count; i++) {
    831       if ((*state_values)->InputAt(i) != env_values[i]) {
    832         should_update = true;
    833         break;
    834       }
    835     }
    836   }
    837   if (should_update) {
    838     const Operator* op = common()->StateValues(count);
    839     (*state_values) = graph()->NewNode(op, count, env_values);
    840   }
    841 }
    842 
    843 
    844 Node* AstGraphBuilder::Environment::Checkpoint(BailoutId ast_id,
    845                                                OutputFrameStateCombine combine,
    846                                                bool owner_has_exception) {
    847   if (!builder()->info()->is_deoptimization_enabled()) {
    848     return builder()->GetEmptyFrameState();
    849   }
    850 
    851   UpdateStateValues(&parameters_node_, 0, parameters_count());
    852   UpdateStateValues(&locals_node_, parameters_count(), locals_count());
    853   UpdateStateValues(&stack_node_, parameters_count() + locals_count(),
    854                     stack_height());
    855 
    856   const Operator* op = common()->FrameState(
    857       ast_id, combine, builder()->frame_state_function_info());
    858 
    859   Node* result = graph()->NewNode(op, parameters_node_, locals_node_,
    860                                   stack_node_, builder()->current_context(),
    861                                   builder()->GetFunctionClosure(),
    862                                   builder()->graph()->start());
    863 
    864   DCHECK(IsLivenessBlockConsistent());
    865   if (liveness_block() != nullptr) {
    866     // If the owning node has an exception, register the checkpoint to the
    867     // predecessor so that the checkpoint is used for both the normal and the
    868     // exceptional paths. Yes, this is a terrible hack and we might want
    869     // to use an explicit frame state for the exceptional path.
    870     if (owner_has_exception) {
    871       liveness_block()->GetPredecessor()->Checkpoint(result);
    872     } else {
    873       liveness_block()->Checkpoint(result);
    874     }
    875   }
    876   return result;
    877 }
    878 
    879 void AstGraphBuilder::Environment::PrepareForLoopExit(
    880     Node* loop, BitVector* assigned_variables) {
    881   if (IsMarkedAsUnreachable()) return;
    882 
    883   DCHECK_EQ(loop->opcode(), IrOpcode::kLoop);
    884 
    885   Node* control = GetControlDependency();
    886 
    887   // Create the loop exit node.
    888   Node* loop_exit = graph()->NewNode(common()->LoopExit(), control, loop);
    889   UpdateControlDependency(loop_exit);
    890 
    891   // Rename the environmnent values.
    892   for (size_t i = 0; i < values()->size(); i++) {
    893     if (assigned_variables == nullptr ||
    894         static_cast<int>(i) >= assigned_variables->length() ||
    895         assigned_variables->Contains(static_cast<int>(i))) {
    896       Node* rename = graph()->NewNode(common()->LoopExitValue(), (*values())[i],
    897                                       loop_exit);
    898       (*values())[i] = rename;
    899     }
    900   }
    901 
    902   // Rename the effect.
    903   Node* effect_rename = graph()->NewNode(common()->LoopExitEffect(),
    904                                          GetEffectDependency(), loop_exit);
    905   UpdateEffectDependency(effect_rename);
    906 }
    907 
    908 bool AstGraphBuilder::Environment::IsLivenessAnalysisEnabled() {
    909   return FLAG_analyze_environment_liveness &&
    910          builder()->info()->is_deoptimization_enabled();
    911 }
    912 
    913 
    914 bool AstGraphBuilder::Environment::IsLivenessBlockConsistent() {
    915   return (!IsLivenessAnalysisEnabled() || IsMarkedAsUnreachable()) ==
    916          (liveness_block() == nullptr);
    917 }
    918 
    919 
    920 AstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own,
    921                                         Expression::Context kind)
    922     : kind_(kind), owner_(own), outer_(own->ast_context()) {
    923   owner()->set_ast_context(this);  // Push.
    924 #ifdef DEBUG
    925   original_height_ = environment()->stack_height();
    926 #endif
    927 }
    928 
    929 
    930 AstGraphBuilder::AstContext::~AstContext() {
    931   owner()->set_ast_context(outer_);  // Pop.
    932 }
    933 
    934 
    935 AstGraphBuilder::AstEffectContext::~AstEffectContext() {
    936   DCHECK(environment()->stack_height() == original_height_);
    937 }
    938 
    939 
    940 AstGraphBuilder::AstValueContext::~AstValueContext() {
    941   DCHECK(environment()->stack_height() == original_height_ + 1);
    942 }
    943 
    944 
    945 AstGraphBuilder::AstTestContext::~AstTestContext() {
    946   DCHECK(environment()->stack_height() == original_height_ + 1);
    947 }
    948 
    949 void AstGraphBuilder::AstEffectContext::ProduceValue(Expression* expr,
    950                                                      Node* value) {
    951   // The value is ignored.
    952   owner()->PrepareEagerCheckpoint(expr->id());
    953 }
    954 
    955 void AstGraphBuilder::AstValueContext::ProduceValue(Expression* expr,
    956                                                     Node* value) {
    957   environment()->Push(value);
    958   owner()->PrepareEagerCheckpoint(expr->id());
    959 }
    960 
    961 void AstGraphBuilder::AstTestContext::ProduceValue(Expression* expr,
    962                                                    Node* value) {
    963   environment()->Push(owner()->BuildToBoolean(value, feedback_id_));
    964   owner()->PrepareEagerCheckpoint(expr->id());
    965 }
    966 
    967 
    968 Node* AstGraphBuilder::AstEffectContext::ConsumeValue() { return nullptr; }
    969 
    970 
    971 Node* AstGraphBuilder::AstValueContext::ConsumeValue() {
    972   return environment()->Pop();
    973 }
    974 
    975 
    976 Node* AstGraphBuilder::AstTestContext::ConsumeValue() {
    977   return environment()->Pop();
    978 }
    979 
    980 
    981 Scope* AstGraphBuilder::current_scope() const {
    982   return execution_context_->scope();
    983 }
    984 
    985 
    986 Node* AstGraphBuilder::current_context() const {
    987   return environment()->Context();
    988 }
    989 
    990 
    991 void AstGraphBuilder::ControlScope::PerformCommand(Command command,
    992                                                    Statement* target,
    993                                                    Node* value) {
    994   Environment* env = environment()->CopyAsUnreachable();
    995   ControlScope* current = this;
    996   while (current != nullptr) {
    997     environment()->TrimStack(current->stack_height());
    998     environment()->TrimContextChain(current->context_length());
    999     if (current->Execute(command, target, &value)) break;
   1000     current = current->outer_;
   1001   }
   1002   builder()->set_environment(env);
   1003   DCHECK_NOT_NULL(current);  // Always handled (unless stack is malformed).
   1004 }
   1005 
   1006 
   1007 void AstGraphBuilder::ControlScope::BreakTo(BreakableStatement* stmt) {
   1008   PerformCommand(CMD_BREAK, stmt, builder()->jsgraph()->TheHoleConstant());
   1009 }
   1010 
   1011 
   1012 void AstGraphBuilder::ControlScope::ContinueTo(BreakableStatement* stmt) {
   1013   PerformCommand(CMD_CONTINUE, stmt, builder()->jsgraph()->TheHoleConstant());
   1014 }
   1015 
   1016 
   1017 void AstGraphBuilder::ControlScope::ReturnValue(Node* return_value) {
   1018   PerformCommand(CMD_RETURN, nullptr, return_value);
   1019 }
   1020 
   1021 
   1022 void AstGraphBuilder::ControlScope::ThrowValue(Node* exception_value) {
   1023   PerformCommand(CMD_THROW, nullptr, exception_value);
   1024 }
   1025 
   1026 
   1027 void AstGraphBuilder::VisitForValueOrNull(Expression* expr) {
   1028   if (expr == nullptr) {
   1029     return environment()->Push(jsgraph()->NullConstant());
   1030   }
   1031   VisitForValue(expr);
   1032 }
   1033 
   1034 
   1035 void AstGraphBuilder::VisitForValueOrTheHole(Expression* expr) {
   1036   if (expr == nullptr) {
   1037     return environment()->Push(jsgraph()->TheHoleConstant());
   1038   }
   1039   VisitForValue(expr);
   1040 }
   1041 
   1042 
   1043 void AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) {
   1044   for (int i = 0; i < exprs->length(); ++i) {
   1045     VisitForValue(exprs->at(i));
   1046   }
   1047 }
   1048 
   1049 
   1050 void AstGraphBuilder::VisitForValue(Expression* expr) {
   1051   AstValueContext for_value(this);
   1052   if (!CheckStackOverflow()) {
   1053     VisitNoStackOverflowCheck(expr);
   1054   } else {
   1055     ast_context()->ProduceValue(expr, jsgraph()->UndefinedConstant());
   1056   }
   1057 }
   1058 
   1059 
   1060 void AstGraphBuilder::VisitForEffect(Expression* expr) {
   1061   AstEffectContext for_effect(this);
   1062   if (!CheckStackOverflow()) {
   1063     VisitNoStackOverflowCheck(expr);
   1064   } else {
   1065     ast_context()->ProduceValue(expr, jsgraph()->UndefinedConstant());
   1066   }
   1067 }
   1068 
   1069 
   1070 void AstGraphBuilder::VisitForTest(Expression* expr) {
   1071   AstTestContext for_condition(this, expr->test_id());
   1072   if (!CheckStackOverflow()) {
   1073     VisitNoStackOverflowCheck(expr);
   1074   } else {
   1075     ast_context()->ProduceValue(expr, jsgraph()->UndefinedConstant());
   1076   }
   1077 }
   1078 
   1079 
   1080 void AstGraphBuilder::Visit(Expression* expr) {
   1081   // Reuses enclosing AstContext.
   1082   if (!CheckStackOverflow()) {
   1083     VisitNoStackOverflowCheck(expr);
   1084   } else {
   1085     ast_context()->ProduceValue(expr, jsgraph()->UndefinedConstant());
   1086   }
   1087 }
   1088 
   1089 
   1090 void AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) {
   1091   Variable* variable = decl->proxy()->var();
   1092   switch (variable->location()) {
   1093     case VariableLocation::UNALLOCATED: {
   1094       DCHECK(!variable->binding_needs_init());
   1095       FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot();
   1096       DCHECK(!slot.IsInvalid());
   1097       globals()->push_back(handle(Smi::FromInt(slot.ToInt()), isolate()));
   1098       globals()->push_back(isolate()->factory()->undefined_value());
   1099       break;
   1100     }
   1101     case VariableLocation::PARAMETER:
   1102     case VariableLocation::LOCAL:
   1103       if (variable->binding_needs_init()) {
   1104         Node* value = jsgraph()->TheHoleConstant();
   1105         environment()->Bind(variable, value);
   1106       }
   1107       break;
   1108     case VariableLocation::CONTEXT:
   1109       if (variable->binding_needs_init()) {
   1110         Node* value = jsgraph()->TheHoleConstant();
   1111         const Operator* op = javascript()->StoreContext(0, variable->index());
   1112         NewNode(op, current_context(), value);
   1113       }
   1114       break;
   1115     case VariableLocation::LOOKUP: {
   1116       DCHECK(!variable->binding_needs_init());
   1117       Node* name = jsgraph()->Constant(variable->name());
   1118       const Operator* op = javascript()->CallRuntime(Runtime::kDeclareEvalVar);
   1119       Node* store = NewNode(op, name);
   1120       PrepareFrameState(store, decl->proxy()->id());
   1121       break;
   1122     }
   1123     case VariableLocation::MODULE:
   1124       UNREACHABLE();
   1125   }
   1126 }
   1127 
   1128 
   1129 void AstGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) {
   1130   Variable* variable = decl->proxy()->var();
   1131   switch (variable->location()) {
   1132     case VariableLocation::UNALLOCATED: {
   1133       Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
   1134           decl->fun(), info()->script(), info());
   1135       // Check for stack-overflow exception.
   1136       if (function.is_null()) return SetStackOverflow();
   1137       FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot();
   1138       DCHECK(!slot.IsInvalid());
   1139       globals()->push_back(handle(Smi::FromInt(slot.ToInt()), isolate()));
   1140       globals()->push_back(function);
   1141       break;
   1142     }
   1143     case VariableLocation::PARAMETER:
   1144     case VariableLocation::LOCAL: {
   1145       VisitForValue(decl->fun());
   1146       Node* value = environment()->Pop();
   1147       environment()->Bind(variable, value);
   1148       break;
   1149     }
   1150     case VariableLocation::CONTEXT: {
   1151       VisitForValue(decl->fun());
   1152       Node* value = environment()->Pop();
   1153       const Operator* op = javascript()->StoreContext(0, variable->index());
   1154       NewNode(op, current_context(), value);
   1155       break;
   1156     }
   1157     case VariableLocation::LOOKUP: {
   1158       VisitForValue(decl->fun());
   1159       Node* value = environment()->Pop();
   1160       Node* name = jsgraph()->Constant(variable->name());
   1161       const Operator* op =
   1162           javascript()->CallRuntime(Runtime::kDeclareEvalFunction);
   1163       Node* store = NewNode(op, name, value);
   1164       PrepareFrameState(store, decl->proxy()->id());
   1165       break;
   1166     }
   1167     case VariableLocation::MODULE:
   1168       UNREACHABLE();
   1169   }
   1170 }
   1171 
   1172 
   1173 void AstGraphBuilder::VisitBlock(Block* stmt) {
   1174   BlockBuilder block(this);
   1175   ControlScopeForBreakable scope(this, stmt, &block);
   1176   if (stmt->labels() != nullptr) block.BeginBlock();
   1177   if (stmt->scope() == nullptr) {
   1178     // Visit statements in the same scope, no declarations.
   1179     VisitStatements(stmt->statements());
   1180   } else {
   1181     // Visit declarations and statements in a block scope.
   1182     if (stmt->scope()->NeedsContext()) {
   1183       Node* context = BuildLocalBlockContext(stmt->scope());
   1184       ContextScope scope(this, stmt->scope(), context);
   1185       VisitDeclarations(stmt->scope()->declarations());
   1186       VisitStatements(stmt->statements());
   1187     } else {
   1188       VisitDeclarations(stmt->scope()->declarations());
   1189       VisitStatements(stmt->statements());
   1190     }
   1191   }
   1192   if (stmt->labels() != nullptr) block.EndBlock();
   1193 }
   1194 
   1195 
   1196 void AstGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) {
   1197   VisitForEffect(stmt->expression());
   1198 }
   1199 
   1200 
   1201 void AstGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) {
   1202   // Do nothing.
   1203 }
   1204 
   1205 
   1206 void AstGraphBuilder::VisitSloppyBlockFunctionStatement(
   1207     SloppyBlockFunctionStatement* stmt) {
   1208   Visit(stmt->statement());
   1209 }
   1210 
   1211 
   1212 void AstGraphBuilder::VisitIfStatement(IfStatement* stmt) {
   1213   IfBuilder compare_if(this);
   1214   VisitForTest(stmt->condition());
   1215   Node* condition = environment()->Pop();
   1216   compare_if.If(condition);
   1217   compare_if.Then();
   1218   Visit(stmt->then_statement());
   1219   compare_if.Else();
   1220   Visit(stmt->else_statement());
   1221   compare_if.End();
   1222 }
   1223 
   1224 
   1225 void AstGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) {
   1226   execution_control()->ContinueTo(stmt->target());
   1227 }
   1228 
   1229 
   1230 void AstGraphBuilder::VisitBreakStatement(BreakStatement* stmt) {
   1231   execution_control()->BreakTo(stmt->target());
   1232 }
   1233 
   1234 
   1235 void AstGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
   1236   VisitForValue(stmt->expression());
   1237   Node* result = environment()->Pop();
   1238   execution_control()->ReturnValue(result);
   1239 }
   1240 
   1241 
   1242 void AstGraphBuilder::VisitWithStatement(WithStatement* stmt) {
   1243   VisitForValue(stmt->expression());
   1244   Node* value = environment()->Pop();
   1245   Node* object = BuildToObject(value, stmt->ToObjectId());
   1246   Handle<ScopeInfo> scope_info = stmt->scope()->scope_info();
   1247   const Operator* op = javascript()->CreateWithContext(scope_info);
   1248   Node* context = NewNode(op, object, GetFunctionClosureForContext());
   1249   PrepareFrameState(context, stmt->EntryId());
   1250   VisitInScope(stmt->statement(), stmt->scope(), context);
   1251 }
   1252 
   1253 
   1254 void AstGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
   1255   ZoneList<CaseClause*>* clauses = stmt->cases();
   1256   SwitchBuilder compare_switch(this, clauses->length());
   1257   ControlScopeForBreakable scope(this, stmt, &compare_switch);
   1258   compare_switch.BeginSwitch();
   1259   int default_index = -1;
   1260 
   1261   // Keep the switch value on the stack until a case matches.
   1262   VisitForValue(stmt->tag());
   1263 
   1264   // Iterate over all cases and create nodes for label comparison.
   1265   for (int i = 0; i < clauses->length(); i++) {
   1266     CaseClause* clause = clauses->at(i);
   1267 
   1268     // The default is not a test, remember index.
   1269     if (clause->is_default()) {
   1270       default_index = i;
   1271       continue;
   1272     }
   1273 
   1274     // Create nodes to perform label comparison as if via '==='. The switch
   1275     // value is still on the operand stack while the label is evaluated.
   1276     VisitForValue(clause->label());
   1277     Node* label = environment()->Pop();
   1278     Node* tag = environment()->Top();
   1279 
   1280     CompareOperationHint hint;
   1281     if (!type_hint_analysis_ ||
   1282         !type_hint_analysis_->GetCompareOperationHint(clause->CompareId(),
   1283                                                       &hint)) {
   1284       hint = CompareOperationHint::kAny;
   1285     }
   1286 
   1287     const Operator* op = javascript()->StrictEqual(hint);
   1288     Node* condition = NewNode(op, tag, label);
   1289     compare_switch.BeginLabel(i, condition);
   1290 
   1291     // Discard the switch value at label match.
   1292     environment()->Pop();
   1293     compare_switch.EndLabel();
   1294   }
   1295 
   1296   // Discard the switch value and mark the default case.
   1297   environment()->Pop();
   1298   if (default_index >= 0) {
   1299     compare_switch.DefaultAt(default_index);
   1300   }
   1301 
   1302   // Iterate over all cases and create nodes for case bodies.
   1303   for (int i = 0; i < clauses->length(); i++) {
   1304     CaseClause* clause = clauses->at(i);
   1305     compare_switch.BeginCase(i);
   1306     VisitStatements(clause->statements());
   1307     compare_switch.EndCase();
   1308   }
   1309 
   1310   compare_switch.EndSwitch();
   1311 }
   1312 
   1313 
   1314 void AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
   1315   LoopBuilder while_loop(this);
   1316   while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
   1317   VisitIterationBody(stmt, &while_loop, stmt->StackCheckId());
   1318   while_loop.EndBody();
   1319   VisitForTest(stmt->cond());
   1320   Node* condition = environment()->Pop();
   1321   while_loop.BreakUnless(condition);
   1322   while_loop.EndLoop();
   1323 }
   1324 
   1325 
   1326 void AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
   1327   LoopBuilder while_loop(this);
   1328   while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
   1329   VisitForTest(stmt->cond());
   1330   Node* condition = environment()->Pop();
   1331   while_loop.BreakUnless(condition);
   1332   VisitIterationBody(stmt, &while_loop, stmt->StackCheckId());
   1333   while_loop.EndBody();
   1334   while_loop.EndLoop();
   1335 }
   1336 
   1337 
   1338 void AstGraphBuilder::VisitForStatement(ForStatement* stmt) {
   1339   LoopBuilder for_loop(this);
   1340   VisitIfNotNull(stmt->init());
   1341   for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
   1342   if (stmt->cond() != nullptr) {
   1343     VisitForTest(stmt->cond());
   1344     Node* condition = environment()->Pop();
   1345     for_loop.BreakUnless(condition);
   1346   } else {
   1347     for_loop.BreakUnless(jsgraph()->TrueConstant());
   1348   }
   1349   VisitIterationBody(stmt, &for_loop, stmt->StackCheckId());
   1350   for_loop.EndBody();
   1351   VisitIfNotNull(stmt->next());
   1352   for_loop.EndLoop();
   1353 }
   1354 
   1355 
   1356 void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
   1357   VisitForValue(stmt->subject());
   1358   Node* object = environment()->Pop();
   1359   BlockBuilder for_block(this);
   1360   for_block.BeginBlock();
   1361   // Check for null or undefined before entering loop.
   1362   Node* is_null_cond =
   1363       NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), object,
   1364               jsgraph()->NullConstant());
   1365   for_block.BreakWhen(is_null_cond, BranchHint::kFalse);
   1366   Node* is_undefined_cond =
   1367       NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), object,
   1368               jsgraph()->UndefinedConstant());
   1369   for_block.BreakWhen(is_undefined_cond, BranchHint::kFalse);
   1370   {
   1371     // Convert object to jsobject.
   1372     object = BuildToObject(object, stmt->ToObjectId());
   1373     environment()->Push(object);
   1374 
   1375     // Prepare for-in cache.
   1376     Node* prepare = NewNode(javascript()->ForInPrepare(), object);
   1377     PrepareFrameState(prepare, stmt->PrepareId(),
   1378                       OutputFrameStateCombine::Push(3));
   1379     Node* cache_type = NewNode(common()->Projection(0), prepare);
   1380     Node* cache_array = NewNode(common()->Projection(1), prepare);
   1381     Node* cache_length = NewNode(common()->Projection(2), prepare);
   1382 
   1383     // Construct the rest of the environment.
   1384     environment()->Push(cache_type);
   1385     environment()->Push(cache_array);
   1386     environment()->Push(cache_length);
   1387     environment()->Push(jsgraph()->ZeroConstant());
   1388 
   1389     // Build the actual loop body.
   1390     LoopBuilder for_loop(this);
   1391     for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
   1392     {
   1393       // These stack values are renamed in the case of OSR, so reload them
   1394       // from the environment.
   1395       Node* index = environment()->Peek(0);
   1396       Node* cache_length = environment()->Peek(1);
   1397       Node* cache_array = environment()->Peek(2);
   1398       Node* cache_type = environment()->Peek(3);
   1399       Node* object = environment()->Peek(4);
   1400 
   1401       // Check loop termination condition (we know that the {index} is always
   1402       // in Smi range, so we can just set the hint on the comparison below).
   1403       PrepareEagerCheckpoint(stmt->EntryId());
   1404       Node* exit_cond =
   1405           NewNode(javascript()->LessThan(CompareOperationHint::kSignedSmall),
   1406                   index, cache_length);
   1407       PrepareFrameState(exit_cond, BailoutId::None());
   1408       for_loop.BreakUnless(exit_cond);
   1409 
   1410       // Compute the next enumerated value.
   1411       Node* value = NewNode(javascript()->ForInNext(), object, cache_array,
   1412                             cache_type, index);
   1413       PrepareFrameState(value, stmt->FilterId(),
   1414                         OutputFrameStateCombine::Push());
   1415       IfBuilder test_value(this);
   1416       Node* test_value_cond =
   1417           NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), value,
   1418                   jsgraph()->UndefinedConstant());
   1419       test_value.If(test_value_cond, BranchHint::kFalse);
   1420       test_value.Then();
   1421       test_value.Else();
   1422       {
   1423         environment()->Push(value);
   1424         PrepareEagerCheckpoint(stmt->FilterId());
   1425         value = environment()->Pop();
   1426         // Bind value and do loop body.
   1427         VectorSlotPair feedback =
   1428             CreateVectorSlotPair(stmt->EachFeedbackSlot());
   1429         VisitForInAssignment(stmt->each(), value, feedback,
   1430                              stmt->AssignmentId());
   1431         VisitIterationBody(stmt, &for_loop, stmt->StackCheckId());
   1432       }
   1433       test_value.End();
   1434       for_loop.EndBody();
   1435 
   1436       // Increment counter and continue (we know that the {index} is always
   1437       // in Smi range, so we can just set the hint on the increment below).
   1438       index = environment()->Peek(0);
   1439       PrepareEagerCheckpoint(stmt->IncrementId());
   1440       index = NewNode(javascript()->Add(BinaryOperationHint::kSignedSmall),
   1441                       index, jsgraph()->OneConstant());
   1442       PrepareFrameState(index, BailoutId::None());
   1443       environment()->Poke(0, index);
   1444     }
   1445     for_loop.EndLoop();
   1446     environment()->Drop(5);
   1447   }
   1448   for_block.EndBlock();
   1449 }
   1450 
   1451 
   1452 void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) {
   1453   LoopBuilder for_loop(this);
   1454   VisitForEffect(stmt->assign_iterator());
   1455   for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
   1456   VisitForEffect(stmt->next_result());
   1457   VisitForTest(stmt->result_done());
   1458   Node* condition = environment()->Pop();
   1459   for_loop.BreakWhen(condition);
   1460   VisitForEffect(stmt->assign_each());
   1461   VisitIterationBody(stmt, &for_loop, stmt->StackCheckId());
   1462   for_loop.EndBody();
   1463   for_loop.EndLoop();
   1464 }
   1465 
   1466 
   1467 void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
   1468   TryCatchBuilder try_control(this);
   1469 
   1470   // Evaluate the try-block inside a control scope. This simulates a handler
   1471   // that is intercepting 'throw' control commands.
   1472   try_control.BeginTry();
   1473   {
   1474     ControlScopeForCatch scope(this, stmt, &try_control);
   1475     STATIC_ASSERT(TryBlockConstant::kElementCount == 1);
   1476     environment()->Push(current_context());
   1477     Visit(stmt->try_block());
   1478     environment()->Pop();
   1479   }
   1480   try_control.EndTry();
   1481 
   1482   // If requested, clear message object as we enter the catch block.
   1483   if (stmt->clear_pending_message()) {
   1484     Node* the_hole = jsgraph()->TheHoleConstant();
   1485     NewNode(javascript()->StoreMessage(), the_hole);
   1486   }
   1487 
   1488   // Create a catch scope that binds the exception.
   1489   Node* exception = try_control.GetExceptionNode();
   1490   Handle<String> name = stmt->variable()->name();
   1491   Handle<ScopeInfo> scope_info = stmt->scope()->scope_info();
   1492   const Operator* op = javascript()->CreateCatchContext(name, scope_info);
   1493   Node* context = NewNode(op, exception, GetFunctionClosureForContext());
   1494 
   1495   // Evaluate the catch-block.
   1496   VisitInScope(stmt->catch_block(), stmt->scope(), context);
   1497   try_control.EndCatch();
   1498 }
   1499 
   1500 
   1501 void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
   1502   TryFinallyBuilder try_control(this);
   1503 
   1504   // We keep a record of all paths that enter the finally-block to be able to
   1505   // dispatch to the correct continuation point after the statements in the
   1506   // finally-block have been evaluated.
   1507   //
   1508   // The try-finally construct can enter the finally-block in three ways:
   1509   // 1. By exiting the try-block normally, falling through at the end.
   1510   // 2. By exiting the try-block with a function-local control flow transfer
   1511   //    (i.e. through break/continue/return statements).
   1512   // 3. By exiting the try-block with a thrown exception.
   1513   Node* fallthrough_result = jsgraph()->TheHoleConstant();
   1514   ControlScope::DeferredCommands* commands =
   1515       new (local_zone()) ControlScope::DeferredCommands(this);
   1516 
   1517   // Evaluate the try-block inside a control scope. This simulates a handler
   1518   // that is intercepting all control commands.
   1519   try_control.BeginTry();
   1520   {
   1521     ControlScopeForFinally scope(this, stmt, commands, &try_control);
   1522     STATIC_ASSERT(TryBlockConstant::kElementCount == 1);
   1523     environment()->Push(current_context());
   1524     Visit(stmt->try_block());
   1525     environment()->Pop();
   1526   }
   1527   try_control.EndTry(commands->GetFallThroughToken(), fallthrough_result);
   1528 
   1529   // The result value semantics depend on how the block was entered:
   1530   //  - ReturnStatement: It represents the return value being returned.
   1531   //  - ThrowStatement: It represents the exception being thrown.
   1532   //  - BreakStatement/ContinueStatement: Filled with the hole.
   1533   //  - Falling through into finally-block: Filled with the hole.
   1534   Node* result = try_control.GetResultValueNode();
   1535   Node* token = try_control.GetDispatchTokenNode();
   1536 
   1537   // The result value, dispatch token and message is expected on the operand
   1538   // stack (this is in sync with FullCodeGenerator::EnterFinallyBlock).
   1539   Node* message = NewNode(javascript()->LoadMessage());
   1540   environment()->Push(token);
   1541   environment()->Push(result);
   1542   environment()->Push(message);
   1543 
   1544   // Clear message object as we enter the finally block.
   1545   Node* the_hole = jsgraph()->TheHoleConstant();
   1546   NewNode(javascript()->StoreMessage(), the_hole);
   1547 
   1548   // Evaluate the finally-block.
   1549   Visit(stmt->finally_block());
   1550   try_control.EndFinally();
   1551 
   1552   // The result value, dispatch token and message is restored from the operand
   1553   // stack (this is in sync with FullCodeGenerator::ExitFinallyBlock).
   1554   message = environment()->Pop();
   1555   result = environment()->Pop();
   1556   token = environment()->Pop();
   1557   NewNode(javascript()->StoreMessage(), message);
   1558 
   1559   // Dynamic dispatch after the finally-block.
   1560   commands->ApplyDeferredCommands(token, result);
   1561 }
   1562 
   1563 
   1564 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
   1565   Node* node =
   1566       NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement));
   1567   PrepareFrameState(node, stmt->DebugBreakId());
   1568   environment()->MarkAllLocalsLive();
   1569 }
   1570 
   1571 
   1572 void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
   1573   // Find or build a shared function info.
   1574   Handle<SharedFunctionInfo> shared_info =
   1575       Compiler::GetSharedFunctionInfo(expr, info()->script(), info());
   1576   CHECK(!shared_info.is_null());  // TODO(mstarzinger): Set stack overflow?
   1577 
   1578   // Create node to instantiate a new closure.
   1579   PretenureFlag pretenure = expr->pretenure() ? TENURED : NOT_TENURED;
   1580   const Operator* op = javascript()->CreateClosure(shared_info, pretenure);
   1581   Node* value = NewNode(op);
   1582   ast_context()->ProduceValue(expr, value);
   1583 }
   1584 
   1585 
   1586 void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) {
   1587   VisitForValueOrTheHole(expr->extends());
   1588   VisitForValue(expr->constructor());
   1589 
   1590   // Create node to instantiate a new class.
   1591   Node* constructor = environment()->Pop();
   1592   Node* extends = environment()->Pop();
   1593   Node* start = jsgraph()->Constant(expr->start_position());
   1594   Node* end = jsgraph()->Constant(expr->end_position());
   1595   const Operator* opc = javascript()->CallRuntime(Runtime::kDefineClass);
   1596   Node* literal = NewNode(opc, extends, constructor, start, end);
   1597   PrepareFrameState(literal, expr->CreateLiteralId(),
   1598                     OutputFrameStateCombine::Push());
   1599   environment()->Push(literal);
   1600 
   1601   // Load the "prototype" from the constructor.
   1602   PrepareEagerCheckpoint(expr->CreateLiteralId());
   1603   Handle<Name> name = isolate()->factory()->prototype_string();
   1604   VectorSlotPair pair = CreateVectorSlotPair(expr->PrototypeSlot());
   1605   Node* prototype = BuildNamedLoad(literal, name, pair);
   1606   PrepareFrameState(prototype, expr->PrototypeId(),
   1607                     OutputFrameStateCombine::Push());
   1608   environment()->Push(prototype);
   1609 
   1610   // Create nodes to store method values into the literal.
   1611   for (int i = 0; i < expr->properties()->length(); i++) {
   1612     ClassLiteral::Property* property = expr->properties()->at(i);
   1613     environment()->Push(environment()->Peek(property->is_static() ? 1 : 0));
   1614 
   1615     VisitForValue(property->key());
   1616     Node* name = BuildToName(environment()->Pop(), expr->GetIdForProperty(i));
   1617     environment()->Push(name);
   1618 
   1619     // The static prototype property is read only. We handle the non computed
   1620     // property name case in the parser. Since this is the only case where we
   1621     // need to check for an own read only property we special case this so we do
   1622     // not need to do this for every property.
   1623     if (property->is_static() && property->is_computed_name()) {
   1624       Node* check = BuildThrowIfStaticPrototype(environment()->Pop(),
   1625                                                 expr->GetIdForProperty(i));
   1626       environment()->Push(check);
   1627     }
   1628 
   1629     VisitForValue(property->value());
   1630     Node* value = environment()->Pop();
   1631     Node* key = environment()->Pop();
   1632     Node* receiver = environment()->Pop();
   1633 
   1634     BuildSetHomeObject(value, receiver, property);
   1635 
   1636     switch (property->kind()) {
   1637       case ClassLiteral::Property::METHOD: {
   1638         Node* attr = jsgraph()->Constant(DONT_ENUM);
   1639         Node* set_function_name =
   1640             jsgraph()->Constant(property->NeedsSetFunctionName());
   1641         const Operator* op =
   1642             javascript()->CallRuntime(Runtime::kDefineDataPropertyInLiteral);
   1643         Node* call = NewNode(op, receiver, key, value, attr, set_function_name);
   1644         PrepareFrameState(call, BailoutId::None());
   1645         break;
   1646       }
   1647       case ClassLiteral::Property::GETTER: {
   1648         Node* attr = jsgraph()->Constant(DONT_ENUM);
   1649         const Operator* op = javascript()->CallRuntime(
   1650             Runtime::kDefineGetterPropertyUnchecked, 4);
   1651         NewNode(op, receiver, key, value, attr);
   1652         break;
   1653       }
   1654       case ClassLiteral::Property::SETTER: {
   1655         Node* attr = jsgraph()->Constant(DONT_ENUM);
   1656         const Operator* op = javascript()->CallRuntime(
   1657             Runtime::kDefineSetterPropertyUnchecked, 4);
   1658         NewNode(op, receiver, key, value, attr);
   1659         break;
   1660       }
   1661       case ClassLiteral::Property::FIELD: {
   1662         UNREACHABLE();
   1663         break;
   1664       }
   1665     }
   1666   }
   1667 
   1668   // Set the constructor to have fast properties.
   1669   prototype = environment()->Pop();
   1670   literal = environment()->Pop();
   1671   const Operator* op = javascript()->CallRuntime(Runtime::kToFastProperties);
   1672   literal = NewNode(op, literal);
   1673 
   1674   // Assign to class variable.
   1675   if (expr->class_variable_proxy() != nullptr) {
   1676     Variable* var = expr->class_variable_proxy()->var();
   1677     VectorSlotPair feedback = CreateVectorSlotPair(
   1678         expr->NeedsProxySlot() ? expr->ProxySlot()
   1679                                : FeedbackVectorSlot::Invalid());
   1680     BuildVariableAssignment(var, literal, Token::INIT, feedback,
   1681                             BailoutId::None());
   1682   }
   1683   ast_context()->ProduceValue(expr, literal);
   1684 }
   1685 
   1686 
   1687 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
   1688   UNREACHABLE();
   1689 }
   1690 
   1691 
   1692 void AstGraphBuilder::VisitDoExpression(DoExpression* expr) {
   1693   VisitBlock(expr->block());
   1694   VisitVariableProxy(expr->result());
   1695   ast_context()->ReplaceValue(expr);
   1696 }
   1697 
   1698 
   1699 void AstGraphBuilder::VisitConditional(Conditional* expr) {
   1700   IfBuilder compare_if(this);
   1701   VisitForTest(expr->condition());
   1702   Node* condition = environment()->Pop();
   1703   compare_if.If(condition);
   1704   compare_if.Then();
   1705   Visit(expr->then_expression());
   1706   compare_if.Else();
   1707   Visit(expr->else_expression());
   1708   compare_if.End();
   1709   // Skip plugging AST evaluation contexts of the test kind. This is to stay in
   1710   // sync with full codegen which doesn't prepare the proper bailout point (see
   1711   // the implementation of FullCodeGenerator::VisitForControl).
   1712   if (ast_context()->IsTest()) return;
   1713   ast_context()->ReplaceValue(expr);
   1714 }
   1715 
   1716 
   1717 void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
   1718   VectorSlotPair pair = CreateVectorSlotPair(expr->VariableFeedbackSlot());
   1719   PrepareEagerCheckpoint(BeforeId(expr));
   1720   Node* value = BuildVariableLoad(expr->var(), expr->id(), pair,
   1721                                   ast_context()->GetStateCombine());
   1722   ast_context()->ProduceValue(expr, value);
   1723 }
   1724 
   1725 
   1726 void AstGraphBuilder::VisitLiteral(Literal* expr) {
   1727   Node* value = jsgraph()->Constant(expr->value());
   1728   ast_context()->ProduceValue(expr, value);
   1729 }
   1730 
   1731 
   1732 void AstGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
   1733   Node* closure = GetFunctionClosure();
   1734 
   1735   // Create node to materialize a regular expression literal.
   1736   const Operator* op = javascript()->CreateLiteralRegExp(
   1737       expr->pattern(), expr->flags(), expr->literal_index());
   1738   Node* literal = NewNode(op, closure);
   1739   PrepareFrameState(literal, expr->id(), ast_context()->GetStateCombine());
   1740   ast_context()->ProduceValue(expr, literal);
   1741 }
   1742 
   1743 
   1744 void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
   1745   Node* closure = GetFunctionClosure();
   1746 
   1747   // Create node to deep-copy the literal boilerplate.
   1748   const Operator* op = javascript()->CreateLiteralObject(
   1749       expr->constant_properties(), expr->ComputeFlags(true),
   1750       expr->literal_index(), expr->properties_count());
   1751   Node* literal = NewNode(op, closure);
   1752   PrepareFrameState(literal, expr->CreateLiteralId(),
   1753                     OutputFrameStateCombine::Push());
   1754 
   1755   // The object is expected on the operand stack during computation of the
   1756   // property values and is the value of the entire expression.
   1757   environment()->Push(literal);
   1758 
   1759   // Create nodes to store computed values into the literal.
   1760   int property_index = 0;
   1761   AccessorTable accessor_table(local_zone());
   1762   for (; property_index < expr->properties()->length(); property_index++) {
   1763     ObjectLiteral::Property* property = expr->properties()->at(property_index);
   1764     if (property->is_computed_name()) break;
   1765     if (property->IsCompileTimeValue()) continue;
   1766 
   1767     Literal* key = property->key()->AsLiteral();
   1768     switch (property->kind()) {
   1769       case ObjectLiteral::Property::CONSTANT:
   1770         UNREACHABLE();
   1771       case ObjectLiteral::Property::MATERIALIZED_LITERAL:
   1772         DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
   1773       // Fall through.
   1774       case ObjectLiteral::Property::COMPUTED: {
   1775         // It is safe to use [[Put]] here because the boilerplate already
   1776         // contains computed properties with an uninitialized value.
   1777         if (key->IsStringLiteral()) {
   1778           DCHECK(key->IsPropertyName());
   1779           if (property->emit_store()) {
   1780             VisitForValue(property->value());
   1781             Node* value = environment()->Pop();
   1782             Node* literal = environment()->Top();
   1783             Handle<Name> name = key->AsPropertyName();
   1784             VectorSlotPair feedback =
   1785                 CreateVectorSlotPair(property->GetSlot(0));
   1786             Node* store = BuildNamedStore(literal, name, value, feedback);
   1787             PrepareFrameState(store, key->id(),
   1788                               OutputFrameStateCombine::Ignore());
   1789             BuildSetHomeObject(value, literal, property, 1);
   1790           } else {
   1791             VisitForEffect(property->value());
   1792           }
   1793           break;
   1794         }
   1795         environment()->Push(environment()->Top());  // Duplicate receiver.
   1796         VisitForValue(property->key());
   1797         VisitForValue(property->value());
   1798         Node* value = environment()->Pop();
   1799         Node* key = environment()->Pop();
   1800         Node* receiver = environment()->Pop();
   1801         if (property->emit_store()) {
   1802           Node* language = jsgraph()->Constant(SLOPPY);
   1803           const Operator* op = javascript()->CallRuntime(Runtime::kSetProperty);
   1804           Node* set_property = NewNode(op, receiver, key, value, language);
   1805           // SetProperty should not lazy deopt on an object literal.
   1806           PrepareFrameState(set_property, BailoutId::None());
   1807           BuildSetHomeObject(value, receiver, property);
   1808         }
   1809         break;
   1810       }
   1811       case ObjectLiteral::Property::PROTOTYPE: {
   1812         environment()->Push(environment()->Top());  // Duplicate receiver.
   1813         VisitForValue(property->value());
   1814         Node* value = environment()->Pop();
   1815         Node* receiver = environment()->Pop();
   1816         DCHECK(property->emit_store());
   1817         const Operator* op =
   1818             javascript()->CallRuntime(Runtime::kInternalSetPrototype);
   1819         Node* set_prototype = NewNode(op, receiver, value);
   1820         // SetPrototype should not lazy deopt on an object literal.
   1821         PrepareFrameState(set_prototype,
   1822                           expr->GetIdForPropertySet(property_index));
   1823         break;
   1824       }
   1825       case ObjectLiteral::Property::GETTER:
   1826         if (property->emit_store()) {
   1827           AccessorTable::Iterator it = accessor_table.lookup(key);
   1828           it->second->bailout_id = expr->GetIdForPropertySet(property_index);
   1829           it->second->getter = property;
   1830         }
   1831         break;
   1832       case ObjectLiteral::Property::SETTER:
   1833         if (property->emit_store()) {
   1834           AccessorTable::Iterator it = accessor_table.lookup(key);
   1835           it->second->bailout_id = expr->GetIdForPropertySet(property_index);
   1836           it->second->setter = property;
   1837         }
   1838         break;
   1839     }
   1840   }
   1841 
   1842   // Create nodes to define accessors, using only a single call to the runtime
   1843   // for each pair of corresponding getters and setters.
   1844   literal = environment()->Top();  // Reload from operand stack.
   1845   for (AccessorTable::Iterator it = accessor_table.begin();
   1846        it != accessor_table.end(); ++it) {
   1847     VisitForValue(it->first);
   1848     VisitObjectLiteralAccessor(literal, it->second->getter);
   1849     VisitObjectLiteralAccessor(literal, it->second->setter);
   1850     Node* setter = environment()->Pop();
   1851     Node* getter = environment()->Pop();
   1852     Node* name = environment()->Pop();
   1853     Node* attr = jsgraph()->Constant(NONE);
   1854     const Operator* op =
   1855         javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked);
   1856     Node* call = NewNode(op, literal, name, getter, setter, attr);
   1857     PrepareFrameState(call, it->second->bailout_id);
   1858   }
   1859 
   1860   // Object literals have two parts. The "static" part on the left contains no
   1861   // computed property names, and so we can compute its map ahead of time; see
   1862   // Runtime_CreateObjectLiteralBoilerplate. The second "dynamic" part starts
   1863   // with the first computed property name and continues with all properties to
   1864   // its right. All the code from above initializes the static component of the
   1865   // object literal, and arranges for the map of the result to reflect the
   1866   // static order in which the keys appear. For the dynamic properties, we
   1867   // compile them into a series of "SetOwnProperty" runtime calls. This will
   1868   // preserve insertion order.
   1869   for (; property_index < expr->properties()->length(); property_index++) {
   1870     ObjectLiteral::Property* property = expr->properties()->at(property_index);
   1871 
   1872     if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
   1873       environment()->Push(environment()->Top());  // Duplicate receiver.
   1874       VisitForValue(property->value());
   1875       Node* value = environment()->Pop();
   1876       Node* receiver = environment()->Pop();
   1877       const Operator* op =
   1878           javascript()->CallRuntime(Runtime::kInternalSetPrototype);
   1879       Node* call = NewNode(op, receiver, value);
   1880       PrepareFrameState(call, expr->GetIdForPropertySet(property_index));
   1881       continue;
   1882     }
   1883 
   1884     environment()->Push(environment()->Top());  // Duplicate receiver.
   1885     VisitForValue(property->key());
   1886     Node* name = BuildToName(environment()->Pop(),
   1887                              expr->GetIdForPropertyName(property_index));
   1888     environment()->Push(name);
   1889     VisitForValue(property->value());
   1890     Node* value = environment()->Pop();
   1891     Node* key = environment()->Pop();
   1892     Node* receiver = environment()->Pop();
   1893     BuildSetHomeObject(value, receiver, property);
   1894     switch (property->kind()) {
   1895       case ObjectLiteral::Property::CONSTANT:
   1896       case ObjectLiteral::Property::COMPUTED:
   1897       case ObjectLiteral::Property::MATERIALIZED_LITERAL: {
   1898         if (!property->emit_store()) continue;
   1899         Node* attr = jsgraph()->Constant(NONE);
   1900         Node* set_function_name =
   1901             jsgraph()->Constant(property->NeedsSetFunctionName());
   1902         const Operator* op =
   1903             javascript()->CallRuntime(Runtime::kDefineDataPropertyInLiteral);
   1904         Node* call = NewNode(op, receiver, key, value, attr, set_function_name);
   1905         PrepareFrameState(call, expr->GetIdForPropertySet(property_index));
   1906         break;
   1907       }
   1908       case ObjectLiteral::Property::PROTOTYPE:
   1909         UNREACHABLE();  // Handled specially above.
   1910         break;
   1911       case ObjectLiteral::Property::GETTER: {
   1912         Node* attr = jsgraph()->Constant(NONE);
   1913         const Operator* op = javascript()->CallRuntime(
   1914             Runtime::kDefineGetterPropertyUnchecked, 4);
   1915         Node* call = NewNode(op, receiver, key, value, attr);
   1916         PrepareFrameState(call, BailoutId::None());
   1917         break;
   1918       }
   1919       case ObjectLiteral::Property::SETTER: {
   1920         Node* attr = jsgraph()->Constant(NONE);
   1921         const Operator* op = javascript()->CallRuntime(
   1922             Runtime::kDefineSetterPropertyUnchecked, 4);
   1923         Node* call = NewNode(op, receiver, key, value, attr);
   1924         PrepareFrameState(call, BailoutId::None());
   1925         break;
   1926       }
   1927     }
   1928   }
   1929 
   1930   ast_context()->ProduceValue(expr, environment()->Pop());
   1931 }
   1932 
   1933 
   1934 void AstGraphBuilder::VisitObjectLiteralAccessor(
   1935     Node* home_object, ObjectLiteralProperty* property) {
   1936   if (property == nullptr) {
   1937     VisitForValueOrNull(nullptr);
   1938   } else {
   1939     VisitForValue(property->value());
   1940     BuildSetHomeObject(environment()->Top(), home_object, property);
   1941   }
   1942 }
   1943 
   1944 
   1945 void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
   1946   Node* closure = GetFunctionClosure();
   1947 
   1948   // Create node to deep-copy the literal boilerplate.
   1949   const Operator* op = javascript()->CreateLiteralArray(
   1950       expr->constant_elements(), expr->ComputeFlags(true),
   1951       expr->literal_index(), expr->values()->length());
   1952   Node* literal = NewNode(op, closure);
   1953   PrepareFrameState(literal, expr->CreateLiteralId(),
   1954                     OutputFrameStateCombine::Push());
   1955 
   1956   // The array is expected on the operand stack during computation of the
   1957   // element values.
   1958   environment()->Push(literal);
   1959 
   1960   // Create nodes to evaluate all the non-constant subexpressions and to store
   1961   // them into the newly cloned array.
   1962   for (int array_index = 0; array_index < expr->values()->length();
   1963        array_index++) {
   1964     Expression* subexpr = expr->values()->at(array_index);
   1965     DCHECK(!subexpr->IsSpread());
   1966     if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
   1967 
   1968     VisitForValue(subexpr);
   1969     VectorSlotPair pair = CreateVectorSlotPair(expr->LiteralFeedbackSlot());
   1970     Node* value = environment()->Pop();
   1971     Node* index = jsgraph()->Constant(array_index);
   1972     Node* literal = environment()->Top();
   1973     Node* store = BuildKeyedStore(literal, index, value, pair);
   1974     PrepareFrameState(store, expr->GetIdForElement(array_index),
   1975                       OutputFrameStateCombine::Ignore());
   1976   }
   1977 
   1978   ast_context()->ProduceValue(expr, environment()->Pop());
   1979 }
   1980 
   1981 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value,
   1982                                            const VectorSlotPair& feedback,
   1983                                            BailoutId bailout_id) {
   1984   DCHECK(expr->IsValidReferenceExpressionOrThis());
   1985 
   1986   // Left-hand side can only be a property, a global or a variable slot.
   1987   Property* property = expr->AsProperty();
   1988   LhsKind assign_type = Property::GetAssignType(property);
   1989 
   1990   // Evaluate LHS expression and store the value.
   1991   switch (assign_type) {
   1992     case VARIABLE: {
   1993       Variable* var = expr->AsVariableProxy()->var();
   1994       BuildVariableAssignment(var, value, Token::ASSIGN, feedback, bailout_id);
   1995       break;
   1996     }
   1997     case NAMED_PROPERTY: {
   1998       environment()->Push(value);
   1999       VisitForValue(property->obj());
   2000       Node* object = environment()->Pop();
   2001       value = environment()->Pop();
   2002       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2003       Node* store = BuildNamedStore(object, name, value, feedback);
   2004       PrepareFrameState(store, bailout_id, OutputFrameStateCombine::Ignore());
   2005       break;
   2006     }
   2007     case KEYED_PROPERTY: {
   2008       environment()->Push(value);
   2009       VisitForValue(property->obj());
   2010       VisitForValue(property->key());
   2011       Node* key = environment()->Pop();
   2012       Node* object = environment()->Pop();
   2013       value = environment()->Pop();
   2014       Node* store = BuildKeyedStore(object, key, value, feedback);
   2015       PrepareFrameState(store, bailout_id, OutputFrameStateCombine::Ignore());
   2016       break;
   2017     }
   2018     case NAMED_SUPER_PROPERTY: {
   2019       environment()->Push(value);
   2020       VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
   2021       VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
   2022       Node* home_object = environment()->Pop();
   2023       Node* receiver = environment()->Pop();
   2024       value = environment()->Pop();
   2025       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2026       Node* store = BuildNamedSuperStore(receiver, home_object, name, value);
   2027       PrepareFrameState(store, bailout_id, OutputFrameStateCombine::Ignore());
   2028       break;
   2029     }
   2030     case KEYED_SUPER_PROPERTY: {
   2031       environment()->Push(value);
   2032       VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
   2033       VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
   2034       VisitForValue(property->key());
   2035       Node* key = environment()->Pop();
   2036       Node* home_object = environment()->Pop();
   2037       Node* receiver = environment()->Pop();
   2038       value = environment()->Pop();
   2039       Node* store = BuildKeyedSuperStore(receiver, home_object, key, value);
   2040       PrepareFrameState(store, bailout_id, OutputFrameStateCombine::Ignore());
   2041       break;
   2042     }
   2043   }
   2044 }
   2045 
   2046 
   2047 void AstGraphBuilder::VisitAssignment(Assignment* expr) {
   2048   DCHECK(expr->target()->IsValidReferenceExpressionOrThis());
   2049 
   2050   // Left-hand side can only be a property, a global or a variable slot.
   2051   Property* property = expr->target()->AsProperty();
   2052   LhsKind assign_type = Property::GetAssignType(property);
   2053   bool needs_frame_state_before = true;
   2054 
   2055   // Evaluate LHS expression.
   2056   switch (assign_type) {
   2057     case VARIABLE: {
   2058       Variable* variable = expr->target()->AsVariableProxy()->var();
   2059       if (variable->location() == VariableLocation::PARAMETER ||
   2060           variable->location() == VariableLocation::LOCAL ||
   2061           variable->location() == VariableLocation::CONTEXT) {
   2062         needs_frame_state_before = false;
   2063       }
   2064       break;
   2065     }
   2066     case NAMED_PROPERTY:
   2067       VisitForValue(property->obj());
   2068       break;
   2069     case KEYED_PROPERTY:
   2070       VisitForValue(property->obj());
   2071       VisitForValue(property->key());
   2072       break;
   2073     case NAMED_SUPER_PROPERTY:
   2074       VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
   2075       VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
   2076       break;
   2077     case KEYED_SUPER_PROPERTY:
   2078       VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
   2079       VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
   2080       VisitForValue(property->key());
   2081       break;
   2082   }
   2083 
   2084   // Evaluate the value and potentially handle compound assignments by loading
   2085   // the left-hand side value and performing a binary operation.
   2086   if (expr->is_compound()) {
   2087     Node* old_value = nullptr;
   2088     switch (assign_type) {
   2089       case VARIABLE: {
   2090         VariableProxy* proxy = expr->target()->AsVariableProxy();
   2091         VectorSlotPair pair =
   2092             CreateVectorSlotPair(proxy->VariableFeedbackSlot());
   2093         PrepareEagerCheckpoint(BeforeId(proxy));
   2094         old_value = BuildVariableLoad(proxy->var(), expr->target()->id(), pair,
   2095                                       OutputFrameStateCombine::Push());
   2096         break;
   2097       }
   2098       case NAMED_PROPERTY: {
   2099         Node* object = environment()->Top();
   2100         Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2101         VectorSlotPair pair =
   2102             CreateVectorSlotPair(property->PropertyFeedbackSlot());
   2103         old_value = BuildNamedLoad(object, name, pair);
   2104         PrepareFrameState(old_value, property->LoadId(),
   2105                           OutputFrameStateCombine::Push());
   2106         break;
   2107       }
   2108       case KEYED_PROPERTY: {
   2109         Node* key = environment()->Top();
   2110         Node* object = environment()->Peek(1);
   2111         VectorSlotPair pair =
   2112             CreateVectorSlotPair(property->PropertyFeedbackSlot());
   2113         old_value = BuildKeyedLoad(object, key, pair);
   2114         PrepareFrameState(old_value, property->LoadId(),
   2115                           OutputFrameStateCombine::Push());
   2116         break;
   2117       }
   2118       case NAMED_SUPER_PROPERTY: {
   2119         Node* home_object = environment()->Top();
   2120         Node* receiver = environment()->Peek(1);
   2121         Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2122         VectorSlotPair pair =
   2123             CreateVectorSlotPair(property->PropertyFeedbackSlot());
   2124         old_value = BuildNamedSuperLoad(receiver, home_object, name, pair);
   2125         PrepareFrameState(old_value, property->LoadId(),
   2126                           OutputFrameStateCombine::Push());
   2127         break;
   2128       }
   2129       case KEYED_SUPER_PROPERTY: {
   2130         Node* key = environment()->Top();
   2131         Node* home_object = environment()->Peek(1);
   2132         Node* receiver = environment()->Peek(2);
   2133         VectorSlotPair pair =
   2134             CreateVectorSlotPair(property->PropertyFeedbackSlot());
   2135         old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair);
   2136         PrepareFrameState(old_value, property->LoadId(),
   2137                           OutputFrameStateCombine::Push());
   2138         break;
   2139       }
   2140     }
   2141     environment()->Push(old_value);
   2142     VisitForValue(expr->value());
   2143     Node* right = environment()->Pop();
   2144     Node* left = environment()->Pop();
   2145     Node* value =
   2146         BuildBinaryOp(left, right, expr->binary_op(),
   2147                       expr->binary_operation()->BinaryOperationFeedbackId());
   2148     PrepareFrameState(value, expr->binary_operation()->id(),
   2149                       OutputFrameStateCombine::Push());
   2150     environment()->Push(value);
   2151     if (needs_frame_state_before) {
   2152       PrepareEagerCheckpoint(expr->binary_operation()->id());
   2153     }
   2154   } else {
   2155     VisitForValue(expr->value());
   2156   }
   2157 
   2158   // Store the value.
   2159   Node* value = environment()->Pop();
   2160   VectorSlotPair feedback = CreateVectorSlotPair(expr->AssignmentSlot());
   2161   switch (assign_type) {
   2162     case VARIABLE: {
   2163       Variable* variable = expr->target()->AsVariableProxy()->var();
   2164       BuildVariableAssignment(variable, value, expr->op(), feedback, expr->id(),
   2165                               ast_context()->GetStateCombine());
   2166       break;
   2167     }
   2168     case NAMED_PROPERTY: {
   2169       Node* object = environment()->Pop();
   2170       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2171       Node* store = BuildNamedStore(object, name, value, feedback);
   2172       PrepareFrameState(store, expr->AssignmentId(),
   2173                         OutputFrameStateCombine::Push());
   2174       break;
   2175     }
   2176     case KEYED_PROPERTY: {
   2177       Node* key = environment()->Pop();
   2178       Node* object = environment()->Pop();
   2179       Node* store = BuildKeyedStore(object, key, value, feedback);
   2180       PrepareFrameState(store, expr->AssignmentId(),
   2181                         OutputFrameStateCombine::Push());
   2182       break;
   2183     }
   2184     case NAMED_SUPER_PROPERTY: {
   2185       Node* home_object = environment()->Pop();
   2186       Node* receiver = environment()->Pop();
   2187       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2188       Node* store = BuildNamedSuperStore(receiver, home_object, name, value);
   2189       PrepareFrameState(store, expr->id(), ast_context()->GetStateCombine());
   2190       break;
   2191     }
   2192     case KEYED_SUPER_PROPERTY: {
   2193       Node* key = environment()->Pop();
   2194       Node* home_object = environment()->Pop();
   2195       Node* receiver = environment()->Pop();
   2196       Node* store = BuildKeyedSuperStore(receiver, home_object, key, value);
   2197       PrepareFrameState(store, expr->id(), ast_context()->GetStateCombine());
   2198       break;
   2199     }
   2200   }
   2201 
   2202   ast_context()->ProduceValue(expr, value);
   2203 }
   2204 
   2205 
   2206 void AstGraphBuilder::VisitYield(Yield* expr) {
   2207   // Generator functions are supported only by going through Ignition first.
   2208   SetStackOverflow();
   2209   ast_context()->ProduceValue(expr, jsgraph()->UndefinedConstant());
   2210 }
   2211 
   2212 
   2213 void AstGraphBuilder::VisitThrow(Throw* expr) {
   2214   VisitForValue(expr->exception());
   2215   Node* exception = environment()->Pop();
   2216   Node* value = BuildThrowError(exception, expr->id());
   2217   ast_context()->ProduceValue(expr, value);
   2218 }
   2219 
   2220 
   2221 void AstGraphBuilder::VisitProperty(Property* expr) {
   2222   Node* value = nullptr;
   2223   LhsKind property_kind = Property::GetAssignType(expr);
   2224   VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot());
   2225   switch (property_kind) {
   2226     case VARIABLE:
   2227       UNREACHABLE();
   2228       break;
   2229     case NAMED_PROPERTY: {
   2230       VisitForValue(expr->obj());
   2231       Node* object = environment()->Pop();
   2232       Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName();
   2233       value = BuildNamedLoad(object, name, pair);
   2234       PrepareFrameState(value, expr->LoadId(), OutputFrameStateCombine::Push());
   2235       break;
   2236     }
   2237     case KEYED_PROPERTY: {
   2238       VisitForValue(expr->obj());
   2239       VisitForValue(expr->key());
   2240       Node* key = environment()->Pop();
   2241       Node* object = environment()->Pop();
   2242       value = BuildKeyedLoad(object, key, pair);
   2243       PrepareFrameState(value, expr->LoadId(), OutputFrameStateCombine::Push());
   2244       break;
   2245     }
   2246     case NAMED_SUPER_PROPERTY: {
   2247       VisitForValue(expr->obj()->AsSuperPropertyReference()->this_var());
   2248       VisitForValue(expr->obj()->AsSuperPropertyReference()->home_object());
   2249       Node* home_object = environment()->Pop();
   2250       Node* receiver = environment()->Pop();
   2251       Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName();
   2252       value = BuildNamedSuperLoad(receiver, home_object, name, pair);
   2253       PrepareFrameState(value, expr->LoadId(), OutputFrameStateCombine::Push());
   2254       break;
   2255     }
   2256     case KEYED_SUPER_PROPERTY: {
   2257       VisitForValue(expr->obj()->AsSuperPropertyReference()->this_var());
   2258       VisitForValue(expr->obj()->AsSuperPropertyReference()->home_object());
   2259       VisitForValue(expr->key());
   2260       Node* key = environment()->Pop();
   2261       Node* home_object = environment()->Pop();
   2262       Node* receiver = environment()->Pop();
   2263       value = BuildKeyedSuperLoad(receiver, home_object, key, pair);
   2264       PrepareFrameState(value, expr->LoadId(), OutputFrameStateCombine::Push());
   2265       break;
   2266     }
   2267   }
   2268   ast_context()->ProduceValue(expr, value);
   2269 }
   2270 
   2271 
   2272 void AstGraphBuilder::VisitCall(Call* expr) {
   2273   Expression* callee = expr->expression();
   2274   Call::CallType call_type = expr->GetCallType();
   2275 
   2276   // Prepare the callee and the receiver to the function call. This depends on
   2277   // the semantics of the underlying call type.
   2278   ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny;
   2279   Node* receiver_value = nullptr;
   2280   Node* callee_value = nullptr;
   2281   if (expr->is_possibly_eval()) {
   2282     if (callee->AsVariableProxy()->var()->IsLookupSlot()) {
   2283       Variable* variable = callee->AsVariableProxy()->var();
   2284       Node* name = jsgraph()->Constant(variable->name());
   2285       const Operator* op =
   2286           javascript()->CallRuntime(Runtime::kLoadLookupSlotForCall);
   2287       Node* pair = NewNode(op, name);
   2288       callee_value = NewNode(common()->Projection(0), pair);
   2289       receiver_value = NewNode(common()->Projection(1), pair);
   2290       PrepareFrameState(pair, expr->LookupId(),
   2291                         OutputFrameStateCombine::Push(2));
   2292     } else {
   2293       VisitForValue(callee);
   2294       callee_value = environment()->Pop();
   2295       receiver_hint = ConvertReceiverMode::kNullOrUndefined;
   2296       receiver_value = jsgraph()->UndefinedConstant();
   2297     }
   2298   } else {
   2299     switch (call_type) {
   2300       case Call::GLOBAL_CALL: {
   2301         VariableProxy* proxy = callee->AsVariableProxy();
   2302         VectorSlotPair pair =
   2303             CreateVectorSlotPair(proxy->VariableFeedbackSlot());
   2304         PrepareEagerCheckpoint(BeforeId(proxy));
   2305         callee_value = BuildVariableLoad(proxy->var(), expr->expression()->id(),
   2306                                          pair, OutputFrameStateCombine::Push());
   2307         receiver_hint = ConvertReceiverMode::kNullOrUndefined;
   2308         receiver_value = jsgraph()->UndefinedConstant();
   2309         break;
   2310       }
   2311       case Call::WITH_CALL: {
   2312         Variable* variable = callee->AsVariableProxy()->var();
   2313         Node* name = jsgraph()->Constant(variable->name());
   2314         const Operator* op =
   2315             javascript()->CallRuntime(Runtime::kLoadLookupSlotForCall);
   2316         Node* pair = NewNode(op, name);
   2317         callee_value = NewNode(common()->Projection(0), pair);
   2318         receiver_value = NewNode(common()->Projection(1), pair);
   2319         PrepareFrameState(pair, expr->LookupId(),
   2320                           OutputFrameStateCombine::Push(2));
   2321         break;
   2322       }
   2323       case Call::NAMED_PROPERTY_CALL: {
   2324         Property* property = callee->AsProperty();
   2325         VectorSlotPair feedback =
   2326             CreateVectorSlotPair(property->PropertyFeedbackSlot());
   2327         VisitForValue(property->obj());
   2328         Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2329         Node* object = environment()->Top();
   2330         callee_value = BuildNamedLoad(object, name, feedback);
   2331         PrepareFrameState(callee_value, property->LoadId(),
   2332                           OutputFrameStateCombine::Push());
   2333         // Note that a property call requires the receiver to be wrapped into
   2334         // an object for sloppy callees. However the receiver is guaranteed
   2335         // not to be null or undefined at this point.
   2336         receiver_hint = ConvertReceiverMode::kNotNullOrUndefined;
   2337         receiver_value = environment()->Pop();
   2338         break;
   2339       }
   2340       case Call::KEYED_PROPERTY_CALL: {
   2341         Property* property = callee->AsProperty();
   2342         VectorSlotPair feedback =
   2343             CreateVectorSlotPair(property->PropertyFeedbackSlot());
   2344         VisitForValue(property->obj());
   2345         VisitForValue(property->key());
   2346         Node* key = environment()->Pop();
   2347         Node* object = environment()->Top();
   2348         callee_value = BuildKeyedLoad(object, key, feedback);
   2349         PrepareFrameState(callee_value, property->LoadId(),
   2350                           OutputFrameStateCombine::Push());
   2351         // Note that a property call requires the receiver to be wrapped into
   2352         // an object for sloppy callees. However the receiver is guaranteed
   2353         // not to be null or undefined at this point.
   2354         receiver_hint = ConvertReceiverMode::kNotNullOrUndefined;
   2355         receiver_value = environment()->Pop();
   2356         break;
   2357       }
   2358       case Call::NAMED_SUPER_PROPERTY_CALL: {
   2359         Property* property = callee->AsProperty();
   2360         SuperPropertyReference* super_ref =
   2361             property->obj()->AsSuperPropertyReference();
   2362         VisitForValue(super_ref->home_object());
   2363         VisitForValue(super_ref->this_var());
   2364         Node* home = environment()->Peek(1);
   2365         Node* object = environment()->Top();
   2366         Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2367         callee_value =
   2368             BuildNamedSuperLoad(object, home, name, VectorSlotPair());
   2369         PrepareFrameState(callee_value, property->LoadId(),
   2370                           OutputFrameStateCombine::Push());
   2371         // Note that a property call requires the receiver to be wrapped into
   2372         // an object for sloppy callees. Since the receiver is not the target of
   2373         // the load, it could very well be null or undefined at this point.
   2374         receiver_value = environment()->Pop();
   2375         environment()->Drop(1);
   2376         break;
   2377       }
   2378       case Call::KEYED_SUPER_PROPERTY_CALL: {
   2379         Property* property = callee->AsProperty();
   2380         SuperPropertyReference* super_ref =
   2381             property->obj()->AsSuperPropertyReference();
   2382         VisitForValue(super_ref->home_object());
   2383         VisitForValue(super_ref->this_var());
   2384         environment()->Push(environment()->Top());    // Duplicate this_var.
   2385         environment()->Push(environment()->Peek(2));  // Duplicate home_obj.
   2386         VisitForValue(property->key());
   2387         Node* key = environment()->Pop();
   2388         Node* home = environment()->Pop();
   2389         Node* object = environment()->Pop();
   2390         callee_value = BuildKeyedSuperLoad(object, home, key, VectorSlotPair());
   2391         PrepareFrameState(callee_value, property->LoadId(),
   2392                           OutputFrameStateCombine::Push());
   2393         // Note that a property call requires the receiver to be wrapped into
   2394         // an object for sloppy callees. Since the receiver is not the target of
   2395         // the load, it could very well be null or undefined at this point.
   2396         receiver_value = environment()->Pop();
   2397         environment()->Drop(1);
   2398         break;
   2399       }
   2400       case Call::SUPER_CALL:
   2401         return VisitCallSuper(expr);
   2402       case Call::OTHER_CALL:
   2403         VisitForValue(callee);
   2404         callee_value = environment()->Pop();
   2405         receiver_hint = ConvertReceiverMode::kNullOrUndefined;
   2406         receiver_value = jsgraph()->UndefinedConstant();
   2407         break;
   2408     }
   2409   }
   2410 
   2411   // The callee and the receiver both have to be pushed onto the operand stack
   2412   // before arguments are being evaluated.
   2413   environment()->Push(callee_value);
   2414   environment()->Push(receiver_value);
   2415 
   2416   // Evaluate all arguments to the function call,
   2417   ZoneList<Expression*>* args = expr->arguments();
   2418   VisitForValues(args);
   2419 
   2420   // Resolve callee for a potential direct eval call. This block will mutate the
   2421   // callee value pushed onto the environment.
   2422   if (expr->is_possibly_eval() && args->length() > 0) {
   2423     int arg_count = args->length();
   2424 
   2425     // Extract callee and source string from the environment.
   2426     Node* callee = environment()->Peek(arg_count + 1);
   2427     Node* source = environment()->Peek(arg_count - 1);
   2428 
   2429     // Create node to ask for help resolving potential eval call. This will
   2430     // provide a fully resolved callee to patch into the environment.
   2431     Node* function = GetFunctionClosure();
   2432     Node* language = jsgraph()->Constant(language_mode());
   2433     Node* eval_scope_position =
   2434         jsgraph()->Constant(current_scope()->start_position());
   2435     Node* eval_position = jsgraph()->Constant(expr->position());
   2436     const Operator* op =
   2437         javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval);
   2438     Node* new_callee = NewNode(op, callee, source, function, language,
   2439                                eval_scope_position, eval_position);
   2440     PrepareFrameState(new_callee, expr->EvalId(),
   2441                       OutputFrameStateCombine::PokeAt(arg_count + 1));
   2442 
   2443     // Patch callee on the environment.
   2444     environment()->Poke(arg_count + 1, new_callee);
   2445   }
   2446 
   2447   // Create node to perform the function call.
   2448   float const frequency = ComputeCallFrequency(expr->CallFeedbackICSlot());
   2449   VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot());
   2450   const Operator* call =
   2451       javascript()->CallFunction(args->length() + 2, frequency, feedback,
   2452                                  receiver_hint, expr->tail_call_mode());
   2453   PrepareEagerCheckpoint(expr->is_possibly_eval() ? expr->EvalId()
   2454                                                   : expr->CallId());
   2455   Node* value = ProcessArguments(call, args->length() + 2);
   2456   // The callee passed to the call, we just need to push something here to
   2457   // satisfy the bailout location contract. The fullcodegen code will not
   2458   // ever look at this value, so we just push optimized_out here.
   2459   environment()->Push(jsgraph()->OptimizedOutConstant());
   2460   PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push());
   2461   environment()->Drop(1);
   2462   ast_context()->ProduceValue(expr, value);
   2463 }
   2464 
   2465 
   2466 void AstGraphBuilder::VisitCallSuper(Call* expr) {
   2467   SuperCallReference* super = expr->expression()->AsSuperCallReference();
   2468   DCHECK_NOT_NULL(super);
   2469 
   2470   // Prepare the callee to the super call.
   2471   VisitForValue(super->this_function_var());
   2472   Node* this_function = environment()->Pop();
   2473   const Operator* op =
   2474       javascript()->CallRuntime(Runtime::kInlineGetSuperConstructor, 1);
   2475   Node* super_function = NewNode(op, this_function);
   2476   environment()->Push(super_function);
   2477 
   2478   // Evaluate all arguments to the super call.
   2479   ZoneList<Expression*>* args = expr->arguments();
   2480   VisitForValues(args);
   2481 
   2482   // The new target is loaded from the {new.target} variable.
   2483   VisitForValue(super->new_target_var());
   2484 
   2485   // Create node to perform the super call.
   2486   const Operator* call =
   2487       javascript()->CallConstruct(args->length() + 2, 0.0f, VectorSlotPair());
   2488   Node* value = ProcessArguments(call, args->length() + 2);
   2489   PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push());
   2490   ast_context()->ProduceValue(expr, value);
   2491 }
   2492 
   2493 
   2494 void AstGraphBuilder::VisitCallNew(CallNew* expr) {
   2495   VisitForValue(expr->expression());
   2496 
   2497   // Evaluate all arguments to the construct call.
   2498   ZoneList<Expression*>* args = expr->arguments();
   2499   VisitForValues(args);
   2500 
   2501   // The new target is the same as the callee.
   2502   environment()->Push(environment()->Peek(args->length()));
   2503 
   2504   // Create node to perform the construct call.
   2505   float const frequency = ComputeCallFrequency(expr->CallNewFeedbackSlot());
   2506   VectorSlotPair feedback = CreateVectorSlotPair(expr->CallNewFeedbackSlot());
   2507   const Operator* call =
   2508       javascript()->CallConstruct(args->length() + 2, frequency, feedback);
   2509   Node* value = ProcessArguments(call, args->length() + 2);
   2510   PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push());
   2511   ast_context()->ProduceValue(expr, value);
   2512 }
   2513 
   2514 
   2515 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) {
   2516   // The callee and the receiver both have to be pushed onto the operand stack
   2517   // before arguments are being evaluated.
   2518   Node* callee_value = BuildLoadNativeContextField(expr->context_index());
   2519   Node* receiver_value = jsgraph()->UndefinedConstant();
   2520 
   2521   environment()->Push(callee_value);
   2522   environment()->Push(receiver_value);
   2523 
   2524   // Evaluate all arguments to the JS runtime call.
   2525   ZoneList<Expression*>* args = expr->arguments();
   2526   VisitForValues(args);
   2527 
   2528   // Create node to perform the JS runtime call.
   2529   const Operator* call = javascript()->CallFunction(args->length() + 2);
   2530   PrepareEagerCheckpoint(expr->CallId());
   2531   Node* value = ProcessArguments(call, args->length() + 2);
   2532   PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
   2533   ast_context()->ProduceValue(expr, value);
   2534 }
   2535 
   2536 
   2537 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
   2538   // Handle calls to runtime functions implemented in JavaScript separately as
   2539   // the call follows JavaScript ABI and the callee is statically unknown.
   2540   if (expr->is_jsruntime()) {
   2541     return VisitCallJSRuntime(expr);
   2542   }
   2543 
   2544   // Evaluate all arguments to the runtime call.
   2545   ZoneList<Expression*>* args = expr->arguments();
   2546   VisitForValues(args);
   2547 
   2548   // Create node to perform the runtime call.
   2549   Runtime::FunctionId functionId = expr->function()->function_id;
   2550   const Operator* call = javascript()->CallRuntime(functionId, args->length());
   2551   if (expr->function()->intrinsic_type == Runtime::IntrinsicType::RUNTIME ||
   2552       expr->function()->function_id == Runtime::kInlineCall) {
   2553     PrepareEagerCheckpoint(expr->CallId());
   2554   }
   2555   Node* value = ProcessArguments(call, args->length());
   2556   PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
   2557   ast_context()->ProduceValue(expr, value);
   2558 }
   2559 
   2560 
   2561 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
   2562   switch (expr->op()) {
   2563     case Token::DELETE:
   2564       return VisitDelete(expr);
   2565     case Token::VOID:
   2566       return VisitVoid(expr);
   2567     case Token::TYPEOF:
   2568       return VisitTypeof(expr);
   2569     case Token::NOT:
   2570       return VisitNot(expr);
   2571     default:
   2572       UNREACHABLE();
   2573   }
   2574 }
   2575 
   2576 
   2577 void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
   2578   DCHECK(expr->expression()->IsValidReferenceExpressionOrThis());
   2579 
   2580   // Left-hand side can only be a property, a global or a variable slot.
   2581   Property* property = expr->expression()->AsProperty();
   2582   LhsKind assign_type = Property::GetAssignType(property);
   2583 
   2584   // Reserve space for result of postfix operation.
   2585   bool is_postfix = expr->is_postfix() && !ast_context()->IsEffect();
   2586   if (is_postfix && assign_type != VARIABLE) {
   2587     environment()->Push(jsgraph()->ZeroConstant());
   2588   }
   2589 
   2590   // Evaluate LHS expression and get old value.
   2591   Node* old_value = nullptr;
   2592   int stack_depth = -1;
   2593   switch (assign_type) {
   2594     case VARIABLE: {
   2595       VariableProxy* proxy = expr->expression()->AsVariableProxy();
   2596       VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
   2597       PrepareEagerCheckpoint(BeforeId(proxy));
   2598       old_value = BuildVariableLoad(proxy->var(), expr->expression()->id(),
   2599                                     pair, OutputFrameStateCombine::Push());
   2600       stack_depth = 0;
   2601       break;
   2602     }
   2603     case NAMED_PROPERTY: {
   2604       VisitForValue(property->obj());
   2605       Node* object = environment()->Top();
   2606       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2607       VectorSlotPair pair =
   2608           CreateVectorSlotPair(property->PropertyFeedbackSlot());
   2609       old_value = BuildNamedLoad(object, name, pair);
   2610       PrepareFrameState(old_value, property->LoadId(),
   2611                         OutputFrameStateCombine::Push());
   2612       stack_depth = 1;
   2613       break;
   2614     }
   2615     case KEYED_PROPERTY: {
   2616       VisitForValue(property->obj());
   2617       VisitForValue(property->key());
   2618       Node* key = environment()->Top();
   2619       Node* object = environment()->Peek(1);
   2620       VectorSlotPair pair =
   2621           CreateVectorSlotPair(property->PropertyFeedbackSlot());
   2622       old_value = BuildKeyedLoad(object, key, pair);
   2623       PrepareFrameState(old_value, property->LoadId(),
   2624                         OutputFrameStateCombine::Push());
   2625       stack_depth = 2;
   2626       break;
   2627     }
   2628     case NAMED_SUPER_PROPERTY: {
   2629       VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
   2630       VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
   2631       Node* home_object = environment()->Top();
   2632       Node* receiver = environment()->Peek(1);
   2633       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2634       VectorSlotPair pair =
   2635           CreateVectorSlotPair(property->PropertyFeedbackSlot());
   2636       old_value = BuildNamedSuperLoad(receiver, home_object, name, pair);
   2637       PrepareFrameState(old_value, property->LoadId(),
   2638                         OutputFrameStateCombine::Push());
   2639       stack_depth = 2;
   2640       break;
   2641     }
   2642     case KEYED_SUPER_PROPERTY: {
   2643       VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
   2644       VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
   2645       VisitForValue(property->key());
   2646       Node* key = environment()->Top();
   2647       Node* home_object = environment()->Peek(1);
   2648       Node* receiver = environment()->Peek(2);
   2649       VectorSlotPair pair =
   2650           CreateVectorSlotPair(property->PropertyFeedbackSlot());
   2651       old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair);
   2652       PrepareFrameState(old_value, property->LoadId(),
   2653                         OutputFrameStateCombine::Push());
   2654       stack_depth = 3;
   2655       break;
   2656     }
   2657   }
   2658 
   2659   // Convert old value into a number.
   2660   old_value = NewNode(javascript()->ToNumber(), old_value);
   2661   PrepareFrameState(old_value, expr->ToNumberId(),
   2662                     OutputFrameStateCombine::Push());
   2663 
   2664   // Create a proper eager frame state for the stores.
   2665   environment()->Push(old_value);
   2666   PrepareEagerCheckpoint(expr->ToNumberId());
   2667   old_value = environment()->Pop();
   2668 
   2669   // Save result for postfix expressions at correct stack depth.
   2670   if (is_postfix) {
   2671     if (assign_type != VARIABLE) {
   2672       environment()->Poke(stack_depth, old_value);
   2673     } else {
   2674       environment()->Push(old_value);
   2675     }
   2676   }
   2677 
   2678   // Create node to perform +1/-1 operation.
   2679   Node* value = BuildBinaryOp(old_value, jsgraph()->OneConstant(),
   2680                               expr->binary_op(), expr->CountBinOpFeedbackId());
   2681   // This should never lazy deopt because we have converted to number before.
   2682   PrepareFrameState(value, BailoutId::None());
   2683 
   2684   // Store the value.
   2685   VectorSlotPair feedback = CreateVectorSlotPair(expr->CountSlot());
   2686   switch (assign_type) {
   2687     case VARIABLE: {
   2688       Variable* variable = expr->expression()->AsVariableProxy()->var();
   2689       environment()->Push(value);
   2690       BuildVariableAssignment(variable, value, expr->op(), feedback,
   2691                               expr->AssignmentId());
   2692       environment()->Pop();
   2693       break;
   2694     }
   2695     case NAMED_PROPERTY: {
   2696       Node* object = environment()->Pop();
   2697       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2698       Node* store = BuildNamedStore(object, name, value, feedback);
   2699       PrepareFrameState(store, expr->AssignmentId(),
   2700                         OutputFrameStateCombine::Push());
   2701       break;
   2702     }
   2703     case KEYED_PROPERTY: {
   2704       Node* key = environment()->Pop();
   2705       Node* object = environment()->Pop();
   2706       Node* store = BuildKeyedStore(object, key, value, feedback);
   2707       PrepareFrameState(store, expr->AssignmentId(),
   2708                         OutputFrameStateCombine::Push());
   2709       break;
   2710     }
   2711     case NAMED_SUPER_PROPERTY: {
   2712       Node* home_object = environment()->Pop();
   2713       Node* receiver = environment()->Pop();
   2714       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2715       Node* store = BuildNamedSuperStore(receiver, home_object, name, value);
   2716       PrepareFrameState(store, expr->AssignmentId(),
   2717                         OutputFrameStateCombine::Push());
   2718       break;
   2719     }
   2720     case KEYED_SUPER_PROPERTY: {
   2721       Node* key = environment()->Pop();
   2722       Node* home_object = environment()->Pop();
   2723       Node* receiver = environment()->Pop();
   2724       Node* store = BuildKeyedSuperStore(receiver, home_object, key, value);
   2725       PrepareFrameState(store, expr->AssignmentId(),
   2726                         OutputFrameStateCombine::Push());
   2727       break;
   2728     }
   2729   }
   2730 
   2731   // Restore old value for postfix expressions.
   2732   if (is_postfix) value = environment()->Pop();
   2733 
   2734   ast_context()->ProduceValue(expr, value);
   2735 }
   2736 
   2737 
   2738 void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) {
   2739   switch (expr->op()) {
   2740     case Token::COMMA:
   2741       return VisitComma(expr);
   2742     case Token::OR:
   2743     case Token::AND:
   2744       return VisitLogicalExpression(expr);
   2745     default: {
   2746       VisitForValue(expr->left());
   2747       VisitForValue(expr->right());
   2748       Node* right = environment()->Pop();
   2749       Node* left = environment()->Pop();
   2750       Node* value = BuildBinaryOp(left, right, expr->op(),
   2751                                   expr->BinaryOperationFeedbackId());
   2752       PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
   2753       ast_context()->ProduceValue(expr, value);
   2754     }
   2755   }
   2756 }
   2757 
   2758 void AstGraphBuilder::VisitLiteralCompareNil(CompareOperation* expr,
   2759                                              Expression* sub_expr,
   2760                                              Node* nil_value) {
   2761   const Operator* op = nullptr;
   2762   switch (expr->op()) {
   2763     case Token::EQ:
   2764       op = javascript()->Equal(CompareOperationHint::kAny);
   2765       break;
   2766     case Token::EQ_STRICT:
   2767       op = javascript()->StrictEqual(CompareOperationHint::kAny);
   2768       break;
   2769     default:
   2770       UNREACHABLE();
   2771   }
   2772   VisitForValue(sub_expr);
   2773   Node* value_to_compare = environment()->Pop();
   2774   Node* value = NewNode(op, value_to_compare, nil_value);
   2775   PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
   2776   return ast_context()->ProduceValue(expr, value);
   2777 }
   2778 
   2779 void AstGraphBuilder::VisitLiteralCompareTypeof(CompareOperation* expr,
   2780                                                 Expression* sub_expr,
   2781                                                 Handle<String> check) {
   2782   VisitTypeofExpression(sub_expr);
   2783   Node* typeof_arg = NewNode(javascript()->TypeOf(), environment()->Pop());
   2784   Node* value = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
   2785                         typeof_arg, jsgraph()->Constant(check));
   2786   PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
   2787   return ast_context()->ProduceValue(expr, value);
   2788 }
   2789 
   2790 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
   2791   // Check for a few fast cases. The AST visiting behavior must be in sync
   2792   // with the full codegen: We don't push both left and right values onto
   2793   // the expression stack when one side is a special-case literal.
   2794   Expression* sub_expr = nullptr;
   2795   Handle<String> check;
   2796   if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) {
   2797     return VisitLiteralCompareTypeof(expr, sub_expr, check);
   2798   }
   2799   if (expr->IsLiteralCompareUndefined(&sub_expr)) {
   2800     return VisitLiteralCompareNil(expr, sub_expr,
   2801                                   jsgraph()->UndefinedConstant());
   2802   }
   2803   if (expr->IsLiteralCompareNull(&sub_expr)) {
   2804     return VisitLiteralCompareNil(expr, sub_expr, jsgraph()->NullConstant());
   2805   }
   2806 
   2807   CompareOperationHint hint;
   2808   if (!type_hint_analysis_ ||
   2809       !type_hint_analysis_->GetCompareOperationHint(
   2810           expr->CompareOperationFeedbackId(), &hint)) {
   2811     hint = CompareOperationHint::kAny;
   2812   }
   2813 
   2814   const Operator* op;
   2815   switch (expr->op()) {
   2816     case Token::EQ:
   2817       op = javascript()->Equal(hint);
   2818       break;
   2819     case Token::NE:
   2820       op = javascript()->NotEqual(hint);
   2821       break;
   2822     case Token::EQ_STRICT:
   2823       op = javascript()->StrictEqual(hint);
   2824       break;
   2825     case Token::NE_STRICT:
   2826       op = javascript()->StrictNotEqual(hint);
   2827       break;
   2828     case Token::LT:
   2829       op = javascript()->LessThan(hint);
   2830       break;
   2831     case Token::GT:
   2832       op = javascript()->GreaterThan(hint);
   2833       break;
   2834     case Token::LTE:
   2835       op = javascript()->LessThanOrEqual(hint);
   2836       break;
   2837     case Token::GTE:
   2838       op = javascript()->GreaterThanOrEqual(hint);
   2839       break;
   2840     case Token::INSTANCEOF:
   2841       op = javascript()->InstanceOf();
   2842       break;
   2843     case Token::IN:
   2844       op = javascript()->HasProperty();
   2845       break;
   2846     default:
   2847       op = nullptr;
   2848       UNREACHABLE();
   2849   }
   2850   VisitForValue(expr->left());
   2851   VisitForValue(expr->right());
   2852   Node* right = environment()->Pop();
   2853   Node* left = environment()->Pop();
   2854   Node* value = NewNode(op, left, right);
   2855   PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
   2856   ast_context()->ProduceValue(expr, value);
   2857 }
   2858 
   2859 
   2860 void AstGraphBuilder::VisitSpread(Spread* expr) {
   2861   // Handled entirely by the parser itself.
   2862   UNREACHABLE();
   2863 }
   2864 
   2865 
   2866 void AstGraphBuilder::VisitEmptyParentheses(EmptyParentheses* expr) {
   2867   // Handled entirely by the parser itself.
   2868   UNREACHABLE();
   2869 }
   2870 
   2871 
   2872 void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) {
   2873   Node* value = GetFunctionClosure();
   2874   ast_context()->ProduceValue(expr, value);
   2875 }
   2876 
   2877 
   2878 void AstGraphBuilder::VisitSuperPropertyReference(
   2879     SuperPropertyReference* expr) {
   2880   Node* value = BuildThrowUnsupportedSuperError(expr->id());
   2881   ast_context()->ProduceValue(expr, value);
   2882 }
   2883 
   2884 
   2885 void AstGraphBuilder::VisitSuperCallReference(SuperCallReference* expr) {
   2886   // Handled by VisitCall
   2887   UNREACHABLE();
   2888 }
   2889 
   2890 
   2891 void AstGraphBuilder::VisitCaseClause(CaseClause* expr) {
   2892   // Handled entirely in VisitSwitch.
   2893   UNREACHABLE();
   2894 }
   2895 
   2896 void AstGraphBuilder::VisitDeclarations(Declaration::List* declarations) {
   2897   DCHECK(globals()->empty());
   2898   AstVisitor<AstGraphBuilder>::VisitDeclarations(declarations);
   2899   if (globals()->empty()) return;
   2900   int array_index = 0;
   2901   Handle<TypeFeedbackVector> feedback_vector(
   2902       info()->closure()->feedback_vector());
   2903   Handle<FixedArray> data = isolate()->factory()->NewFixedArray(
   2904       static_cast<int>(globals()->size()), TENURED);
   2905   for (Handle<Object> obj : *globals()) data->set(array_index++, *obj);
   2906   int encoded_flags = info()->GetDeclareGlobalsFlags();
   2907   Node* flags = jsgraph()->Constant(encoded_flags);
   2908   Node* pairs = jsgraph()->Constant(data);
   2909   Node* vector = jsgraph()->Constant(feedback_vector);
   2910   const Operator* op = javascript()->CallRuntime(Runtime::kDeclareGlobals);
   2911   Node* call = NewNode(op, pairs, flags, vector);
   2912   PrepareFrameState(call, BailoutId::Declarations());
   2913   globals()->clear();
   2914 }
   2915 
   2916 
   2917 void AstGraphBuilder::VisitIfNotNull(Statement* stmt) {
   2918   if (stmt == nullptr) return;
   2919   Visit(stmt);
   2920 }
   2921 
   2922 
   2923 void AstGraphBuilder::VisitInScope(Statement* stmt, Scope* s, Node* context) {
   2924   ContextScope scope(this, s, context);
   2925   DCHECK(s->declarations()->is_empty());
   2926   Visit(stmt);
   2927 }
   2928 
   2929 void AstGraphBuilder::VisitIterationBody(IterationStatement* stmt,
   2930                                          LoopBuilder* loop,
   2931                                          BailoutId stack_check_id) {
   2932   ControlScopeForIteration scope(this, stmt, loop);
   2933   if (FLAG_turbo_loop_stackcheck || !info()->shared_info()->asm_function()) {
   2934     Node* node = NewNode(javascript()->StackCheck());
   2935     PrepareFrameState(node, stack_check_id);
   2936   }
   2937   Visit(stmt->body());
   2938 }
   2939 
   2940 
   2941 void AstGraphBuilder::VisitDelete(UnaryOperation* expr) {
   2942   Node* value;
   2943   if (expr->expression()->IsVariableProxy()) {
   2944     // Delete of an unqualified identifier is disallowed in strict mode but
   2945     // "delete this" is allowed.
   2946     Variable* variable = expr->expression()->AsVariableProxy()->var();
   2947     DCHECK(is_sloppy(language_mode()) || variable->is_this());
   2948     value = BuildVariableDelete(variable, expr->id(),
   2949                                 ast_context()->GetStateCombine());
   2950   } else if (expr->expression()->IsProperty()) {
   2951     Property* property = expr->expression()->AsProperty();
   2952     VisitForValue(property->obj());
   2953     VisitForValue(property->key());
   2954     Node* key = environment()->Pop();
   2955     Node* object = environment()->Pop();
   2956     value = NewNode(javascript()->DeleteProperty(language_mode()), object, key);
   2957     PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
   2958   } else {
   2959     VisitForEffect(expr->expression());
   2960     value = jsgraph()->TrueConstant();
   2961   }
   2962   ast_context()->ProduceValue(expr, value);
   2963 }
   2964 
   2965 
   2966 void AstGraphBuilder::VisitVoid(UnaryOperation* expr) {
   2967   VisitForEffect(expr->expression());
   2968   Node* value = jsgraph()->UndefinedConstant();
   2969   ast_context()->ProduceValue(expr, value);
   2970 }
   2971 
   2972 void AstGraphBuilder::VisitTypeofExpression(Expression* expr) {
   2973   if (expr->IsVariableProxy()) {
   2974     // Typeof does not throw a reference error on global variables, hence we
   2975     // perform a non-contextual load in case the operand is a variable proxy.
   2976     VariableProxy* proxy = expr->AsVariableProxy();
   2977     VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
   2978     PrepareEagerCheckpoint(BeforeId(proxy));
   2979     Node* load =
   2980         BuildVariableLoad(proxy->var(), expr->id(), pair,
   2981                           OutputFrameStateCombine::Push(), INSIDE_TYPEOF);
   2982     environment()->Push(load);
   2983   } else {
   2984     VisitForValue(expr);
   2985   }
   2986 }
   2987 
   2988 void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) {
   2989   VisitTypeofExpression(expr->expression());
   2990   Node* value = NewNode(javascript()->TypeOf(), environment()->Pop());
   2991   ast_context()->ProduceValue(expr, value);
   2992 }
   2993 
   2994 
   2995 void AstGraphBuilder::VisitNot(UnaryOperation* expr) {
   2996   VisitForTest(expr->expression());
   2997   Node* input = environment()->Pop();
   2998   Node* value = NewNode(common()->Select(MachineRepresentation::kTagged), input,
   2999                         jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
   3000   // Skip plugging AST evaluation contexts of the test kind. This is to stay in
   3001   // sync with full codegen which doesn't prepare the proper bailout point (see
   3002   // the implementation of FullCodeGenerator::VisitForControl).
   3003   if (ast_context()->IsTest()) return environment()->Push(value);
   3004   ast_context()->ProduceValue(expr, value);
   3005 }
   3006 
   3007 
   3008 void AstGraphBuilder::VisitComma(BinaryOperation* expr) {
   3009   VisitForEffect(expr->left());
   3010   Visit(expr->right());
   3011   // Skip plugging AST evaluation contexts of the test kind. This is to stay in
   3012   // sync with full codegen which doesn't prepare the proper bailout point (see
   3013   // the implementation of FullCodeGenerator::VisitForControl).
   3014   if (ast_context()->IsTest()) return;
   3015   ast_context()->ReplaceValue(expr);
   3016 }
   3017 
   3018 
   3019 void AstGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) {
   3020   bool is_logical_and = expr->op() == Token::AND;
   3021   IfBuilder compare_if(this);
   3022   // Only use an AST evaluation context of the value kind when this expression
   3023   // is evaluated as value as well. Otherwise stick to a test context which is
   3024   // in sync with full codegen (see FullCodeGenerator::VisitLogicalExpression).
   3025   Node* condition = nullptr;
   3026   if (ast_context()->IsValue()) {
   3027     VisitForValue(expr->left());
   3028     Node* left = environment()->Top();
   3029     condition = BuildToBoolean(left, expr->left()->test_id());
   3030   } else {
   3031     VisitForTest(expr->left());
   3032     condition = environment()->Top();
   3033   }
   3034   compare_if.If(condition);
   3035   compare_if.Then();
   3036   if (is_logical_and) {
   3037     environment()->Pop();
   3038     Visit(expr->right());
   3039   } else if (ast_context()->IsEffect()) {
   3040     environment()->Pop();
   3041   } else if (ast_context()->IsTest()) {
   3042     environment()->Poke(0, jsgraph()->TrueConstant());
   3043   }
   3044   compare_if.Else();
   3045   if (!is_logical_and) {
   3046     environment()->Pop();
   3047     Visit(expr->right());
   3048   } else if (ast_context()->IsEffect()) {
   3049     environment()->Pop();
   3050   } else if (ast_context()->IsTest()) {
   3051     environment()->Poke(0, jsgraph()->FalseConstant());
   3052   }
   3053   compare_if.End();
   3054   // Skip plugging AST evaluation contexts of the test kind. This is to stay in
   3055   // sync with full codegen which doesn't prepare the proper bailout point (see
   3056   // the implementation of FullCodeGenerator::VisitForControl).
   3057   if (ast_context()->IsTest()) return;
   3058   ast_context()->ReplaceValue(expr);
   3059 }
   3060 
   3061 
   3062 LanguageMode AstGraphBuilder::language_mode() const {
   3063   return current_scope()->language_mode();
   3064 }
   3065 
   3066 
   3067 VectorSlotPair AstGraphBuilder::CreateVectorSlotPair(
   3068     FeedbackVectorSlot slot) const {
   3069   return VectorSlotPair(handle(info()->closure()->feedback_vector()), slot);
   3070 }
   3071 
   3072 
   3073 void AstGraphBuilder::VisitRewritableExpression(RewritableExpression* node) {
   3074   Visit(node->expression());
   3075 }
   3076 
   3077 
   3078 namespace {
   3079 
   3080 // Limit of context chain length to which inline check is possible.
   3081 const int kMaxCheckDepth = 30;
   3082 
   3083 // Sentinel for {TryLoadDynamicVariable} disabling inline checks.
   3084 const uint32_t kFullCheckRequired = -1;
   3085 
   3086 }  // namespace
   3087 
   3088 
   3089 uint32_t AstGraphBuilder::ComputeBitsetForDynamicGlobal(Variable* variable) {
   3090   DCHECK_EQ(DYNAMIC_GLOBAL, variable->mode());
   3091   uint32_t check_depths = 0;
   3092   for (Scope* s = current_scope(); s != nullptr; s = s->outer_scope()) {
   3093     if (!s->NeedsContext()) continue;
   3094     if (!s->calls_sloppy_eval()) continue;
   3095     int depth = current_scope()->ContextChainLength(s);
   3096     if (depth > kMaxCheckDepth) return kFullCheckRequired;
   3097     check_depths |= 1 << depth;
   3098   }
   3099   return check_depths;
   3100 }
   3101 
   3102 
   3103 uint32_t AstGraphBuilder::ComputeBitsetForDynamicContext(Variable* variable) {
   3104   DCHECK_EQ(DYNAMIC_LOCAL, variable->mode());
   3105   uint32_t check_depths = 0;
   3106   for (Scope* s = current_scope(); s != nullptr; s = s->outer_scope()) {
   3107     if (!s->NeedsContext()) continue;
   3108     if (!s->calls_sloppy_eval() && s != variable->scope()) continue;
   3109     int depth = current_scope()->ContextChainLength(s);
   3110     if (depth > kMaxCheckDepth) return kFullCheckRequired;
   3111     check_depths |= 1 << depth;
   3112     if (s == variable->scope()) break;
   3113   }
   3114   return check_depths;
   3115 }
   3116 
   3117 float AstGraphBuilder::ComputeCallFrequency(FeedbackVectorSlot slot) const {
   3118   if (slot.IsInvalid()) return 0.0f;
   3119   Handle<TypeFeedbackVector> feedback_vector(
   3120       info()->closure()->feedback_vector(), isolate());
   3121   CallICNexus nexus(feedback_vector, slot);
   3122   return nexus.ComputeCallFrequency() * invocation_frequency_;
   3123 }
   3124 
   3125 Node* AstGraphBuilder::ProcessArguments(const Operator* op, int arity) {
   3126   DCHECK(environment()->stack_height() >= arity);
   3127   Node** all = info()->zone()->NewArray<Node*>(arity);
   3128   for (int i = arity - 1; i >= 0; --i) {
   3129     all[i] = environment()->Pop();
   3130   }
   3131   Node* value = NewNode(op, arity, all);
   3132   return value;
   3133 }
   3134 
   3135 
   3136 Node* AstGraphBuilder::BuildLocalActivationContext(Node* context) {
   3137   DeclarationScope* scope = info()->scope();
   3138 
   3139   // Allocate a new local context.
   3140   Node* local_context = scope->is_script_scope()
   3141                             ? BuildLocalScriptContext(scope)
   3142                             : BuildLocalFunctionContext(scope);
   3143 
   3144   if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) {
   3145     Node* receiver = environment()->RawParameterLookup(0);
   3146     // Context variable (at bottom of the context chain).
   3147     Variable* variable = scope->receiver();
   3148     DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
   3149     const Operator* op = javascript()->StoreContext(0, variable->index());
   3150     NewNode(op, local_context, receiver);
   3151   }
   3152 
   3153   // Copy parameters into context if necessary.
   3154   int num_parameters = scope->num_parameters();
   3155   for (int i = 0; i < num_parameters; i++) {
   3156     Variable* variable = scope->parameter(i);
   3157     if (!variable->IsContextSlot()) continue;
   3158     Node* parameter = environment()->RawParameterLookup(i + 1);
   3159     // Context variable (at bottom of the context chain).
   3160     DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
   3161     const Operator* op = javascript()->StoreContext(0, variable->index());
   3162     NewNode(op, local_context, parameter);
   3163   }
   3164 
   3165   return local_context;
   3166 }
   3167 
   3168 
   3169 Node* AstGraphBuilder::BuildLocalFunctionContext(Scope* scope) {
   3170   DCHECK(scope->is_function_scope() || scope->is_eval_scope());
   3171 
   3172   // Allocate a new local context.
   3173   int slot_count = scope->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
   3174   const Operator* op = javascript()->CreateFunctionContext(slot_count);
   3175   Node* local_context = NewNode(op, GetFunctionClosure());
   3176 
   3177   return local_context;
   3178 }
   3179 
   3180 
   3181 Node* AstGraphBuilder::BuildLocalScriptContext(Scope* scope) {
   3182   DCHECK(scope->is_script_scope());
   3183 
   3184   // Allocate a new local context.
   3185   Handle<ScopeInfo> scope_info = scope->scope_info();
   3186   const Operator* op = javascript()->CreateScriptContext(scope_info);
   3187   Node* local_context = NewNode(op, GetFunctionClosure());
   3188   PrepareFrameState(local_context, BailoutId::ScriptContext(),
   3189                     OutputFrameStateCombine::Push());
   3190 
   3191   return local_context;
   3192 }
   3193 
   3194 
   3195 Node* AstGraphBuilder::BuildLocalBlockContext(Scope* scope) {
   3196   DCHECK(scope->is_block_scope());
   3197 
   3198   // Allocate a new local context.
   3199   Handle<ScopeInfo> scope_info = scope->scope_info();
   3200   const Operator* op = javascript()->CreateBlockContext(scope_info);
   3201   Node* local_context = NewNode(op, GetFunctionClosureForContext());
   3202 
   3203   return local_context;
   3204 }
   3205 
   3206 
   3207 Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) {
   3208   if (arguments == nullptr) return nullptr;
   3209 
   3210   // Allocate and initialize a new arguments object.
   3211   CreateArgumentsType type =
   3212       is_strict(language_mode()) || !info()->has_simple_parameters()
   3213           ? CreateArgumentsType::kUnmappedArguments
   3214           : CreateArgumentsType::kMappedArguments;
   3215   const Operator* op = javascript()->CreateArguments(type);
   3216   Node* object = NewNode(op, GetFunctionClosure());
   3217   PrepareFrameState(object, BailoutId::None());
   3218 
   3219   // Assign the object to the {arguments} variable. This should never lazy
   3220   // deopt, so it is fine to send invalid bailout id.
   3221   DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated());
   3222   BuildVariableAssignment(arguments, object, Token::ASSIGN, VectorSlotPair(),
   3223                           BailoutId::None());
   3224   return object;
   3225 }
   3226 
   3227 Node* AstGraphBuilder::BuildRestArgumentsArray(Variable* rest) {
   3228   if (rest == nullptr) return nullptr;
   3229 
   3230   // Allocate and initialize a new arguments object.
   3231   CreateArgumentsType type = CreateArgumentsType::kRestParameter;
   3232   const Operator* op = javascript()->CreateArguments(type);
   3233   Node* object = NewNode(op, GetFunctionClosure());
   3234   PrepareFrameState(object, BailoutId::None());
   3235 
   3236   // Assign the object to the {rest} variable. This should never lazy
   3237   // deopt, so it is fine to send invalid bailout id.
   3238   DCHECK(rest->IsContextSlot() || rest->IsStackAllocated());
   3239   BuildVariableAssignment(rest, object, Token::ASSIGN, VectorSlotPair(),
   3240                           BailoutId::None());
   3241   return object;
   3242 }
   3243 
   3244 
   3245 Node* AstGraphBuilder::BuildThisFunctionVariable(Variable* this_function_var) {
   3246   if (this_function_var == nullptr) return nullptr;
   3247 
   3248   // Retrieve the closure we were called with.
   3249   Node* this_function = GetFunctionClosure();
   3250 
   3251   // Assign the object to the {.this_function} variable. This should never lazy
   3252   // deopt, so it is fine to send invalid bailout id.
   3253   BuildVariableAssignment(this_function_var, this_function, Token::INIT,
   3254                           VectorSlotPair(), BailoutId::None());
   3255   return this_function;
   3256 }
   3257 
   3258 
   3259 Node* AstGraphBuilder::BuildNewTargetVariable(Variable* new_target_var) {
   3260   if (new_target_var == nullptr) return nullptr;
   3261 
   3262   // Retrieve the new target we were called with.
   3263   Node* object = GetNewTarget();
   3264 
   3265   // Assign the object to the {new.target} variable. This should never lazy
   3266   // deopt, so it is fine to send invalid bailout id.
   3267   BuildVariableAssignment(new_target_var, object, Token::INIT, VectorSlotPair(),
   3268                           BailoutId::None());
   3269   return object;
   3270 }
   3271 
   3272 
   3273 Node* AstGraphBuilder::BuildHoleCheckThenThrow(Node* value, Variable* variable,
   3274                                                Node* not_hole,
   3275                                                BailoutId bailout_id) {
   3276   IfBuilder hole_check(this);
   3277   Node* the_hole = jsgraph()->TheHoleConstant();
   3278   Node* check = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
   3279                         value, the_hole);
   3280   hole_check.If(check);
   3281   hole_check.Then();
   3282   Node* error = BuildThrowReferenceError(variable, bailout_id);
   3283   environment()->Push(error);
   3284   hole_check.Else();
   3285   environment()->Push(not_hole);
   3286   hole_check.End();
   3287   return environment()->Pop();
   3288 }
   3289 
   3290 
   3291 Node* AstGraphBuilder::BuildHoleCheckElseThrow(Node* value, Variable* variable,
   3292                                                Node* for_hole,
   3293                                                BailoutId bailout_id) {
   3294   IfBuilder hole_check(this);
   3295   Node* the_hole = jsgraph()->TheHoleConstant();
   3296   Node* check = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
   3297                         value, the_hole);
   3298   hole_check.If(check);
   3299   hole_check.Then();
   3300   environment()->Push(for_hole);
   3301   hole_check.Else();
   3302   Node* error = BuildThrowReferenceError(variable, bailout_id);
   3303   environment()->Push(error);
   3304   hole_check.End();
   3305   return environment()->Pop();
   3306 }
   3307 
   3308 
   3309 Node* AstGraphBuilder::BuildThrowIfStaticPrototype(Node* name,
   3310                                                    BailoutId bailout_id) {
   3311   IfBuilder prototype_check(this);
   3312   Node* prototype_string =
   3313       jsgraph()->Constant(isolate()->factory()->prototype_string());
   3314   Node* check = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
   3315                         name, prototype_string);
   3316   prototype_check.If(check);
   3317   prototype_check.Then();
   3318   Node* error = BuildThrowStaticPrototypeError(bailout_id);
   3319   environment()->Push(error);
   3320   prototype_check.Else();
   3321   environment()->Push(name);
   3322   prototype_check.End();
   3323   return environment()->Pop();
   3324 }
   3325 
   3326 
   3327 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
   3328                                          BailoutId bailout_id,
   3329                                          const VectorSlotPair& feedback,
   3330                                          OutputFrameStateCombine combine,
   3331                                          TypeofMode typeof_mode) {
   3332   Node* the_hole = jsgraph()->TheHoleConstant();
   3333   switch (variable->location()) {
   3334     case VariableLocation::UNALLOCATED: {
   3335       // Global var, const, or let variable.
   3336       Handle<Name> name = variable->name();
   3337       if (Node* node = TryLoadGlobalConstant(name)) return node;
   3338       Node* value = BuildGlobalLoad(name, feedback, typeof_mode);
   3339       PrepareFrameState(value, bailout_id, combine);
   3340       return value;
   3341     }
   3342     case VariableLocation::PARAMETER:
   3343     case VariableLocation::LOCAL: {
   3344       // Local var, const, or let variable.
   3345       Node* value = environment()->Lookup(variable);
   3346       if (variable->binding_needs_init()) {
   3347         // Perform check for uninitialized let/const variables.
   3348         if (value->op() == the_hole->op()) {
   3349           value = BuildThrowReferenceError(variable, bailout_id);
   3350         } else if (value->opcode() == IrOpcode::kPhi) {
   3351           value = BuildHoleCheckThenThrow(value, variable, value, bailout_id);
   3352         }
   3353       }
   3354       return value;
   3355     }
   3356     case VariableLocation::CONTEXT: {
   3357       // Context variable (potentially up the context chain).
   3358       int depth = current_scope()->ContextChainLength(variable->scope());
   3359       // TODO(mstarzinger): The {maybe_assigned} flag computed during variable
   3360       // resolution is highly inaccurate and cannot be trusted. We are only
   3361       // taking this information into account when asm.js compilation is used.
   3362       bool immutable = variable->maybe_assigned() == kNotAssigned &&
   3363                        info()->is_function_context_specializing();
   3364       const Operator* op =
   3365           javascript()->LoadContext(depth, variable->index(), immutable);
   3366       Node* value = NewNode(op, current_context());
   3367       // TODO(titzer): initialization checks are redundant for already
   3368       // initialized immutable context loads, but only specialization knows.
   3369       // Maybe specializer should be a parameter to the graph builder?
   3370       if (variable->binding_needs_init()) {
   3371         // Perform check for uninitialized let/const variables.
   3372         value = BuildHoleCheckThenThrow(value, variable, value, bailout_id);
   3373       }
   3374       return value;
   3375     }
   3376     case VariableLocation::LOOKUP: {
   3377       // Dynamic lookup of context variable (anywhere in the chain).
   3378       Handle<String> name = variable->name();
   3379       if (Node* node = TryLoadDynamicVariable(variable, name, bailout_id,
   3380                                               feedback, combine, typeof_mode)) {
   3381         return node;
   3382       }
   3383       Node* value = BuildDynamicLoad(name, typeof_mode);
   3384       PrepareFrameState(value, bailout_id, combine);
   3385       return value;
   3386     }
   3387     case VariableLocation::MODULE:
   3388       UNREACHABLE();
   3389   }
   3390   UNREACHABLE();
   3391   return nullptr;
   3392 }
   3393 
   3394 
   3395 Node* AstGraphBuilder::BuildVariableDelete(Variable* variable,
   3396                                            BailoutId bailout_id,
   3397                                            OutputFrameStateCombine combine) {
   3398   switch (variable->location()) {
   3399     case VariableLocation::UNALLOCATED: {
   3400       // Global var, const, or let variable.
   3401       Node* global = BuildLoadGlobalObject();
   3402       Node* name = jsgraph()->Constant(variable->name());
   3403       const Operator* op = javascript()->DeleteProperty(language_mode());
   3404       Node* result = NewNode(op, global, name);
   3405       PrepareFrameState(result, bailout_id, combine);
   3406       return result;
   3407     }
   3408     case VariableLocation::PARAMETER:
   3409     case VariableLocation::LOCAL:
   3410     case VariableLocation::CONTEXT: {
   3411       // Local var, const, or let variable or context variable.
   3412       return jsgraph()->BooleanConstant(variable->is_this());
   3413     }
   3414     case VariableLocation::LOOKUP: {
   3415       // Dynamic lookup of context variable (anywhere in the chain).
   3416       Node* name = jsgraph()->Constant(variable->name());
   3417       const Operator* op =
   3418           javascript()->CallRuntime(Runtime::kDeleteLookupSlot);
   3419       Node* result = NewNode(op, name);
   3420       PrepareFrameState(result, bailout_id, combine);
   3421       return result;
   3422     }
   3423     case VariableLocation::MODULE:
   3424       UNREACHABLE();
   3425   }
   3426   UNREACHABLE();
   3427   return nullptr;
   3428 }
   3429 
   3430 Node* AstGraphBuilder::BuildVariableAssignment(
   3431     Variable* variable, Node* value, Token::Value op,
   3432     const VectorSlotPair& feedback, BailoutId bailout_id,
   3433     OutputFrameStateCombine combine) {
   3434   Node* the_hole = jsgraph()->TheHoleConstant();
   3435   VariableMode mode = variable->mode();
   3436   switch (variable->location()) {
   3437     case VariableLocation::UNALLOCATED: {
   3438       // Global var, const, or let variable.
   3439       Handle<Name> name = variable->name();
   3440       Node* store = BuildGlobalStore(name, value, feedback);
   3441       PrepareFrameState(store, bailout_id, combine);
   3442       return store;
   3443     }
   3444     case VariableLocation::PARAMETER:
   3445     case VariableLocation::LOCAL:
   3446       // Local var, const, or let variable.
   3447       if (mode == LET && op == Token::INIT) {
   3448         // No initialization check needed because scoping guarantees it. Note
   3449         // that we still perform a lookup to keep the variable live, because
   3450         // baseline code might contain debug code that inspects the variable.
   3451         Node* current = environment()->Lookup(variable);
   3452         CHECK_NOT_NULL(current);
   3453       } else if (mode == LET && op != Token::INIT &&
   3454                  variable->binding_needs_init()) {
   3455         // Perform an initialization check for let declared variables.
   3456         Node* current = environment()->Lookup(variable);
   3457         if (current->op() == the_hole->op()) {
   3458           return BuildThrowReferenceError(variable, bailout_id);
   3459         } else if (current->opcode() == IrOpcode::kPhi) {
   3460           BuildHoleCheckThenThrow(current, variable, value, bailout_id);
   3461         }
   3462       } else if (mode == CONST && op == Token::INIT) {
   3463         // Perform an initialization check for const {this} variables.
   3464         // Note that the {this} variable is the only const variable being able
   3465         // to trigger bind operations outside the TDZ, via {super} calls.
   3466         Node* current = environment()->Lookup(variable);
   3467         if (current->op() != the_hole->op() && variable->is_this()) {
   3468           value = BuildHoleCheckElseThrow(current, variable, value, bailout_id);
   3469         }
   3470       } else if (mode == CONST && op != Token::INIT &&
   3471                  variable->is_sloppy_function_name()) {
   3472         // Non-initializing assignment to sloppy function names is
   3473         // - exception in strict mode.
   3474         // - ignored in sloppy mode.
   3475         DCHECK(!variable->binding_needs_init());
   3476         if (variable->throw_on_const_assignment(language_mode())) {
   3477           return BuildThrowConstAssignError(bailout_id);
   3478         }
   3479         return value;
   3480       } else if (mode == CONST && op != Token::INIT) {
   3481         if (variable->binding_needs_init()) {
   3482           Node* current = environment()->Lookup(variable);
   3483           if (current->op() == the_hole->op()) {
   3484             return BuildThrowReferenceError(variable, bailout_id);
   3485           } else if (current->opcode() == IrOpcode::kPhi) {
   3486             BuildHoleCheckThenThrow(current, variable, value, bailout_id);
   3487           }
   3488         }
   3489         // Assignment to const is exception in all modes.
   3490         return BuildThrowConstAssignError(bailout_id);
   3491       }
   3492       environment()->Bind(variable, value);
   3493       return value;
   3494     case VariableLocation::CONTEXT: {
   3495       // Context variable (potentially up the context chain).
   3496       int depth = current_scope()->ContextChainLength(variable->scope());
   3497       if (mode == LET && op != Token::INIT && variable->binding_needs_init()) {
   3498         // Perform an initialization check for let declared variables.
   3499         const Operator* op =
   3500             javascript()->LoadContext(depth, variable->index(), false);
   3501         Node* current = NewNode(op, current_context());
   3502         value = BuildHoleCheckThenThrow(current, variable, value, bailout_id);
   3503       } else if (mode == CONST && op == Token::INIT) {
   3504         // Perform an initialization check for const {this} variables.
   3505         // Note that the {this} variable is the only const variable being able
   3506         // to trigger bind operations outside the TDZ, via {super} calls.
   3507         if (variable->is_this()) {
   3508           const Operator* op =
   3509               javascript()->LoadContext(depth, variable->index(), false);
   3510           Node* current = NewNode(op, current_context());
   3511           value = BuildHoleCheckElseThrow(current, variable, value, bailout_id);
   3512         }
   3513       } else if (mode == CONST && op != Token::INIT &&
   3514                  variable->is_sloppy_function_name()) {
   3515         // Non-initializing assignment to sloppy function names is
   3516         // - exception in strict mode.
   3517         // - ignored in sloppy mode.
   3518         DCHECK(!variable->binding_needs_init());
   3519         if (variable->throw_on_const_assignment(language_mode())) {
   3520           return BuildThrowConstAssignError(bailout_id);
   3521         }
   3522         return value;
   3523       } else if (mode == CONST && op != Token::INIT) {
   3524         if (variable->binding_needs_init()) {
   3525           const Operator* op =
   3526               javascript()->LoadContext(depth, variable->index(), false);
   3527           Node* current = NewNode(op, current_context());
   3528           BuildHoleCheckThenThrow(current, variable, value, bailout_id);
   3529         }
   3530         // Assignment to const is exception in all modes.
   3531         return BuildThrowConstAssignError(bailout_id);
   3532       }
   3533       const Operator* op = javascript()->StoreContext(depth, variable->index());
   3534       return NewNode(op, current_context(), value);
   3535     }
   3536     case VariableLocation::LOOKUP: {
   3537       // Dynamic lookup of context variable (anywhere in the chain).
   3538       Handle<Name> name = variable->name();
   3539       Node* store = BuildDynamicStore(name, value);
   3540       PrepareFrameState(store, bailout_id, combine);
   3541       return store;
   3542     }
   3543     case VariableLocation::MODULE:
   3544       UNREACHABLE();
   3545   }
   3546   UNREACHABLE();
   3547   return nullptr;
   3548 }
   3549 
   3550 
   3551 Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key,
   3552                                       const VectorSlotPair& feedback) {
   3553   const Operator* op = javascript()->LoadProperty(feedback);
   3554   Node* node = NewNode(op, object, key, GetFunctionClosure());
   3555   return node;
   3556 }
   3557 
   3558 
   3559 Node* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name,
   3560                                       const VectorSlotPair& feedback) {
   3561   const Operator* op = javascript()->LoadNamed(name, feedback);
   3562   Node* node = NewNode(op, object, GetFunctionClosure());
   3563   return node;
   3564 }
   3565 
   3566 
   3567 Node* AstGraphBuilder::BuildKeyedStore(Node* object, Node* key, Node* value,
   3568                                        const VectorSlotPair& feedback) {
   3569   const Operator* op = javascript()->StoreProperty(language_mode(), feedback);
   3570   Node* node = NewNode(op, object, key, value, GetFunctionClosure());
   3571   return node;
   3572 }
   3573 
   3574 
   3575 Node* AstGraphBuilder::BuildNamedStore(Node* object, Handle<Name> name,
   3576                                        Node* value,
   3577                                        const VectorSlotPair& feedback) {
   3578   const Operator* op =
   3579       javascript()->StoreNamed(language_mode(), name, feedback);
   3580   Node* node = NewNode(op, object, value, GetFunctionClosure());
   3581   return node;
   3582 }
   3583 
   3584 
   3585 Node* AstGraphBuilder::BuildNamedSuperLoad(Node* receiver, Node* home_object,
   3586                                            Handle<Name> name,
   3587                                            const VectorSlotPair& feedback) {
   3588   Node* name_node = jsgraph()->Constant(name);
   3589   const Operator* op = javascript()->CallRuntime(Runtime::kLoadFromSuper);
   3590   Node* node = NewNode(op, receiver, home_object, name_node);
   3591   return node;
   3592 }
   3593 
   3594 
   3595 Node* AstGraphBuilder::BuildKeyedSuperLoad(Node* receiver, Node* home_object,
   3596                                            Node* key,
   3597                                            const VectorSlotPair& feedback) {
   3598   const Operator* op = javascript()->CallRuntime(Runtime::kLoadKeyedFromSuper);
   3599   Node* node = NewNode(op, receiver, home_object, key);
   3600   return node;
   3601 }
   3602 
   3603 
   3604 Node* AstGraphBuilder::BuildKeyedSuperStore(Node* receiver, Node* home_object,
   3605                                             Node* key, Node* value) {
   3606   Runtime::FunctionId function_id = is_strict(language_mode())
   3607                                         ? Runtime::kStoreKeyedToSuper_Strict
   3608                                         : Runtime::kStoreKeyedToSuper_Sloppy;
   3609   const Operator* op = javascript()->CallRuntime(function_id, 4);
   3610   Node* node = NewNode(op, receiver, home_object, key, value);
   3611   return node;
   3612 }
   3613 
   3614 
   3615 Node* AstGraphBuilder::BuildNamedSuperStore(Node* receiver, Node* home_object,
   3616                                             Handle<Name> name, Node* value) {
   3617   Node* name_node = jsgraph()->Constant(name);
   3618   Runtime::FunctionId function_id = is_strict(language_mode())
   3619                                         ? Runtime::kStoreToSuper_Strict
   3620                                         : Runtime::kStoreToSuper_Sloppy;
   3621   const Operator* op = javascript()->CallRuntime(function_id, 4);
   3622   Node* node = NewNode(op, receiver, home_object, name_node, value);
   3623   return node;
   3624 }
   3625 
   3626 
   3627 Node* AstGraphBuilder::BuildGlobalLoad(Handle<Name> name,
   3628                                        const VectorSlotPair& feedback,
   3629                                        TypeofMode typeof_mode) {
   3630   const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
   3631   Node* node = NewNode(op, GetFunctionClosure());
   3632   return node;
   3633 }
   3634 
   3635 
   3636 Node* AstGraphBuilder::BuildGlobalStore(Handle<Name> name, Node* value,
   3637                                         const VectorSlotPair& feedback) {
   3638   const Operator* op =
   3639       javascript()->StoreGlobal(language_mode(), name, feedback);
   3640   Node* node = NewNode(op, value, GetFunctionClosure());
   3641   return node;
   3642 }
   3643 
   3644 
   3645 Node* AstGraphBuilder::BuildDynamicLoad(Handle<Name> name,
   3646                                         TypeofMode typeof_mode) {
   3647   Node* name_node = jsgraph()->Constant(name);
   3648   const Operator* op =
   3649       javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
   3650                                     ? Runtime::kLoadLookupSlot
   3651                                     : Runtime::kLoadLookupSlotInsideTypeof);
   3652   Node* node = NewNode(op, name_node);
   3653   return node;
   3654 }
   3655 
   3656 
   3657 Node* AstGraphBuilder::BuildDynamicStore(Handle<Name> name, Node* value) {
   3658   Node* name_node = jsgraph()->Constant(name);
   3659   const Operator* op = javascript()->CallRuntime(
   3660       is_strict(language_mode()) ? Runtime::kStoreLookupSlot_Strict
   3661                                  : Runtime::kStoreLookupSlot_Sloppy);
   3662   Node* node = NewNode(op, name_node, value);
   3663   return node;
   3664 }
   3665 
   3666 
   3667 Node* AstGraphBuilder::BuildLoadGlobalObject() {
   3668   return BuildLoadNativeContextField(Context::EXTENSION_INDEX);
   3669 }
   3670 
   3671 
   3672 Node* AstGraphBuilder::BuildLoadNativeContextField(int index) {
   3673   const Operator* op =
   3674       javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true);
   3675   Node* native_context = NewNode(op, current_context());
   3676   return NewNode(javascript()->LoadContext(0, index, true), native_context);
   3677 }
   3678 
   3679 
   3680 Node* AstGraphBuilder::BuildToBoolean(Node* input, TypeFeedbackId feedback_id) {
   3681   if (Node* node = TryFastToBoolean(input)) return node;
   3682   ToBooleanHints hints;
   3683   if (!type_hint_analysis_ ||
   3684       !type_hint_analysis_->GetToBooleanHints(feedback_id, &hints)) {
   3685     hints = ToBooleanHint::kAny;
   3686   }
   3687   return NewNode(javascript()->ToBoolean(hints), input);
   3688 }
   3689 
   3690 
   3691 Node* AstGraphBuilder::BuildToName(Node* input, BailoutId bailout_id) {
   3692   if (Node* node = TryFastToName(input)) return node;
   3693   Node* name = NewNode(javascript()->ToName(), input);
   3694   PrepareFrameState(name, bailout_id, OutputFrameStateCombine::Push());
   3695   return name;
   3696 }
   3697 
   3698 
   3699 Node* AstGraphBuilder::BuildToObject(Node* input, BailoutId bailout_id) {
   3700   Node* object = NewNode(javascript()->ToObject(), input);
   3701   PrepareFrameState(object, bailout_id, OutputFrameStateCombine::Push());
   3702   return object;
   3703 }
   3704 
   3705 Node* AstGraphBuilder::BuildSetHomeObject(Node* value, Node* home_object,
   3706                                           LiteralProperty* property,
   3707                                           int slot_number) {
   3708   Expression* expr = property->value();
   3709   if (!FunctionLiteral::NeedsHomeObject(expr)) return value;
   3710   Handle<Name> name = isolate()->factory()->home_object_symbol();
   3711   VectorSlotPair feedback =
   3712       CreateVectorSlotPair(property->GetSlot(slot_number));
   3713   Node* store = BuildNamedStore(value, name, home_object, feedback);
   3714   PrepareFrameState(store, BailoutId::None(),
   3715                     OutputFrameStateCombine::Ignore());
   3716   return store;
   3717 }
   3718 
   3719 
   3720 Node* AstGraphBuilder::BuildThrowError(Node* exception, BailoutId bailout_id) {
   3721   const Operator* op = javascript()->CallRuntime(Runtime::kThrow);
   3722   Node* call = NewNode(op, exception);
   3723   PrepareFrameState(call, bailout_id);
   3724   Node* control = NewNode(common()->Throw(), call);
   3725   UpdateControlDependencyToLeaveFunction(control);
   3726   return call;
   3727 }
   3728 
   3729 
   3730 Node* AstGraphBuilder::BuildThrowReferenceError(Variable* variable,
   3731                                                 BailoutId bailout_id) {
   3732   Node* variable_name = jsgraph()->Constant(variable->name());
   3733   const Operator* op = javascript()->CallRuntime(Runtime::kThrowReferenceError);
   3734   Node* call = NewNode(op, variable_name);
   3735   PrepareFrameState(call, bailout_id);
   3736   Node* control = NewNode(common()->Throw(), call);
   3737   UpdateControlDependencyToLeaveFunction(control);
   3738   return call;
   3739 }
   3740 
   3741 
   3742 Node* AstGraphBuilder::BuildThrowConstAssignError(BailoutId bailout_id) {
   3743   const Operator* op =
   3744       javascript()->CallRuntime(Runtime::kThrowConstAssignError);
   3745   Node* call = NewNode(op);
   3746   PrepareFrameState(call, bailout_id);
   3747   Node* control = NewNode(common()->Throw(), call);
   3748   UpdateControlDependencyToLeaveFunction(control);
   3749   return call;
   3750 }
   3751 
   3752 
   3753 Node* AstGraphBuilder::BuildThrowStaticPrototypeError(BailoutId bailout_id) {
   3754   const Operator* op =
   3755       javascript()->CallRuntime(Runtime::kThrowStaticPrototypeError);
   3756   Node* call = NewNode(op);
   3757   PrepareFrameState(call, bailout_id);
   3758   Node* control = NewNode(common()->Throw(), call);
   3759   UpdateControlDependencyToLeaveFunction(control);
   3760   return call;
   3761 }
   3762 
   3763 
   3764 Node* AstGraphBuilder::BuildThrowUnsupportedSuperError(BailoutId bailout_id) {
   3765   const Operator* op =
   3766       javascript()->CallRuntime(Runtime::kThrowUnsupportedSuperError);
   3767   Node* call = NewNode(op);
   3768   PrepareFrameState(call, bailout_id);
   3769   Node* control = NewNode(common()->Throw(), call);
   3770   UpdateControlDependencyToLeaveFunction(control);
   3771   return call;
   3772 }
   3773 
   3774 
   3775 Node* AstGraphBuilder::BuildReturn(Node* return_value) {
   3776   // Emit tracing call if requested to do so.
   3777   if (FLAG_trace) {
   3778     return_value =
   3779         NewNode(javascript()->CallRuntime(Runtime::kTraceExit), return_value);
   3780   }
   3781   Node* pop_node = jsgraph()->ZeroConstant();
   3782   Node* control = NewNode(common()->Return(), pop_node, return_value);
   3783   UpdateControlDependencyToLeaveFunction(control);
   3784   return control;
   3785 }
   3786 
   3787 
   3788 Node* AstGraphBuilder::BuildThrow(Node* exception_value) {
   3789   NewNode(javascript()->CallRuntime(Runtime::kReThrow), exception_value);
   3790   Node* control = NewNode(common()->Throw(), exception_value);
   3791   UpdateControlDependencyToLeaveFunction(control);
   3792   return control;
   3793 }
   3794 
   3795 
   3796 Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op,
   3797                                      TypeFeedbackId feedback_id) {
   3798   const Operator* js_op;
   3799   BinaryOperationHint hint;
   3800   if (!type_hint_analysis_ ||
   3801       !type_hint_analysis_->GetBinaryOperationHint(feedback_id, &hint)) {
   3802     hint = BinaryOperationHint::kAny;
   3803   }
   3804   switch (op) {
   3805     case Token::BIT_OR:
   3806       js_op = javascript()->BitwiseOr(hint);
   3807       break;
   3808     case Token::BIT_AND:
   3809       js_op = javascript()->BitwiseAnd(hint);
   3810       break;
   3811     case Token::BIT_XOR:
   3812       js_op = javascript()->BitwiseXor(hint);
   3813       break;
   3814     case Token::SHL:
   3815       js_op = javascript()->ShiftLeft(hint);
   3816       break;
   3817     case Token::SAR:
   3818       js_op = javascript()->ShiftRight(hint);
   3819       break;
   3820     case Token::SHR:
   3821       js_op = javascript()->ShiftRightLogical(hint);
   3822       break;
   3823     case Token::ADD:
   3824       js_op = javascript()->Add(hint);
   3825       break;
   3826     case Token::SUB:
   3827       js_op = javascript()->Subtract(hint);
   3828       break;
   3829     case Token::MUL:
   3830       js_op = javascript()->Multiply(hint);
   3831       break;
   3832     case Token::DIV:
   3833       js_op = javascript()->Divide(hint);
   3834       break;
   3835     case Token::MOD:
   3836       js_op = javascript()->Modulus(hint);
   3837       break;
   3838     default:
   3839       UNREACHABLE();
   3840       js_op = nullptr;
   3841   }
   3842   return NewNode(js_op, left, right);
   3843 }
   3844 
   3845 
   3846 Node* AstGraphBuilder::TryLoadGlobalConstant(Handle<Name> name) {
   3847   // Optimize global constants like "undefined", "Infinity", and "NaN".
   3848   Handle<Object> constant_value = isolate()->factory()->GlobalConstantFor(name);
   3849   if (!constant_value.is_null()) return jsgraph()->Constant(constant_value);
   3850   return nullptr;
   3851 }
   3852 
   3853 Node* AstGraphBuilder::TryLoadDynamicVariable(Variable* variable,
   3854                                               Handle<String> name,
   3855                                               BailoutId bailout_id,
   3856                                               const VectorSlotPair& feedback,
   3857                                               OutputFrameStateCombine combine,
   3858                                               TypeofMode typeof_mode) {
   3859   VariableMode mode = variable->mode();
   3860 
   3861   if (mode == DYNAMIC_GLOBAL) {
   3862     uint32_t bitset = ComputeBitsetForDynamicGlobal(variable);
   3863     if (bitset == kFullCheckRequired) return nullptr;
   3864 
   3865     // We are using two blocks to model fast and slow cases.
   3866     BlockBuilder fast_block(this);
   3867     BlockBuilder slow_block(this);
   3868     environment()->Push(jsgraph()->TheHoleConstant());
   3869     slow_block.BeginBlock();
   3870     environment()->Pop();
   3871     fast_block.BeginBlock();
   3872 
   3873     // Perform checks whether the fast mode applies, by looking for any
   3874     // extension object which might shadow the optimistic declaration.
   3875     for (int depth = 0; bitset != 0; bitset >>= 1, depth++) {
   3876       if ((bitset & 1) == 0) continue;
   3877       Node* load = NewNode(
   3878           javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false),
   3879           current_context());
   3880       Node* check =
   3881           NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), load,
   3882                   jsgraph()->TheHoleConstant());
   3883       fast_block.BreakUnless(check, BranchHint::kTrue);
   3884     }
   3885 
   3886     // Fast case, because variable is not shadowed.
   3887     if (Node* constant = TryLoadGlobalConstant(name)) {
   3888       environment()->Push(constant);
   3889     } else {
   3890       // Perform global slot load.
   3891       Node* fast = BuildGlobalLoad(name, feedback, typeof_mode);
   3892       PrepareFrameState(fast, bailout_id, combine);
   3893       environment()->Push(fast);
   3894     }
   3895     slow_block.Break();
   3896     environment()->Pop();
   3897     fast_block.EndBlock();
   3898 
   3899     // Slow case, because variable potentially shadowed. Perform dynamic lookup.
   3900     Node* slow = BuildDynamicLoad(name, typeof_mode);
   3901     PrepareFrameState(slow, bailout_id, combine);
   3902     environment()->Push(slow);
   3903     slow_block.EndBlock();
   3904 
   3905     return environment()->Pop();
   3906   }
   3907 
   3908   if (mode == DYNAMIC_LOCAL) {
   3909     uint32_t bitset = ComputeBitsetForDynamicContext(variable);
   3910     if (bitset == kFullCheckRequired) return nullptr;
   3911 
   3912     // We are using two blocks to model fast and slow cases.
   3913     BlockBuilder fast_block(this);
   3914     BlockBuilder slow_block(this);
   3915     environment()->Push(jsgraph()->TheHoleConstant());
   3916     slow_block.BeginBlock();
   3917     environment()->Pop();
   3918     fast_block.BeginBlock();
   3919 
   3920     // Perform checks whether the fast mode applies, by looking for any
   3921     // extension object which might shadow the optimistic declaration.
   3922     for (int depth = 0; bitset != 0; bitset >>= 1, depth++) {
   3923       if ((bitset & 1) == 0) continue;
   3924       Node* load = NewNode(
   3925           javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false),
   3926           current_context());
   3927       Node* check =
   3928           NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), load,
   3929                   jsgraph()->TheHoleConstant());
   3930       fast_block.BreakUnless(check, BranchHint::kTrue);
   3931     }
   3932 
   3933     // Fast case, because variable is not shadowed. Perform context slot load.
   3934     Variable* local = variable->local_if_not_shadowed();
   3935     DCHECK(local->location() == VariableLocation::CONTEXT);  // Must be context.
   3936     Node* fast =
   3937         BuildVariableLoad(local, bailout_id, feedback, combine, typeof_mode);
   3938     environment()->Push(fast);
   3939     slow_block.Break();
   3940     environment()->Pop();
   3941     fast_block.EndBlock();
   3942 
   3943     // Slow case, because variable potentially shadowed. Perform dynamic lookup.
   3944     Node* slow = BuildDynamicLoad(name, typeof_mode);
   3945     PrepareFrameState(slow, bailout_id, combine);
   3946     environment()->Push(slow);
   3947     slow_block.EndBlock();
   3948 
   3949     return environment()->Pop();
   3950   }
   3951 
   3952   return nullptr;
   3953 }
   3954 
   3955 
   3956 Node* AstGraphBuilder::TryFastToBoolean(Node* input) {
   3957   switch (input->opcode()) {
   3958     case IrOpcode::kNumberConstant: {
   3959       NumberMatcher m(input);
   3960       return jsgraph_->BooleanConstant(!m.Is(0) && !m.IsNaN());
   3961     }
   3962     case IrOpcode::kHeapConstant: {
   3963       Handle<HeapObject> object = HeapObjectMatcher(input).Value();
   3964       return jsgraph_->BooleanConstant(object->BooleanValue());
   3965     }
   3966     case IrOpcode::kJSEqual:
   3967     case IrOpcode::kJSNotEqual:
   3968     case IrOpcode::kJSStrictEqual:
   3969     case IrOpcode::kJSStrictNotEqual:
   3970     case IrOpcode::kJSLessThan:
   3971     case IrOpcode::kJSLessThanOrEqual:
   3972     case IrOpcode::kJSGreaterThan:
   3973     case IrOpcode::kJSGreaterThanOrEqual:
   3974     case IrOpcode::kJSToBoolean:
   3975     case IrOpcode::kJSDeleteProperty:
   3976     case IrOpcode::kJSHasProperty:
   3977     case IrOpcode::kJSInstanceOf:
   3978       return input;
   3979     default:
   3980       break;
   3981   }
   3982   return nullptr;
   3983 }
   3984 
   3985 
   3986 Node* AstGraphBuilder::TryFastToName(Node* input) {
   3987   switch (input->opcode()) {
   3988     case IrOpcode::kHeapConstant: {
   3989       Handle<HeapObject> object = HeapObjectMatcher(input).Value();
   3990       if (object->IsName()) return input;
   3991       break;
   3992     }
   3993     case IrOpcode::kJSToString:
   3994     case IrOpcode::kJSToName:
   3995     case IrOpcode::kJSTypeOf:
   3996       return input;
   3997     default:
   3998       break;
   3999   }
   4000   return nullptr;
   4001 }
   4002 
   4003 
   4004 bool AstGraphBuilder::CheckOsrEntry(IterationStatement* stmt) {
   4005   if (info()->osr_ast_id() == stmt->OsrEntryId()) {
   4006     DCHECK_EQ(-1, info()->osr_expr_stack_height());
   4007     info()->set_osr_expr_stack_height(environment()->stack_height());
   4008     return true;
   4009   }
   4010   return false;
   4011 }
   4012 
   4013 
   4014 void AstGraphBuilder::PrepareFrameState(Node* node, BailoutId ast_id,
   4015                                         OutputFrameStateCombine combine) {
   4016   if (OperatorProperties::HasFrameStateInput(node->op())) {
   4017     DCHECK(ast_id.IsNone() || info()->shared_info()->VerifyBailoutId(ast_id));
   4018     DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
   4019     DCHECK_EQ(IrOpcode::kDead,
   4020               NodeProperties::GetFrameStateInput(node)->opcode());
   4021     bool has_exception = NodeProperties::IsExceptionalCall(node);
   4022     Node* state = environment()->Checkpoint(ast_id, combine, has_exception);
   4023     NodeProperties::ReplaceFrameStateInput(node, state);
   4024   }
   4025 }
   4026 
   4027 void AstGraphBuilder::PrepareEagerCheckpoint(BailoutId ast_id) {
   4028   if (environment()->GetEffectDependency()->opcode() == IrOpcode::kCheckpoint) {
   4029     // We skip preparing a checkpoint if there already is one the current effect
   4030     // dependency. This is just an optimization and not need for correctness.
   4031     return;
   4032   }
   4033   if (ast_id != BailoutId::None()) {
   4034     DCHECK(info()->shared_info()->VerifyBailoutId(ast_id));
   4035     Node* node = NewNode(common()->Checkpoint());
   4036     DCHECK_EQ(IrOpcode::kDead,
   4037               NodeProperties::GetFrameStateInput(node)->opcode());
   4038     Node* state = environment()->Checkpoint(ast_id);
   4039     NodeProperties::ReplaceFrameStateInput(node, state);
   4040   }
   4041 }
   4042 
   4043 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop(
   4044     IterationStatement* stmt) {
   4045   if (loop_assignment_analysis_ == nullptr) return nullptr;
   4046   return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt);
   4047 }
   4048 
   4049 
   4050 Node** AstGraphBuilder::EnsureInputBufferSize(int size) {
   4051   if (size > input_buffer_size_) {
   4052     size = size + kInputBufferSizeIncrement + input_buffer_size_;
   4053     input_buffer_ = local_zone()->NewArray<Node*>(size);
   4054     input_buffer_size_ = size;
   4055   }
   4056   return input_buffer_;
   4057 }
   4058 
   4059 
   4060 Node* AstGraphBuilder::MakeNode(const Operator* op, int value_input_count,
   4061                                 Node** value_inputs, bool incomplete) {
   4062   DCHECK_EQ(op->ValueInputCount(), value_input_count);
   4063 
   4064   bool has_context = OperatorProperties::HasContextInput(op);
   4065   bool has_frame_state = OperatorProperties::HasFrameStateInput(op);
   4066   bool has_control = op->ControlInputCount() == 1;
   4067   bool has_effect = op->EffectInputCount() == 1;
   4068 
   4069   DCHECK(op->ControlInputCount() < 2);
   4070   DCHECK(op->EffectInputCount() < 2);
   4071 
   4072   Node* result = nullptr;
   4073   if (!has_context && !has_frame_state && !has_control && !has_effect) {
   4074     result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
   4075   } else {
   4076     bool inside_try_scope = try_nesting_level_ > 0;
   4077     int input_count_with_deps = value_input_count;
   4078     if (has_context) ++input_count_with_deps;
   4079     if (has_frame_state) ++input_count_with_deps;
   4080     if (has_control) ++input_count_with_deps;
   4081     if (has_effect) ++input_count_with_deps;
   4082     Node** buffer = EnsureInputBufferSize(input_count_with_deps);
   4083     memcpy(buffer, value_inputs, kPointerSize * value_input_count);
   4084     Node** current_input = buffer + value_input_count;
   4085     if (has_context) {
   4086       *current_input++ = current_context();
   4087     }
   4088     if (has_frame_state) {
   4089       // The frame state will be inserted later. Here we misuse
   4090       // the {Dead} node as a sentinel to be later overwritten
   4091       // with the real frame state.
   4092       *current_input++ = jsgraph()->Dead();
   4093     }
   4094     if (has_effect) {
   4095       *current_input++ = environment_->GetEffectDependency();
   4096     }
   4097     if (has_control) {
   4098       *current_input++ = environment_->GetControlDependency();
   4099     }
   4100     result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
   4101     if (!environment()->IsMarkedAsUnreachable()) {
   4102       // Update the current control dependency for control-producing nodes.
   4103       if (NodeProperties::IsControl(result)) {
   4104         environment_->UpdateControlDependency(result);
   4105       }
   4106       // Update the current effect dependency for effect-producing nodes.
   4107       if (result->op()->EffectOutputCount() > 0) {
   4108         environment_->UpdateEffectDependency(result);
   4109       }
   4110       // Add implicit exception continuation for throwing nodes.
   4111       if (!result->op()->HasProperty(Operator::kNoThrow) && inside_try_scope) {
   4112         // Copy the environment for the success continuation.
   4113         Environment* success_env = environment()->CopyForConditional();
   4114         const Operator* op = common()->IfException();
   4115         Node* effect = environment()->GetEffectDependency();
   4116         Node* on_exception = graph()->NewNode(op, effect, result);
   4117         environment_->UpdateControlDependency(on_exception);
   4118         environment_->UpdateEffectDependency(on_exception);
   4119         execution_control()->ThrowValue(on_exception);
   4120         set_environment(success_env);
   4121       }
   4122       // Add implicit success continuation for throwing nodes.
   4123       if (!result->op()->HasProperty(Operator::kNoThrow)) {
   4124         const Operator* op = common()->IfSuccess();
   4125         Node* on_success = graph()->NewNode(op, result);
   4126         environment_->UpdateControlDependency(on_success);
   4127       }
   4128     }
   4129   }
   4130 
   4131   return result;
   4132 }
   4133 
   4134 
   4135 void AstGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
   4136   if (environment()->IsMarkedAsUnreachable()) return;
   4137   environment()->MarkAsUnreachable();
   4138   exit_controls_.push_back(exit);
   4139 }
   4140 
   4141 
   4142 void AstGraphBuilder::Environment::Merge(Environment* other) {
   4143   DCHECK(values_.size() == other->values_.size());
   4144   DCHECK(contexts_.size() == other->contexts_.size());
   4145 
   4146   // Nothing to do if the other environment is dead.
   4147   if (other->IsMarkedAsUnreachable()) return;
   4148 
   4149   // Resurrect a dead environment by copying the contents of the other one and
   4150   // placing a singleton merge as the new control dependency.
   4151   if (this->IsMarkedAsUnreachable()) {
   4152     Node* other_control = other->control_dependency_;
   4153     Node* inputs[] = {other_control};
   4154     control_dependency_ =
   4155         graph()->NewNode(common()->Merge(1), arraysize(inputs), inputs, true);
   4156     effect_dependency_ = other->effect_dependency_;
   4157     values_ = other->values_;
   4158     contexts_ = other->contexts_;
   4159     if (IsLivenessAnalysisEnabled()) {
   4160       liveness_block_ =
   4161           builder_->liveness_analyzer()->NewBlock(other->liveness_block());
   4162     }
   4163     return;
   4164   }
   4165 
   4166   // Record the merge for the local variable liveness calculation.
   4167   // For loops, we are connecting a back edge into the existing block;
   4168   // for merges, we create a new merged block.
   4169   if (IsLivenessAnalysisEnabled()) {
   4170     if (GetControlDependency()->opcode() != IrOpcode::kLoop) {
   4171       liveness_block_ =
   4172           builder_->liveness_analyzer()->NewBlock(liveness_block());
   4173     }
   4174     liveness_block()->AddPredecessor(other->liveness_block());
   4175   }
   4176 
   4177   // Create a merge of the control dependencies of both environments and update
   4178   // the current environment's control dependency accordingly.
   4179   Node* control = builder_->MergeControl(this->GetControlDependency(),
   4180                                          other->GetControlDependency());
   4181   UpdateControlDependency(control);
   4182 
   4183   // Create a merge of the effect dependencies of both environments and update
   4184   // the current environment's effect dependency accordingly.
   4185   Node* effect = builder_->MergeEffect(this->GetEffectDependency(),
   4186                                        other->GetEffectDependency(), control);
   4187   UpdateEffectDependency(effect);
   4188 
   4189   // Introduce Phi nodes for values that have differing input at merge points,
   4190   // potentially extending an existing Phi node if possible.
   4191   for (int i = 0; i < static_cast<int>(values_.size()); ++i) {
   4192     values_[i] = builder_->MergeValue(values_[i], other->values_[i], control);
   4193   }
   4194   for (int i = 0; i < static_cast<int>(contexts_.size()); ++i) {
   4195     contexts_[i] =
   4196         builder_->MergeValue(contexts_[i], other->contexts_[i], control);
   4197   }
   4198 }
   4199 
   4200 void AstGraphBuilder::Environment::PrepareForOsrEntry() {
   4201   int size = static_cast<int>(values()->size());
   4202   Graph* graph = builder_->graph();
   4203 
   4204   // Set the control and effect to the OSR loop entry.
   4205   Node* osr_loop_entry = graph->NewNode(builder_->common()->OsrLoopEntry(),
   4206                                         graph->start(), graph->start());
   4207   UpdateControlDependency(osr_loop_entry);
   4208   UpdateEffectDependency(osr_loop_entry);
   4209 
   4210   // Set OSR values.
   4211   for (int i = 0; i < size; ++i) {
   4212     values()->at(i) =
   4213         graph->NewNode(builder_->common()->OsrValue(i), osr_loop_entry);
   4214   }
   4215 
   4216   // Set the innermost context.
   4217   const Operator* op_inner =
   4218       builder_->common()->OsrValue(Linkage::kOsrContextSpillSlotIndex);
   4219   contexts()->back() = graph->NewNode(op_inner, osr_loop_entry);
   4220 
   4221   // Create a checkpoint.
   4222   Node* frame_state = Checkpoint(builder_->info()->osr_ast_id());
   4223   Node* checkpoint = graph->NewNode(common()->Checkpoint(), frame_state,
   4224                                     osr_loop_entry, osr_loop_entry);
   4225   UpdateEffectDependency(checkpoint);
   4226 
   4227   // Create the OSR guard nodes.
   4228   const Operator* guard_op =
   4229       builder_->info()->is_deoptimization_enabled()
   4230           ? builder_->common()->OsrGuard(OsrGuardType::kUninitialized)
   4231           : builder_->common()->OsrGuard(OsrGuardType::kAny);
   4232   Node* effect = checkpoint;
   4233   for (int i = 0; i < size; ++i) {
   4234     values()->at(i) = effect =
   4235         graph->NewNode(guard_op, values()->at(i), effect, osr_loop_entry);
   4236   }
   4237   contexts()->back() = effect =
   4238       graph->NewNode(guard_op, contexts()->back(), effect, osr_loop_entry);
   4239 
   4240   // The innermost context is the OSR value, and the outer contexts are
   4241   // reconstructed by dynamically walking up the context chain.
   4242   const Operator* load_op =
   4243       builder_->javascript()->LoadContext(0, Context::PREVIOUS_INDEX, true);
   4244   Node* osr_context = effect = contexts()->back();
   4245   int last = static_cast<int>(contexts()->size() - 1);
   4246   for (int i = last - 1; i >= 0; i--) {
   4247     osr_context = effect =
   4248         graph->NewNode(load_op, osr_context, osr_context, effect);
   4249     contexts()->at(i) = osr_context;
   4250   }
   4251   UpdateEffectDependency(effect);
   4252 }
   4253 
   4254 void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned) {
   4255   int size = static_cast<int>(values()->size());
   4256 
   4257   Node* control = builder_->NewLoop();
   4258   if (assigned == nullptr) {
   4259     // Assume that everything is updated in the loop.
   4260     for (int i = 0; i < size; ++i) {
   4261       values()->at(i) = builder_->NewPhi(1, values()->at(i), control);
   4262     }
   4263   } else {
   4264     // Only build phis for those locals assigned in this loop.
   4265     for (int i = 0; i < size; ++i) {
   4266       if (i < assigned->length() && !assigned->Contains(i)) continue;
   4267       Node* phi = builder_->NewPhi(1, values()->at(i), control);
   4268       values()->at(i) = phi;
   4269     }
   4270   }
   4271   Node* effect = builder_->NewEffectPhi(1, GetEffectDependency(), control);
   4272   UpdateEffectDependency(effect);
   4273 
   4274   // Connect the loop to end via Terminate if it's not marked as unreachable.
   4275   if (!IsMarkedAsUnreachable()) {
   4276     // Connect the Loop node to end via a Terminate node.
   4277     Node* terminate = builder_->graph()->NewNode(
   4278         builder_->common()->Terminate(), effect, control);
   4279     builder_->exit_controls_.push_back(terminate);
   4280   }
   4281 
   4282   if (builder_->info()->is_osr()) {
   4283     // Introduce phis for all context values in the case of an OSR graph.
   4284     for (size_t i = 0; i < contexts()->size(); ++i) {
   4285       Node* context = contexts()->at(i);
   4286       contexts()->at(i) = builder_->NewPhi(1, context, control);
   4287     }
   4288   }
   4289 }
   4290 
   4291 
   4292 Node* AstGraphBuilder::NewPhi(int count, Node* input, Node* control) {
   4293   const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
   4294   Node** buffer = EnsureInputBufferSize(count + 1);
   4295   MemsetPointer(buffer, input, count);
   4296   buffer[count] = control;
   4297   return graph()->NewNode(phi_op, count + 1, buffer, true);
   4298 }
   4299 
   4300 
   4301 Node* AstGraphBuilder::NewEffectPhi(int count, Node* input, Node* control) {
   4302   const Operator* phi_op = common()->EffectPhi(count);
   4303   Node** buffer = EnsureInputBufferSize(count + 1);
   4304   MemsetPointer(buffer, input, count);
   4305   buffer[count] = control;
   4306   return graph()->NewNode(phi_op, count + 1, buffer, true);
   4307 }
   4308 
   4309 
   4310 Node* AstGraphBuilder::MergeControl(Node* control, Node* other) {
   4311   int inputs = control->op()->ControlInputCount() + 1;
   4312   if (control->opcode() == IrOpcode::kLoop) {
   4313     // Control node for loop exists, add input.
   4314     const Operator* op = common()->Loop(inputs);
   4315     control->AppendInput(graph_zone(), other);
   4316     NodeProperties::ChangeOp(control, op);
   4317   } else if (control->opcode() == IrOpcode::kMerge) {
   4318     // Control node for merge exists, add input.
   4319     const Operator* op = common()->Merge(inputs);
   4320     control->AppendInput(graph_zone(), other);
   4321     NodeProperties::ChangeOp(control, op);
   4322   } else {
   4323     // Control node is a singleton, introduce a merge.
   4324     const Operator* op = common()->Merge(inputs);
   4325     Node* inputs[] = {control, other};
   4326     control = graph()->NewNode(op, arraysize(inputs), inputs, true);
   4327   }
   4328   return control;
   4329 }
   4330 
   4331 
   4332 Node* AstGraphBuilder::MergeEffect(Node* value, Node* other, Node* control) {
   4333   int inputs = control->op()->ControlInputCount();
   4334   if (value->opcode() == IrOpcode::kEffectPhi &&
   4335       NodeProperties::GetControlInput(value) == control) {
   4336     // Phi already exists, add input.
   4337     value->InsertInput(graph_zone(), inputs - 1, other);
   4338     NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
   4339   } else if (value != other) {
   4340     // Phi does not exist yet, introduce one.
   4341     value = NewEffectPhi(inputs, value, control);
   4342     value->ReplaceInput(inputs - 1, other);
   4343   }
   4344   return value;
   4345 }
   4346 
   4347 
   4348 Node* AstGraphBuilder::MergeValue(Node* value, Node* other, Node* control) {
   4349   int inputs = control->op()->ControlInputCount();
   4350   if (value->opcode() == IrOpcode::kPhi &&
   4351       NodeProperties::GetControlInput(value) == control) {
   4352     // Phi already exists, add input.
   4353     value->InsertInput(graph_zone(), inputs - 1, other);
   4354     NodeProperties::ChangeOp(
   4355         value, common()->Phi(MachineRepresentation::kTagged, inputs));
   4356   } else if (value != other) {
   4357     // Phi does not exist yet, introduce one.
   4358     value = NewPhi(inputs, value, control);
   4359     value->ReplaceInput(inputs - 1, other);
   4360   }
   4361   return value;
   4362 }
   4363 
   4364 AstGraphBuilderWithPositions::AstGraphBuilderWithPositions(
   4365     Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph,
   4366     float invocation_frequency, LoopAssignmentAnalysis* loop_assignment,
   4367     TypeHintAnalysis* type_hint_analysis, SourcePositionTable* source_positions,
   4368     int inlining_id)
   4369     : AstGraphBuilder(local_zone, info, jsgraph, invocation_frequency,
   4370                       loop_assignment, type_hint_analysis),
   4371       source_positions_(source_positions),
   4372       start_position_(info->shared_info()->start_position(), inlining_id) {}
   4373 
   4374 }  // namespace compiler
   4375 }  // namespace internal
   4376 }  // namespace v8
   4377