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); ~AstGraphBuilder()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. NewIfTrue()50 Node* NewIfTrue() { return NewNode(common()->IfTrue()); } NewIfFalse()51 Node* NewIfFalse() { return NewNode(common()->IfFalse()); } NewMerge()52 Node* NewMerge() { return NewNode(common()->Merge(1), true); } NewLoop()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 local_zone()138 Zone* local_zone() const { return local_zone_; } environment()139 Environment* environment() const { return environment_; } ast_context()140 AstContext* ast_context() const { return ast_context_; } execution_control()141 ControlScope* execution_control() const { return execution_control_; } execution_context()142 ContextScope* execution_context() const { return execution_context_; } common()143 CommonOperatorBuilder* common() const { return jsgraph_->common(); } info()144 CompilationInfo* info() const { return info_; } isolate()145 Isolate* isolate() const { return isolate_; } 146 LanguageMode language_mode() const; jsgraph()147 JSGraph* jsgraph() { return jsgraph_; } graph()148 Graph* graph() { return jsgraph_->graph(); } graph_zone()149 Zone* graph_zone() { return graph()->zone(); } javascript()150 JSOperatorBuilder* javascript() { return jsgraph_->javascript(); } globals()151 ZoneVector<Handle<Object>>* globals() { return &globals_; } 152 Scope* current_scope() const; 153 Node* current_context() const; liveness_analyzer()154 LivenessAnalyzer* liveness_analyzer() { return &liveness_analyzer_; } frame_state_function_info()155 const FrameStateFunctionInfo* frame_state_function_info() const { 156 return frame_state_function_info_; 157 } 158 set_environment(Environment * env)159 void set_environment(Environment* env) { environment_ = env; } set_ast_context(AstContext * ctx)160 void set_ast_context(AstContext* ctx) { ast_context_ = ctx; } set_execution_control(ControlScope * ctrl)161 void set_execution_control(ControlScope* ctrl) { execution_control_ = ctrl; } set_execution_context(ContextScope * ctx)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 NewNode(const Operator * op,Node * n1)185 Node* NewNode(const Operator* op, Node* n1) { 186 return MakeNode(op, 1, &n1, false); 187 } 188 NewNode(const Operator * op,Node * n1,Node * n2)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 NewNode(const Operator * op,Node * n1,Node * n2,Node * n3)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 NewNode(const Operator * op,Node * n1,Node * n2,Node * n3,Node * n4)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 NewNode(const Operator * op,Node * n1,Node * n2,Node * n3,Node * n4,Node * n5)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 NewNode(const Operator * op,Node * n1,Node * n2,Node * n3,Node * n4,Node * n5,Node * n6)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 parameters_count()479 int parameters_count() const { return parameters_count_; } locals_count()480 int locals_count() const { return locals_count_; } context_chain_length()481 int context_chain_length() { return static_cast<int>(contexts_.size()); } stack_height()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. Context()497 Node* Context() const { return contexts_.back(); } PushContext(Node * context)498 void PushContext(Node* context) { contexts()->push_back(context); } PopContext()499 void PopContext() { contexts()->pop_back(); } TrimContextChain(int trim_to_length)500 void TrimContextChain(int trim_to_length) { 501 contexts()->resize(trim_to_length); 502 } 503 504 // Operations on the operand stack. Push(Node * node)505 void Push(Node* node) { 506 values()->push_back(node); 507 } Top()508 Node* Top() { 509 DCHECK(stack_height() > 0); 510 return values()->back(); 511 } Pop()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. Poke(int depth,Node * node)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 } Peek(int depth)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 } Drop(int depth)530 void Drop(int depth) { 531 DCHECK(depth >= 0 && depth <= stack_height()); 532 values()->erase(values()->end() - depth, values()->end()); 533 } TrimStack(int trim_to_height)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. GetControlDependency()551 Node* GetControlDependency() { return control_dependency_; } UpdateControlDependency(Node * dependency)552 void UpdateControlDependency(Node* dependency) { 553 control_dependency_ = dependency; 554 } 555 556 // Effect dependency tracked by this environment. GetEffectDependency()557 Node* GetEffectDependency() { return effect_dependency_; } UpdateEffectDependency(Node * dependency)558 void UpdateEffectDependency(Node* dependency) { 559 effect_dependency_ = dependency; 560 } 561 562 // Mark this environment as being unreachable. MarkAsUnreachable()563 void MarkAsUnreachable() { 564 UpdateControlDependency(builder()->jsgraph()->Dead()); 565 liveness_block_ = nullptr; 566 } IsMarkedAsUnreachable()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); zone()605 Zone* zone() const { return builder_->local_zone(); } graph()606 Graph* graph() const { return builder_->graph(); } builder()607 AstGraphBuilder* builder() const { return builder_; } common()608 CommonOperatorBuilder* common() { return builder_->common(); } values()609 NodeVector* values() { return &values_; } contexts()610 NodeVector* contexts() { return &contexts_; } liveness_block()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