OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 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 "v8.h" | |
29 | |
30 #include "feedbackslots.h" | |
31 | |
32 #include "ast.h" | |
33 #include "compiler.h" | |
34 #include "scopes.h" | |
35 | |
36 namespace v8 { | |
37 namespace internal { | |
38 | |
39 #define RECURSE(call) \ | |
danno
2014/01/28 08:27:17
Here and below, this seems like a lot of boilerpla
mvstanton
2014/01/30 15:13:41
Done.
| |
40 do { \ | |
41 ASSERT(!allocator.HasStackOverflow()); \ | |
42 call; \ | |
43 if (allocator.HasStackOverflow()) return false; \ | |
44 } while (false) | |
45 | |
46 | |
47 bool FeedbackSlotAllocator::Run(CompilationInfo* info) { | |
48 FeedbackSlotAllocator allocator(info->zone()); | |
49 Scope* scope = info->scope(); | |
50 // Handle implicit declaration of the function name in named function | |
51 // expressions before other declarations. | |
52 if (scope->is_function_scope() && scope->function() != NULL) { | |
53 RECURSE(allocator.VisitVariableDeclaration(scope->function())); | |
54 } | |
55 RECURSE(allocator.VisitDeclarations(scope->declarations())); | |
56 RECURSE(allocator.VisitStatements(info->function()->body())); | |
57 info->set_feedback_slots(allocator.slot_count()); | |
58 return true; | |
59 } | |
60 #undef RECURSE | |
61 | |
62 | |
63 #define RECURSE(call) \ | |
64 do { \ | |
65 ASSERT(!HasStackOverflow()); \ | |
66 call; \ | |
67 if (HasStackOverflow()) return; \ | |
68 } while (false) | |
69 | |
70 | |
71 void FeedbackSlotAllocator::DoVisitBlock(Block* stmt) { | |
72 RECURSE(VisitStatements(stmt->statements())); | |
73 } | |
74 | |
75 | |
76 void FeedbackSlotAllocator::DoVisitExpressionStatement( | |
77 ExpressionStatement* stmt) { | |
78 RECURSE(Visit(stmt->expression())); | |
79 } | |
80 | |
81 | |
82 void FeedbackSlotAllocator::DoVisitEmptyStatement(EmptyStatement* stmt) { | |
83 } | |
84 | |
85 | |
86 void FeedbackSlotAllocator::DoVisitIfStatement(IfStatement* stmt) { | |
87 RECURSE(Visit(stmt->condition())); | |
88 RECURSE(Visit(stmt->then_statement())); | |
89 RECURSE(Visit(stmt->else_statement())); | |
90 } | |
91 | |
92 | |
93 void FeedbackSlotAllocator::DoVisitContinueStatement(ContinueStatement* stmt) { | |
94 } | |
95 | |
96 | |
97 void FeedbackSlotAllocator::DoVisitBreakStatement(BreakStatement* stmt) { | |
98 } | |
99 | |
100 | |
101 void FeedbackSlotAllocator::DoVisitReturnStatement(ReturnStatement* stmt) { | |
102 RECURSE(Visit(stmt->expression())); | |
103 } | |
104 | |
105 | |
106 void FeedbackSlotAllocator::DoVisitWithStatement(WithStatement* stmt) { | |
107 RECURSE(Visit(stmt->expression())); | |
108 RECURSE(Visit(stmt->statement())); | |
109 } | |
110 | |
111 | |
112 void FeedbackSlotAllocator::DoVisitSwitchStatement(SwitchStatement* stmt) { | |
113 RECURSE(Visit(stmt->tag())); | |
114 | |
115 ZoneList<CaseClause*>* clauses = stmt->cases(); | |
116 for (int i = 0; i < clauses->length(); ++i) { | |
117 CaseClause* clause = clauses->at(i); | |
118 if (!clause->is_default()) { | |
119 Expression* label = clause->label(); | |
120 RECURSE(Visit(label)); | |
121 } | |
122 | |
123 ZoneList<Statement*>* stmts = clause->statements(); | |
124 RECURSE(VisitStatements(stmts)); | |
125 } | |
126 } | |
127 | |
128 | |
129 void FeedbackSlotAllocator::DoVisitCaseClause(CaseClause* clause) { | |
130 } | |
131 | |
132 | |
133 void FeedbackSlotAllocator::DoVisitDoWhileStatement(DoWhileStatement* stmt) { | |
134 RECURSE(Visit(stmt->body())); | |
135 RECURSE(Visit(stmt->cond())); | |
136 } | |
137 | |
138 | |
139 void FeedbackSlotAllocator::DoVisitWhileStatement(WhileStatement* stmt) { | |
140 RECURSE(Visit(stmt->cond())); | |
141 RECURSE(Visit(stmt->body())); | |
142 } | |
143 | |
144 | |
145 void FeedbackSlotAllocator::DoVisitForStatement(ForStatement* stmt) { | |
146 if (stmt->init() != NULL) { | |
147 RECURSE(Visit(stmt->init())); | |
148 } | |
149 if (stmt->cond() != NULL) { | |
150 RECURSE(Visit(stmt->cond())); | |
151 } | |
152 RECURSE(Visit(stmt->body())); | |
153 if (stmt->next() != NULL) { | |
154 RECURSE(Visit(stmt->next())); | |
155 } | |
156 } | |
157 | |
158 | |
159 void FeedbackSlotAllocator::DoVisitForInStatement(ForInStatement* stmt) { | |
160 RECURSE(Visit(stmt->enumerable())); | |
161 RECURSE(Visit(stmt->body())); | |
162 } | |
163 | |
164 | |
165 void FeedbackSlotAllocator::DoVisitForOfStatement(ForOfStatement* stmt) { | |
166 RECURSE(Visit(stmt->iterable())); | |
167 RECURSE(Visit(stmt->body())); | |
168 } | |
169 | |
170 | |
171 void FeedbackSlotAllocator::DoVisitTryCatchStatement(TryCatchStatement* stmt) { | |
172 RECURSE(Visit(stmt->try_block())); | |
173 RECURSE(Visit(stmt->catch_block())); | |
174 } | |
175 | |
176 | |
177 void FeedbackSlotAllocator::DoVisitTryFinallyStatement( | |
178 TryFinallyStatement* stmt) { | |
179 RECURSE(Visit(stmt->try_block())); | |
180 RECURSE(Visit(stmt->finally_block())); | |
181 } | |
182 | |
183 | |
184 void FeedbackSlotAllocator::DoVisitDebuggerStatement(DebuggerStatement* stmt) { | |
185 } | |
186 | |
187 | |
188 void FeedbackSlotAllocator::DoVisitFunctionLiteral(FunctionLiteral* expr) { | |
189 } | |
190 | |
191 | |
192 void FeedbackSlotAllocator::DoVisitNativeFunctionLiteral( | |
193 NativeFunctionLiteral* expr) { | |
194 } | |
195 | |
196 | |
197 void FeedbackSlotAllocator::DoVisitConditional(Conditional* expr) { | |
198 RECURSE(Visit(expr->condition())); | |
199 RECURSE(Visit(expr->then_expression())); | |
200 RECURSE(Visit(expr->else_expression())); | |
201 } | |
202 | |
203 | |
204 void FeedbackSlotAllocator::DoVisitVariableProxy(VariableProxy* expr) { | |
205 } | |
206 | |
207 | |
208 void FeedbackSlotAllocator::DoVisitLiteral(Literal* expr) { | |
209 } | |
210 | |
211 | |
212 void FeedbackSlotAllocator::DoVisitRegExpLiteral(RegExpLiteral* expr) { | |
213 } | |
214 | |
215 | |
216 void FeedbackSlotAllocator::DoVisitObjectLiteral(ObjectLiteral* expr) { | |
217 ZoneList<ObjectLiteral::Property*>* properties = expr->properties(); | |
218 for (int i = 0; i < properties->length(); ++i) { | |
219 ObjectLiteral::Property* prop = properties->at(i); | |
220 RECURSE(Visit(prop->value())); | |
221 } | |
222 } | |
223 | |
224 | |
225 void FeedbackSlotAllocator::DoVisitArrayLiteral(ArrayLiteral* expr) { | |
226 ZoneList<Expression*>* values = expr->values(); | |
227 for (int i = 0; i < values->length(); ++i) { | |
228 Expression* value = values->at(i); | |
229 RECURSE(Visit(value)); | |
230 } | |
231 } | |
232 | |
233 | |
234 void FeedbackSlotAllocator::DoVisitAssignment(Assignment* expr) { | |
235 Expression* rhs = | |
236 expr->is_compound() ? expr->binary_operation() : expr->value(); | |
237 RECURSE(Visit(expr->target())); | |
238 RECURSE(Visit(rhs)); | |
239 } | |
240 | |
241 | |
242 void FeedbackSlotAllocator::DoVisitYield(Yield* expr) { | |
243 RECURSE(Visit(expr->generator_object())); | |
244 RECURSE(Visit(expr->expression())); | |
245 } | |
246 | |
247 | |
248 void FeedbackSlotAllocator::DoVisitThrow(Throw* expr) { | |
249 RECURSE(Visit(expr->exception())); | |
250 } | |
251 | |
252 | |
253 void FeedbackSlotAllocator::DoVisitProperty(Property* expr) { | |
254 RECURSE(Visit(expr->obj())); | |
255 RECURSE(Visit(expr->key())); | |
256 } | |
257 | |
258 | |
259 void FeedbackSlotAllocator::DoVisitCall(Call* expr) { | |
260 RECURSE(Visit(expr->expression())); | |
261 ZoneList<Expression*>* args = expr->arguments(); | |
262 for (int i = 0; i < args->length(); ++i) { | |
263 Expression* arg = args->at(i); | |
264 RECURSE(Visit(arg)); | |
265 } | |
266 } | |
267 | |
268 | |
269 void FeedbackSlotAllocator::DoVisitCallNew(CallNew* expr) { | |
270 RECURSE(Visit(expr->expression())); | |
271 ZoneList<Expression*>* args = expr->arguments(); | |
272 for (int i = 0; i < args->length(); ++i) { | |
273 Expression* arg = args->at(i); | |
274 RECURSE(Visit(arg)); | |
275 } | |
276 } | |
277 | |
278 | |
279 void FeedbackSlotAllocator::DoVisitCallRuntime(CallRuntime* expr) { | |
280 ZoneList<Expression*>* args = expr->arguments(); | |
281 for (int i = 0; i < args->length(); ++i) { | |
282 Expression* arg = args->at(i); | |
283 RECURSE(Visit(arg)); | |
284 } | |
285 } | |
286 | |
287 | |
288 void FeedbackSlotAllocator::DoVisitUnaryOperation(UnaryOperation* expr) { | |
289 RECURSE(Visit(expr->expression())); | |
290 } | |
291 | |
292 | |
293 void FeedbackSlotAllocator::DoVisitCountOperation(CountOperation* expr) { | |
294 RECURSE(Visit(expr->expression())); | |
295 } | |
296 | |
297 | |
298 void FeedbackSlotAllocator::DoVisitBinaryOperation(BinaryOperation* expr) { | |
299 RECURSE(Visit(expr->left())); | |
300 RECURSE(Visit(expr->right())); | |
301 } | |
302 | |
303 | |
304 void FeedbackSlotAllocator::DoVisitCompareOperation(CompareOperation* expr) { | |
305 RECURSE(Visit(expr->left())); | |
306 RECURSE(Visit(expr->right())); | |
307 } | |
308 | |
309 | |
310 void FeedbackSlotAllocator::DoVisitThisFunction(ThisFunction* expr) { | |
311 } | |
312 | |
313 | |
314 void FeedbackSlotAllocator::DoVisitVariableDeclaration( | |
315 VariableDeclaration* declaration) { | |
316 } | |
317 | |
318 | |
319 void FeedbackSlotAllocator::DoVisitFunctionDeclaration( | |
320 FunctionDeclaration* declaration) { | |
321 RECURSE(Visit(declaration->fun())); | |
322 } | |
323 | |
324 | |
325 void FeedbackSlotAllocator::DoVisitModuleDeclaration( | |
326 ModuleDeclaration* declaration) { | |
327 RECURSE(Visit(declaration->module())); | |
328 } | |
329 | |
330 | |
331 void FeedbackSlotAllocator::DoVisitImportDeclaration( | |
332 ImportDeclaration* declaration) { | |
333 RECURSE(Visit(declaration->module())); | |
334 } | |
335 | |
336 | |
337 void FeedbackSlotAllocator::DoVisitExportDeclaration( | |
338 ExportDeclaration* declaration) { | |
339 } | |
340 | |
341 | |
342 void FeedbackSlotAllocator::DoVisitModuleLiteral(ModuleLiteral* module) { | |
343 RECURSE(Visit(module->body())); | |
344 } | |
345 | |
346 | |
347 void FeedbackSlotAllocator::DoVisitModuleVariable(ModuleVariable* module) { | |
348 } | |
349 | |
350 | |
351 void FeedbackSlotAllocator::DoVisitModulePath(ModulePath* module) { | |
352 RECURSE(Visit(module->module())); | |
353 } | |
354 | |
355 | |
356 void FeedbackSlotAllocator::DoVisitModuleUrl(ModuleUrl* module) { | |
357 } | |
358 | |
359 | |
360 void FeedbackSlotAllocator::DoVisitModuleStatement(ModuleStatement* stmt) { | |
361 RECURSE(Visit(stmt->body())); | |
362 } | |
363 | |
364 | |
365 } } // namespace v8::internal | |
OLD | NEW |