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

Side by Side Diff: src/cfg.cc

Issue 159701: Restructure to support recursive invocation of the CFG builder. Add... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 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
« no previous file with comments | « src/cfg.h ('k') | src/compiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 18 matching lines...) Expand all
29 29
30 #include "bootstrapper.h" 30 #include "bootstrapper.h"
31 #include "cfg.h" 31 #include "cfg.h"
32 #include "scopeinfo.h" 32 #include "scopeinfo.h"
33 #include "scopes.h" 33 #include "scopes.h"
34 34
35 namespace v8 { 35 namespace v8 {
36 namespace internal { 36 namespace internal {
37 37
38 38
39 ExitNode* Cfg::global_exit_ = NULL; 39 CfgGlobals* CfgGlobals::top_ = NULL;
40 40
41 41
42 void CfgNode::Reset() { 42 CfgGlobals::CfgGlobals(FunctionLiteral* fun)
43 : global_fun_(fun),
44 global_exit_(new ExitNode()),
43 #ifdef DEBUG 45 #ifdef DEBUG
44 node_counter_ = 0; 46 node_counter_(0),
45 #endif 47 #endif
46 } 48 previous_(top_) {
47 49 top_ = this;
48
49 void Cfg::Reset(FunctionLiteral* fun) {
50 global_exit_ = new ExitNode(fun);
51 CfgNode::Reset();
52 } 50 }
53 51
54 52
55 #define BAILOUT(reason) \ 53 #define BAILOUT(reason) \
56 do { return NULL; } while (false) 54 do { return NULL; } while (false)
57 55
58 Cfg* Cfg::Build(FunctionLiteral* fun) { 56 Cfg* Cfg::Build() {
57 FunctionLiteral* fun = CfgGlobals::current()->fun();
58 if (fun->scope()->num_heap_slots() > 0) {
59 BAILOUT("function has context slots");
60 }
61 if (fun->scope()->arguments() != NULL) {
62 BAILOUT("function uses .arguments");
63 }
64
59 ZoneList<Statement*>* body = fun->body(); 65 ZoneList<Statement*>* body = fun->body();
60 if (body->is_empty()) { 66 if (body->is_empty()) {
61 BAILOUT("empty function body"); 67 BAILOUT("empty function body");
62 } 68 }
63 69
64 Cfg::Reset(fun);
65 StatementBuilder builder; 70 StatementBuilder builder;
66 builder.VisitStatements(body); 71 builder.VisitStatements(body);
67 Cfg* cfg = builder.cfg(); 72 Cfg* cfg = builder.cfg();
68 if (cfg == NULL) { 73 if (cfg == NULL) {
69 BAILOUT("unsupported statement type"); 74 BAILOUT("unsupported statement type");
70 } 75 }
71 if (cfg->has_exit()) { 76 if (cfg->has_exit()) {
72 BAILOUT("control path without explicit return"); 77 BAILOUT("control path without explicit return");
73 } 78 }
74 cfg->PrependEntryNode(fun); 79 cfg->PrependEntryNode();
75 return cfg; 80 return cfg;
76 } 81 }
77 82
78 #undef BAILOUT 83 #undef BAILOUT
79 84
80 85
81 void Cfg::PrependEntryNode(FunctionLiteral* fun) { 86 void Cfg::PrependEntryNode() {
82 ASSERT(!is_empty()); 87 ASSERT(!is_empty());
83 entry_ = new EntryNode(fun, InstructionBlock::cast(entry())); 88 entry_ = new EntryNode(InstructionBlock::cast(entry()));
84 } 89 }
85 90
86 91
87 void Cfg::Append(Instruction* instr) { 92 void Cfg::Append(Instruction* instr) {
88 ASSERT(has_exit()); 93 ASSERT(has_exit());
89 ASSERT(!is_empty()); 94 ASSERT(!is_empty());
90 InstructionBlock::cast(exit_)->Append(instr); 95 InstructionBlock::cast(exit_)->Append(instr);
91 } 96 }
92 97
93 98
94 void Cfg::AppendReturnInstruction(Value* value) { 99 void Cfg::AppendReturnInstruction(Value* value) {
95 Append(new ReturnInstr(value)); 100 Append(new ReturnInstr(value));
96 InstructionBlock::cast(exit_)->set_successor(global_exit_); 101 ExitNode* global_exit = CfgGlobals::current()->exit();
102 InstructionBlock::cast(exit_)->set_successor(global_exit);
97 exit_ = NULL; 103 exit_ = NULL;
98 } 104 }
99 105
100 106
101 EntryNode::EntryNode(FunctionLiteral* fun, InstructionBlock* succ)
102 : successor_(succ), local_count_(fun->scope()->num_stack_slots()) {
103 }
104
105
106 ExitNode::ExitNode(FunctionLiteral* fun)
107 : parameter_count_(fun->scope()->num_parameters()) {
108 }
109
110
111 void InstructionBlock::Unmark() { 107 void InstructionBlock::Unmark() {
112 if (is_marked_) { 108 if (is_marked_) {
113 is_marked_ = false; 109 is_marked_ = false;
114 successor_->Unmark(); 110 successor_->Unmark();
115 } 111 }
116 } 112 }
117 113
118 114
119 void EntryNode::Unmark() { 115 void EntryNode::Unmark() {
120 if (is_marked_) { 116 if (is_marked_) {
121 is_marked_ = false; 117 is_marked_ = false;
122 successor_->Unmark(); 118 successor_->Unmark();
123 } 119 }
124 } 120 }
125 121
126 122
127 void ExitNode::Unmark() {} 123 void ExitNode::Unmark() { is_marked_ = false; }
Kasper Lund 2009/08/03 05:55:44 I would put this on three lines.
Kevin Millikin (Chromium) 2009/08/03 07:54:43 Done.
128 124
129 125
130 Handle<Code> Cfg::Compile(FunctionLiteral* fun, Handle<Script> script) { 126 Handle<Code> Cfg::Compile(Handle<Script> script) {
131 const int kInitialBufferSize = 4 * KB; 127 const int kInitialBufferSize = 4 * KB;
132 MacroAssembler* masm = new MacroAssembler(NULL, kInitialBufferSize); 128 MacroAssembler* masm = new MacroAssembler(NULL, kInitialBufferSize);
133 entry()->Compile(masm); 129 entry()->Compile(masm);
134 entry()->Unmark(); 130 entry()->Unmark();
135 CodeDesc desc; 131 CodeDesc desc;
136 masm->GetCode(&desc); 132 masm->GetCode(&desc);
133 FunctionLiteral* fun = CfgGlobals::current()->fun();
137 ZoneScopeInfo info(fun->scope()); 134 ZoneScopeInfo info(fun->scope());
138 InLoopFlag in_loop = fun->loop_nesting() ? IN_LOOP : NOT_IN_LOOP; 135 InLoopFlag in_loop = fun->loop_nesting() ? IN_LOOP : NOT_IN_LOOP;
139 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, in_loop); 136 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, in_loop);
140 Handle<Code> code = Factory::NewCode(desc, &info, flags, masm->CodeObject()); 137 Handle<Code> code = Factory::NewCode(desc, &info, flags, masm->CodeObject());
141 138
142 // Add unresolved entries in the code to the fixup list. 139 // Add unresolved entries in the code to the fixup list.
143 Bootstrapper::AddFixup(*code, masm); 140 Bootstrapper::AddFixup(*code, masm);
144 141
145 #ifdef ENABLE_DISASSEMBLER 142 #ifdef ENABLE_DISASSEMBLER
146 if (FLAG_print_code) { 143 if (FLAG_print_code) {
147 // Print the source code if available. 144 // Print the source code if available.
148 if (!script->IsUndefined() && !script->source()->IsUndefined()) { 145 if (!script->IsUndefined() && !script->source()->IsUndefined()) {
149 PrintF("--- Raw source ---\n"); 146 PrintF("--- Raw source ---\n");
150 StringInputBuffer stream(String::cast(script->source())); 147 StringInputBuffer stream(String::cast(script->source()));
151 stream.Seek(fun->start_position()); 148 stream.Seek(fun->start_position());
152 // fun->end_position() points to the last character in the stream. We 149 // fun->end_position() points to the last character in the
153 // need to compensate by adding one to calculate the length. 150 // stream. We need to compensate by adding one to calculate the
151 // length.
154 int source_len = fun->end_position() - fun->start_position() + 1; 152 int source_len = fun->end_position() - fun->start_position() + 1;
155 for (int i = 0; i < source_len; i++) { 153 for (int i = 0; i < source_len; i++) {
156 if (stream.has_more()) PrintF("%c", stream.GetNext()); 154 if (stream.has_more()) PrintF("%c", stream.GetNext());
157 } 155 }
158 PrintF("\n\n"); 156 PrintF("\n\n");
159 } 157 }
160 PrintF("--- Code ---\n"); 158 PrintF("--- Code ---\n");
161 code->Disassemble(*fun->name()->ToCString()); 159 code->Disassemble(*fun->name()->ToCString());
162 } 160 }
163 #endif 161 #endif
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 BAILOUT("Conditional"); 198 BAILOUT("Conditional");
201 } 199 }
202 200
203 201
204 void ExpressionBuilder::VisitSlot(Slot* expr) { 202 void ExpressionBuilder::VisitSlot(Slot* expr) {
205 BAILOUT("Slot"); 203 BAILOUT("Slot");
206 } 204 }
207 205
208 206
209 void ExpressionBuilder::VisitVariableProxy(VariableProxy* expr) { 207 void ExpressionBuilder::VisitVariableProxy(VariableProxy* expr) {
210 BAILOUT("VariableProxy"); 208 Expression* rewrite = expr->var()->rewrite();
209 if (rewrite == NULL || rewrite->AsSlot() == NULL) {
210 BAILOUT("unsupported variable (not a slot)");
211 }
212 Slot* slot = rewrite->AsSlot();
213 if (slot->type() != Slot::PARAMETER && slot->type() != Slot::LOCAL) {
214 BAILOUT("unsupported slot type (not a parameter or local)");
215 }
216 value_ = new SlotLocation(slot->type(), slot->index());
211 } 217 }
212 218
213 219
214 void ExpressionBuilder::VisitLiteral(Literal* expr) { 220 void ExpressionBuilder::VisitLiteral(Literal* expr) {
215 value_ = new Constant(expr->handle()); 221 value_ = new Constant(expr->handle());
216 } 222 }
217 223
218 224
219 void ExpressionBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { 225 void ExpressionBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
220 BAILOUT("RegExpLiteral"); 226 BAILOUT("RegExpLiteral");
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 #ifdef DEBUG 415 #ifdef DEBUG
410 // CFG printing support (via depth-first, preorder block traversal). 416 // CFG printing support (via depth-first, preorder block traversal).
411 417
412 void Cfg::Print() { 418 void Cfg::Print() {
413 entry_->Print(); 419 entry_->Print();
414 entry_->Unmark(); 420 entry_->Unmark();
415 } 421 }
416 422
417 423
418 void Constant::Print() { 424 void Constant::Print() {
425 PrintF("Constant(");
419 handle_->Print(); 426 handle_->Print();
427 PrintF(")");
428 }
429
430
431 void SlotLocation::Print() {
432 PrintF("Slot(");
433 switch (type_) {
434 case Slot::PARAMETER:
435 PrintF("PARAMETER, %d)", index_);
436 break;
437 case Slot::LOCAL:
438 PrintF("LOCAL, %d)", index_);
439 break;
440 default:
441 UNREACHABLE();
442 }
420 } 443 }
421 444
422 445
423 void ReturnInstr::Print() { 446 void ReturnInstr::Print() {
424 PrintF("Return "); 447 PrintF("Return ");
425 value_->Print(); 448 value_->Print();
426 PrintF("\n"); 449 PrintF("\n");
427 } 450 }
428 451
429 452
430 int CfgNode::node_counter_ = 0;
431
432
433 void InstructionBlock::Print() { 453 void InstructionBlock::Print() {
434 if (!is_marked_) { 454 if (!is_marked_) {
435 is_marked_ = true; 455 is_marked_ = true;
436 PrintF("L%d:\n", number()); 456 PrintF("L%d:\n", number());
437 for (int i = 0, len = instructions_.length(); i < len; i++) { 457 for (int i = 0, len = instructions_.length(); i < len; i++) {
438 instructions_[i]->Print(); 458 instructions_[i]->Print();
439 } 459 }
440 PrintF("Goto L%d\n\n", successor_->number()); 460 PrintF("Goto L%d\n\n", successor_->number());
441 successor_->Print(); 461 successor_->Print();
442 } 462 }
(...skipping 11 matching lines...) Expand all
454 void ExitNode::Print() { 474 void ExitNode::Print() {
455 if (!is_marked_) { 475 if (!is_marked_) {
456 is_marked_ = true; 476 is_marked_ = true;
457 PrintF("L%d:\nExit\n\n", number()); 477 PrintF("L%d:\nExit\n\n", number());
458 } 478 }
459 } 479 }
460 480
461 #endif // DEBUG 481 #endif // DEBUG
462 482
463 } } // namespace v8::internal 483 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/cfg.h ('k') | src/compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698