ast-graph-builder.h revision c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7a
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
14namespace v8 {
15namespace internal {
16
17// Forward declarations.
18class BitVector;
19class CompilationInfo;
20
21namespace compiler {
22
23// Forward declarations.
24class ControlBuilder;
25class Graph;
26class LoopAssignmentAnalysis;
27class LoopBuilder;
28class Node;
29class 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.
38class 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//
474class 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
620class 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