OLD | NEW |
---|---|
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 15 matching lines...) Expand all Loading... | |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include "v8.h" | 28 #include "v8.h" |
29 | 29 |
30 #include "data-flow.h" | 30 #include "data-flow.h" |
31 | 31 |
32 namespace v8 { | 32 namespace v8 { |
33 namespace internal { | 33 namespace internal { |
34 | 34 |
35 | 35 |
36 void FlowGraph::Append(AstNode* instruction) { | |
37 ASSERT(instruction != NULL); | |
38 if (is_empty() || !exit()->IsBlockNode()) { | |
39 Append(new BlockNode()); | |
40 } | |
41 BlockNode::cast(exit())->AddInstruction(instruction); | |
42 } | |
43 | |
44 | |
45 void FlowGraph::Append(Node* node) { | |
46 ASSERT(node != NULL); | |
47 if (is_empty()) { | |
48 entry_ = exit_ = node; | |
49 } else { | |
50 exit()->AddSuccessor(node); | |
51 node->AddPredecessor(exit()); | |
52 exit_ = node; | |
53 } | |
54 } | |
55 | |
56 | |
57 void FlowGraph::Append(FlowGraph* graph) { | |
58 ASSERT(!graph->is_empty()); | |
59 if (is_empty()) { | |
60 entry_ = graph->entry(); | |
61 exit_ = graph->exit(); | |
62 } else { | |
63 exit()->AddSuccessor(graph->entry()); | |
64 graph->entry()->AddPredecessor(exit()); | |
65 exit_ = graph->exit(); | |
66 } | |
67 } | |
68 | |
69 | |
70 void FlowGraph::Split(BranchNode* branch, | |
71 FlowGraph* left, | |
72 FlowGraph* right, | |
73 JoinNode* merge) { | |
74 // Graphs are in edge split form. Add empty blocks if necessary. | |
75 if (left->is_empty()) left->Append(new BlockNode()); | |
76 if (right->is_empty()) right->Append(new BlockNode()); | |
77 | |
78 // Add the branch, left flowgraph and merge. | |
79 Append(branch); | |
80 Append(left); | |
81 Append(merge); | |
82 | |
83 // Splice in the right flowgraph. | |
84 right->Append(merge); | |
85 branch->AddSuccessor(right->entry()); | |
86 right->entry()->AddPredecessor(branch); | |
87 } | |
88 | |
89 | |
90 void FlowGraph::Loop(JoinNode* merge, | |
91 FlowGraph* condition, | |
92 BranchNode* branch, | |
93 FlowGraph* body) { | |
94 // Add the merge, condition and branch. Add merge's predecessors in | |
95 // left-to-right order. | |
96 Append(merge); | |
97 body->Append(merge); | |
98 Append(condition); | |
99 Append(branch); | |
100 | |
101 // Splice in the body flowgraph. | |
102 branch->AddSuccessor(body->entry()); | |
103 body->entry()->AddPredecessor(branch); | |
104 } | |
105 | |
106 | |
107 void EntryNode::Traverse(bool mark, | |
108 ZoneList<Node*>* preorder, | |
109 ZoneList<Node*>* postorder) { | |
110 ASSERT(successor_ != NULL); | |
111 preorder->Add(this); | |
112 if (!successor_->IsMarkedWith(mark)) { | |
113 successor_->MarkWith(mark); | |
114 successor_->Traverse(mark, preorder, postorder); | |
115 } | |
116 postorder->Add(this); | |
117 } | |
118 | |
119 | |
120 void ExitNode::Traverse(bool mark, | |
121 ZoneList<Node*>* preorder, | |
122 ZoneList<Node*>* postorder) { | |
123 preorder->Add(this); | |
124 postorder->Add(this); | |
125 } | |
126 | |
127 | |
128 void BlockNode::Traverse(bool mark, | |
129 ZoneList<Node*>* preorder, | |
130 ZoneList<Node*>* postorder) { | |
131 ASSERT(successor_ != NULL); | |
132 preorder->Add(this); | |
133 if (!successor_->IsMarkedWith(mark)) { | |
134 successor_->MarkWith(mark); | |
135 successor_->Traverse(mark, preorder, postorder); | |
136 } | |
137 postorder->Add(this); | |
138 } | |
139 | |
140 | |
141 void BranchNode::Traverse(bool mark, | |
142 ZoneList<Node*>* preorder, | |
143 ZoneList<Node*>* postorder) { | |
144 ASSERT(successor0_ != NULL && successor1_ != NULL); | |
145 preorder->Add(this); | |
146 if (!successor0_->IsMarkedWith(mark)) { | |
147 successor0_->MarkWith(mark); | |
148 successor0_->Traverse(mark, preorder, postorder); | |
149 } | |
150 if (!successor1_->IsMarkedWith(mark)) { | |
151 successor1_->MarkWith(mark); | |
152 successor1_->Traverse(mark, preorder, postorder); | |
153 } | |
154 postorder->Add(this); | |
155 } | |
156 | |
157 | |
158 void JoinNode::Traverse(bool mark, | |
159 ZoneList<Node*>* preorder, | |
160 ZoneList<Node*>* postorder) { | |
161 ASSERT(successor_ != NULL); | |
162 preorder->Add(this); | |
163 if (!successor_->IsMarkedWith(mark)) { | |
164 successor_->MarkWith(mark); | |
165 successor_->Traverse(mark, preorder, postorder); | |
166 } | |
167 postorder->Add(this); | |
168 } | |
169 | |
170 | |
171 void FlowGraphBuilder::Build(FunctionLiteral* lit) { | |
172 graph_ = FlowGraph::Empty(); | |
173 graph_.Append(new EntryNode()); | |
174 global_exit_ = new ExitNode(); | |
175 VisitStatements(lit->body()); | |
176 | |
177 if (HasStackOverflow()) { | |
178 graph_ = FlowGraph::Empty(); | |
179 return; | |
180 } | |
181 | |
182 graph_.Append(global_exit_); | |
183 | |
184 // Build preorder and postorder traversal orders. All the nodes in | |
185 // the graph have the same mark flag. For the traversal, use that | |
186 // flag's negation. Traversal will flip all the flags. | |
187 bool mark = graph_.entry()->IsMarkedWith(false); | |
188 graph_.entry()->MarkWith(mark); | |
189 graph_.entry()->Traverse(mark, &preorder_, &postorder_); | |
190 } | |
191 | |
192 | |
193 void FlowGraphBuilder::VisitDeclaration(Declaration* decl) { | |
194 UNREACHABLE(); | |
195 } | |
196 | |
197 | |
198 void FlowGraphBuilder::VisitBlock(Block* stmt) { | |
199 VisitStatements(stmt->statements()); | |
200 } | |
201 | |
202 | |
203 void FlowGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) { | |
204 Visit(stmt->expression()); | |
205 } | |
206 | |
207 | |
208 void FlowGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) { | |
209 // Nothing to do. | |
210 } | |
211 | |
212 | |
213 void FlowGraphBuilder::VisitIfStatement(IfStatement* stmt) { | |
214 Visit(stmt->condition()); | |
215 | |
216 BranchNode* branch = new BranchNode(); | |
217 FlowGraph original = graph_; | |
218 graph_ = FlowGraph::Empty(); | |
219 Visit(stmt->then_statement()); | |
220 | |
221 FlowGraph left = graph_; | |
222 graph_ = FlowGraph::Empty(); | |
223 Visit(stmt->else_statement()); | |
224 | |
225 JoinNode* join = new JoinNode(); | |
226 original.Split(branch, &left, &graph_, join); | |
227 graph_ = original; | |
228 } | |
229 | |
230 | |
231 void FlowGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) { | |
232 SetStackOverflow(); | |
233 } | |
234 | |
235 | |
236 void FlowGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { | |
237 SetStackOverflow(); | |
238 } | |
239 | |
240 | |
241 void FlowGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { | |
242 Visit(stmt->expression()); | |
243 graph_.Append(stmt); | |
244 graph_.Append(global_exit()); | |
245 } | |
246 | |
247 | |
248 void FlowGraphBuilder::VisitWithEnterStatement(WithEnterStatement* stmt) { | |
249 Visit(stmt->expression()); | |
250 graph_.Append(stmt); | |
251 } | |
252 | |
253 | |
254 void FlowGraphBuilder::VisitWithExitStatement(WithExitStatement* stmt) { | |
255 graph_.Append(stmt); | |
256 } | |
257 | |
258 | |
259 void FlowGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { | |
260 SetStackOverflow(); | |
261 } | |
262 | |
263 | |
264 void FlowGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { | |
265 JoinNode* join = new JoinNode(); | |
266 FlowGraph original = graph_; | |
267 graph_ = FlowGraph::Empty(); | |
268 Visit(stmt->body()); | |
269 | |
270 FlowGraph body = graph_; | |
271 graph_ = FlowGraph::Empty(); | |
272 Visit(stmt->cond()); | |
273 | |
274 BranchNode* branch = new BranchNode(); | |
275 | |
276 // Add body, condition and branch. | |
277 original.Append(join); | |
278 original.Append(&body); | |
279 original.Append(&graph_); // The condition. | |
280 original.Append(branch); | |
281 | |
282 // Tie the knot. | |
283 branch->AddSuccessor(join); | |
284 join->AddPredecessor(branch); | |
285 | |
286 graph_ = original; | |
287 } | |
288 | |
289 | |
290 void FlowGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { | |
291 JoinNode* join = new JoinNode(); | |
292 FlowGraph original = graph_; | |
293 graph_ = FlowGraph::Empty(); | |
294 Visit(stmt->cond()); | |
295 | |
296 BranchNode* branch = new BranchNode(); | |
297 FlowGraph condition = graph_; | |
298 graph_ = FlowGraph::Empty(); | |
299 Visit(stmt->body()); | |
300 | |
301 original.Loop(join, &condition, branch, &graph_); | |
302 graph_ = original; | |
303 } | |
304 | |
305 | |
306 void FlowGraphBuilder::VisitForStatement(ForStatement* stmt) { | |
307 if (stmt->init() != NULL) Visit(stmt->init()); | |
308 | |
309 JoinNode* join = new JoinNode(); | |
310 FlowGraph original = graph_; | |
311 graph_ = FlowGraph::Empty(); | |
312 if (stmt->cond() != NULL) Visit(stmt->cond()); | |
313 | |
314 BranchNode* branch = new BranchNode(); | |
315 FlowGraph condition = graph_; | |
316 graph_ = FlowGraph::Empty(); | |
317 Visit(stmt->body()); | |
318 | |
319 if (stmt->next() != NULL) Visit(stmt->next()); | |
320 | |
321 original.Loop(join, &condition, branch, &graph_); | |
322 graph_ = original; | |
323 } | |
324 | |
325 | |
326 void FlowGraphBuilder::VisitForInStatement(ForInStatement* stmt) { | |
327 Visit(stmt->enumerable()); | |
328 | |
329 JoinNode* join = new JoinNode(); | |
330 FlowGraph empty; | |
331 BranchNode* branch = new BranchNode(); | |
332 FlowGraph original = graph_; | |
333 graph_ = FlowGraph::Empty(); | |
334 Visit(stmt->body()); | |
335 | |
336 original.Loop(join, &empty, branch, &graph_); | |
337 graph_ = original; | |
338 } | |
339 | |
340 | |
341 void FlowGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { | |
342 SetStackOverflow(); | |
343 } | |
344 | |
345 | |
346 void FlowGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) { | |
347 SetStackOverflow(); | |
348 } | |
349 | |
350 | |
351 void FlowGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { | |
352 graph_.Append(stmt); | |
353 } | |
354 | |
355 | |
356 void FlowGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { | |
357 graph_.Append(expr); | |
358 } | |
359 | |
360 | |
361 void FlowGraphBuilder::VisitFunctionBoilerplateLiteral( | |
362 FunctionBoilerplateLiteral* expr) { | |
363 graph_.Append(expr); | |
364 } | |
365 | |
366 | |
367 void FlowGraphBuilder::VisitConditional(Conditional* expr) { | |
368 Visit(expr->condition()); | |
369 | |
370 BranchNode* branch = new BranchNode(); | |
371 FlowGraph original = graph_; | |
372 graph_ = FlowGraph::Empty(); | |
373 Visit(expr->then_expression()); | |
374 | |
375 FlowGraph left = graph_; | |
376 graph_ = FlowGraph::Empty(); | |
377 Visit(expr->else_expression()); | |
378 | |
379 JoinNode* join = new JoinNode(); | |
380 original.Split(branch, &left, &graph_, join); | |
381 graph_ = original; | |
382 } | |
383 | |
384 | |
385 void FlowGraphBuilder::VisitSlot(Slot* expr) { | |
386 UNREACHABLE(); | |
387 } | |
388 | |
389 | |
390 void FlowGraphBuilder::VisitVariableProxy(VariableProxy* expr) { | |
391 graph_.Append(expr); | |
392 } | |
393 | |
394 | |
395 void FlowGraphBuilder::VisitLiteral(Literal* expr) { | |
396 graph_.Append(expr); | |
397 } | |
398 | |
399 | |
400 void FlowGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { | |
401 graph_.Append(expr); | |
402 } | |
403 | |
404 | |
405 void FlowGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { | |
406 ZoneList<ObjectLiteral::Property*>* properties = expr->properties(); | |
407 for (int i = 0, len = properties->length(); i < len; i++) { | |
408 Visit(properties->at(i)->value()); | |
409 } | |
410 graph_.Append(expr); | |
411 } | |
412 | |
413 | |
414 void FlowGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { | |
415 ZoneList<Expression*>* values = expr->values(); | |
416 for (int i = 0, len = values->length(); i < len; i++) { | |
417 Visit(values->at(i)); | |
418 } | |
419 graph_.Append(expr); | |
420 } | |
421 | |
422 | |
423 void FlowGraphBuilder::VisitCatchExtensionObject(CatchExtensionObject* expr) { | |
424 graph_.Append(expr); | |
425 } | |
426 | |
427 | |
428 void FlowGraphBuilder::VisitAssignment(Assignment* expr) { | |
429 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | |
430 Property* prop = expr->target()->AsProperty(); | |
431 // Left-hand side can be a variable or property (or reference error) but | |
432 // not both. | |
433 ASSERT(var == NULL || prop == NULL); | |
434 if (prop != NULL) { | |
435 Visit(prop->obj()); | |
436 if (!prop->key()->IsPropertyName()) Visit(prop->key()); | |
437 } | |
438 if (var != NULL || prop != NULL) { | |
439 Visit(expr->value()); | |
440 } | |
441 graph_.Append(expr); | |
442 } | |
443 | |
444 | |
445 void FlowGraphBuilder::VisitThrow(Throw* expr) { | |
446 Visit(expr->exception()); | |
447 graph_.Append(expr); | |
448 } | |
449 | |
450 | |
451 void FlowGraphBuilder::VisitProperty(Property* expr) { | |
452 Visit(expr->obj()); | |
453 if (!expr->key()->IsPropertyName()) Visit(expr->key()); | |
454 graph_.Append(expr); | |
455 } | |
456 | |
457 | |
458 void FlowGraphBuilder::VisitCall(Call* expr) { | |
459 Visit(expr->expression()); | |
460 ZoneList<Expression*>* arguments = expr->arguments(); | |
461 for (int i = 0, len = arguments->length(); i < len; i++) { | |
462 Visit(arguments->at(i)); | |
463 } | |
464 graph_.Append(expr); | |
465 } | |
466 | |
467 | |
468 void FlowGraphBuilder::VisitCallNew(CallNew* expr) { | |
469 Visit(expr->expression()); | |
470 ZoneList<Expression*>* arguments = expr->arguments(); | |
471 for (int i = 0, len = arguments->length(); i < len; i++) { | |
472 Visit(arguments->at(i)); | |
473 } | |
474 graph_.Append(expr); | |
475 } | |
476 | |
477 | |
478 void FlowGraphBuilder::VisitCallRuntime(CallRuntime* expr) { | |
479 ZoneList<Expression*>* arguments = expr->arguments(); | |
480 for (int i = 0, len = arguments->length(); i < len; i++) { | |
481 Visit(arguments->at(i)); | |
482 } | |
483 graph_.Append(expr); | |
484 } | |
485 | |
486 | |
487 void FlowGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { | |
488 Visit(expr->expression()); | |
489 graph_.Append(expr); | |
490 } | |
491 | |
492 | |
493 void FlowGraphBuilder::VisitCountOperation(CountOperation* expr) { | |
494 Visit(expr->expression()); | |
495 graph_.Append(expr); | |
496 } | |
497 | |
498 | |
499 void FlowGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { | |
500 Visit(expr->left()); | |
501 | |
502 switch (expr->op()) { | |
503 case Token::COMMA: | |
504 Visit(expr->right()); | |
505 break; | |
506 | |
507 case Token::OR: { | |
508 BranchNode* branch = new BranchNode(); | |
509 FlowGraph original = graph_; | |
510 graph_ = FlowGraph::Empty(); | |
511 Visit(expr->right()); | |
512 FlowGraph empty; | |
513 JoinNode* join = new JoinNode(); | |
514 original.Split(branch, &empty, &graph_, join); | |
515 graph_ = original; | |
516 break; | |
517 } | |
518 | |
519 case Token::AND: { | |
520 BranchNode* branch = new BranchNode(); | |
521 FlowGraph original = graph_; | |
522 graph_ = FlowGraph::Empty(); | |
523 Visit(expr->right()); | |
524 FlowGraph empty; | |
525 JoinNode* join = new JoinNode(); | |
526 original.Split(branch, &graph_, &empty, join); | |
527 graph_ = original; | |
528 break; | |
529 } | |
530 | |
531 case Token::BIT_OR: | |
532 case Token::BIT_XOR: | |
533 case Token::BIT_AND: | |
534 case Token::SHL: | |
535 case Token::SAR: | |
536 case Token::SHR: | |
537 case Token::ADD: | |
538 case Token::SUB: | |
539 case Token::MUL: | |
540 case Token::DIV: | |
541 case Token::MOD: | |
542 Visit(expr->right()); | |
543 graph_.Append(expr); | |
544 break; | |
545 | |
546 default: | |
547 UNREACHABLE(); | |
548 } | |
549 } | |
550 | |
551 | |
552 void FlowGraphBuilder::VisitCompareOperation(CompareOperation* expr) { | |
553 Visit(expr->left()); | |
554 Visit(expr->right()); | |
555 graph_.Append(expr); | |
556 } | |
557 | |
558 | |
559 void FlowGraphBuilder::VisitThisFunction(ThisFunction* expr) { | |
560 graph_.Append(expr); | |
561 } | |
562 | |
563 | |
36 void AstLabeler::Label(CompilationInfo* info) { | 564 void AstLabeler::Label(CompilationInfo* info) { |
37 info_ = info; | 565 info_ = info; |
38 VisitStatements(info_->function()->body()); | 566 VisitStatements(info_->function()->body()); |
39 } | 567 } |
40 | 568 |
41 | 569 |
42 void AstLabeler::VisitStatements(ZoneList<Statement*>* stmts) { | 570 void AstLabeler::VisitStatements(ZoneList<Statement*>* stmts) { |
43 for (int i = 0, len = stmts->length(); i < len; i++) { | 571 for (int i = 0, len = stmts->length(); i < len; i++) { |
44 Visit(stmts->at(i)); | 572 Visit(stmts->at(i)); |
45 } | 573 } |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
197 | 725 |
198 | 726 |
199 void AstLabeler::VisitAssignment(Assignment* expr) { | 727 void AstLabeler::VisitAssignment(Assignment* expr) { |
200 Property* prop = expr->target()->AsProperty(); | 728 Property* prop = expr->target()->AsProperty(); |
201 ASSERT(prop != NULL); | 729 ASSERT(prop != NULL); |
202 ASSERT(prop->key()->IsPropertyName()); | 730 ASSERT(prop->key()->IsPropertyName()); |
203 VariableProxy* proxy = prop->obj()->AsVariableProxy(); | 731 VariableProxy* proxy = prop->obj()->AsVariableProxy(); |
204 USE(proxy); | 732 USE(proxy); |
205 ASSERT(proxy != NULL && proxy->var()->is_this()); | 733 ASSERT(proxy != NULL && proxy->var()->is_this()); |
206 info()->set_has_this_properties(true); | 734 info()->set_has_this_properties(true); |
735 | |
736 prop->obj()->set_num(AstNode::kNoNumber); | |
fschneider
2010/03/08 12:14:27
We should remove depending on certain nodes having
| |
737 prop->key()->set_num(AstNode::kNoNumber); | |
207 Visit(expr->value()); | 738 Visit(expr->value()); |
208 expr->set_num(next_number_++); | 739 expr->set_num(next_number_++); |
209 } | 740 } |
210 | 741 |
211 | 742 |
212 void AstLabeler::VisitThrow(Throw* expr) { | 743 void AstLabeler::VisitThrow(Throw* expr) { |
213 UNREACHABLE(); | 744 UNREACHABLE(); |
214 } | 745 } |
215 | 746 |
216 | 747 |
217 void AstLabeler::VisitProperty(Property* expr) { | 748 void AstLabeler::VisitProperty(Property* expr) { |
218 ASSERT(expr->key()->IsPropertyName()); | 749 ASSERT(expr->key()->IsPropertyName()); |
219 VariableProxy* proxy = expr->obj()->AsVariableProxy(); | 750 VariableProxy* proxy = expr->obj()->AsVariableProxy(); |
220 USE(proxy); | 751 USE(proxy); |
221 ASSERT(proxy != NULL && proxy->var()->is_this()); | 752 ASSERT(proxy != NULL && proxy->var()->is_this()); |
222 info()->set_has_this_properties(true); | 753 info()->set_has_this_properties(true); |
754 | |
755 expr->obj()->set_num(AstNode::kNoNumber); | |
756 expr->key()->set_num(AstNode::kNoNumber); | |
223 expr->set_num(next_number_++); | 757 expr->set_num(next_number_++); |
224 } | 758 } |
225 | 759 |
226 | 760 |
227 void AstLabeler::VisitCall(Call* expr) { | 761 void AstLabeler::VisitCall(Call* expr) { |
228 UNREACHABLE(); | 762 UNREACHABLE(); |
229 } | 763 } |
230 | 764 |
231 | 765 |
232 void AstLabeler::VisitCallNew(CallNew* expr) { | 766 void AstLabeler::VisitCallNew(CallNew* expr) { |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
551 void LivenessAnalyzer::VisitCompareOperation(CompareOperation* expr) { | 1085 void LivenessAnalyzer::VisitCompareOperation(CompareOperation* expr) { |
552 UNREACHABLE(); | 1086 UNREACHABLE(); |
553 } | 1087 } |
554 | 1088 |
555 | 1089 |
556 void LivenessAnalyzer::VisitThisFunction(ThisFunction* expr) { | 1090 void LivenessAnalyzer::VisitThisFunction(ThisFunction* expr) { |
557 UNREACHABLE(); | 1091 UNREACHABLE(); |
558 } | 1092 } |
559 | 1093 |
560 | 1094 |
1095 #ifdef DEBUG | |
1096 | |
1097 // Print a textual representation of an instruction in a flow graph. Using | |
1098 // the AstVisitor is overkill because there is no recursion here. It is | |
1099 // only used for printing in debug mode. | |
1100 class TextInstructionPrinter: public AstVisitor { | |
1101 public: | |
1102 TextInstructionPrinter() {} | |
1103 | |
1104 private: | |
1105 // AST node visit functions. | |
1106 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); | |
1107 AST_NODE_LIST(DECLARE_VISIT) | |
1108 #undef DECLARE_VISIT | |
1109 | |
1110 DISALLOW_COPY_AND_ASSIGN(TextInstructionPrinter); | |
1111 }; | |
1112 | |
1113 | |
1114 void TextInstructionPrinter::VisitDeclaration(Declaration* decl) { | |
1115 UNREACHABLE(); | |
1116 } | |
1117 | |
1118 | |
1119 void TextInstructionPrinter::VisitBlock(Block* stmt) { | |
1120 PrintF("Block"); | |
1121 } | |
1122 | |
1123 | |
1124 void TextInstructionPrinter::VisitExpressionStatement(ExpressionStatement* stmt) { | |
1125 PrintF("ExpressionStatement"); | |
1126 } | |
1127 | |
1128 | |
1129 void TextInstructionPrinter::VisitEmptyStatement(EmptyStatement* stmt) { | |
1130 PrintF("EmptyStatement"); | |
1131 } | |
1132 | |
1133 | |
1134 void TextInstructionPrinter::VisitIfStatement(IfStatement* stmt) { | |
1135 PrintF("IfStatement"); | |
1136 } | |
1137 | |
1138 | |
1139 void TextInstructionPrinter::VisitContinueStatement(ContinueStatement* stmt) { | |
1140 UNREACHABLE(); | |
1141 } | |
1142 | |
1143 | |
1144 void TextInstructionPrinter::VisitBreakStatement(BreakStatement* stmt) { | |
1145 UNREACHABLE(); | |
1146 } | |
1147 | |
1148 | |
1149 void TextInstructionPrinter::VisitReturnStatement(ReturnStatement* stmt) { | |
1150 PrintF("return @%d", stmt->expression()->num()); | |
1151 } | |
1152 | |
1153 | |
1154 void TextInstructionPrinter::VisitWithEnterStatement(WithEnterStatement* stmt) { | |
1155 PrintF("WithEnterStatement"); | |
1156 } | |
1157 | |
1158 | |
1159 void TextInstructionPrinter::VisitWithExitStatement(WithExitStatement* stmt) { | |
1160 PrintF("WithExitStatement"); | |
1161 } | |
1162 | |
1163 | |
1164 void TextInstructionPrinter::VisitSwitchStatement(SwitchStatement* stmt) { | |
1165 UNREACHABLE(); | |
1166 } | |
1167 | |
1168 | |
1169 void TextInstructionPrinter::VisitDoWhileStatement(DoWhileStatement* stmt) { | |
1170 PrintF("DoWhileStatement"); | |
1171 } | |
1172 | |
1173 | |
1174 void TextInstructionPrinter::VisitWhileStatement(WhileStatement* stmt) { | |
1175 PrintF("WhileStatement"); | |
1176 } | |
1177 | |
1178 | |
1179 void TextInstructionPrinter::VisitForStatement(ForStatement* stmt) { | |
1180 PrintF("ForStatement"); | |
1181 } | |
1182 | |
1183 | |
1184 void TextInstructionPrinter::VisitForInStatement(ForInStatement* stmt) { | |
1185 PrintF("ForInStatement"); | |
1186 } | |
1187 | |
1188 | |
1189 void TextInstructionPrinter::VisitTryCatchStatement(TryCatchStatement* stmt) { | |
1190 UNREACHABLE(); | |
1191 } | |
1192 | |
1193 | |
1194 void TextInstructionPrinter::VisitTryFinallyStatement( | |
1195 TryFinallyStatement* stmt) { | |
1196 UNREACHABLE(); | |
1197 } | |
1198 | |
1199 | |
1200 void TextInstructionPrinter::VisitDebuggerStatement(DebuggerStatement* stmt) { | |
1201 PrintF("DebuggerStatement"); | |
1202 } | |
1203 | |
1204 | |
1205 void TextInstructionPrinter::VisitFunctionLiteral(FunctionLiteral* expr) { | |
1206 PrintF("FunctionLiteral"); | |
1207 } | |
1208 | |
1209 | |
1210 void TextInstructionPrinter::VisitFunctionBoilerplateLiteral( | |
1211 FunctionBoilerplateLiteral* expr) { | |
1212 PrintF("FunctionBoilerplateLiteral"); | |
1213 } | |
1214 | |
1215 | |
1216 void TextInstructionPrinter::VisitConditional(Conditional* expr) { | |
1217 PrintF("Conditional"); | |
1218 } | |
1219 | |
1220 | |
1221 void TextInstructionPrinter::VisitSlot(Slot* expr) { | |
1222 UNREACHABLE(); | |
1223 } | |
1224 | |
1225 | |
1226 void TextInstructionPrinter::VisitVariableProxy(VariableProxy* expr) { | |
1227 Variable* var = expr->AsVariable(); | |
1228 if (var != NULL) { | |
1229 SmartPointer<char> name = var->name()->ToCString(); | |
1230 PrintF("%s", *name); | |
1231 } else { | |
1232 ASSERT(expr->AsProperty() != NULL); | |
1233 VisitProperty(expr->AsProperty()); | |
1234 } | |
1235 } | |
1236 | |
1237 | |
1238 void TextInstructionPrinter::VisitLiteral(Literal* expr) { | |
1239 expr->handle()->ShortPrint(); | |
1240 } | |
1241 | |
1242 | |
1243 void TextInstructionPrinter::VisitRegExpLiteral(RegExpLiteral* expr) { | |
1244 PrintF("RegExpLiteral"); | |
1245 } | |
1246 | |
1247 | |
1248 void TextInstructionPrinter::VisitObjectLiteral(ObjectLiteral* expr) { | |
1249 PrintF("ObjectLiteral"); | |
1250 } | |
1251 | |
1252 | |
1253 void TextInstructionPrinter::VisitArrayLiteral(ArrayLiteral* expr) { | |
1254 PrintF("ArrayLiteral"); | |
1255 } | |
1256 | |
1257 | |
1258 void TextInstructionPrinter::VisitCatchExtensionObject( | |
1259 CatchExtensionObject* expr) { | |
1260 PrintF("CatchExtensionObject"); | |
1261 } | |
1262 | |
1263 | |
1264 void TextInstructionPrinter::VisitAssignment(Assignment* expr) { | |
1265 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | |
1266 Property* prop = expr->target()->AsProperty(); | |
1267 | |
1268 if (var != NULL) { | |
1269 SmartPointer<char> name = var->name()->ToCString(); | |
1270 PrintF("%s %s @%d", | |
1271 *name, | |
1272 Token::String(expr->op()), | |
1273 expr->value()->num()); | |
1274 } else if (prop != NULL) { | |
1275 if (prop->key()->IsPropertyName()) { | |
1276 PrintF("@%d.", prop->obj()->num()); | |
1277 ASSERT(prop->key()->AsLiteral() != NULL); | |
1278 prop->key()->AsLiteral()->handle()->Print(); | |
1279 PrintF(" %s @%d", | |
1280 Token::String(expr->op()), | |
1281 expr->value()->num()); | |
1282 } else { | |
1283 PrintF("@%d[@%d] %s @%d", | |
1284 prop->obj()->num(), | |
1285 prop->key()->num(), | |
1286 Token::String(expr->op()), | |
1287 expr->value()->num()); | |
1288 } | |
1289 } else { | |
1290 // Throw reference error. | |
1291 Visit(expr->target()); | |
1292 } | |
1293 } | |
1294 | |
1295 | |
1296 void TextInstructionPrinter::VisitThrow(Throw* expr) { | |
1297 PrintF("throw @%d", expr->exception()->num()); | |
1298 } | |
1299 | |
1300 | |
1301 void TextInstructionPrinter::VisitProperty(Property* expr) { | |
1302 if (expr->key()->IsPropertyName()) { | |
1303 PrintF("@%d.", expr->obj()->num()); | |
1304 ASSERT(expr->key()->AsLiteral() != NULL); | |
1305 expr->key()->AsLiteral()->handle()->Print(); | |
1306 } else { | |
1307 PrintF("@%d[@%d]", expr->obj()->num(), expr->key()->num()); | |
1308 } | |
1309 } | |
1310 | |
1311 | |
1312 void TextInstructionPrinter::VisitCall(Call* expr) { | |
1313 PrintF("@%d(", expr->expression()->num()); | |
1314 ZoneList<Expression*>* arguments = expr->arguments(); | |
1315 for (int i = 0, len = arguments->length(); i < len; i++) { | |
1316 if (i != 0) PrintF(", "); | |
1317 PrintF("@%d", arguments->at(i)->num()); | |
1318 } | |
1319 PrintF(")"); | |
1320 } | |
1321 | |
1322 | |
1323 void TextInstructionPrinter::VisitCallNew(CallNew* expr) { | |
1324 PrintF("new @%d(", expr->expression()->num()); | |
1325 ZoneList<Expression*>* arguments = expr->arguments(); | |
1326 for (int i = 0, len = arguments->length(); i < len; i++) { | |
1327 if (i != 0) PrintF(", "); | |
1328 PrintF("@%d", arguments->at(i)->num()); | |
1329 } | |
1330 PrintF(")"); | |
1331 } | |
1332 | |
1333 | |
1334 void TextInstructionPrinter::VisitCallRuntime(CallRuntime* expr) { | |
1335 SmartPointer<char> name = expr->name()->ToCString(); | |
1336 PrintF("%s(", *name); | |
1337 ZoneList<Expression*>* arguments = expr->arguments(); | |
1338 for (int i = 0, len = arguments->length(); i < len; i++) { | |
1339 if (i != 0) PrintF(", "); | |
1340 PrintF("@%d", arguments->at(i)->num()); | |
1341 } | |
1342 PrintF(")"); | |
1343 } | |
1344 | |
1345 | |
1346 void TextInstructionPrinter::VisitUnaryOperation(UnaryOperation* expr) { | |
1347 PrintF("%s(@%d)", Token::String(expr->op()), expr->expression()->num()); | |
1348 } | |
1349 | |
1350 | |
1351 void TextInstructionPrinter::VisitCountOperation(CountOperation* expr) { | |
1352 if (expr->is_prefix()) { | |
1353 PrintF("%s@%d", Token::String(expr->op()), expr->expression()->num()); | |
1354 } else { | |
1355 PrintF("@%d%s", expr->expression()->num(), Token::String(expr->op())); | |
1356 } | |
1357 } | |
1358 | |
1359 | |
1360 void TextInstructionPrinter::VisitBinaryOperation(BinaryOperation* expr) { | |
1361 ASSERT(expr->op() != Token::COMMA); | |
1362 ASSERT(expr->op() != Token::OR); | |
1363 ASSERT(expr->op() != Token::AND); | |
1364 PrintF("@%d %s @%d", | |
1365 expr->left()->num(), | |
1366 Token::String(expr->op()), | |
1367 expr->right()->num()); | |
1368 } | |
1369 | |
1370 | |
1371 void TextInstructionPrinter::VisitCompareOperation(CompareOperation* expr) { | |
1372 PrintF("@%d %s @%d", | |
1373 expr->left()->num(), | |
1374 Token::String(expr->op()), | |
1375 expr->right()->num()); | |
1376 } | |
1377 | |
1378 | |
1379 void TextInstructionPrinter::VisitThisFunction(ThisFunction* expr) { | |
1380 PrintF("ThisFunction"); | |
1381 } | |
1382 | |
1383 | |
1384 static int node_count = 0; | |
1385 static int instruction_count = 0; | |
1386 | |
1387 | |
1388 void Node::AssignNumbers() { | |
1389 set_number(node_count++); | |
1390 } | |
1391 | |
1392 | |
1393 void BlockNode::AssignNumbers() { | |
1394 set_number(node_count++); | |
1395 for (int i = 0, len = instructions_.length(); i < len; i++) { | |
1396 instructions_[i]->set_num(instruction_count++); | |
1397 } | |
1398 } | |
1399 | |
1400 | |
1401 void EntryNode::PrintText() { | |
1402 PrintF("L%d: Entry\n", number()); | |
1403 PrintF("goto L%d\n\n", successor_->number()); | |
1404 } | |
1405 | |
1406 void ExitNode::PrintText() { | |
1407 PrintF("L%d: Exit\n\n", number()); | |
1408 } | |
1409 | |
1410 | |
1411 void BlockNode::PrintText() { | |
1412 // Print the instructions in the block. | |
1413 PrintF("L%d: Block\n", number()); | |
1414 TextInstructionPrinter printer; | |
1415 for (int i = 0, len = instructions_.length(); i < len; i++) { | |
1416 PrintF("%d ", instructions_[i]->num()); | |
1417 printer.Visit(instructions_[i]); | |
1418 PrintF("\n"); | |
1419 } | |
1420 PrintF("goto L%d\n\n", successor_->number()); | |
1421 } | |
1422 | |
1423 | |
1424 void BranchNode::PrintText() { | |
1425 PrintF("L%d: Branch\n", number()); | |
1426 PrintF("goto (L%d, L%d)\n\n", successor0_->number(), successor1_->number()); | |
1427 } | |
1428 | |
1429 | |
1430 void JoinNode::PrintText() { | |
1431 PrintF("L%d: Join(", number()); | |
1432 for (int i = 0, len = predecessors_.length(); i < len; i++) { | |
1433 if (i != 0) PrintF(", "); | |
1434 PrintF("L%d", predecessors_[i]->number()); | |
1435 } | |
1436 PrintF(")\ngoto L%d\n\n", successor_->number()); | |
1437 } | |
1438 | |
1439 | |
1440 void FlowGraph::PrintText(ZoneList<Node*>* postorder) { | |
1441 PrintF("\n========\n"); | |
1442 | |
1443 // Number nodes and instructions in reverse postorder. | |
1444 node_count = 0; | |
1445 instruction_count = 0; | |
1446 for (int i = postorder->length() - 1; i >= 0; i--) { | |
1447 postorder->at(i)->AssignNumbers(); | |
1448 } | |
1449 | |
1450 // Print basic blocks in reverse postorder. | |
1451 for (int i = postorder->length() - 1; i >= 0; i--) { | |
1452 postorder->at(i)->PrintText(); | |
1453 } | |
1454 } | |
1455 | |
1456 | |
1457 #endif // defined(DEBUG) | |
1458 | |
1459 | |
561 } } // namespace v8::internal | 1460 } } // namespace v8::internal |
OLD | NEW |