Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Unified Diff: src/data-flow.cc

Issue 804003: Add defensive checks to the flow graph builder. (Closed)
Patch Set: Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/compiler.cc ('K') | « src/data-flow.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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());
}
« src/compiler.cc ('K') | « src/data-flow.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698