ast-graph-builder.h 23.1 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_COMPILER_AST_GRAPH_BUILDER_H_
#define V8_COMPILER_AST_GRAPH_BUILDER_H_

8
#include "src/ast/ast.h"
9
#include "src/compiler/js-graph.h"
10
#include "src/compiler/liveness-analyzer.h"
11
#include "src/compiler/state-values-utils.h"
12 13 14

namespace v8 {
namespace internal {
15

16
// Forward declarations.
17 18
class BitVector;

19

20 21
namespace compiler {

22
// Forward declarations.
23 24
class ControlBuilder;
class Graph;
25 26
class LoopAssignmentAnalysis;
class LoopBuilder;
27
class Node;
28 29
class TypeHintAnalysis;

30 31 32 33 34

// The AstGraphBuilder produces a high-level IR graph, based on an
// underlying AST. The produced graph can either be compiled into a
// stand-alone function or be wired into another graph for the purposes
// of function inlining.
35
class AstGraphBuilder : public AstVisitor {
36
 public:
37
  AstGraphBuilder(Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph,
38 39
                  LoopAssignmentAnalysis* loop_assignment = nullptr,
                  TypeHintAnalysis* type_hint_analysis = nullptr);
40 41

  // Creates a graph by visiting the entire AST.
42
  bool CreateGraph(bool stack_check = true);
43

44 45 46 47 48 49 50 51 52
  // Helpers to create new control nodes.
  Node* NewIfTrue() { return NewNode(common()->IfTrue()); }
  Node* NewIfFalse() { return NewNode(common()->IfFalse()); }
  Node* NewMerge() { return NewNode(common()->Merge(1), true); }
  Node* NewLoop() { return NewNode(common()->Loop(1), true); }
  Node* NewBranch(Node* condition, BranchHint hint = BranchHint::kNone) {
    return NewNode(common()->Branch(hint), condition);
  }

53
 protected:
54
#define DECLARE_VISIT(type) void Visit##type(type* node) override;
55 56 57 58 59
  // Visiting functions for AST nodes make this an AstVisitor.
  AST_NODE_LIST(DECLARE_VISIT)
#undef DECLARE_VISIT

  // Visiting function for declarations list is overridden.
60
  void VisitDeclarations(ZoneList<Declaration*>* declarations) override;
61 62

 private:
63 64 65 66 67
  class AstContext;
  class AstEffectContext;
  class AstValueContext;
  class AstTestContext;
  class ContextScope;
68 69 70 71 72
  class ControlScope;
  class ControlScopeForBreakable;
  class ControlScopeForIteration;
  class ControlScopeForCatch;
  class ControlScopeForFinally;
73
  class Environment;
74
  class FrameStateBeforeAndAfter;
75
  friend class ControlBuilder;
76

77
  Isolate* isolate_;
78 79 80 81 82 83 84 85 86
  Zone* local_zone_;
  CompilationInfo* info_;
  JSGraph* jsgraph_;
  Environment* environment_;
  AstContext* ast_context_;

  // List of global declarations for functions and variables.
  ZoneVector<Handle<Object>> globals_;

87 88
  // Stack of control scopes currently entered by the visitor.
  ControlScope* execution_control_;
89 90 91 92 93 94

  // Stack of context objects pushed onto the chain by the visitor.
  ContextScope* execution_context_;

  // Nodes representing values in the activation record.
  SetOncePointer<Node> function_closure_;
95
  SetOncePointer<Node> function_context_;
96
  SetOncePointer<Node> new_target_;
97

98
  // Tracks how many try-blocks are currently entered.
99
  int try_catch_nesting_level_;
100 101
  int try_nesting_level_;

102 103 104
  // Temporary storage for building node input lists.
  int input_buffer_size_;
  Node** input_buffer_;
105

106 107 108
  // Optimization to cache loaded feedback vector.
  SetOncePointer<Node> feedback_vector_;

109 110
  // Control nodes that exit the function body.
  ZoneVector<Node*> exit_controls_;
111 112 113 114

  // Result of loop assignment analysis performed before graph creation.
  LoopAssignmentAnalysis* loop_assignment_analysis_;

115 116 117
  // Result of type hint analysis performed before graph creation.
  TypeHintAnalysis* type_hint_analysis_;

118 119 120
  // Cache for StateValues nodes for frame states.
  StateValuesCache state_values_cache_;

121 122 123
  // Analyzer of local variable liveness.
  LivenessAnalyzer liveness_analyzer_;

124 125 126
  // Function info for frame state construction.
  const FrameStateFunctionInfo* const frame_state_function_info_;

127 128 129 130 131
  // Growth increment for the temporary buffer used to construct input lists to
  // new nodes.
  static const int kInputBufferSizeIncrement = 64;

  Zone* local_zone() const { return local_zone_; }
132
  Environment* environment() const { return environment_; }
133
  AstContext* ast_context() const { return ast_context_; }
134
  ControlScope* execution_control() const { return execution_control_; }
135
  ContextScope* execution_context() const { return execution_context_; }
136 137
  CommonOperatorBuilder* common() const { return jsgraph_->common(); }
  CompilationInfo* info() const { return info_; }
138
  Isolate* isolate() const { return isolate_; }
139
  LanguageMode language_mode() const;
140 141 142 143 144
  JSGraph* jsgraph() { return jsgraph_; }
  Graph* graph() { return jsgraph_->graph(); }
  Zone* graph_zone() { return graph()->zone(); }
  JSOperatorBuilder* javascript() { return jsgraph_->javascript(); }
  ZoneVector<Handle<Object>>* globals() { return &globals_; }
145
  Scope* current_scope() const;
146
  Node* current_context() const;
147
  LivenessAnalyzer* liveness_analyzer() { return &liveness_analyzer_; }
148 149 150
  const FrameStateFunctionInfo* frame_state_function_info() const {
    return frame_state_function_info_;
  }
151

152
  void set_environment(Environment* env) { environment_ = env; }
153
  void set_ast_context(AstContext* ctx) { ast_context_ = ctx; }
154
  void set_execution_control(ControlScope* ctrl) { execution_control_ = ctrl; }
155 156
  void set_execution_context(ContextScope* ctx) { execution_context_ = ctx; }

157
  // Create the main graph body by visiting the AST.
158
  void CreateGraphBody(bool stack_check);
159

160
  // Get or create the node that represents the incoming function closure.
161
  Node* GetFunctionClosureForContext();
162 163
  Node* GetFunctionClosure();

164
  // Get or create the node that represents the incoming function context.
165 166
  Node* GetFunctionContext();

167 168 169
  // Get or create the node that represents the incoming new target value.
  Node* GetNewTarget();

170 171
  // Node creation helpers.
  Node* NewNode(const Operator* op, bool incomplete = false) {
172
    return MakeNode(op, 0, static_cast<Node**>(nullptr), incomplete);
173
  }
174

175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
  Node* NewNode(const Operator* op, Node* n1) {
    return MakeNode(op, 1, &n1, false);
  }

  Node* NewNode(const Operator* op, Node* n1, Node* n2) {
    Node* buffer[] = {n1, n2};
    return MakeNode(op, arraysize(buffer), buffer, false);
  }

  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) {
    Node* buffer[] = {n1, n2, n3};
    return MakeNode(op, arraysize(buffer), buffer, false);
  }

  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) {
    Node* buffer[] = {n1, n2, n3, n4};
    return MakeNode(op, arraysize(buffer), buffer, false);
  }

  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
                Node* n5) {
    Node* buffer[] = {n1, n2, n3, n4, n5};
    return MakeNode(op, arraysize(buffer), buffer, false);
  }

  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
                Node* n5, Node* n6) {
    Node* nodes[] = {n1, n2, n3, n4, n5, n6};
    return MakeNode(op, arraysize(nodes), nodes, false);
  }

  Node* NewNode(const Operator* op, int value_input_count, Node** value_inputs,
                bool incomplete = false) {
    return MakeNode(op, value_input_count, value_inputs, incomplete);
  }

  // Creates a new Phi node having {count} input values.
  Node* NewPhi(int count, Node* input, Node* control);
  Node* NewEffectPhi(int count, Node* input, Node* control);

  // Helpers for merging control, effect or value dependencies.
  Node* MergeControl(Node* control, Node* other);
  Node* MergeEffect(Node* value, Node* other, Node* control);
  Node* MergeValue(Node* value, Node* other, Node* control);

  // The main node creation chokepoint. Adds context, frame state, effect,
  // and control dependencies depending on the operator.
  Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs,
                 bool incomplete);

  // Helper to indicate a node exits the function body.
  void UpdateControlDependencyToLeaveFunction(Node* exit);
227

228
  // Builds deoptimization for a given node.
229 230 231
  void PrepareFrameState(Node* node, BailoutId ast_id,
                         OutputFrameStateCombine framestate_combine =
                             OutputFrameStateCombine::Ignore());
232 233 234 235 236 237 238

  BitVector* GetVariablesAssignedInLoop(IterationStatement* stmt);

  // Check if the given statement is an OSR entry.
  // If so, record the stack height into the compilation and return {true}.
  bool CheckOsrEntry(IterationStatement* stmt);

239 240 241 242
  // Computes local variable liveness and replaces dead variables in
  // frame states with the undefined values.
  void ClearNonLiveSlotsInFrameStates();

243 244
  Node** EnsureInputBufferSize(int size);

245
  // Named and keyed loads require a VectorSlotPair for successful lowering.
246
  VectorSlotPair CreateVectorSlotPair(FeedbackVectorSlot slot) const;
247

248 249 250 251 252
  // Determine which contexts need to be checked for extension objects that
  // might shadow the optimistic declaration of dynamic lookup variables.
  uint32_t ComputeBitsetForDynamicGlobal(Variable* variable);
  uint32_t ComputeBitsetForDynamicContext(Variable* variable);

253
  // ===========================================================================
254 255 256 257
  // The following build methods all generate graph fragments and return one
  // resulting node. The operand stack height remains the same, variables and
  // other dependencies tracked by the environment might be mutated though.

258
  // Builders to create local function, script and block contexts.
259 260
  Node* BuildLocalActivationContext(Node* context);
  Node* BuildLocalFunctionContext(Scope* scope);
261
  Node* BuildLocalScriptContext(Scope* scope);
262
  Node* BuildLocalBlockContext(Scope* scope);
263 264 265

  // Builder to create an arguments object if it is used.
  Node* BuildArgumentsObject(Variable* arguments);
266 267 268

  // Builder to create an array of rest parameters if used
  Node* BuildRestArgumentsArray(Variable* rest, int index);
269

270 271 272 273 274
  // Builder that assigns to the {.this_function} internal variable if needed.
  Node* BuildThisFunctionVariable(Variable* this_function_var);

  // Builder that assigns to the {new.target} internal variable if needed.
  Node* BuildNewTargetVariable(Variable* new_target_var);
275

276
  // Builders for variable load and assignment.
277
  Node* BuildVariableAssignment(Variable* variable, Node* value,
278
                                Token::Value op, const VectorSlotPair& slot,
279
                                BailoutId bailout_id,
280 281 282 283 284 285 286
                                FrameStateBeforeAndAfter& states,
                                OutputFrameStateCombine framestate_combine =
                                    OutputFrameStateCombine::Ignore());
  Node* BuildVariableDelete(Variable* variable, BailoutId bailout_id,
                            OutputFrameStateCombine framestate_combine);
  Node* BuildVariableLoad(Variable* variable, BailoutId bailout_id,
                          FrameStateBeforeAndAfter& states,
287
                          const VectorSlotPair& feedback,
288
                          OutputFrameStateCombine framestate_combine,
289
                          TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
290

291 292
  // Builders for property loads and stores.
  Node* BuildKeyedLoad(Node* receiver, Node* key,
293
                       const VectorSlotPair& feedback);
294
  Node* BuildNamedLoad(Node* receiver, Handle<Name> name,
295
                       const VectorSlotPair& feedback);
296
  Node* BuildKeyedStore(Node* receiver, Node* key, Node* value,
297
                        const VectorSlotPair& feedback);
298
  Node* BuildNamedStore(Node* receiver, Handle<Name> name, Node* value,
299
                        const VectorSlotPair& feedback);
300

301 302
  // Builders for super property loads and stores.
  Node* BuildKeyedSuperStore(Node* receiver, Node* home_object, Node* key,
303
                             Node* value);
304
  Node* BuildNamedSuperStore(Node* receiver, Node* home_object,
305
                             Handle<Name> name, Node* value);
306
  Node* BuildNamedSuperLoad(Node* receiver, Node* home_object,
307
                            Handle<Name> name, const VectorSlotPair& feedback);
308
  Node* BuildKeyedSuperLoad(Node* receiver, Node* home_object, Node* key,
309
                            const VectorSlotPair& feedback);
310

311
  // Builders for global variable loads and stores.
312 313 314
  Node* BuildGlobalLoad(Handle<Name> name, const VectorSlotPair& feedback,
                        TypeofMode typeof_mode);
  Node* BuildGlobalStore(Handle<Name> name, Node* value,
315
                         const VectorSlotPair& feedback);
316

317 318 319 320
  // Builders for dynamic variable loads and stores.
  Node* BuildDynamicLoad(Handle<Name> name, TypeofMode typeof_mode);
  Node* BuildDynamicStore(Handle<Name> name, Node* value);

321 322
  // Builders for accessing the function context.
  Node* BuildLoadGlobalObject();
323
  Node* BuildLoadNativeContextField(int index);
324 325

  // Builders for automatic type conversion.
326
  Node* BuildToBoolean(Node* input, TypeFeedbackId feedback_id);
327 328
  Node* BuildToName(Node* input, BailoutId bailout_id);
  Node* BuildToObject(Node* input, BailoutId bailout_id);
329

330 331
  // Builder for adding the [[HomeObject]] to a value if the value came from a
  // function literal and needs a home object. Do nothing otherwise.
332 333 334
  Node* BuildSetHomeObject(Node* value, Node* home_object,
                           ObjectLiteralProperty* property,
                           int slot_number = 0);
335

336
  // Builders for error reporting at runtime.
337
  Node* BuildThrowError(Node* exception, BailoutId bailout_id);
338
  Node* BuildThrowReferenceError(Variable* var, BailoutId bailout_id);
339
  Node* BuildThrowConstAssignError(BailoutId bailout_id);
340
  Node* BuildThrowStaticPrototypeError(BailoutId bailout_id);
341
  Node* BuildThrowUnsupportedSuperError(BailoutId bailout_id);
342 343 344

  // Builders for dynamic hole-checks at runtime.
  Node* BuildHoleCheckSilent(Node* value, Node* for_hole, Node* not_hole);
345 346 347 348
  Node* BuildHoleCheckThenThrow(Node* value, Variable* var, Node* not_hole,
                                BailoutId bailout_id);
  Node* BuildHoleCheckElseThrow(Node* value, Variable* var, Node* for_hole,
                                BailoutId bailout_id);
349 350 351

  // Builders for conditional errors.
  Node* BuildThrowIfStaticPrototype(Node* name, BailoutId bailout_id);
352

353 354 355 356
  // Builders for non-local control flow.
  Node* BuildReturn(Node* return_value);
  Node* BuildThrow(Node* exception_value);

357
  // Builders for binary operations.
358 359
  Node* BuildBinaryOp(Node* left, Node* right, Token::Value op,
                      TypeFeedbackId feedback_id);
360 361 362

  // Process arguments to a call by popping {arity} elements off the operand
  // stack and build a call node using the given call operator.
363
  Node* ProcessArguments(const Operator* op, int arity);
364

365 366
  // ===========================================================================
  // The following build methods have the same contract as the above ones, but
367
  // they can also return {nullptr} to indicate that no fragment was built. Note
368 369 370 371 372 373
  // that these are optimizations, disabling any of them should still produce
  // correct graphs.

  // Optimization for variable load from global object.
  Node* TryLoadGlobalConstant(Handle<Name> name);

374 375 376 377 378 379 380 381 382
  // Optimization for variable load of dynamic lookup slot that is most likely
  // to resolve to a global slot or context slot (inferred from scope chain).
  Node* TryLoadDynamicVariable(Variable* variable, Handle<String> name,
                               BailoutId bailout_id,
                               FrameStateBeforeAndAfter& states,
                               const VectorSlotPair& feedback,
                               OutputFrameStateCombine combine,
                               TypeofMode typeof_mode);

383 384 385 386
  // Optimizations for automatic type conversion.
  Node* TryFastToBoolean(Node* input);
  Node* TryFastToName(Node* input);

387 388 389 390 391 392 393
  // ===========================================================================
  // The following visitation methods all recursively visit a subtree of the
  // underlying AST and extent the graph. The operand stack is mutated in a way
  // consistent with other compilers:
  //  - Expressions pop operands and push result, depending on {AstContext}.
  //  - Statements keep the operand stack balanced.

394 395
  // Visit statements.
  void VisitIfNotNull(Statement* stmt);
396
  void VisitInScope(Statement* stmt, Scope* scope, Node* context);
397 398

  // Visit expressions.
399
  void Visit(Expression* expr);
400 401 402 403
  void VisitForTest(Expression* expr);
  void VisitForEffect(Expression* expr);
  void VisitForValue(Expression* expr);
  void VisitForValueOrNull(Expression* expr);
404
  void VisitForValueOrTheHole(Expression* expr);
405 406 407
  void VisitForValues(ZoneList<Expression*>* exprs);

  // Common for all IterationStatement bodies.
408
  void VisitIterationBody(IterationStatement* stmt, LoopBuilder* loop);
409

410 411 412
  // Dispatched from VisitCall.
  void VisitCallSuper(Call* expr);

413 414 415 416 417 418 419 420 421
  // Dispatched from VisitCallRuntime.
  void VisitCallJSRuntime(CallRuntime* expr);

  // Dispatched from VisitUnaryOperation.
  void VisitDelete(UnaryOperation* expr);
  void VisitVoid(UnaryOperation* expr);
  void VisitTypeof(UnaryOperation* expr);
  void VisitNot(UnaryOperation* expr);

422 423 424
  // Dispatched from VisitTypeof, VisitLiteralCompareTypeof.
  void VisitTypeofExpression(Expression* expr);

425 426 427 428 429
  // Dispatched from VisitBinaryOperation.
  void VisitComma(BinaryOperation* expr);
  void VisitLogicalExpression(BinaryOperation* expr);
  void VisitArithmeticExpression(BinaryOperation* expr);

430 431 432 433 434 435
  // Dispatched from VisitCompareOperation.
  void VisitLiteralCompareNil(CompareOperation* expr, Expression* sub_expr,
                              Node* nil_value);
  void VisitLiteralCompareTypeof(CompareOperation* expr, Expression* sub_expr,
                                 Handle<String> check);

436
  // Dispatched from VisitForInStatement.
437
  void VisitForInAssignment(Expression* expr, Node* value,
438
                            const VectorSlotPair& feedback,
439 440
                            BailoutId bailout_id_before,
                            BailoutId bailout_id_after);
441

442 443 444 445
  // Dispatched from VisitObjectLiteral.
  void VisitObjectLiteralAccessor(Node* home_object,
                                  ObjectLiteralProperty* property);

446 447 448
  // Dispatched from VisitClassLiteral.
  void VisitClassLiteralContents(ClassLiteral* expr);

449 450 451 452 453 454 455 456 457 458 459 460 461
  DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
  DISALLOW_COPY_AND_ASSIGN(AstGraphBuilder);
};


// The abstract execution environment for generated code consists of
// parameter variables, local variables and the operand stack. The
// environment will perform proper SSA-renaming of all tracked nodes
// at split and merge points in the control flow. Internally all the
// values are stored in one list using the following layout:
//
//  [parameters (+receiver)] [locals] [operand stack]
//
462
class AstGraphBuilder::Environment : public ZoneObject {
463 464 465 466 467
 public:
  Environment(AstGraphBuilder* builder, Scope* scope, Node* control_dependency);

  int parameters_count() const { return parameters_count_; }
  int locals_count() const { return locals_count_; }
468
  int context_chain_length() { return static_cast<int>(contexts_.size()); }
469
  int stack_height() {
470 471
    return static_cast<int>(values()->size()) - parameters_count_ -
           locals_count_;
472 473
  }

474 475 476 477
  // Operations on parameter or local variables.
  void Bind(Variable* variable, Node* node);
  Node* Lookup(Variable* variable);
  void MarkAllLocalsLive();
478

479 480 481 482
  // Raw operations on parameter variables.
  void RawParameterBind(int index, Node* node);
  Node* RawParameterLookup(int index);

483
  // Operations on the context chain.
484 485 486
  Node* Context() const { return contexts_.back(); }
  void PushContext(Node* context) { contexts()->push_back(context); }
  void PopContext() { contexts()->pop_back(); }
487 488 489
  void TrimContextChain(int trim_to_length) {
    contexts()->resize(trim_to_length);
  }
490

491 492 493 494 495
  // Operations on the operand stack.
  void Push(Node* node) {
    values()->push_back(node);
  }
  Node* Top() {
496
    DCHECK(stack_height() > 0);
497 498 499
    return values()->back();
  }
  Node* Pop() {
500
    DCHECK(stack_height() > 0);
501 502 503 504 505 506 507
    Node* back = values()->back();
    values()->pop_back();
    return back;
  }

  // Direct mutations of the operand stack.
  void Poke(int depth, Node* node) {
508
    DCHECK(depth >= 0 && depth < stack_height());
509
    int index = static_cast<int>(values()->size()) - depth - 1;
510 511 512
    values()->at(index) = node;
  }
  Node* Peek(int depth) {
513
    DCHECK(depth >= 0 && depth < stack_height());
514
    int index = static_cast<int>(values()->size()) - depth - 1;
515 516 517
    return values()->at(index);
  }
  void Drop(int depth) {
518
    DCHECK(depth >= 0 && depth <= stack_height());
519 520
    values()->erase(values()->end() - depth, values()->end());
  }
521
  void TrimStack(int trim_to_height) {
522 523 524 525
    int depth = stack_height() - trim_to_height;
    DCHECK(depth >= 0 && depth <= stack_height());
    values()->erase(values()->end() - depth, values()->end());
  }
526 527 528

  // Preserve a checkpoint of the environment for the IR graph. Any
  // further mutation of the environment will not affect checkpoints.
529
  Node* Checkpoint(BailoutId ast_id, OutputFrameStateCombine combine =
530 531
                                         OutputFrameStateCombine::Ignore(),
                   bool node_has_exception = false);
532

533 534 535 536
  // Control dependency tracked by this environment.
  Node* GetControlDependency() { return control_dependency_; }
  void UpdateControlDependency(Node* dependency) {
    control_dependency_ = dependency;
537 538
  }

539 540 541 542 543 544 545 546
  // Effect dependency tracked by this environment.
  Node* GetEffectDependency() { return effect_dependency_; }
  void UpdateEffectDependency(Node* dependency) {
    effect_dependency_ = dependency;
  }

  // Mark this environment as being unreachable.
  void MarkAsUnreachable() {
547
    UpdateControlDependency(builder()->jsgraph()->Dead());
548
    liveness_block_ = nullptr;
549 550
  }
  bool IsMarkedAsUnreachable() {
551
    return GetControlDependency()->opcode() == IrOpcode::kDead;
552 553 554 555 556 557
  }

  // Merge another environment into this one.
  void Merge(Environment* other);

  // Copies this environment at a control-flow split point.
558
  Environment* CopyForConditional();
559

560
  // Copies this environment to a potentially unreachable control-flow point.
561
  Environment* CopyAsUnreachable();
562 563

  // Copies this environment at a loop header control-flow point.
564
  Environment* CopyForLoop(BitVector* assigned, bool is_osr = false);
565 566 567

 private:
  AstGraphBuilder* builder_;
568 569
  int parameters_count_;
  int locals_count_;
570
  LivenessAnalyzerBlock* liveness_block_;
571
  NodeVector values_;
572
  NodeVector contexts_;
573 574
  Node* control_dependency_;
  Node* effect_dependency_;
575 576 577
  Node* parameters_node_;
  Node* locals_node_;
  Node* stack_node_;
578

579 580
  explicit Environment(Environment* copy,
                       LivenessAnalyzerBlock* liveness_block);
581
  Environment* CopyAndShareLiveness();
582
  void UpdateStateValues(Node** state_values, int offset, int count);
583
  void UpdateStateValuesWithCache(Node** state_values, int offset, int count);
584 585 586 587 588
  Zone* zone() const { return builder_->local_zone(); }
  Graph* graph() const { return builder_->graph(); }
  AstGraphBuilder* builder() const { return builder_; }
  CommonOperatorBuilder* common() { return builder_->common(); }
  NodeVector* values() { return &values_; }
589
  NodeVector* contexts() { return &contexts_; }
590
  LivenessAnalyzerBlock* liveness_block() { return liveness_block_; }
591 592
  bool IsLivenessAnalysisEnabled();
  bool IsLivenessBlockConsistent();
593 594 595

  // Prepare environment to be used as loop header.
  void PrepareForLoop(BitVector* assigned, bool is_osr = false);
596 597
};

598 599 600
}  // namespace compiler
}  // namespace internal
}  // namespace v8
601 602

#endif  // V8_COMPILER_AST_GRAPH_BUILDER_H_