Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_COMPILER_AST_GRAPH_BUILDER_H_ | 5 #ifndef V8_COMPILER_AST_GRAPH_BUILDER_H_ |
| 6 #define V8_COMPILER_AST_GRAPH_BUILDER_H_ | 6 #define V8_COMPILER_AST_GRAPH_BUILDER_H_ |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/ast.h" | 10 #include "src/ast.h" |
| 11 #include "src/compiler/graph-builder.h" | 11 #include "src/compiler/graph-builder.h" |
| 12 #include "src/compiler/js-graph.h" | 12 #include "src/compiler/js-graph.h" |
| 13 | 13 |
| 14 namespace v8 { | 14 namespace v8 { |
| 15 namespace internal { | 15 namespace internal { |
| 16 namespace compiler { | 16 namespace compiler { |
| 17 | 17 |
| 18 class ControlBuilder; | 18 class ControlBuilder; |
| 19 class Graph; | 19 class Graph; |
| 20 class LoopAssignmentAnalysis; | 20 class LoopAssignmentAnalysis; |
| 21 class LoopBuilder; | 21 class LoopBuilder; |
| 22 class TryCatchBuilder; | |
| 23 class TryFinallyBuilder; | |
| 22 | 24 |
| 23 // The AstGraphBuilder produces a high-level IR graph, based on an | 25 // The AstGraphBuilder produces a high-level IR graph, based on an |
| 24 // underlying AST. The produced graph can either be compiled into a | 26 // underlying AST. The produced graph can either be compiled into a |
| 25 // stand-alone function or be wired into another graph for the purposes | 27 // stand-alone function or be wired into another graph for the purposes |
| 26 // of function inlining. | 28 // of function inlining. |
| 27 class AstGraphBuilder : public StructuredGraphBuilder, public AstVisitor { | 29 class AstGraphBuilder : public StructuredGraphBuilder, public AstVisitor { |
| 28 public: | 30 public: |
| 29 AstGraphBuilder(Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph, | 31 AstGraphBuilder(Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph, |
| 30 LoopAssignmentAnalysis* loop_assignment = NULL); | 32 LoopAssignmentAnalysis* loop_assignment = NULL); |
| 31 | 33 |
| 32 // Creates a graph by visiting the entire AST. | 34 // Creates a graph by visiting the entire AST. |
| 33 bool CreateGraph(); | 35 bool CreateGraph(); |
| 34 | 36 |
| 35 protected: | 37 protected: |
| 36 class AstContext; | 38 class AstContext; |
| 37 class AstEffectContext; | 39 class AstEffectContext; |
| 38 class AstValueContext; | 40 class AstValueContext; |
| 39 class AstTestContext; | 41 class AstTestContext; |
| 40 class BreakableScope; | |
| 41 class ContextScope; | 42 class ContextScope; |
|
titzer
2015/02/02 09:47:29
Do this class and its subclasses really need to be
Michael Starzinger
2015/02/02 14:47:41
Acknowledged. As discussed offline, it gives acces
| |
| 43 class ControlScope; | |
| 44 class ControlScopeForBreakable; | |
| 45 class ControlScopeForIteration; | |
| 46 class ControlScopeForCatch; | |
| 47 class ControlScopeForFinally; | |
| 42 class Environment; | 48 class Environment; |
| 43 | 49 |
| 44 Environment* environment() { | 50 Environment* environment() { |
| 45 return reinterpret_cast<Environment*>( | 51 return reinterpret_cast<Environment*>( |
| 46 StructuredGraphBuilder::environment()); | 52 StructuredGraphBuilder::environment()); |
| 47 } | 53 } |
| 48 | 54 |
| 49 AstContext* ast_context() const { return ast_context_; } | 55 AstContext* ast_context() const { return ast_context_; } |
| 50 BreakableScope* breakable() const { return breakable_; } | 56 ControlScope* execution_control() const { return execution_control_; } |
| 51 ContextScope* execution_context() const { return execution_context_; } | 57 ContextScope* execution_context() const { return execution_context_; } |
| 52 | 58 |
| 53 void set_ast_context(AstContext* ctx) { ast_context_ = ctx; } | 59 void set_ast_context(AstContext* ctx) { ast_context_ = ctx; } |
| 54 void set_breakable(BreakableScope* brk) { breakable_ = brk; } | 60 void set_execution_control(ControlScope* ctrl) { execution_control_ = ctrl; } |
| 55 void set_execution_context(ContextScope* ctx) { execution_context_ = ctx; } | 61 void set_execution_context(ContextScope* ctx) { execution_context_ = ctx; } |
| 56 | 62 |
| 57 // Support for control flow builders. The concrete type of the environment | 63 // Support for control flow builders. The concrete type of the environment |
| 58 // depends on the graph builder, but environments themselves are not virtual. | 64 // depends on the graph builder, but environments themselves are not virtual. |
| 59 typedef StructuredGraphBuilder::Environment BaseEnvironment; | 65 typedef StructuredGraphBuilder::Environment BaseEnvironment; |
| 60 BaseEnvironment* CopyEnvironment(BaseEnvironment* env) OVERRIDE; | 66 BaseEnvironment* CopyEnvironment(BaseEnvironment* env) OVERRIDE; |
| 61 | 67 |
| 62 // Getters for values in the activation record. | 68 // Getters for values in the activation record. |
| 63 Node* GetFunctionClosure(); | 69 Node* GetFunctionClosure(); |
| 64 Node* GetFunctionContext(); | 70 Node* GetFunctionContext(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 103 | 109 |
| 104 // Builders for error reporting at runtime. | 110 // Builders for error reporting at runtime. |
| 105 Node* BuildThrowReferenceError(Variable* var, BailoutId bailout_id); | 111 Node* BuildThrowReferenceError(Variable* var, BailoutId bailout_id); |
| 106 Node* BuildThrowConstAssignError(BailoutId bailout_id); | 112 Node* BuildThrowConstAssignError(BailoutId bailout_id); |
| 107 | 113 |
| 108 // Builders for dynamic hole-checks at runtime. | 114 // Builders for dynamic hole-checks at runtime. |
| 109 Node* BuildHoleCheckSilent(Node* value, Node* for_hole, Node* not_hole); | 115 Node* BuildHoleCheckSilent(Node* value, Node* for_hole, Node* not_hole); |
| 110 Node* BuildHoleCheckThrow(Node* value, Variable* var, Node* not_hole, | 116 Node* BuildHoleCheckThrow(Node* value, Variable* var, Node* not_hole, |
| 111 BailoutId bailout_id); | 117 BailoutId bailout_id); |
| 112 | 118 |
| 119 // Builders for non-local control flow. | |
| 120 Node* BuildReturn(Node* return_value); | |
| 121 Node* BuildThrow(Node* exception_value); | |
| 122 | |
| 113 // Builders for binary operations. | 123 // Builders for binary operations. |
| 114 Node* BuildBinaryOp(Node* left, Node* right, Token::Value op); | 124 Node* BuildBinaryOp(Node* left, Node* right, Token::Value op); |
| 115 | 125 |
| 116 // Builder for stack-check guards. | 126 // Builder for stack-check guards. |
| 117 Node* BuildStackCheck(); | 127 Node* BuildStackCheck(); |
| 118 | 128 |
| 119 bool IsOsrLoopEntry(IterationStatement* stmt); | 129 bool IsOsrLoopEntry(IterationStatement* stmt); |
| 120 | 130 |
| 121 #define DECLARE_VISIT(type) void Visit##type(type* node) OVERRIDE; | 131 #define DECLARE_VISIT(type) void Visit##type(type* node) OVERRIDE; |
| 122 | 132 |
| 123 // Visiting functions for AST nodes make this an AstVisitor. | 133 // Visiting functions for AST nodes make this an AstVisitor. |
| 124 AST_NODE_LIST(DECLARE_VISIT) | 134 AST_NODE_LIST(DECLARE_VISIT) |
| 125 #undef DECLARE_VISIT | 135 #undef DECLARE_VISIT |
| 126 | 136 |
| 127 // Visiting function for declarations list is overridden. | 137 // Visiting function for declarations list is overridden. |
| 128 void VisitDeclarations(ZoneList<Declaration*>* declarations) OVERRIDE; | 138 void VisitDeclarations(ZoneList<Declaration*>* declarations) OVERRIDE; |
| 129 | 139 |
| 130 private: | 140 private: |
| 131 CompilationInfo* info_; | 141 CompilationInfo* info_; |
| 132 AstContext* ast_context_; | 142 AstContext* ast_context_; |
| 133 JSGraph* jsgraph_; | 143 JSGraph* jsgraph_; |
| 134 | 144 |
| 135 // List of global declarations for functions and variables. | 145 // List of global declarations for functions and variables. |
| 136 ZoneVector<Handle<Object>> globals_; | 146 ZoneVector<Handle<Object>> globals_; |
| 137 | 147 |
| 138 // Stack of breakable statements entered by the visitor. | 148 // Stack of control scopes currently entered by the visitor. |
| 139 BreakableScope* breakable_; | 149 ControlScope* execution_control_; |
| 140 | 150 |
| 141 // Stack of context objects pushed onto the chain by the visitor. | 151 // Stack of context objects pushed onto the chain by the visitor. |
| 142 ContextScope* execution_context_; | 152 ContextScope* execution_context_; |
| 143 | 153 |
| 144 // Nodes representing values in the activation record. | 154 // Nodes representing values in the activation record. |
| 145 SetOncePointer<Node> function_closure_; | 155 SetOncePointer<Node> function_closure_; |
| 146 SetOncePointer<Node> function_context_; | 156 SetOncePointer<Node> function_context_; |
| 147 | 157 |
| 148 // The node representing the OSR entry into the loop, if any. | 158 // The node representing the OSR entry into the loop, if any. |
| 149 SetOncePointer<Node> osr_loop_entry_; | 159 SetOncePointer<Node> osr_loop_entry_; |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 382 class AstGraphBuilder::AstTestContext FINAL : public AstContext { | 392 class AstGraphBuilder::AstTestContext FINAL : public AstContext { |
| 383 public: | 393 public: |
| 384 explicit AstTestContext(AstGraphBuilder* owner) | 394 explicit AstTestContext(AstGraphBuilder* owner) |
| 385 : AstContext(owner, Expression::kTest) {} | 395 : AstContext(owner, Expression::kTest) {} |
| 386 ~AstTestContext() FINAL; | 396 ~AstTestContext() FINAL; |
| 387 void ProduceValue(Node* value) FINAL; | 397 void ProduceValue(Node* value) FINAL; |
| 388 Node* ConsumeValue() FINAL; | 398 Node* ConsumeValue() FINAL; |
| 389 }; | 399 }; |
| 390 | 400 |
| 391 | 401 |
| 392 // Scoped class tracking breakable statements entered by the visitor. Allows to | 402 // Scoped class tracking control statements entered by the visitor. There are |
| 393 // properly 'break' and 'continue' iteration statements as well as to 'break' | 403 // different types of statements participating in this stack to properly track |
| 394 // from blocks within switch statements. | 404 // local as well as non-local control flow: |
| 395 class AstGraphBuilder::BreakableScope BASE_EMBEDDED { | 405 // - IterationStatement : Allows proper 'break' and 'continue' behavior. |
| 406 // - BreakableStatement : Allows 'break' from block and switch statements. | |
| 407 // - TryCatchStatement : Intercepts 'throw' and implicit exceptional edges. | |
| 408 // - TryFinallyStatement: Intercepts 'break', 'continue', 'throw' and 'return'. | |
| 409 class AstGraphBuilder::ControlScope BASE_EMBEDDED { | |
| 396 public: | 410 public: |
| 397 BreakableScope(AstGraphBuilder* owner, BreakableStatement* target, | 411 ControlScope(AstGraphBuilder* owner, int drop_extra) |
|
titzer
2015/02/02 09:47:29
{owner} is a bad name. Would prefer the more verbo
Michael Starzinger
2015/02/02 14:47:41
Done. As discussed offline, used {builder} instead
| |
| 398 ControlBuilder* control, int drop_extra) | |
| 399 : owner_(owner), | 412 : owner_(owner), |
| 400 target_(target), | 413 next_(owner->execution_control()), |
| 401 next_(owner->breakable()), | |
| 402 control_(control), | |
| 403 drop_extra_(drop_extra) { | 414 drop_extra_(drop_extra) { |
| 404 owner_->set_breakable(this); // Push. | 415 owner_->set_execution_control(this); // Push. |
| 405 } | 416 } |
| 406 | 417 |
| 407 ~BreakableScope() { | 418 virtual ~ControlScope() { |
| 408 owner_->set_breakable(next_); // Pop. | 419 owner_->set_execution_control(next_); // Pop. |
| 409 } | 420 } |
| 410 | 421 |
| 411 // Either 'break' or 'continue' the target statement. | 422 // Either 'break' or 'continue' the target statement. |
| 412 void BreakTarget(BreakableStatement* target); | 423 void BreakTarget(BreakableStatement* target); |
| 413 void ContinueTarget(BreakableStatement* target); | 424 void ContinueTarget(BreakableStatement* target); |
| 414 | 425 |
| 426 // Either 'return' or 'throw' the given value. | |
| 427 void ReturnValue(Node* return_value); | |
| 428 void ThrowValue(Node* exception_value); | |
| 429 | |
| 430 class DeferredCommands; | |
| 431 | |
| 432 protected: | |
| 433 enum Command { CMD_BREAK, CMD_CONTINUE, CMD_RETURN, CMD_THROW }; | |
| 434 | |
| 435 // Performs one of the above commands on this stack of control scopes. This | |
| 436 // walks through the stack giving each scope a chance to execute or defer the | |
| 437 // given command by overriding the {Execute} method appropriately. Note that | |
| 438 // this also drops extra operands from the environment for each skipped scope. | |
| 439 void PerformCommand(Command cmd, Statement* stmt, Node* value); | |
|
titzer
2015/02/02 09:47:29
{stmt} is called {target} in all the subclasses.
Michael Starzinger
2015/02/02 14:47:41
Done. Here and in the occurrences below.
| |
| 440 | |
| 441 // Interface to execute a given command in this scope. Returning {true} here | |
| 442 // indicates successful execution whereas {false} requests to skip scope. | |
| 443 virtual bool Execute(Command cmd, Statement* stmt, Node* value); | |
| 444 | |
| 445 Environment* environment() { return owner_->environment(); } | |
| 446 AstGraphBuilder* owner() const { return owner_; } | |
| 447 int drop_extra() const { return drop_extra_; } | |
| 448 | |
| 415 private: | 449 private: |
| 416 AstGraphBuilder* owner_; | 450 AstGraphBuilder* owner_; |
| 417 BreakableStatement* target_; | 451 ControlScope* next_; |
| 418 BreakableScope* next_; | |
| 419 ControlBuilder* control_; | |
| 420 int drop_extra_; | 452 int drop_extra_; |
| 421 | |
| 422 // Find the correct scope for the target statement. Note that this also drops | |
| 423 // extra operands from the environment for each scope skipped along the way. | |
| 424 BreakableScope* FindBreakable(BreakableStatement* target); | |
| 425 }; | 453 }; |
| 426 | 454 |
| 427 | 455 |
| 456 // Control scope implementation for a BreakableStatement. | |
| 457 class AstGraphBuilder::ControlScopeForBreakable : public ControlScope { | |
| 458 public: | |
| 459 ControlScopeForBreakable(AstGraphBuilder* owner, BreakableStatement* target, | |
| 460 ControlBuilder* control) | |
| 461 : ControlScope(owner, 0), target_(target), control_(control) {} | |
| 462 | |
| 463 protected: | |
| 464 virtual bool Execute(Command cmd, Statement* stmt, Node* value) OVERRIDE; | |
| 465 | |
| 466 private: | |
| 467 BreakableStatement* target_; | |
| 468 ControlBuilder* control_; | |
| 469 }; | |
| 470 | |
| 471 | |
| 472 // Control scope implementation for an IterationStatement. | |
| 473 class AstGraphBuilder::ControlScopeForIteration : public ControlScope { | |
| 474 public: | |
| 475 ControlScopeForIteration(AstGraphBuilder* owner, IterationStatement* target, | |
| 476 LoopBuilder* control, int drop_extra) | |
| 477 : ControlScope(owner, drop_extra), target_(target), control_(control) {} | |
| 478 | |
| 479 protected: | |
| 480 virtual bool Execute(Command cmd, Statement* stmt, Node* value) OVERRIDE; | |
| 481 | |
| 482 private: | |
| 483 BreakableStatement* target_; | |
| 484 LoopBuilder* control_; | |
| 485 }; | |
| 486 | |
| 487 | |
| 488 // Control scope implementation for a TryCatchStatement. | |
| 489 class AstGraphBuilder::ControlScopeForCatch : public ControlScope { | |
| 490 public: | |
| 491 ControlScopeForCatch(AstGraphBuilder* owner, TryCatchBuilder* control) | |
| 492 : ControlScope(owner, 0), control_(control) {} | |
| 493 | |
| 494 protected: | |
| 495 virtual bool Execute(Command cmd, Statement* stmt, Node* value) OVERRIDE; | |
| 496 | |
| 497 private: | |
| 498 TryCatchBuilder* control_; | |
| 499 }; | |
| 500 | |
| 501 | |
| 502 // Control scope implementation for a TryFinallyStatement. | |
| 503 class AstGraphBuilder::ControlScopeForFinally : public ControlScope { | |
| 504 public: | |
| 505 ControlScopeForFinally(AstGraphBuilder* owner, DeferredCommands* commands, | |
| 506 TryFinallyBuilder* control) | |
| 507 : ControlScope(owner, 0), commands_(commands), control_(control) {} | |
| 508 | |
| 509 protected: | |
| 510 virtual bool Execute(Command cmd, Statement* stmt, Node* value) OVERRIDE; | |
| 511 | |
| 512 private: | |
| 513 DeferredCommands* commands_; | |
| 514 TryFinallyBuilder* control_; | |
| 515 }; | |
| 516 | |
| 517 | |
| 428 // Scoped class tracking context objects created by the visitor. Represents | 518 // Scoped class tracking context objects created by the visitor. Represents |
| 429 // mutations of the context chain within the function body and allows to | 519 // mutations of the context chain within the function body and allows to |
| 430 // change the current {scope} and {context} during visitation. | 520 // change the current {scope} and {context} during visitation. |
| 431 class AstGraphBuilder::ContextScope BASE_EMBEDDED { | 521 class AstGraphBuilder::ContextScope BASE_EMBEDDED { |
| 432 public: | 522 public: |
| 433 ContextScope(AstGraphBuilder* owner, Scope* scope, Node* context) | 523 ContextScope(AstGraphBuilder* owner, Scope* scope, Node* context) |
| 434 : owner_(owner), | 524 : owner_(owner), |
| 435 next_(owner->execution_context()), | 525 next_(owner->execution_context()), |
| 436 outer_(owner->current_context()), | 526 outer_(owner->current_context()), |
| 437 scope_(scope) { | 527 scope_(scope) { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 456 | 546 |
| 457 Scope* AstGraphBuilder::current_scope() const { | 547 Scope* AstGraphBuilder::current_scope() const { |
| 458 return execution_context_->scope(); | 548 return execution_context_->scope(); |
| 459 } | 549 } |
| 460 | 550 |
| 461 } // namespace compiler | 551 } // namespace compiler |
| 462 } // namespace internal | 552 } // namespace internal |
| 463 } // namespace v8 | 553 } // namespace v8 |
| 464 | 554 |
| 465 #endif // V8_COMPILER_AST_GRAPH_BUILDER_H_ | 555 #endif // V8_COMPILER_AST_GRAPH_BUILDER_H_ |
| OLD | NEW |