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

Side by Side Diff: src/flow-graph.cc

Issue 3146037: Cleanup the AST code by removing unused parts and get rid of the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 4 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include "flow-graph.h"
29 #include "scopes.h"
30
31 namespace v8 {
32 namespace internal {
33
34 void BasicBlock::BuildTraversalOrder(ZoneList<BasicBlock*>* preorder,
35 ZoneList<BasicBlock*>* postorder,
36 bool mark) {
37 if (mark_ == mark) return;
38 mark_ = mark;
39 preorder->Add(this);
40 if (right_successor_ != NULL) {
41 right_successor_->BuildTraversalOrder(preorder, postorder, mark);
42 }
43 if (left_successor_ != NULL) {
44 left_successor_->BuildTraversalOrder(preorder, postorder, mark);
45 }
46 postorder->Add(this);
47 }
48
49
50 FlowGraph* FlowGraphBuilder::Build(FunctionLiteral* lit) {
51 // Create new entry and exit nodes. These will not change during
52 // construction.
53 entry_ = new BasicBlock(NULL);
54 exit_ = new BasicBlock(NULL);
55 // Begin accumulating instructions in the entry block.
56 current_ = entry_;
57
58 VisitDeclarations(lit->scope()->declarations());
59 VisitStatements(lit->body());
60 // In the event of stack overflow or failure to handle a syntactic
61 // construct, return an invalid flow graph.
62 if (HasStackOverflow()) return new FlowGraph(NULL, NULL);
63
64 // If current is not the exit, add a link to the exit.
65 if (current_ != exit_) {
66 // If current already has a successor (i.e., will be a branch node) and
67 // if the exit already has a predecessor, insert an empty block to
68 // maintain edge split form.
69 if (current_->HasSuccessor() && exit_->HasPredecessor()) {
70 current_ = new BasicBlock(current_);
71 }
72 Literal* undefined = new Literal(Factory::undefined_value());
73 current_->AddInstruction(new ReturnStatement(undefined));
74 exit_->AddPredecessor(current_);
75 }
76
77 FlowGraph* graph = new FlowGraph(entry_, exit_);
78 bool mark = !entry_->GetMark();
79 entry_->BuildTraversalOrder(graph->preorder(), graph->postorder(), mark);
80
81 #ifdef DEBUG
82 // Number the nodes in reverse postorder.
83 int n = 0;
84 for (int i = graph->postorder()->length() - 1; i >= 0; --i) {
85 graph->postorder()->at(i)->set_number(n++);
86 }
87 #endif
88
89 return graph;
90 }
91
92
93 void FlowGraphBuilder::VisitDeclaration(Declaration* decl) {
94 Variable* var = decl->proxy()->AsVariable();
95 Slot* slot = var->slot();
96 // We allow only declarations that do not require code generation.
97 // The following all require code generation: global variables and
98 // functions, variables with slot type LOOKUP, declarations with
99 // mode CONST, and functions.
100
101 if (var->is_global() ||
102 (slot != NULL && slot->type() == Slot::LOOKUP) ||
103 decl->mode() == Variable::CONST ||
104 decl->fun() != NULL) {
105 // Here and in the rest of the flow graph builder we indicate an
106 // unsupported syntactic construct by setting the stack overflow
107 // flag on the visitor. This causes bailout of the visitor.
108 SetStackOverflow();
109 }
110 }
111
112
113 void FlowGraphBuilder::VisitBlock(Block* stmt) {
114 VisitStatements(stmt->statements());
115 }
116
117
118 void FlowGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) {
119 Visit(stmt->expression());
120 }
121
122
123 void FlowGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) {
124 // Nothing to do.
125 }
126
127
128 void FlowGraphBuilder::VisitIfStatement(IfStatement* stmt) {
129 // Build a diamond in the flow graph. First accumulate the instructions
130 // of the test in the current basic block.
131 Visit(stmt->condition());
132
133 // Remember the branch node and accumulate the true branch as its left
134 // successor. This relies on the successors being added left to right.
135 BasicBlock* branch = current_;
136 current_ = new BasicBlock(branch);
137 Visit(stmt->then_statement());
138
139 // Construct a join node and then accumulate the false branch in a fresh
140 // successor of the branch node.
141 BasicBlock* join = new BasicBlock(current_);
142 current_ = new BasicBlock(branch);
143 Visit(stmt->else_statement());
144 join->AddPredecessor(current_);
145
146 current_ = join;
147 }
148
149
150 void FlowGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) {
151 SetStackOverflow();
152 }
153
154
155 void FlowGraphBuilder::VisitBreakStatement(BreakStatement* stmt) {
156 SetStackOverflow();
157 }
158
159
160 void FlowGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
161 SetStackOverflow();
162 }
163
164
165 void FlowGraphBuilder::VisitWithEnterStatement(WithEnterStatement* stmt) {
166 SetStackOverflow();
167 }
168
169
170 void FlowGraphBuilder::VisitWithExitStatement(WithExitStatement* stmt) {
171 SetStackOverflow();
172 }
173
174
175 void FlowGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
176 SetStackOverflow();
177 }
178
179
180 void FlowGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
181 SetStackOverflow();
182 }
183
184
185 void FlowGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
186 SetStackOverflow();
187 }
188
189
190 void FlowGraphBuilder::VisitForStatement(ForStatement* stmt) {
191 // Build a loop in the flow graph. First accumulate the instructions of
192 // the initializer in the current basic block.
193 if (stmt->init() != NULL) Visit(stmt->init());
194
195 // Create a new basic block for the test. This will be the join node.
196 BasicBlock* join = new BasicBlock(current_);
197 current_ = join;
198 if (stmt->cond() != NULL) Visit(stmt->cond());
199
200 // The current node is the branch node. Create a new basic block to begin
201 // the body.
202 BasicBlock* branch = current_;
203 current_ = new BasicBlock(branch);
204 Visit(stmt->body());
205 if (stmt->next() != NULL) Visit(stmt->next());
206
207 // Add the backward edge from the end of the body and continue with the
208 // false arm of the branch.
209 join->AddPredecessor(current_);
210 current_ = new BasicBlock(branch);
211 }
212
213
214 void FlowGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
215 SetStackOverflow();
216 }
217
218
219 void FlowGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
220 SetStackOverflow();
221 }
222
223
224 void FlowGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
225 SetStackOverflow();
226 }
227
228
229 void FlowGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
230 SetStackOverflow();
231 }
232
233
234 void FlowGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
235 SetStackOverflow();
236 }
237
238
239 void FlowGraphBuilder::VisitSharedFunctionInfoLiteral(
240 SharedFunctionInfoLiteral* expr) {
241 SetStackOverflow();
242 }
243
244
245 void FlowGraphBuilder::VisitConditional(Conditional* expr) {
246 SetStackOverflow();
247 }
248
249
250 void FlowGraphBuilder::VisitSlot(Slot* expr) {
251 // Slots do not appear in the AST.
252 UNREACHABLE();
253 }
254
255
256 void FlowGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
257 current_->AddInstruction(expr);
258 }
259
260
261 void FlowGraphBuilder::VisitLiteral(Literal* expr) {
262 current_->AddInstruction(expr);
263 }
264
265
266 void FlowGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
267 SetStackOverflow();
268 }
269
270
271 void FlowGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
272 SetStackOverflow();
273 }
274
275
276 void FlowGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
277 SetStackOverflow();
278 }
279
280
281 void FlowGraphBuilder::VisitCatchExtensionObject(CatchExtensionObject* expr) {
282 SetStackOverflow();
283 }
284
285
286 void FlowGraphBuilder::VisitAssignment(Assignment* expr) {
287 // There are three basic kinds of assignment: variable assignments,
288 // property assignments, and invalid left-hand sides (which are translated
289 // to "throw ReferenceError" by the parser).
290 Variable* var = expr->target()->AsVariableProxy()->AsVariable();
291 Property* prop = expr->target()->AsProperty();
292 ASSERT(var == NULL || prop == NULL);
293 if (var != NULL) {
294 if (expr->is_compound() && !expr->target()->IsTrivial()) {
295 Visit(expr->target());
296 }
297 if (!expr->value()->IsTrivial()) Visit(expr->value());
298 current_->AddInstruction(expr);
299
300 } else if (prop != NULL) {
301 if (!prop->obj()->IsTrivial()) Visit(prop->obj());
302 if (!prop->key()->IsPropertyName() && !prop->key()->IsTrivial()) {
303 Visit(prop->key());
304 }
305 if (!expr->value()->IsTrivial()) Visit(expr->value());
306 current_->AddInstruction(expr);
307
308 } else {
309 Visit(expr->target());
310 }
311 }
312
313
314 void FlowGraphBuilder::VisitThrow(Throw* expr) {
315 SetStackOverflow();
316 }
317
318
319 void FlowGraphBuilder::VisitProperty(Property* expr) {
320 if (!expr->obj()->IsTrivial()) Visit(expr->obj());
321 if (!expr->key()->IsPropertyName() && !expr->key()->IsTrivial()) {
322 Visit(expr->key());
323 }
324 current_->AddInstruction(expr);
325 }
326
327
328 void FlowGraphBuilder::VisitCall(Call* expr) {
329 Visit(expr->expression());
330 VisitExpressions(expr->arguments());
331 current_->AddInstruction(expr);
332 }
333
334
335 void FlowGraphBuilder::VisitCallNew(CallNew* expr) {
336 SetStackOverflow();
337 }
338
339
340 void FlowGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
341 SetStackOverflow();
342 }
343
344
345 void FlowGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
346 switch (expr->op()) {
347 case Token::NOT:
348 case Token::BIT_NOT:
349 case Token::DELETE:
350 case Token::TYPEOF:
351 case Token::VOID:
352 SetStackOverflow();
353 break;
354
355 case Token::ADD:
356 case Token::SUB:
357 Visit(expr->expression());
358 current_->AddInstruction(expr);
359 break;
360
361 default:
362 UNREACHABLE();
363 }
364 }
365
366
367 void FlowGraphBuilder::VisitCountOperation(CountOperation* expr) {
368 Visit(expr->expression());
369 current_->AddInstruction(expr);
370 }
371
372
373 void FlowGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) {
374 switch (expr->op()) {
375 case Token::COMMA:
376 case Token::OR:
377 case Token::AND:
378 SetStackOverflow();
379 break;
380
381 case Token::BIT_OR:
382 case Token::BIT_XOR:
383 case Token::BIT_AND:
384 case Token::SHL:
385 case Token::SAR:
386 case Token::SHR:
387 case Token::ADD:
388 case Token::SUB:
389 case Token::MUL:
390 case Token::DIV:
391 case Token::MOD:
392 if (!expr->left()->IsTrivial()) Visit(expr->left());
393 if (!expr->right()->IsTrivial()) Visit(expr->right());
394 current_->AddInstruction(expr);
395 break;
396
397 default:
398 UNREACHABLE();
399 }
400 }
401
402
403 void FlowGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
404 switch (expr->op()) {
405 case Token::EQ:
406 case Token::NE:
407 case Token::EQ_STRICT:
408 case Token::NE_STRICT:
409 case Token::INSTANCEOF:
410 case Token::IN:
411 SetStackOverflow();
412 break;
413
414 case Token::LT:
415 case Token::GT:
416 case Token::LTE:
417 case Token::GTE:
418 if (!expr->left()->IsTrivial()) Visit(expr->left());
419 if (!expr->right()->IsTrivial()) Visit(expr->right());
420 current_->AddInstruction(expr);
421 break;
422
423 default:
424 UNREACHABLE();
425 }
426 }
427
428
429 void FlowGraphBuilder::VisitThisFunction(ThisFunction* expr) {
430 SetStackOverflow();
431 }
432
433
434 #ifdef DEBUG
435
436 // Print a textual representation of an instruction in a flow graph.
437 class InstructionPrinter: public AstVisitor {
438 public:
439 InstructionPrinter() {}
440
441 private:
442 // Overridden from the base class.
443 virtual void VisitExpressions(ZoneList<Expression*>* exprs);
444
445 // AST node visit functions.
446 #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
447 AST_NODE_LIST(DECLARE_VISIT)
448 #undef DECLARE_VISIT
449
450 DISALLOW_COPY_AND_ASSIGN(InstructionPrinter);
451 };
452
453
454 static void PrintSubexpression(Expression* expr) {
455 if (!expr->IsTrivial()) {
456 PrintF("@%d", expr->num());
457 } else if (expr->AsLiteral() != NULL) {
458 expr->AsLiteral()->handle()->Print();
459 } else if (expr->AsVariableProxy() != NULL) {
460 PrintF("%s", *expr->AsVariableProxy()->name()->ToCString());
461 } else {
462 UNREACHABLE();
463 }
464 }
465
466
467 void InstructionPrinter::VisitExpressions(ZoneList<Expression*>* exprs) {
468 for (int i = 0; i < exprs->length(); ++i) {
469 if (i != 0) PrintF(", ");
470 PrintF("@%d", exprs->at(i)->num());
471 }
472 }
473
474
475 // We only define printing functions for the node types that can occur as
476 // instructions in a flow graph. The rest are unreachable.
477 void InstructionPrinter::VisitDeclaration(Declaration* decl) {
478 UNREACHABLE();
479 }
480
481
482 void InstructionPrinter::VisitBlock(Block* stmt) {
483 UNREACHABLE();
484 }
485
486
487 void InstructionPrinter::VisitExpressionStatement(ExpressionStatement* stmt) {
488 UNREACHABLE();
489 }
490
491
492 void InstructionPrinter::VisitEmptyStatement(EmptyStatement* stmt) {
493 UNREACHABLE();
494 }
495
496
497 void InstructionPrinter::VisitIfStatement(IfStatement* stmt) {
498 UNREACHABLE();
499 }
500
501
502 void InstructionPrinter::VisitContinueStatement(ContinueStatement* stmt) {
503 UNREACHABLE();
504 }
505
506
507 void InstructionPrinter::VisitBreakStatement(BreakStatement* stmt) {
508 UNREACHABLE();
509 }
510
511
512 void InstructionPrinter::VisitReturnStatement(ReturnStatement* stmt) {
513 PrintF("return ");
514 PrintSubexpression(stmt->expression());
515 }
516
517
518 void InstructionPrinter::VisitWithEnterStatement(WithEnterStatement* stmt) {
519 UNREACHABLE();
520 }
521
522
523 void InstructionPrinter::VisitWithExitStatement(WithExitStatement* stmt) {
524 UNREACHABLE();
525 }
526
527
528 void InstructionPrinter::VisitSwitchStatement(SwitchStatement* stmt) {
529 UNREACHABLE();
530 }
531
532
533 void InstructionPrinter::VisitDoWhileStatement(DoWhileStatement* stmt) {
534 UNREACHABLE();
535 }
536
537
538 void InstructionPrinter::VisitWhileStatement(WhileStatement* stmt) {
539 UNREACHABLE();
540 }
541
542
543 void InstructionPrinter::VisitForStatement(ForStatement* stmt) {
544 UNREACHABLE();
545 }
546
547
548 void InstructionPrinter::VisitForInStatement(ForInStatement* stmt) {
549 UNREACHABLE();
550 }
551
552
553 void InstructionPrinter::VisitTryCatchStatement(TryCatchStatement* stmt) {
554 UNREACHABLE();
555 }
556
557
558 void InstructionPrinter::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
559 UNREACHABLE();
560 }
561
562
563 void InstructionPrinter::VisitDebuggerStatement(DebuggerStatement* stmt) {
564 UNREACHABLE();
565 }
566
567
568 void InstructionPrinter::VisitFunctionLiteral(FunctionLiteral* expr) {
569 UNREACHABLE();
570 }
571
572
573 void InstructionPrinter::VisitSharedFunctionInfoLiteral(
574 SharedFunctionInfoLiteral* expr) {
575 UNREACHABLE();
576 }
577
578
579 void InstructionPrinter::VisitConditional(Conditional* expr) {
580 UNREACHABLE();
581 }
582
583
584 void InstructionPrinter::VisitSlot(Slot* expr) {
585 UNREACHABLE();
586 }
587
588
589 void InstructionPrinter::VisitVariableProxy(VariableProxy* expr) {
590 Variable* var = expr->AsVariable();
591 if (var != NULL) {
592 PrintF("%s", *var->name()->ToCString());
593 } else {
594 ASSERT(expr->AsProperty() != NULL);
595 Visit(expr->AsProperty());
596 }
597 }
598
599
600 void InstructionPrinter::VisitLiteral(Literal* expr) {
601 expr->handle()->Print();
602 }
603
604
605 void InstructionPrinter::VisitRegExpLiteral(RegExpLiteral* expr) {
606 UNREACHABLE();
607 }
608
609
610 void InstructionPrinter::VisitObjectLiteral(ObjectLiteral* expr) {
611 UNREACHABLE();
612 }
613
614
615 void InstructionPrinter::VisitArrayLiteral(ArrayLiteral* expr) {
616 UNREACHABLE();
617 }
618
619
620 void InstructionPrinter::VisitCatchExtensionObject(
621 CatchExtensionObject* expr) {
622 UNREACHABLE();
623 }
624
625
626 void InstructionPrinter::VisitAssignment(Assignment* expr) {
627 Variable* var = expr->target()->AsVariableProxy()->AsVariable();
628 Property* prop = expr->target()->AsProperty();
629
630 // Print the left-hand side.
631 Visit(expr->target());
632 if (var == NULL && prop == NULL) return; // Throw reference error.
633 PrintF(" = ");
634 // For compound assignments, print the left-hand side again and the
635 // corresponding binary operator.
636 if (expr->is_compound()) {
637 PrintSubexpression(expr->target());
638 PrintF(" %s ", Token::String(expr->binary_op()));
639 }
640
641 // Print the right-hand side.
642 PrintSubexpression(expr->value());
643 }
644
645
646 void InstructionPrinter::VisitThrow(Throw* expr) {
647 UNREACHABLE();
648 }
649
650
651 void InstructionPrinter::VisitProperty(Property* expr) {
652 PrintSubexpression(expr->obj());
653 if (expr->key()->IsPropertyName()) {
654 PrintF(".");
655 ASSERT(expr->key()->AsLiteral() != NULL);
656 expr->key()->AsLiteral()->handle()->Print();
657 } else {
658 PrintF("[");
659 PrintSubexpression(expr->key());
660 PrintF("]");
661 }
662 }
663
664
665 void InstructionPrinter::VisitCall(Call* expr) {
666 PrintF("@%d(", expr->expression()->num());
667 VisitExpressions(expr->arguments());
668 PrintF(")");
669 }
670
671
672 void InstructionPrinter::VisitCallNew(CallNew* expr) {
673 UNREACHABLE();
674 }
675
676
677 void InstructionPrinter::VisitCallRuntime(CallRuntime* expr) {
678 UNREACHABLE();
679 }
680
681
682 void InstructionPrinter::VisitUnaryOperation(UnaryOperation* expr) {
683 PrintF("%s(@%d)", Token::String(expr->op()), expr->expression()->num());
684 }
685
686
687 void InstructionPrinter::VisitCountOperation(CountOperation* expr) {
688 if (expr->is_prefix()) {
689 PrintF("%s@%d", Token::String(expr->op()), expr->expression()->num());
690 } else {
691 PrintF("@%d%s", expr->expression()->num(), Token::String(expr->op()));
692 }
693 }
694
695
696 void InstructionPrinter::VisitBinaryOperation(BinaryOperation* expr) {
697 PrintSubexpression(expr->left());
698 PrintF(" %s ", Token::String(expr->op()));
699 PrintSubexpression(expr->right());
700 }
701
702
703 void InstructionPrinter::VisitCompareOperation(CompareOperation* expr) {
704 PrintSubexpression(expr->left());
705 PrintF(" %s ", Token::String(expr->op()));
706 PrintSubexpression(expr->right());
707 }
708
709
710 void InstructionPrinter::VisitThisFunction(ThisFunction* expr) {
711 UNREACHABLE();
712 }
713
714
715 int BasicBlock::PrintAsText(int instruction_number) {
716 // Print a label for all blocks except the entry.
717 if (HasPredecessor()) {
718 PrintF("L%d:", number());
719 }
720
721 // Number and print the instructions. Since AST child nodes are visited
722 // before their parents, the parent nodes can refer to them by number.
723 InstructionPrinter printer;
724 for (int i = 0; i < instructions_.length(); ++i) {
725 PrintF("\n%d ", instruction_number);
726 instructions_[i]->set_num(instruction_number++);
727 instructions_[i]->Accept(&printer);
728 }
729
730 // If this is the exit, print "exit". If there is a single successor,
731 // print "goto" successor on a separate line. If there are two
732 // successors, print "goto" successor on the same line as the last
733 // instruction in the block. There is a blank line between blocks (and
734 // after the last one).
735 if (left_successor_ == NULL) {
736 PrintF("\nexit\n\n");
737 } else if (right_successor_ == NULL) {
738 PrintF("\ngoto L%d\n\n", left_successor_->number());
739 } else {
740 PrintF(", goto (L%d, L%d)\n\n",
741 left_successor_->number(),
742 right_successor_->number());
743 }
744
745 return instruction_number;
746 }
747
748
749 void FlowGraph::PrintAsText(Handle<String> name) {
750 PrintF("\n==== name = \"%s\" ====\n", *name->ToCString());
751 // Print nodes in reverse postorder. Note that AST node numbers are used
752 // during printing of instructions and thus their current values are
753 // destroyed.
754 int number = 0;
755 for (int i = postorder_.length() - 1; i >= 0; --i) {
756 number = postorder_[i]->PrintAsText(number);
757 }
758 }
759
760 #endif // DEBUG
761
762
763 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/flow-graph.h ('k') | src/full-codegen.cc » ('j') | src/x64/full-codegen-x64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698