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

Unified Diff: src/data-flow.h

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
Index: src/data-flow.h
diff --git a/src/data-flow.h b/src/data-flow.h
index 2dc2d73275c8a8ab02ea0bdbdd075f66d7e8b712..8f58283e0e6b15e2b72cce3eb2554464475d288c 100644
--- a/src/data-flow.h
+++ b/src/data-flow.h
@@ -122,59 +122,6 @@ class BitVector: public ZoneObject {
};
-// Forward declarations of Node types.
-class Node;
-class BranchNode;
-class JoinNode;
-
-// Flow graphs have a single entry and single exit. The empty flowgraph is
-// represented by both entry and exit being NULL.
-class FlowGraph BASE_EMBEDDED {
- public:
- FlowGraph() : entry_(NULL), exit_(NULL) {}
-
- static FlowGraph Empty() { return FlowGraph(); }
-
- bool is_empty() const { return entry_ == NULL; }
- Node* entry() const { return entry_; }
- Node* exit() const { return exit_; }
-
- // Add a single instruction to the end of this flowgraph.
- void AppendInstruction(AstNode* instruction);
-
- // Add a single node to the end of this flow graph.
- void AppendNode(Node* node);
-
- // Add a flow graph fragment to the end of this one.
- void AppendGraph(FlowGraph* graph);
-
- // Concatenate an if-then-else flow-graph to this one. Control is split
- // and merged, so the graph remains single-entry, single-exit.
- void Split(BranchNode* branch,
- FlowGraph* left,
- FlowGraph* right,
- JoinNode* merge);
-
- // Concatenate a forward loop (e.g., while or for loop) flow-graph to this
- // one. Control is split by the condition and merged back from the back
- // edge at end of the body to the beginning of the condition. The single
- // (free) exit of the result graph is the right (false) arm of the branch
- // node.
- void Loop(JoinNode* merge,
- FlowGraph* condition,
- BranchNode* branch,
- FlowGraph* body);
-
-#ifdef DEBUG
- void PrintText(ZoneList<Node*>* postorder);
-#endif
-
- private:
- Node* entry_;
- Node* exit_;
-};
-
-
// Flow-graph nodes.
class Node: public ZoneObject {
public:
@@ -182,7 +129,9 @@ class Node: public ZoneObject {
virtual ~Node() {}
+ virtual bool IsExitNode() { return false; }
virtual bool IsBlockNode() { return false; }
+ virtual bool IsBranchNode() { return false; }
virtual bool IsJoinNode() { return false; }
virtual void AddPredecessor(Node* predecessor) = 0;
@@ -213,44 +162,19 @@ class Node: public ZoneObject {
};
-// An entry node has no predecessors and a single successor.
-class EntryNode: public Node {
- public:
- EntryNode() : successor_(NULL) {}
-
- void AddPredecessor(Node* predecessor) { UNREACHABLE(); }
-
- void AddSuccessor(Node* successor) {
- ASSERT(successor_ == NULL && successor != NULL);
- successor_ = successor;
- }
-
- void Traverse(bool mark,
- ZoneList<Node*>* preorder,
- ZoneList<Node*>* postorder);
-
-#ifdef DEBUG
- void PrintText();
-#endif
-
- private:
- Node* successor_;
-
- DISALLOW_COPY_AND_ASSIGN(EntryNode);
-};
-
-
// An exit node has a arbitrarily many predecessors and no successors.
class ExitNode: public Node {
public:
ExitNode() : predecessors_(4) {}
+ bool IsExitNode() { return true; }
+
void AddPredecessor(Node* predecessor) {
ASSERT(predecessor != NULL);
predecessors_.Add(predecessor);
}
- void AddSuccessor(Node* successor) { /* Do nothing. */ }
+ void AddSuccessor(Node* successor) { UNREACHABLE(); }
void Traverse(bool mark,
ZoneList<Node*>* preorder,
@@ -280,6 +204,8 @@ class BlockNode: public Node {
bool IsBlockNode() { return true; }
+ bool is_empty() { return instructions_.is_empty(); }
+
void AddPredecessor(Node* predecessor) {
ASSERT(predecessor_ == NULL && predecessor != NULL);
predecessor_ = predecessor;
@@ -317,6 +243,8 @@ class BranchNode: public Node {
public:
BranchNode() : predecessor_(NULL), successor0_(NULL), successor1_(NULL) {}
+ bool IsBranchNode() { return true; }
+
void AddPredecessor(Node* predecessor) {
ASSERT(predecessor_ == NULL && predecessor != NULL);
predecessor_ = predecessor;
@@ -386,12 +314,68 @@ class JoinNode: public Node {
};
+// Flow graphs have a single entry and single exit. The empty flowgraph is
+// represented by both entry and exit being NULL.
+class FlowGraph BASE_EMBEDDED {
+ public:
+ static FlowGraph Empty() {
+ FlowGraph graph;
+ graph.entry_ = new BlockNode();
+ graph.exit_ = graph.entry_;
+ return graph;
+ }
+
+ bool is_empty() const {
+ return entry_ == exit_ && BlockNode::cast(entry_)->is_empty();
+ }
+ Node* entry() const { return entry_; }
+ Node* exit() const { return exit_; }
+
+ // Add a single instruction to the end of this flowgraph.
+ void AppendInstruction(AstNode* instruction);
+
+ // Add a single node to the end of this flow graph.
+ void AppendNode(Node* node);
+
+ // Add a flow graph fragment to the end of this one.
+ void AppendGraph(FlowGraph* graph);
+
+ // Concatenate an if-then-else flow-graph to this one. Control is split
+ // and merged, so the graph remains single-entry, single-exit.
+ void Split(BranchNode* branch,
+ FlowGraph* left,
+ FlowGraph* right,
+ JoinNode* merge);
+
+ // Concatenate a forward loop (e.g., while or for loop) flow-graph to this
+ // one. Control is split by the condition and merged back from the back
+ // edge at end of the body to the beginning of the condition. The single
+ // (free) exit of the result graph is the right (false) arm of the branch
+ // node.
+ void Loop(JoinNode* merge,
+ FlowGraph* condition,
+ BranchNode* branch,
+ FlowGraph* body);
+
+#ifdef DEBUG
+ void PrintText(ZoneList<Node*>* postorder);
+#endif
+
+ private:
+ FlowGraph() : entry_(NULL), exit_(NULL) {}
+
+ Node* entry_;
+ Node* exit_;
+};
+
+
// Construct a flow graph from a function literal. Build pre- and postorder
// traversal orders as a byproduct.
class FlowGraphBuilder: public AstVisitor {
public:
FlowGraphBuilder()
- : global_exit_(NULL),
+ : graph_(FlowGraph::Empty()),
+ global_exit_(NULL),
preorder_(4),
postorder_(4),
definitions_(4) {

Powered by Google App Engine
This is Rietveld 408576698