Chromium Code Reviews| Index: src/data-flow.cc |
| diff --git a/src/data-flow.cc b/src/data-flow.cc |
| index f8af2c16e699eb5790e8d4953deca5cb8dbb22ec..186d897876281a7c1f08b0e447c9db3a75b8787f 100644 |
| --- a/src/data-flow.cc |
| +++ b/src/data-flow.cc |
| @@ -34,67 +34,68 @@ namespace internal { |
| void FlowGraph::AppendInstruction(AstNode* instruction) { |
| + // Add a (non-null) AstNode to the end of the graph fragment. |
| ASSERT(instruction != NULL); |
| - if (is_empty() || !exit()->IsBlockNode()) { |
| - AppendNode(new BlockNode()); |
| - } |
| + if (exit()->IsExitNode()) return; |
| + if (!exit()->IsBlockNode()) AppendNode(new BlockNode()); |
| BlockNode::cast(exit())->AddInstruction(instruction); |
| } |
| void FlowGraph::AppendNode(Node* node) { |
| + // Add a node to the end of the graph. An empty block is added to |
| + // maintain edge-split form (that no join nodes or exit nodes as |
| + // successors to branch nodes). |
| ASSERT(node != NULL); |
| - if (is_empty()) { |
| - entry_ = exit_ = node; |
| - } else { |
| - exit()->AddSuccessor(node); |
| - node->AddPredecessor(exit()); |
| - exit_ = node; |
| + if (exit()->IsExitNode()) return; |
| + if (exit()->IsBranchNode() && (node->IsJoinNode() || node->IsExitNode())) { |
| + AppendNode(new BlockNode()); |
| } |
| + exit()->AddSuccessor(node); |
| + node->AddPredecessor(exit()); |
| + exit_ = node; |
| } |
| void FlowGraph::AppendGraph(FlowGraph* graph) { |
| - ASSERT(!graph->is_empty()); |
| - if (is_empty()) { |
| - entry_ = graph->entry(); |
| - exit_ = graph->exit(); |
| - } else { |
| - exit()->AddSuccessor(graph->entry()); |
| - graph->entry()->AddPredecessor(exit()); |
| - exit_ = graph->exit(); |
| + // Add a flow graph fragment to the end of this one. An empty block is |
| + // added to maintain edge-split form (that no join nodes or exit nodes as |
| + // successors to branch nodes). |
|
fschneider
2010/03/10 16:51:09
Maybe ASSERT(graph != NULL) for consistency with t
|
| + if (exit()->IsExitNode()) return; |
| + Node* node = graph->entry(); |
| + if (exit()->IsBranchNode() && (node->IsJoinNode() || node->IsExitNode())) { |
| + AppendNode(new BlockNode()); |
| } |
| + exit()->AddSuccessor(node); |
| + node->AddPredecessor(exit()); |
| + exit_ = graph->exit(); |
| } |
| void FlowGraph::Split(BranchNode* branch, |
| FlowGraph* left, |
| FlowGraph* right, |
| - JoinNode* merge) { |
| - // Graphs are in edge split form. Add empty blocks if necessary. |
| - if (left->is_empty()) left->AppendNode(new BlockNode()); |
| - if (right->is_empty()) right->AppendNode(new BlockNode()); |
| - |
| - // Add the branch, left flowgraph and merge. |
| + JoinNode* join) { |
| + // Add the branch node, left flowgraph, join node. |
| AppendNode(branch); |
| AppendGraph(left); |
| - AppendNode(merge); |
| + AppendNode(join); |
| // Splice in the right flowgraph. |
| - right->AppendNode(merge); |
| + right->AppendNode(join); |
| branch->AddSuccessor(right->entry()); |
| right->entry()->AddPredecessor(branch); |
| } |
| -void FlowGraph::Loop(JoinNode* merge, |
| +void FlowGraph::Loop(JoinNode* join, |
| FlowGraph* condition, |
| BranchNode* branch, |
| FlowGraph* body) { |
| - // Add the merge, condition and branch. Add merge's predecessors in |
| + // Add the join, condition and branch. Add join's predecessors in |
| // left-to-right order. |
| - AppendNode(merge); |
| - body->AppendNode(merge); |
| + AppendNode(join); |
| + body->AppendNode(join); |
| AppendGraph(condition); |
| AppendNode(branch); |
| @@ -104,19 +105,6 @@ void FlowGraph::Loop(JoinNode* merge, |
| } |
| -void EntryNode::Traverse(bool mark, |
| - ZoneList<Node*>* preorder, |
| - ZoneList<Node*>* postorder) { |
| - ASSERT(successor_ != NULL); |
| - preorder->Add(this); |
| - if (!successor_->IsMarkedWith(mark)) { |
| - successor_->MarkWith(mark); |
| - successor_->Traverse(mark, preorder, postorder); |
| - } |
| - postorder->Add(this); |
| -} |
| - |
| - |
| void ExitNode::Traverse(bool mark, |
| ZoneList<Node*>* preorder, |
| ZoneList<Node*>* postorder) { |
| @@ -169,16 +157,15 @@ void JoinNode::Traverse(bool mark, |
| void FlowGraphBuilder::Build(FunctionLiteral* lit) { |
| - graph_ = FlowGraph::Empty(); |
| - graph_.AppendNode(new EntryNode()); |
| global_exit_ = new ExitNode(); |
| VisitStatements(lit->body()); |
| - if (HasStackOverflow()) { |
| - graph_ = FlowGraph::Empty(); |
| - return; |
| - } |
| + if (HasStackOverflow()) return; |
| + // The graph can end with a branch node (if the function ended with a |
| + // loop). Maintain edge-split form (no join nodes or exit nodes as |
| + // successors to branch nodes). |
| + if (graph_.exit()->IsBranchNode()) graph_.AppendNode(new BlockNode()); |
| graph_.AppendNode(global_exit_); |
| // Build preorder and postorder traversal orders. All the nodes in |
| @@ -222,6 +209,7 @@ void FlowGraphBuilder::VisitIfStatement(IfStatement* stmt) { |
| graph_ = FlowGraph::Empty(); |
| Visit(stmt->else_statement()); |
| + if (HasStackOverflow()) return; |
| JoinNode* join = new JoinNode(); |
| original.Split(branch, &left, &graph_, join); |
| graph_ = original; |
| @@ -283,6 +271,7 @@ void FlowGraphBuilder::VisitForStatement(ForStatement* stmt) { |
| if (stmt->next() != NULL) Visit(stmt->next()); |
| + if (HasStackOverflow()) return; |
| original.Loop(join, &condition, branch, &graph_); |
| graph_ = original; |
| } |
| @@ -374,6 +363,8 @@ void FlowGraphBuilder::VisitAssignment(Assignment* expr) { |
| if (!prop->key()->IsPropertyName()) Visit(prop->key()); |
| Visit(expr->value()); |
| } |
| + |
| + if (HasStackOverflow()) return; |
| graph_.AppendInstruction(expr); |
| } |
| @@ -386,6 +377,8 @@ void FlowGraphBuilder::VisitThrow(Throw* expr) { |
| void FlowGraphBuilder::VisitProperty(Property* expr) { |
| Visit(expr->obj()); |
| if (!expr->key()->IsPropertyName()) Visit(expr->key()); |
| + |
| + if (HasStackOverflow()) return; |
| graph_.AppendInstruction(expr); |
| } |
| @@ -396,6 +389,8 @@ void FlowGraphBuilder::VisitCall(Call* expr) { |
| for (int i = 0, len = arguments->length(); i < len; i++) { |
| Visit(arguments->at(i)); |
| } |
| + |
| + if (HasStackOverflow()) return; |
| graph_.AppendInstruction(expr); |
| } |
| @@ -423,6 +418,7 @@ void FlowGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { |
| case Token::ADD: |
| case Token::SUB: |
| Visit(expr->expression()); |
| + if (HasStackOverflow()) return; |
| graph_.AppendInstruction(expr); |
| break; |
| @@ -438,6 +434,8 @@ void FlowGraphBuilder::VisitCountOperation(CountOperation* expr) { |
| if (var != NULL && var->IsStackAllocated()) { |
| definitions_.Add(expr); |
| } |
| + |
| + if (HasStackOverflow()) return; |
| graph_.AppendInstruction(expr); |
| } |
| @@ -463,6 +461,7 @@ void FlowGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { |
| case Token::SAR: |
| Visit(expr->left()); |
| Visit(expr->right()); |
| + if (HasStackOverflow()) return; |
| graph_.AppendInstruction(expr); |
| break; |
| @@ -489,6 +488,7 @@ void FlowGraphBuilder::VisitCompareOperation(CompareOperation* expr) { |
| case Token::GTE: |
| Visit(expr->left()); |
| Visit(expr->right()); |
| + if (HasStackOverflow()) return; |
| graph_.AppendInstruction(expr); |
| break; |
| @@ -1341,11 +1341,6 @@ void BlockNode::AssignNumbers() { |
| } |
| -void EntryNode::PrintText() { |
| - PrintF("L%d: Entry\n", number()); |
| - PrintF("goto L%d\n\n", successor_->number()); |
| -} |
| - |
| void ExitNode::PrintText() { |
| PrintF("L%d: Exit\n\n", number()); |
| } |