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 #ifndef V8_COMPILER_AST_GRAPH_BUILDER_H_
      6 #define V8_COMPILER_AST_GRAPH_BUILDER_H_
      7 
      8 #include "src/ast/ast.h"
      9 #include "src/compiler/compiler-source-position-table.h"
     10 #include "src/compiler/js-graph.h"
     11 #include "src/compiler/liveness-analyzer.h"
     12 #include "src/compiler/state-values-utils.h"
     13 
     14 namespace v8 {
     15 namespace internal {
     16 
     17 // Forward declarations.
     18 class BitVector;
     19 class CompilationInfo;
     20 
     21 namespace compiler {
     22 
     23 // Forward declarations.
     24 class ControlBuilder;
     25 class Graph;
     26 class LoopAssignmentAnalysis;
     27 class LoopBuilder;
     28 class Node;
     29 class TypeHintAnalysis;
     30 
     31 
     32 // The AstGraphBuilder produces a high-level IR graph, based on an
     33 // underlying AST. The produced graph can either be compiled into a
     34 // stand-alone function or be wired into another graph for the purposes
     35 // of function inlining.
     36 // This AstVistor is not final, and provides the AstVisitor methods as virtual
     37 // methods so they can be specialized by subclasses.
     38 class AstGraphBuilder : public AstVisitor<AstGraphBuilder> {
     39  public:
     40   AstGraphBuilder(Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph,
     41                   float invocation_frequency,
     42                   LoopAssignmentAnalysis* loop_assignment = nullptr,
     43                   TypeHintAnalysis* type_hint_analysis = nullptr);
     44   virtual ~AstGraphBuilder() {}
     45 
     46   // Creates a graph by visiting the entire AST.
     47   bool CreateGraph(bool stack_check = true);
     48 
     49   // Helpers to create new control nodes.
     50   Node* NewIfTrue() { return NewNode(common()->IfTrue()); }
     51   Node* NewIfFalse() { return NewNode(common()->IfFalse()); }
     52   Node* NewMerge() { return NewNode(common()->Merge(1), true); }
     53   Node* NewLoop() { return NewNode(common()->Loop(1), true); }
     54   Node* NewBranch(Node* condition, BranchHint hint = BranchHint::kNone) {
     55     return NewNode(common()->Branch(hint), condition);
     56   }
     57 
     58  protected:
     59 #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
     60   // Visiting functions for AST nodes make this an AstVisitor.
     61   AST_NODE_LIST(DECLARE_VISIT)
     62 #undef DECLARE_VISIT
     63 
     64   // Visiting function for declarations list is overridden.
     65   void VisitDeclarations(Declaration::List* declarations);
     66 
     67  private:
     68   class AstContext;
     69   class AstEffectContext;
     70   class AstValueContext;
     71   class AstTestContext;
     72   class ContextScope;
     73   class ControlScope;
     74   class ControlScopeForBreakable;
     75   class ControlScopeForIteration;
     76   class ControlScopeForCatch;
     77   class ControlScopeForFinally;
     78   class Environment;
     79   friend class ControlBuilder;
     80 
     81   Isolate* isolate_;
     82   Zone* local_zone_;
     83   CompilationInfo* info_;
     84   JSGraph* jsgraph_;
     85   float const invocation_frequency_;
     86   Environment* environment_;
     87   AstContext* ast_context_;
     88 
     89   // List of global declarations for functions and variables.
     90   ZoneVector<Handle<Object>> globals_;
     91 
     92   // Stack of control scopes currently entered by the visitor.
     93   ControlScope* execution_control_;
     94 
     95   // Stack of context objects pushed onto the chain by the visitor.
     96   ContextScope* execution_context_;
     97 
     98   // Nodes representing values in the activation record.
     99   SetOncePointer<Node> function_closure_;
    100   SetOncePointer<Node> function_context_;
    101   SetOncePointer<Node> new_target_;
    102 
    103   // Tracks how many try-blocks are currently entered.
    104   int try_nesting_level_;
    105 
    106   // Temporary storage for building node input lists.
    107   int input_buffer_size_;
    108   Node** input_buffer_;
    109 
    110   // Optimization to cache loaded feedback vector.
    111   SetOncePointer<Node> feedback_vector_;
    112 
    113   // Optimization to cache empty frame state.
    114   SetOncePointer<Node> empty_frame_state_;
    115 
    116   // Control nodes that exit the function body.
    117   ZoneVector<Node*> exit_controls_;
    118 
    119   // Result of loop assignment analysis performed before graph creation.
    120   LoopAssignmentAnalysis* loop_assignment_analysis_;
    121 
    122   // Result of type hint analysis performed before graph creation.
    123   TypeHintAnalysis* type_hint_analysis_;
    124 
    125   // Cache for StateValues nodes for frame states.
    126   StateValuesCache state_values_cache_;
    127 
    128   // Analyzer of local variable liveness.
    129   LivenessAnalyzer liveness_analyzer_;
    130 
    131   // Function info for frame state construction.
    132   const FrameStateFunctionInfo* const frame_state_function_info_;
    133 
    134   // Growth increment for the temporary buffer used to construct input lists to
    135   // new nodes.
    136   static const int kInputBufferSizeIncrement = 64;
    137 
    138   Zone* local_zone() const { return local_zone_; }
    139   Environment* environment() const { return environment_; }
    140   AstContext* ast_context() const { return ast_context_; }
    141   ControlScope* execution_control() const { return execution_control_; }
    142   ContextScope* execution_context() const { return execution_context_; }
    143   CommonOperatorBuilder* common() const { return jsgraph_->common(); }
    144   CompilationInfo* info() const { return info_; }
    145   Isolate* isolate() const { return isolate_; }
    146   LanguageMode language_mode() const;
    147   JSGraph* jsgraph() { return jsgraph_; }
    148   Graph* graph() { return jsgraph_->graph(); }
    149   Zone* graph_zone() { return graph()->zone(); }
    150   JSOperatorBuilder* javascript() { return jsgraph_->javascript(); }
    151   ZoneVector<Handle<Object>>* globals() { return &globals_; }
    152   Scope* current_scope() const;
    153   Node* current_context() const;
    154   LivenessAnalyzer* liveness_analyzer() { return &liveness_analyzer_; }
    155   const FrameStateFunctionInfo* frame_state_function_info() const {
    156     return frame_state_function_info_;
    157   }
    158 
    159   void set_environment(Environment* env) { environment_ = env; }
    160   void set_ast_context(AstContext* ctx) { ast_context_ = ctx; }
    161   void set_execution_control(ControlScope* ctrl) { execution_control_ = ctrl; }
    162   void set_execution_context(ContextScope* ctx) { execution_context_ = ctx; }
    163 
    164   // Create the main graph body by visiting the AST.
    165   void CreateGraphBody(bool stack_check);
    166 
    167   // Get or create the node that represents the incoming function closure.
    168   Node* GetFunctionClosureForContext();
    169   Node* GetFunctionClosure();
    170 
    171   // Get or create the node that represents the incoming function context.
    172   Node* GetFunctionContext();
    173 
    174   // Get or create the node that represents the incoming new target value.
    175   Node* GetNewTarget();
    176 
    177   // Get or create the node that represents the empty frame state.
    178   Node* GetEmptyFrameState();
    179 
    180   // Node creation helpers.
    181   Node* NewNode(const Operator* op, bool incomplete = false) {
    182     return MakeNode(op, 0, static_cast<Node**>(nullptr), incomplete);
    183   }
    184 
    185   Node* NewNode(const Operator* op, Node* n1) {
    186     return MakeNode(op, 1, &n1, false);
    187   }
    188 
    189   Node* NewNode(const Operator* op, Node* n1, Node* n2) {
    190     Node* buffer[] = {n1, n2};
    191     return MakeNode(op, arraysize(buffer), buffer, false);
    192   }
    193 
    194   Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) {
    195     Node* buffer[] = {n1, n2, n3};
    196     return MakeNode(op, arraysize(buffer), buffer, false);
    197   }
    198 
    199   Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) {
    200     Node* buffer[] = {n1, n2, n3, n4};
    201     return MakeNode(op, arraysize(buffer), buffer, false);
    202   }
    203 
    204   Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
    205                 Node* n5) {
    206     Node* buffer[] = {n1, n2, n3, n4, n5};
    207     return MakeNode(op, arraysize(buffer), buffer, false);
    208   }
    209 
    210   Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
    211                 Node* n5, Node* n6) {
    212     Node* nodes[] = {n1, n2, n3, n4, n5, n6};
    213     return MakeNode(op, arraysize(nodes), nodes, false);
    214   }
    215 
    216   Node* NewNode(const Operator* op, int value_input_count, Node** value_inputs,
    217                 bool incomplete = false) {
    218     return MakeNode(op, value_input_count, value_inputs, incomplete);
    219   }
    220 
    221   // Creates a new Phi node having {count} input values.
    222   Node* NewPhi(int count, Node* input, Node* control);
    223   Node* NewEffectPhi(int count, Node* input, Node* control);
    224 
    225   // Helpers for merging control, effect or value dependencies.
    226   Node* MergeControl(Node* control, Node* other);
    227   Node* MergeEffect(Node* value, Node* other, Node* control);
    228   Node* MergeValue(Node* value, Node* other, Node* control);
    229 
    230   // The main node creation chokepoint. Adds context, frame state, effect,
    231   // and control dependencies depending on the operator.
    232   Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs,
    233                  bool incomplete);
    234 
    235   // Helper to indicate a node exits the function body.
    236   void UpdateControlDependencyToLeaveFunction(Node* exit);
    237 
    238   // Prepare information for lazy deoptimization. This information is attached
    239   // to the given node and the output value produced by the node is combined.
    240   // Conceptually this frame state is "after" a given operation.
    241   void PrepareFrameState(Node* node, BailoutId ast_id,
    242                          OutputFrameStateCombine framestate_combine =
    243                              OutputFrameStateCombine::Ignore());
    244 
    245   // Prepare information for eager deoptimization. This information is carried
    246   // by dedicated {Checkpoint} nodes that are wired into the effect chain.
    247   // Conceptually this frame state is "before" a given operation.
    248   void PrepareEagerCheckpoint(BailoutId ast_id);
    249 
    250   BitVector* GetVariablesAssignedInLoop(IterationStatement* stmt);
    251 
    252   // Check if the given statement is an OSR entry.
    253   // If so, record the stack height into the compilation and return {true}.
    254   bool CheckOsrEntry(IterationStatement* stmt);
    255 
    256   // Computes local variable liveness and replaces dead variables in
    257   // frame states with the undefined values.
    258   void ClearNonLiveSlotsInFrameStates();
    259 
    260   Node** EnsureInputBufferSize(int size);
    261 
    262   // Named and keyed loads require a VectorSlotPair for successful lowering.
    263   VectorSlotPair CreateVectorSlotPair(FeedbackVectorSlot slot) const;
    264 
    265   // Determine which contexts need to be checked for extension objects that
    266   // might shadow the optimistic declaration of dynamic lookup variables.
    267   uint32_t ComputeBitsetForDynamicGlobal(Variable* variable);
    268   uint32_t ComputeBitsetForDynamicContext(Variable* variable);
    269 
    270   // Computes the frequency for JSCallFunction and JSCallConstruct nodes.
    271   float ComputeCallFrequency(FeedbackVectorSlot slot) const;
    272 
    273   // ===========================================================================
    274   // The following build methods all generate graph fragments and return one
    275   // resulting node. The operand stack height remains the same, variables and
    276   // other dependencies tracked by the environment might be mutated though.
    277 
    278   // Builders to create local function, script and block contexts.
    279   Node* BuildLocalActivationContext(Node* context);
    280   Node* BuildLocalFunctionContext(Scope* scope);
    281   Node* BuildLocalScriptContext(Scope* scope);
    282   Node* BuildLocalBlockContext(Scope* scope);
    283 
    284   // Builder to create an arguments object if it is used.
    285   Node* BuildArgumentsObject(Variable* arguments);
    286 
    287   // Builder to create an array of rest parameters if used.
    288   Node* BuildRestArgumentsArray(Variable* rest);
    289 
    290   // Builder that assigns to the {.this_function} internal variable if needed.
    291   Node* BuildThisFunctionVariable(Variable* this_function_var);
    292 
    293   // Builder that assigns to the {new.target} internal variable if needed.
    294   Node* BuildNewTargetVariable(Variable* new_target_var);
    295 
    296   // Builders for variable load and assignment.
    297   Node* BuildVariableAssignment(Variable* variable, Node* value,
    298                                 Token::Value op, const VectorSlotPair& slot,
    299                                 BailoutId bailout_id,
    300                                 OutputFrameStateCombine framestate_combine =
    301                                     OutputFrameStateCombine::Ignore());
    302   Node* BuildVariableDelete(Variable* variable, BailoutId bailout_id,
    303                             OutputFrameStateCombine framestate_combine);
    304   Node* BuildVariableLoad(Variable* variable, BailoutId bailout_id,
    305                           const VectorSlotPair& feedback,
    306                           OutputFrameStateCombine framestate_combine,
    307                           TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
    308 
    309   // Builders for property loads and stores.
    310   Node* BuildKeyedLoad(Node* receiver, Node* key,
    311                        const VectorSlotPair& feedback);
    312   Node* BuildNamedLoad(Node* receiver, Handle<Name> name,
    313                        const VectorSlotPair& feedback);
    314   Node* BuildKeyedStore(Node* receiver, Node* key, Node* value,
    315                         const VectorSlotPair& feedback);
    316   Node* BuildNamedStore(Node* receiver, Handle<Name> name, Node* value,
    317                         const VectorSlotPair& feedback);
    318 
    319   // Builders for super property loads and stores.
    320   Node* BuildKeyedSuperStore(Node* receiver, Node* home_object, Node* key,
    321                              Node* value);
    322   Node* BuildNamedSuperStore(Node* receiver, Node* home_object,
    323                              Handle<Name> name, Node* value);
    324   Node* BuildNamedSuperLoad(Node* receiver, Node* home_object,
    325                             Handle<Name> name, const VectorSlotPair& feedback);
    326   Node* BuildKeyedSuperLoad(Node* receiver, Node* home_object, Node* key,
    327                             const VectorSlotPair& feedback);
    328 
    329   // Builders for global variable loads and stores.
    330   Node* BuildGlobalLoad(Handle<Name> name, const VectorSlotPair& feedback,
    331                         TypeofMode typeof_mode);
    332   Node* BuildGlobalStore(Handle<Name> name, Node* value,
    333                          const VectorSlotPair& feedback);
    334 
    335   // Builders for dynamic variable loads and stores.
    336   Node* BuildDynamicLoad(Handle<Name> name, TypeofMode typeof_mode);
    337   Node* BuildDynamicStore(Handle<Name> name, Node* value);
    338 
    339   // Builders for accessing the function context.
    340   Node* BuildLoadGlobalObject();
    341   Node* BuildLoadNativeContextField(int index);
    342 
    343   // Builders for automatic type conversion.
    344   Node* BuildToBoolean(Node* input, TypeFeedbackId feedback_id);
    345   Node* BuildToName(Node* input, BailoutId bailout_id);
    346   Node* BuildToObject(Node* input, BailoutId bailout_id);
    347 
    348   // Builder for adding the [[HomeObject]] to a value if the value came from a
    349   // function literal and needs a home object. Do nothing otherwise.
    350   Node* BuildSetHomeObject(Node* value, Node* home_object,
    351                            LiteralProperty* property, int slot_number = 0);
    352 
    353   // Builders for error reporting at runtime.
    354   Node* BuildThrowError(Node* exception, BailoutId bailout_id);
    355   Node* BuildThrowReferenceError(Variable* var, BailoutId bailout_id);
    356   Node* BuildThrowConstAssignError(BailoutId bailout_id);
    357   Node* BuildThrowStaticPrototypeError(BailoutId bailout_id);
    358   Node* BuildThrowUnsupportedSuperError(BailoutId bailout_id);
    359 
    360   // Builders for dynamic hole-checks at runtime.
    361   Node* BuildHoleCheckThenThrow(Node* value, Variable* var, Node* not_hole,
    362                                 BailoutId bailout_id);
    363   Node* BuildHoleCheckElseThrow(Node* value, Variable* var, Node* for_hole,
    364                                 BailoutId bailout_id);
    365 
    366   // Builders for conditional errors.
    367   Node* BuildThrowIfStaticPrototype(Node* name, BailoutId bailout_id);
    368 
    369   // Builders for non-local control flow.
    370   Node* BuildReturn(Node* return_value);
    371   Node* BuildThrow(Node* exception_value);
    372 
    373   // Builders for binary operations.
    374   Node* BuildBinaryOp(Node* left, Node* right, Token::Value op,
    375                       TypeFeedbackId feedback_id);
    376 
    377   // Process arguments to a call by popping {arity} elements off the operand
    378   // stack and build a call node using the given call operator.
    379   Node* ProcessArguments(const Operator* op, int arity);
    380 
    381   // ===========================================================================
    382   // The following build methods have the same contract as the above ones, but
    383   // they can also return {nullptr} to indicate that no fragment was built. Note
    384   // that these are optimizations, disabling any of them should still produce
    385   // correct graphs.
    386 
    387   // Optimization for variable load from global object.
    388   Node* TryLoadGlobalConstant(Handle<Name> name);
    389 
    390   // Optimization for variable load of dynamic lookup slot that is most likely
    391   // to resolve to a global slot or context slot (inferred from scope chain).
    392   Node* TryLoadDynamicVariable(Variable* variable, Handle<String> name,
    393                                BailoutId bailout_id,
    394                                const VectorSlotPair& feedback,
    395                                OutputFrameStateCombine combine,
    396                                TypeofMode typeof_mode);
    397 
    398   // Optimizations for automatic type conversion.
    399   Node* TryFastToBoolean(Node* input);
    400   Node* TryFastToName(Node* input);
    401 
    402   // ===========================================================================
    403   // The following visitation methods all recursively visit a subtree of the
    404   // underlying AST and extent the graph. The operand stack is mutated in a way
    405   // consistent with other compilers:
    406   //  - Expressions pop operands and push result, depending on {AstContext}.
    407   //  - Statements keep the operand stack balanced.
    408 
    409   // Visit statements.
    410   void VisitIfNotNull(Statement* stmt);
    411   void VisitInScope(Statement* stmt, Scope* scope, Node* context);
    412 
    413   // Visit expressions.
    414   void Visit(Expression* expr);
    415   void VisitForTest(Expression* expr);
    416   void VisitForEffect(Expression* expr);
    417   void VisitForValue(Expression* expr);
    418   void VisitForValueOrNull(Expression* expr);
    419   void VisitForValueOrTheHole(Expression* expr);
    420   void VisitForValues(ZoneList<Expression*>* exprs);
    421 
    422   // Common for all IterationStatement bodies.
    423   void VisitIterationBody(IterationStatement* stmt, LoopBuilder* loop,
    424                           BailoutId stack_check_id);
    425 
    426   // Dispatched from VisitCall.
    427   void VisitCallSuper(Call* expr);
    428 
    429   // Dispatched from VisitCallRuntime.
    430   void VisitCallJSRuntime(CallRuntime* expr);
    431 
    432   // Dispatched from VisitUnaryOperation.
    433   void VisitDelete(UnaryOperation* expr);
    434   void VisitVoid(UnaryOperation* expr);
    435   void VisitTypeof(UnaryOperation* expr);
    436   void VisitNot(UnaryOperation* expr);
    437 
    438   // Dispatched from VisitTypeof, VisitLiteralCompareTypeof.
    439   void VisitTypeofExpression(Expression* expr);
    440 
    441   // Dispatched from VisitBinaryOperation.
    442   void VisitComma(BinaryOperation* expr);
    443   void VisitLogicalExpression(BinaryOperation* expr);
    444   void VisitArithmeticExpression(BinaryOperation* expr);
    445 
    446   // Dispatched from VisitCompareOperation.
    447   void VisitLiteralCompareNil(CompareOperation* expr, Expression* sub_expr,
    448                               Node* nil_value);
    449   void VisitLiteralCompareTypeof(CompareOperation* expr, Expression* sub_expr,
    450                                  Handle<String> check);
    451 
    452   // Dispatched from VisitForInStatement.
    453   void VisitForInAssignment(Expression* expr, Node* value,
    454                             const VectorSlotPair& feedback,
    455                             BailoutId bailout_id);
    456 
    457   // Dispatched from VisitObjectLiteral.
    458   void VisitObjectLiteralAccessor(Node* home_object,
    459                                   ObjectLiteralProperty* property);
    460 
    461   DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
    462   DISALLOW_COPY_AND_ASSIGN(AstGraphBuilder);
    463 };
    464 
    465 
    466 // The abstract execution environment for generated code consists of
    467 // parameter variables, local variables and the operand stack. The
    468 // environment will perform proper SSA-renaming of all tracked nodes
    469 // at split and merge points in the control flow. Internally all the
    470 // values are stored in one list using the following layout:
    471 //
    472 //  [parameters (+receiver)] [locals] [operand stack]
    473 //
    474 class AstGraphBuilder::Environment : public ZoneObject {
    475  public:
    476   Environment(AstGraphBuilder* builder, DeclarationScope* scope,
    477               Node* control_dependency);
    478 
    479   int parameters_count() const { return parameters_count_; }
    480   int locals_count() const { return locals_count_; }
    481   int context_chain_length() { return static_cast<int>(contexts_.size()); }
    482   int stack_height() {
    483     return static_cast<int>(values()->size()) - parameters_count_ -
    484            locals_count_;
    485   }
    486 
    487   // Operations on parameter or local variables.
    488   void Bind(Variable* variable, Node* node);
    489   Node* Lookup(Variable* variable);
    490   void MarkAllLocalsLive();
    491 
    492   // Raw operations on parameter variables.
    493   void RawParameterBind(int index, Node* node);
    494   Node* RawParameterLookup(int index);
    495 
    496   // Operations on the context chain.
    497   Node* Context() const { return contexts_.back(); }
    498   void PushContext(Node* context) { contexts()->push_back(context); }
    499   void PopContext() { contexts()->pop_back(); }
    500   void TrimContextChain(int trim_to_length) {
    501     contexts()->resize(trim_to_length);
    502   }
    503 
    504   // Operations on the operand stack.
    505   void Push(Node* node) {
    506     values()->push_back(node);
    507   }
    508   Node* Top() {
    509     DCHECK(stack_height() > 0);
    510     return values()->back();
    511   }
    512   Node* Pop() {
    513     DCHECK(stack_height() > 0);
    514     Node* back = values()->back();
    515     values()->pop_back();
    516     return back;
    517   }
    518 
    519   // Direct mutations of the operand stack.
    520   void Poke(int depth, Node* node) {
    521     DCHECK(depth >= 0 && depth < stack_height());
    522     int index = static_cast<int>(values()->size()) - depth - 1;
    523     values()->at(index) = node;
    524   }
    525   Node* Peek(int depth) {
    526     DCHECK(depth >= 0 && depth < stack_height());
    527     int index = static_cast<int>(values()->size()) - depth - 1;
    528     return values()->at(index);
    529   }
    530   void Drop(int depth) {
    531     DCHECK(depth >= 0 && depth <= stack_height());
    532     values()->erase(values()->end() - depth, values()->end());
    533   }
    534   void TrimStack(int trim_to_height) {
    535     int depth = stack_height() - trim_to_height;
    536     DCHECK(depth >= 0 && depth <= stack_height());
    537     values()->erase(values()->end() - depth, values()->end());
    538   }
    539 
    540   // Preserve a checkpoint of the environment for the IR graph. Any
    541   // further mutation of the environment will not affect checkpoints.
    542   Node* Checkpoint(BailoutId ast_id, OutputFrameStateCombine combine =
    543                                          OutputFrameStateCombine::Ignore(),
    544                    bool node_has_exception = false);
    545 
    546   // Inserts a loop exit control node and renames the environment.
    547   // This is useful for loop peeling to insert phis at loop exits.
    548   void PrepareForLoopExit(Node* loop, BitVector* assigned_variables);
    549 
    550   // Control dependency tracked by this environment.
    551   Node* GetControlDependency() { return control_dependency_; }
    552   void UpdateControlDependency(Node* dependency) {
    553     control_dependency_ = dependency;
    554   }
    555 
    556   // Effect dependency tracked by this environment.
    557   Node* GetEffectDependency() { return effect_dependency_; }
    558   void UpdateEffectDependency(Node* dependency) {
    559     effect_dependency_ = dependency;
    560   }
    561 
    562   // Mark this environment as being unreachable.
    563   void MarkAsUnreachable() {
    564     UpdateControlDependency(builder()->jsgraph()->Dead());
    565     liveness_block_ = nullptr;
    566   }
    567   bool IsMarkedAsUnreachable() {
    568     return GetControlDependency()->opcode() == IrOpcode::kDead;
    569   }
    570 
    571   // Merge another environment into this one.
    572   void Merge(Environment* other);
    573 
    574   // Copies this environment at a control-flow split point.
    575   Environment* CopyForConditional();
    576 
    577   // Copies this environment to a potentially unreachable control-flow point.
    578   Environment* CopyAsUnreachable();
    579 
    580   // Copies this environment at a loop header control-flow point.
    581   Environment* CopyForLoop(BitVector* assigned, bool is_osr = false);
    582 
    583   // Copies this environment for Osr entry. This only produces environment
    584   // of the right shape, the caller is responsible for filling in the right
    585   // values and dependencies.
    586   Environment* CopyForOsrEntry();
    587 
    588  private:
    589   AstGraphBuilder* builder_;
    590   int parameters_count_;
    591   int locals_count_;
    592   LivenessAnalyzerBlock* liveness_block_;
    593   NodeVector values_;
    594   NodeVector contexts_;
    595   Node* control_dependency_;
    596   Node* effect_dependency_;
    597   Node* parameters_node_;
    598   Node* locals_node_;
    599   Node* stack_node_;
    600 
    601   explicit Environment(Environment* copy,
    602                        LivenessAnalyzerBlock* liveness_block);
    603   Environment* CopyAndShareLiveness();
    604   void UpdateStateValues(Node** state_values, int offset, int count);
    605   Zone* zone() const { return builder_->local_zone(); }
    606   Graph* graph() const { return builder_->graph(); }
    607   AstGraphBuilder* builder() const { return builder_; }
    608   CommonOperatorBuilder* common() { return builder_->common(); }
    609   NodeVector* values() { return &values_; }
    610   NodeVector* contexts() { return &contexts_; }
    611   LivenessAnalyzerBlock* liveness_block() { return liveness_block_; }
    612   bool IsLivenessAnalysisEnabled();
    613   bool IsLivenessBlockConsistent();
    614 
    615   // Prepare environment to be used as loop header.
    616   void PrepareForLoop(BitVector* assigned);
    617   void PrepareForOsrEntry();
    618 };
    619 
    620 class AstGraphBuilderWithPositions final : public AstGraphBuilder {
    621  public:
    622   AstGraphBuilderWithPositions(Zone* local_zone, CompilationInfo* info,
    623                                JSGraph* jsgraph, float invocation_frequency,
    624                                LoopAssignmentAnalysis* loop_assignment,
    625                                TypeHintAnalysis* type_hint_analysis,
    626                                SourcePositionTable* source_positions,
    627                                int inlining_id = SourcePosition::kNotInlined);
    628 
    629   bool CreateGraph(bool stack_check = true) {
    630     SourcePositionTable::Scope pos_scope(source_positions_, start_position_);
    631     return AstGraphBuilder::CreateGraph(stack_check);
    632   }
    633 
    634 #define DEF_VISIT(type)                                                  \
    635   void Visit##type(type* node) override {                                \
    636     SourcePositionTable::Scope pos(                                      \
    637         source_positions_,                                               \
    638         SourcePosition(node->position(), start_position_.InliningId())); \
    639     AstGraphBuilder::Visit##type(node);                                  \
    640   }
    641   AST_NODE_LIST(DEF_VISIT)
    642 #undef DEF_VISIT
    643 
    644  private:
    645   SourcePositionTable* const source_positions_;
    646   SourcePosition const start_position_;
    647 };
    648 
    649 }  // namespace compiler
    650 }  // namespace internal
    651 }  // namespace v8
    652 
    653 #endif  // V8_COMPILER_AST_GRAPH_BUILDER_H_
    654