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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 115
116 int length() const { return length_; } 116 int length() const { return length_; }
117 117
118 private: 118 private:
119 int length_; 119 int length_;
120 int data_length_; 120 int data_length_;
121 uint32_t* data_; 121 uint32_t* data_;
122 }; 122 };
123 123
124 124
125 // Forward declarations of Node types.
126 class Node;
127 class BranchNode;
128 class JoinNode;
129
130 // Flow graphs have a single entry and single exit. The empty flowgraph is
131 // represented by both entry and exit being NULL.
132 class FlowGraph BASE_EMBEDDED {
133 public:
134 FlowGraph() : entry_(NULL), exit_(NULL) {}
135
136 static FlowGraph Empty() { return FlowGraph(); }
137
138 bool is_empty() const { return entry_ == NULL; }
139 Node* entry() const { return entry_; }
140 Node* exit() const { return exit_; }
141
142 // Add a single instruction to the end of this flowgraph.
143 void AppendInstruction(AstNode* instruction);
144
145 // Add a single node to the end of this flow graph.
146 void AppendNode(Node* node);
147
148 // Add a flow graph fragment to the end of this one.
149 void AppendGraph(FlowGraph* graph);
150
151 // Concatenate an if-then-else flow-graph to this one. Control is split
152 // and merged, so the graph remains single-entry, single-exit.
153 void Split(BranchNode* branch,
154 FlowGraph* left,
155 FlowGraph* right,
156 JoinNode* merge);
157
158 // Concatenate a forward loop (e.g., while or for loop) flow-graph to this
159 // one. Control is split by the condition and merged back from the back
160 // edge at end of the body to the beginning of the condition. The single
161 // (free) exit of the result graph is the right (false) arm of the branch
162 // node.
163 void Loop(JoinNode* merge,
164 FlowGraph* condition,
165 BranchNode* branch,
166 FlowGraph* body);
167
168 #ifdef DEBUG
169 void PrintText(ZoneList<Node*>* postorder);
170 #endif
171
172 private:
173 Node* entry_;
174 Node* exit_;
175 };
176
177
178 // Flow-graph nodes. 125 // Flow-graph nodes.
179 class Node: public ZoneObject { 126 class Node: public ZoneObject {
180 public: 127 public:
181 Node() : number_(-1), mark_(false) {} 128 Node() : number_(-1), mark_(false) {}
182 129
183 virtual ~Node() {} 130 virtual ~Node() {}
184 131
132 virtual bool IsExitNode() { return false; }
185 virtual bool IsBlockNode() { return false; } 133 virtual bool IsBlockNode() { return false; }
134 virtual bool IsBranchNode() { return false; }
186 virtual bool IsJoinNode() { return false; } 135 virtual bool IsJoinNode() { return false; }
187 136
188 virtual void AddPredecessor(Node* predecessor) = 0; 137 virtual void AddPredecessor(Node* predecessor) = 0;
189 virtual void AddSuccessor(Node* successor) = 0; 138 virtual void AddSuccessor(Node* successor) = 0;
190 139
191 bool IsMarkedWith(bool mark) { return mark_ == mark; } 140 bool IsMarkedWith(bool mark) { return mark_ == mark; }
192 void MarkWith(bool mark) { mark_ = mark; } 141 void MarkWith(bool mark) { mark_ = mark; }
193 142
194 // Perform a depth first search and record preorder and postorder 143 // Perform a depth first search and record preorder and postorder
195 // traversal orders. 144 // traversal orders.
(...skipping 10 matching lines...) Expand all
206 #endif 155 #endif
207 156
208 private: 157 private:
209 int number_; 158 int number_;
210 bool mark_; 159 bool mark_;
211 160
212 DISALLOW_COPY_AND_ASSIGN(Node); 161 DISALLOW_COPY_AND_ASSIGN(Node);
213 }; 162 };
214 163
215 164
216 // An entry node has no predecessors and a single successor.
217 class EntryNode: public Node {
218 public:
219 EntryNode() : successor_(NULL) {}
220
221 void AddPredecessor(Node* predecessor) { UNREACHABLE(); }
222
223 void AddSuccessor(Node* successor) {
224 ASSERT(successor_ == NULL && successor != NULL);
225 successor_ = successor;
226 }
227
228 void Traverse(bool mark,
229 ZoneList<Node*>* preorder,
230 ZoneList<Node*>* postorder);
231
232 #ifdef DEBUG
233 void PrintText();
234 #endif
235
236 private:
237 Node* successor_;
238
239 DISALLOW_COPY_AND_ASSIGN(EntryNode);
240 };
241
242
243 // An exit node has a arbitrarily many predecessors and no successors. 165 // An exit node has a arbitrarily many predecessors and no successors.
244 class ExitNode: public Node { 166 class ExitNode: public Node {
245 public: 167 public:
246 ExitNode() : predecessors_(4) {} 168 ExitNode() : predecessors_(4) {}
247 169
170 bool IsExitNode() { return true; }
171
248 void AddPredecessor(Node* predecessor) { 172 void AddPredecessor(Node* predecessor) {
249 ASSERT(predecessor != NULL); 173 ASSERT(predecessor != NULL);
250 predecessors_.Add(predecessor); 174 predecessors_.Add(predecessor);
251 } 175 }
252 176
253 void AddSuccessor(Node* successor) { /* Do nothing. */ } 177 void AddSuccessor(Node* successor) { UNREACHABLE(); }
254 178
255 void Traverse(bool mark, 179 void Traverse(bool mark,
256 ZoneList<Node*>* preorder, 180 ZoneList<Node*>* preorder,
257 ZoneList<Node*>* postorder); 181 ZoneList<Node*>* postorder);
258 182
259 #ifdef DEBUG 183 #ifdef DEBUG
260 void PrintText(); 184 void PrintText();
261 #endif 185 #endif
262 186
263 private: 187 private:
264 ZoneList<Node*> predecessors_; 188 ZoneList<Node*> predecessors_;
265 189
266 DISALLOW_COPY_AND_ASSIGN(ExitNode); 190 DISALLOW_COPY_AND_ASSIGN(ExitNode);
267 }; 191 };
268 192
269 193
270 // Block nodes have a single successor and predecessor and a list of 194 // Block nodes have a single successor and predecessor and a list of
271 // instructions. 195 // instructions.
272 class BlockNode: public Node { 196 class BlockNode: public Node {
273 public: 197 public:
274 BlockNode() : predecessor_(NULL), successor_(NULL), instructions_(4) {} 198 BlockNode() : predecessor_(NULL), successor_(NULL), instructions_(4) {}
275 199
276 static BlockNode* cast(Node* node) { 200 static BlockNode* cast(Node* node) {
277 ASSERT(node->IsBlockNode()); 201 ASSERT(node->IsBlockNode());
278 return reinterpret_cast<BlockNode*>(node); 202 return reinterpret_cast<BlockNode*>(node);
279 } 203 }
280 204
281 bool IsBlockNode() { return true; } 205 bool IsBlockNode() { return true; }
282 206
207 bool is_empty() { return instructions_.is_empty(); }
208
283 void AddPredecessor(Node* predecessor) { 209 void AddPredecessor(Node* predecessor) {
284 ASSERT(predecessor_ == NULL && predecessor != NULL); 210 ASSERT(predecessor_ == NULL && predecessor != NULL);
285 predecessor_ = predecessor; 211 predecessor_ = predecessor;
286 } 212 }
287 213
288 void AddSuccessor(Node* successor) { 214 void AddSuccessor(Node* successor) {
289 ASSERT(successor_ == NULL && successor != NULL); 215 ASSERT(successor_ == NULL && successor != NULL);
290 successor_ = successor; 216 successor_ = successor;
291 } 217 }
292 218
(...skipping 17 matching lines...) Expand all
310 236
311 DISALLOW_COPY_AND_ASSIGN(BlockNode); 237 DISALLOW_COPY_AND_ASSIGN(BlockNode);
312 }; 238 };
313 239
314 240
315 // Branch nodes have a single predecessor and a pair of successors. 241 // Branch nodes have a single predecessor and a pair of successors.
316 class BranchNode: public Node { 242 class BranchNode: public Node {
317 public: 243 public:
318 BranchNode() : predecessor_(NULL), successor0_(NULL), successor1_(NULL) {} 244 BranchNode() : predecessor_(NULL), successor0_(NULL), successor1_(NULL) {}
319 245
246 bool IsBranchNode() { return true; }
247
320 void AddPredecessor(Node* predecessor) { 248 void AddPredecessor(Node* predecessor) {
321 ASSERT(predecessor_ == NULL && predecessor != NULL); 249 ASSERT(predecessor_ == NULL && predecessor != NULL);
322 predecessor_ = predecessor; 250 predecessor_ = predecessor;
323 } 251 }
324 252
325 void AddSuccessor(Node* successor) { 253 void AddSuccessor(Node* successor) {
326 ASSERT(successor1_ == NULL && successor != NULL); 254 ASSERT(successor1_ == NULL && successor != NULL);
327 if (successor0_ == NULL) { 255 if (successor0_ == NULL) {
328 successor0_ = successor; 256 successor0_ = successor;
329 } else { 257 } else {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 #endif 307 #endif
380 308
381 private: 309 private:
382 ZoneList<Node*> predecessors_; 310 ZoneList<Node*> predecessors_;
383 Node* successor_; 311 Node* successor_;
384 312
385 DISALLOW_COPY_AND_ASSIGN(JoinNode); 313 DISALLOW_COPY_AND_ASSIGN(JoinNode);
386 }; 314 };
387 315
388 316
317 // Flow graphs have a single entry and single exit. The empty flowgraph is
318 // represented by both entry and exit being NULL.
319 class FlowGraph BASE_EMBEDDED {
320 public:
321 static FlowGraph Empty() {
322 FlowGraph graph;
323 graph.entry_ = new BlockNode();
324 graph.exit_ = graph.entry_;
325 return graph;
326 }
327
328 bool is_empty() const {
329 return entry_ == exit_ && BlockNode::cast(entry_)->is_empty();
330 }
331 Node* entry() const { return entry_; }
332 Node* exit() const { return exit_; }
333
334 // Add a single instruction to the end of this flowgraph.
335 void AppendInstruction(AstNode* instruction);
336
337 // Add a single node to the end of this flow graph.
338 void AppendNode(Node* node);
339
340 // Add a flow graph fragment to the end of this one.
341 void AppendGraph(FlowGraph* graph);
342
343 // Concatenate an if-then-else flow-graph to this one. Control is split
344 // and merged, so the graph remains single-entry, single-exit.
345 void Split(BranchNode* branch,
346 FlowGraph* left,
347 FlowGraph* right,
348 JoinNode* merge);
349
350 // Concatenate a forward loop (e.g., while or for loop) flow-graph to this
351 // one. Control is split by the condition and merged back from the back
352 // edge at end of the body to the beginning of the condition. The single
353 // (free) exit of the result graph is the right (false) arm of the branch
354 // node.
355 void Loop(JoinNode* merge,
356 FlowGraph* condition,
357 BranchNode* branch,
358 FlowGraph* body);
359
360 #ifdef DEBUG
361 void PrintText(ZoneList<Node*>* postorder);
362 #endif
363
364 private:
365 FlowGraph() : entry_(NULL), exit_(NULL) {}
366
367 Node* entry_;
368 Node* exit_;
369 };
370
371
389 // Construct a flow graph from a function literal. Build pre- and postorder 372 // Construct a flow graph from a function literal. Build pre- and postorder
390 // traversal orders as a byproduct. 373 // traversal orders as a byproduct.
391 class FlowGraphBuilder: public AstVisitor { 374 class FlowGraphBuilder: public AstVisitor {
392 public: 375 public:
393 FlowGraphBuilder() 376 FlowGraphBuilder()
394 : global_exit_(NULL), 377 : graph_(FlowGraph::Empty()),
378 global_exit_(NULL),
395 preorder_(4), 379 preorder_(4),
396 postorder_(4), 380 postorder_(4),
397 definitions_(4) { 381 definitions_(4) {
398 } 382 }
399 383
400 void Build(FunctionLiteral* lit); 384 void Build(FunctionLiteral* lit);
401 385
402 FlowGraph* graph() { return &graph_; } 386 FlowGraph* graph() { return &graph_; }
403 387
404 ZoneList<Node*>* postorder() { return &postorder_; } 388 ZoneList<Node*>* postorder() { return &postorder_; }
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 VarUseMap live_vars_; 483 VarUseMap live_vars_;
500 484
501 DISALLOW_COPY_AND_ASSIGN(LivenessAnalyzer); 485 DISALLOW_COPY_AND_ASSIGN(LivenessAnalyzer);
502 }; 486 };
503 487
504 488
505 } } // namespace v8::internal 489 } } // namespace v8::internal
506 490
507 491
508 #endif // V8_DATAFLOW_H_ 492 #endif // V8_DATAFLOW_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698