Index: src/hydrogen.h |
diff --git a/src/hydrogen.h b/src/hydrogen.h |
index f8ec150a9de3f64fbafe7792783add942e6fdb96..8a5e8df7cd9c624ac17e293291f8d0c58a7a56d0 100644 |
--- a/src/hydrogen.h |
+++ b/src/hydrogen.h |
@@ -196,8 +196,7 @@ class HSubgraph: public ZoneObject { |
explicit HSubgraph(HGraph* graph) |
: graph_(graph), |
entry_block_(NULL), |
- exit_block_(NULL), |
- break_continue_info_(4) { |
+ exit_block_(NULL) { |
} |
HGraph* graph() const { return graph_; } |
@@ -215,23 +214,24 @@ class HSubgraph: public ZoneObject { |
HSubgraph* body, |
IterationStatement* statement, |
HSubgraph* continue_subgraph, |
- HSubgraph* exit); |
+ HSubgraph* exit, |
+ HBasicBlock* break_block); |
void AppendDoWhile(HSubgraph* body, |
IterationStatement* statement, |
HSubgraph* go_back, |
- HSubgraph* exit); |
- void AppendEndless(HSubgraph* body, IterationStatement* statement); |
- void Append(HSubgraph* next, BreakableStatement* statement); |
- void ResolveContinue(IterationStatement* statement); |
- HBasicBlock* BundleBreak(BreakableStatement* statement); |
- HBasicBlock* BundleContinue(IterationStatement* statement); |
- HBasicBlock* BundleBreakContinue(BreakableStatement* statement, |
- bool is_continue, |
- int join_id); |
+ HSubgraph* exit, |
+ HBasicBlock* break_block); |
+ void AppendEndless(HSubgraph* body, |
+ IterationStatement* statement, |
+ HBasicBlock* break_block); |
+ void Append(HSubgraph* next, |
+ BreakableStatement* stmt, |
+ HBasicBlock* break_block); |
+ void ResolveContinue(IterationStatement* statement, |
+ HBasicBlock* continue_block); |
HBasicBlock* JoinBlocks(HBasicBlock* a, HBasicBlock* b, int id); |
void FinishExit(HControlInstruction* instruction); |
- void FinishBreakContinue(BreakableStatement* target, bool is_continue); |
void Initialize(HBasicBlock* block) { |
ASSERT(entry_block_ == NULL); |
entry_block_ = block; |
@@ -249,38 +249,10 @@ class HSubgraph: public ZoneObject { |
} |
} |
- void AddBreakContinueInfo(HSubgraph* other) { |
- break_continue_info_.AddAll(other->break_continue_info_); |
- } |
- |
protected: |
- class BreakContinueInfo: public ZoneObject { |
- public: |
- BreakContinueInfo(BreakableStatement* target, HBasicBlock* block, |
- bool is_continue) |
- : target_(target), block_(block), continue_(is_continue) {} |
- BreakableStatement* target() const { return target_; } |
- HBasicBlock* block() const { return block_; } |
- bool is_continue() const { return continue_; } |
- bool IsResolved() const { return block_ == NULL; } |
- void Resolve() { block_ = NULL; } |
- |
- private: |
- BreakableStatement* target_; |
- HBasicBlock* block_; |
- bool continue_; |
- }; |
- |
- const ZoneList<BreakContinueInfo*>* break_continue_info() const { |
- return &break_continue_info_; |
- } |
- |
HGraph* graph_; // The graph this is a subgraph of. |
HBasicBlock* entry_block_; |
HBasicBlock* exit_block_; |
- |
- private: |
- ZoneList<BreakContinueInfo*> break_continue_info_; |
}; |
@@ -618,6 +590,53 @@ class TestContext: public AstContext { |
class HGraphBuilder: public AstVisitor { |
public: |
+ enum BreakType { BREAK, CONTINUE }; |
+ |
+ // A class encapsulating (lazily-allocated) break and continue blocks for |
+ // a breakable statement. Separated from BreakAndContinueScope so that it |
+ // can have a separate lifetime. |
+ class BreakAndContinueInfo BASE_EMBEDDED { |
+ public: |
+ explicit BreakAndContinueInfo(BreakableStatement* target) |
+ : target_(target), break_block_(NULL), continue_block_(NULL) { |
+ } |
+ |
+ BreakableStatement* target() { return target_; } |
+ HBasicBlock* break_block() { return break_block_; } |
+ void set_break_block(HBasicBlock* block) { break_block_ = block; } |
+ HBasicBlock* continue_block() { return continue_block_; } |
+ void set_continue_block(HBasicBlock* block) { continue_block_ = block; } |
+ |
+ private: |
+ BreakableStatement* target_; |
+ HBasicBlock* break_block_; |
+ HBasicBlock* continue_block_; |
+ }; |
+ |
+ // A helper class to maintain a stack of current BreakAndContinueInfo |
+ // structures mirroring BreakableStatement nesting. |
+ class BreakAndContinueScope BASE_EMBEDDED { |
+ public: |
+ BreakAndContinueScope(BreakAndContinueInfo* info, HGraphBuilder* owner) |
+ : info_(info), owner_(owner), next_(owner->break_scope()) { |
+ owner->set_break_scope(this); |
+ } |
+ |
+ ~BreakAndContinueScope() { owner_->set_break_scope(next_); } |
+ |
+ BreakAndContinueInfo* info() { return info_; } |
+ HGraphBuilder* owner() { return owner_; } |
+ BreakAndContinueScope* next() { return next_; } |
+ |
+ // Search the break stack for a break or continue target. |
+ HBasicBlock* Get(BreakableStatement* stmt, BreakType type); |
+ |
+ private: |
+ BreakAndContinueInfo* info_; |
+ HGraphBuilder* owner_; |
+ BreakAndContinueScope* next_; |
+ }; |
+ |
explicit HGraphBuilder(TypeFeedbackOracle* oracle) |
: oracle_(oracle), |
graph_(NULL), |
@@ -626,13 +645,17 @@ class HGraphBuilder: public AstVisitor { |
ast_context_(NULL), |
call_context_(NULL), |
function_return_(NULL), |
- inlined_count_(0) { } |
+ inlined_count_(0), |
+ break_scope_(NULL) { |
+ } |
HGraph* CreateGraph(CompilationInfo* info); |
// Simple accessors. |
HGraph* graph() const { return graph_; } |
HSubgraph* subgraph() const { return current_subgraph_; } |
+ BreakAndContinueScope* break_scope() const { return break_scope_; } |
+ void set_break_scope(BreakAndContinueScope* head) { break_scope_ = head; } |
HEnvironment* environment() const { return subgraph()->environment(); } |
HBasicBlock* CurrentBlock() const { return subgraph()->exit_block(); } |
@@ -682,7 +705,8 @@ class HGraphBuilder: public AstVisitor { |
void AppendPeeledWhile(IterationStatement* stmt, |
HSubgraph* cond_graph, |
HSubgraph* body_graph, |
- HSubgraph* exit_graph); |
+ HSubgraph* exit_graph, |
+ HBasicBlock* break_block); |
void AddToSubgraph(HSubgraph* graph, ZoneList<Statement*>* stmts); |
void AddToSubgraph(HSubgraph* graph, Statement* stmt); |
@@ -858,6 +882,8 @@ class HGraphBuilder: public AstVisitor { |
int inlined_count_; |
+ BreakAndContinueScope* break_scope_; |
+ |
friend class AstContext; // Pushes and pops the AST context stack. |
DISALLOW_COPY_AND_ASSIGN(HGraphBuilder); |