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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 if (!first) PrintF(","); | 43 if (!first) PrintF(","); |
44 first = false; | 44 first = false; |
45 PrintF("%d"); | 45 PrintF("%d"); |
46 } | 46 } |
47 } | 47 } |
48 PrintF("}"); | 48 PrintF("}"); |
49 } | 49 } |
50 #endif | 50 #endif |
51 | 51 |
52 | 52 |
53 void AstLabeler::Label(CompilationInfo* info) { | 53 bool AssignedVariablesAnalyzer::Analyze() { |
54 info_ = info; | 54 Scope* scope = fun_->scope(); |
55 VisitStatements(info_->function()->body()); | 55 int variables = scope->num_parameters() + scope->num_stack_slots(); |
| 56 if (variables == 0) return true; |
| 57 av_.ExpandTo(variables); |
| 58 VisitStatements(fun_->body()); |
| 59 return !HasStackOverflow(); |
56 } | 60 } |
57 | 61 |
58 | 62 |
59 void AstLabeler::VisitStatements(ZoneList<Statement*>* stmts) { | |
60 for (int i = 0, len = stmts->length(); i < len; i++) { | |
61 Visit(stmts->at(i)); | |
62 } | |
63 } | |
64 | |
65 | |
66 void AstLabeler::VisitDeclarations(ZoneList<Declaration*>* decls) { | |
67 UNREACHABLE(); | |
68 } | |
69 | |
70 | |
71 void AstLabeler::VisitBlock(Block* stmt) { | |
72 VisitStatements(stmt->statements()); | |
73 } | |
74 | |
75 | |
76 void AstLabeler::VisitExpressionStatement( | |
77 ExpressionStatement* stmt) { | |
78 Visit(stmt->expression()); | |
79 } | |
80 | |
81 | |
82 void AstLabeler::VisitEmptyStatement(EmptyStatement* stmt) { | |
83 // Do nothing. | |
84 } | |
85 | |
86 | |
87 void AstLabeler::VisitIfStatement(IfStatement* stmt) { | |
88 UNREACHABLE(); | |
89 } | |
90 | |
91 | |
92 void AstLabeler::VisitContinueStatement(ContinueStatement* stmt) { | |
93 UNREACHABLE(); | |
94 } | |
95 | |
96 | |
97 void AstLabeler::VisitBreakStatement(BreakStatement* stmt) { | |
98 UNREACHABLE(); | |
99 } | |
100 | |
101 | |
102 void AstLabeler::VisitReturnStatement(ReturnStatement* stmt) { | |
103 UNREACHABLE(); | |
104 } | |
105 | |
106 | |
107 void AstLabeler::VisitWithEnterStatement( | |
108 WithEnterStatement* stmt) { | |
109 UNREACHABLE(); | |
110 } | |
111 | |
112 | |
113 void AstLabeler::VisitWithExitStatement(WithExitStatement* stmt) { | |
114 UNREACHABLE(); | |
115 } | |
116 | |
117 | |
118 void AstLabeler::VisitSwitchStatement(SwitchStatement* stmt) { | |
119 UNREACHABLE(); | |
120 } | |
121 | |
122 | |
123 void AstLabeler::VisitDoWhileStatement(DoWhileStatement* stmt) { | |
124 UNREACHABLE(); | |
125 } | |
126 | |
127 | |
128 void AstLabeler::VisitWhileStatement(WhileStatement* stmt) { | |
129 UNREACHABLE(); | |
130 } | |
131 | |
132 | |
133 void AstLabeler::VisitForStatement(ForStatement* stmt) { | |
134 UNREACHABLE(); | |
135 } | |
136 | |
137 | |
138 void AstLabeler::VisitForInStatement(ForInStatement* stmt) { | |
139 UNREACHABLE(); | |
140 } | |
141 | |
142 | |
143 void AstLabeler::VisitTryCatchStatement(TryCatchStatement* stmt) { | |
144 UNREACHABLE(); | |
145 } | |
146 | |
147 | |
148 void AstLabeler::VisitTryFinallyStatement( | |
149 TryFinallyStatement* stmt) { | |
150 UNREACHABLE(); | |
151 } | |
152 | |
153 | |
154 void AstLabeler::VisitDebuggerStatement( | |
155 DebuggerStatement* stmt) { | |
156 UNREACHABLE(); | |
157 } | |
158 | |
159 | |
160 void AstLabeler::VisitFunctionLiteral(FunctionLiteral* expr) { | |
161 UNREACHABLE(); | |
162 } | |
163 | |
164 | |
165 void AstLabeler::VisitSharedFunctionInfoLiteral( | |
166 SharedFunctionInfoLiteral* expr) { | |
167 UNREACHABLE(); | |
168 } | |
169 | |
170 | |
171 void AstLabeler::VisitConditional(Conditional* expr) { | |
172 UNREACHABLE(); | |
173 } | |
174 | |
175 | |
176 void AstLabeler::VisitSlot(Slot* expr) { | |
177 UNREACHABLE(); | |
178 } | |
179 | |
180 | |
181 void AstLabeler::VisitVariableProxy(VariableProxy* expr) { | |
182 expr->set_num(next_number_++); | |
183 Variable* var = expr->var(); | |
184 if (var->is_global() && !var->is_this()) { | |
185 info_->set_has_globals(true); | |
186 } | |
187 } | |
188 | |
189 | |
190 void AstLabeler::VisitLiteral(Literal* expr) { | |
191 UNREACHABLE(); | |
192 } | |
193 | |
194 | |
195 void AstLabeler::VisitRegExpLiteral(RegExpLiteral* expr) { | |
196 UNREACHABLE(); | |
197 } | |
198 | |
199 | |
200 void AstLabeler::VisitObjectLiteral(ObjectLiteral* expr) { | |
201 UNREACHABLE(); | |
202 } | |
203 | |
204 | |
205 void AstLabeler::VisitArrayLiteral(ArrayLiteral* expr) { | |
206 UNREACHABLE(); | |
207 } | |
208 | |
209 | |
210 void AstLabeler::VisitCatchExtensionObject( | |
211 CatchExtensionObject* expr) { | |
212 UNREACHABLE(); | |
213 } | |
214 | |
215 | |
216 void AstLabeler::VisitAssignment(Assignment* expr) { | |
217 Property* prop = expr->target()->AsProperty(); | |
218 ASSERT(prop != NULL); | |
219 ASSERT(prop->key()->IsPropertyName()); | |
220 VariableProxy* proxy = prop->obj()->AsVariableProxy(); | |
221 USE(proxy); | |
222 ASSERT(proxy != NULL && proxy->var()->is_this()); | |
223 info()->set_has_this_properties(true); | |
224 | |
225 prop->obj()->set_num(AstNode::kNoNumber); | |
226 prop->key()->set_num(AstNode::kNoNumber); | |
227 Visit(expr->value()); | |
228 expr->set_num(next_number_++); | |
229 } | |
230 | |
231 | |
232 void AstLabeler::VisitThrow(Throw* expr) { | |
233 UNREACHABLE(); | |
234 } | |
235 | |
236 | |
237 void AstLabeler::VisitProperty(Property* expr) { | |
238 ASSERT(expr->key()->IsPropertyName()); | |
239 VariableProxy* proxy = expr->obj()->AsVariableProxy(); | |
240 USE(proxy); | |
241 ASSERT(proxy != NULL && proxy->var()->is_this()); | |
242 info()->set_has_this_properties(true); | |
243 | |
244 expr->obj()->set_num(AstNode::kNoNumber); | |
245 expr->key()->set_num(AstNode::kNoNumber); | |
246 expr->set_num(next_number_++); | |
247 } | |
248 | |
249 | |
250 void AstLabeler::VisitCall(Call* expr) { | |
251 UNREACHABLE(); | |
252 } | |
253 | |
254 | |
255 void AstLabeler::VisitCallNew(CallNew* expr) { | |
256 UNREACHABLE(); | |
257 } | |
258 | |
259 | |
260 void AstLabeler::VisitCallRuntime(CallRuntime* expr) { | |
261 UNREACHABLE(); | |
262 } | |
263 | |
264 | |
265 void AstLabeler::VisitUnaryOperation(UnaryOperation* expr) { | |
266 UNREACHABLE(); | |
267 } | |
268 | |
269 | |
270 void AstLabeler::VisitCountOperation(CountOperation* expr) { | |
271 UNREACHABLE(); | |
272 } | |
273 | |
274 | |
275 void AstLabeler::VisitBinaryOperation(BinaryOperation* expr) { | |
276 Visit(expr->left()); | |
277 Visit(expr->right()); | |
278 expr->set_num(next_number_++); | |
279 } | |
280 | |
281 | |
282 void AstLabeler::VisitCompareOperation(CompareOperation* expr) { | |
283 UNREACHABLE(); | |
284 } | |
285 | |
286 | |
287 void AstLabeler::VisitThisFunction(ThisFunction* expr) { | |
288 UNREACHABLE(); | |
289 } | |
290 | |
291 | |
292 void AstLabeler::VisitDeclaration(Declaration* decl) { | |
293 UNREACHABLE(); | |
294 } | |
295 | |
296 | |
297 AssignedVariablesAnalyzer::AssignedVariablesAnalyzer(FunctionLiteral* fun) | |
298 : fun_(fun), | |
299 av_(fun->scope()->num_parameters() + fun->scope()->num_stack_slots()) {} | |
300 | |
301 | |
302 void AssignedVariablesAnalyzer::Analyze() { | |
303 ASSERT(av_.length() > 0); | |
304 VisitStatements(fun_->body()); | |
305 } | |
306 | |
307 | |
308 Variable* AssignedVariablesAnalyzer::FindSmiLoopVariable(ForStatement* stmt) { | 63 Variable* AssignedVariablesAnalyzer::FindSmiLoopVariable(ForStatement* stmt) { |
309 // The loop must have all necessary parts. | 64 // The loop must have all necessary parts. |
310 if (stmt->init() == NULL || stmt->cond() == NULL || stmt->next() == NULL) { | 65 if (stmt->init() == NULL || stmt->cond() == NULL || stmt->next() == NULL) { |
311 return NULL; | 66 return NULL; |
312 } | 67 } |
313 // The initialization statement has to be a simple assignment. | 68 // The initialization statement has to be a simple assignment. |
314 Assignment* init = stmt->init()->StatementAsSimpleAssignment(); | 69 Assignment* init = stmt->init()->StatementAsSimpleAssignment(); |
315 if (init == NULL) return NULL; | 70 if (init == NULL) return NULL; |
316 | 71 |
317 // We only deal with local variables. | 72 // We only deal with local variables. |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 } | 142 } |
388 | 143 |
389 | 144 |
390 void AssignedVariablesAnalyzer::MarkIfTrivial(Expression* expr) { | 145 void AssignedVariablesAnalyzer::MarkIfTrivial(Expression* expr) { |
391 Variable* var = expr->AsVariableProxy()->AsVariable(); | 146 Variable* var = expr->AsVariableProxy()->AsVariable(); |
392 if (var != NULL && | 147 if (var != NULL && |
393 var->IsStackAllocated() && | 148 var->IsStackAllocated() && |
394 !var->is_arguments() && | 149 !var->is_arguments() && |
395 var->mode() != Variable::CONST && | 150 var->mode() != Variable::CONST && |
396 (var->is_this() || !av_.Contains(BitIndex(var)))) { | 151 (var->is_this() || !av_.Contains(BitIndex(var)))) { |
397 expr->AsVariableProxy()->set_is_trivial(true); | 152 expr->AsVariableProxy()->MarkAsTrivial(); |
398 } | 153 } |
399 } | 154 } |
400 | 155 |
401 | 156 |
402 void AssignedVariablesAnalyzer::ProcessExpression(Expression* expr) { | 157 void AssignedVariablesAnalyzer::ProcessExpression(Expression* expr) { |
403 BitVector saved_av(av_); | 158 BitVector saved_av(av_); |
404 av_.Clear(); | 159 av_.Clear(); |
405 Visit(expr); | 160 Visit(expr); |
406 av_.Union(saved_av); | 161 av_.Union(saved_av); |
407 } | 162 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 | 237 |
483 | 238 |
484 void AssignedVariablesAnalyzer::VisitWhileStatement(WhileStatement* stmt) { | 239 void AssignedVariablesAnalyzer::VisitWhileStatement(WhileStatement* stmt) { |
485 ProcessExpression(stmt->cond()); | 240 ProcessExpression(stmt->cond()); |
486 Visit(stmt->body()); | 241 Visit(stmt->body()); |
487 } | 242 } |
488 | 243 |
489 | 244 |
490 void AssignedVariablesAnalyzer::VisitForStatement(ForStatement* stmt) { | 245 void AssignedVariablesAnalyzer::VisitForStatement(ForStatement* stmt) { |
491 if (stmt->init() != NULL) Visit(stmt->init()); | 246 if (stmt->init() != NULL) Visit(stmt->init()); |
492 | |
493 if (stmt->cond() != NULL) ProcessExpression(stmt->cond()); | 247 if (stmt->cond() != NULL) ProcessExpression(stmt->cond()); |
494 | |
495 if (stmt->next() != NULL) Visit(stmt->next()); | 248 if (stmt->next() != NULL) Visit(stmt->next()); |
496 | 249 |
497 // Process loop body. After visiting the loop body av_ contains | 250 // Process loop body. After visiting the loop body av_ contains |
498 // the assigned variables of the loop body. | 251 // the assigned variables of the loop body. |
499 BitVector saved_av(av_); | 252 BitVector saved_av(av_); |
500 av_.Clear(); | 253 av_.Clear(); |
501 Visit(stmt->body()); | 254 Visit(stmt->body()); |
502 | 255 |
503 Variable* var = FindSmiLoopVariable(stmt); | 256 Variable* var = FindSmiLoopVariable(stmt); |
504 if (var != NULL && !av_.Contains(BitIndex(var))) { | 257 if (var != NULL && !av_.Contains(BitIndex(var))) { |
505 stmt->set_loop_variable(var); | 258 stmt->set_loop_variable(var); |
506 } | 259 } |
507 | |
508 av_.Union(saved_av); | 260 av_.Union(saved_av); |
509 } | 261 } |
510 | 262 |
511 | 263 |
512 void AssignedVariablesAnalyzer::VisitForInStatement(ForInStatement* stmt) { | 264 void AssignedVariablesAnalyzer::VisitForInStatement(ForInStatement* stmt) { |
513 ProcessExpression(stmt->each()); | 265 ProcessExpression(stmt->each()); |
514 ProcessExpression(stmt->enumerable()); | 266 ProcessExpression(stmt->enumerable()); |
515 Visit(stmt->body()); | 267 Visit(stmt->body()); |
516 } | 268 } |
517 | 269 |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 av_.Clear(); | 457 av_.Clear(); |
706 Visit(expr->arguments()->at(i)); | 458 Visit(expr->arguments()->at(i)); |
707 result.Union(av_); | 459 result.Union(av_); |
708 } | 460 } |
709 av_ = result; | 461 av_ = result; |
710 } | 462 } |
711 | 463 |
712 | 464 |
713 void AssignedVariablesAnalyzer::VisitUnaryOperation(UnaryOperation* expr) { | 465 void AssignedVariablesAnalyzer::VisitUnaryOperation(UnaryOperation* expr) { |
714 ASSERT(av_.IsEmpty()); | 466 ASSERT(av_.IsEmpty()); |
| 467 MarkIfTrivial(expr->expression()); |
715 Visit(expr->expression()); | 468 Visit(expr->expression()); |
716 } | 469 } |
717 | 470 |
718 | 471 |
719 void AssignedVariablesAnalyzer::VisitCountOperation(CountOperation* expr) { | 472 void AssignedVariablesAnalyzer::VisitCountOperation(CountOperation* expr) { |
720 ASSERT(av_.IsEmpty()); | 473 ASSERT(av_.IsEmpty()); |
721 | 474 if (expr->is_prefix()) MarkIfTrivial(expr->expression()); |
722 Visit(expr->expression()); | 475 Visit(expr->expression()); |
723 | 476 |
724 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); | 477 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); |
725 if (var != NULL) RecordAssignedVar(var); | 478 if (var != NULL) RecordAssignedVar(var); |
726 } | 479 } |
727 | 480 |
728 | 481 |
729 void AssignedVariablesAnalyzer::VisitBinaryOperation(BinaryOperation* expr) { | 482 void AssignedVariablesAnalyzer::VisitBinaryOperation(BinaryOperation* expr) { |
730 ASSERT(av_.IsEmpty()); | 483 ASSERT(av_.IsEmpty()); |
731 MarkIfTrivial(expr->right()); | 484 MarkIfTrivial(expr->right()); |
732 Visit(expr->right()); | 485 Visit(expr->right()); |
733 MarkIfTrivial(expr->left()); | 486 MarkIfTrivial(expr->left()); |
734 ProcessExpression(expr->left()); | 487 ProcessExpression(expr->left()); |
735 } | 488 } |
736 | 489 |
737 | 490 |
738 void AssignedVariablesAnalyzer::VisitCompareOperation(CompareOperation* expr) { | 491 void AssignedVariablesAnalyzer::VisitCompareOperation(CompareOperation* expr) { |
739 ASSERT(av_.IsEmpty()); | 492 ASSERT(av_.IsEmpty()); |
740 MarkIfTrivial(expr->right()); | 493 MarkIfTrivial(expr->right()); |
741 Visit(expr->right()); | 494 Visit(expr->right()); |
742 MarkIfTrivial(expr->left()); | 495 MarkIfTrivial(expr->left()); |
743 ProcessExpression(expr->left()); | 496 ProcessExpression(expr->left()); |
744 } | 497 } |
745 | 498 |
746 | 499 |
| 500 void AssignedVariablesAnalyzer::VisitCompareToNull(CompareToNull* expr) { |
| 501 ASSERT(av_.IsEmpty()); |
| 502 MarkIfTrivial(expr->expression()); |
| 503 Visit(expr->expression()); |
| 504 } |
| 505 |
| 506 |
747 void AssignedVariablesAnalyzer::VisitThisFunction(ThisFunction* expr) { | 507 void AssignedVariablesAnalyzer::VisitThisFunction(ThisFunction* expr) { |
748 // Nothing to do. | 508 // Nothing to do. |
749 ASSERT(av_.IsEmpty()); | 509 ASSERT(av_.IsEmpty()); |
750 } | 510 } |
751 | 511 |
752 | 512 |
753 void AssignedVariablesAnalyzer::VisitDeclaration(Declaration* decl) { | 513 void AssignedVariablesAnalyzer::VisitDeclaration(Declaration* decl) { |
754 UNREACHABLE(); | 514 UNREACHABLE(); |
755 } | 515 } |
756 | 516 |
757 | 517 |
758 } } // namespace v8::internal | 518 } } // namespace v8::internal |
OLD | NEW |