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

Side by Side Diff: src/typing.cc

Issue 14990014: Collect type feedback in separate pass and store it in AST (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixed header file definism Created 7 years, 7 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 2013 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 "typing.h"
29
30 #include <algorithm>
31
32 #include "v8.h"
33 #include "parser.h"
34 #include "scopeinfo.h"
35 #include "scopes.h"
36
37 namespace v8 {
38 namespace internal {
39
40
41 AstTyper::AstTyper(CompilationInfo* info)
42 : info_(info),
43 oracle_(
44 Handle<Code>(info->closure()->shared()->code()),
45 Handle<Context>(info->closure()->context()->native_context()),
46 info->isolate(),
47 info->zone()) {
48 InitializeAstVisitor();
49 }
50
51
52 void AstTyper::Type(CompilationInfo* info) {
53 AstTyper* visitor = new(info->zone()) AstTyper(info);
54 Scope* scope = info->scope();
55
56 // Handle implicit declaration of the function name in named function
57 // expressions before other declarations.
58 if (scope->is_function_scope() && scope->function() != NULL) {
59 visitor->VisitVariableDeclaration(scope->function());
60 }
61 visitor->VisitDeclarations(scope->declarations());
62 visitor->VisitStatements(info->function()->body());
63 }
64
65
66 #define CHECK_ALIVE(call) \
67 do { \
68 call; \
69 if (HasStackOverflow()) return; \
70 } while (false)
71
72
73 void AstTyper::VisitStatements(ZoneList<Statement*>* stmts) {
74 ASSERT(!HasStackOverflow());
75 for (int i = 0; i < stmts->length(); ++i) {
76 Statement* stmt = stmts->at(i);
77 CHECK_ALIVE(Visit(stmt));
78 }
79 }
80
81
82 void AstTyper::VisitBlock(Block* stmt) {
83 ASSERT(!HasStackOverflow());
84 CHECK_ALIVE(VisitStatements(stmt->statements()));
Sven Panne 2013/05/16 11:58:05 Hmmm, do we really need a CHECK_ALIVE here? I thou
rossberg 2013/05/17 10:59:50 You have to check at every level to make failure a
85 }
86
87
88 void AstTyper::VisitExpressionStatement(ExpressionStatement* stmt) {
89 ASSERT(!HasStackOverflow());
90 Visit(stmt->expression());
91 }
92
93
94 void AstTyper::VisitEmptyStatement(EmptyStatement* stmt) {
95 ASSERT(!HasStackOverflow());
96 }
97
98
99 void AstTyper::VisitIfStatement(IfStatement* stmt) {
100 ASSERT(!HasStackOverflow());
101 CHECK_ALIVE(Visit(stmt->condition()));
102 CHECK_ALIVE(Visit(stmt->then_statement()));
103 CHECK_ALIVE(Visit(stmt->else_statement()));
104
105 if (!stmt->condition()->ToBooleanIsTrue() &&
106 !stmt->condition()->ToBooleanIsFalse()) {
107 stmt->condition()->RecordToBooleanTypeFeedback(oracle());
108 }
109 }
110
111
112 void AstTyper::VisitContinueStatement(ContinueStatement* stmt) {
113 ASSERT(!HasStackOverflow());
114 }
115
116
117 void AstTyper::VisitBreakStatement(BreakStatement* stmt) {
118 ASSERT(!HasStackOverflow());
119 }
120
121
122 void AstTyper::VisitReturnStatement(ReturnStatement* stmt) {
123 ASSERT(!HasStackOverflow());
124 CHECK_ALIVE(Visit(stmt->expression()));
125
126 // TODO(rossberg): we only need this for inlining into test contexts...
127 stmt->expression()->RecordToBooleanTypeFeedback(oracle());
128 }
129
130
131 void AstTyper::VisitWithStatement(WithStatement* stmt) {
132 ASSERT(!HasStackOverflow());
133 CHECK_ALIVE(stmt->expression());
134 CHECK_ALIVE(stmt->statement());
135 }
136
137
138 void AstTyper::VisitSwitchStatement(SwitchStatement* stmt) {
139 ASSERT(!HasStackOverflow());
140 CHECK_ALIVE(Visit(stmt->tag()));
141 ZoneList<CaseClause*>* clauses = stmt->cases();
142 SwitchStatement::SwitchType switch_type = stmt->switch_type();
143 for (int i = 0; i < clauses->length(); ++i) {
144 CaseClause* clause = clauses->at(i);
145 if (!clause->is_default()) {
146 Expression* label = clause->label();
147 CHECK_ALIVE(Visit(label));
148
149 SwitchStatement::SwitchType label_switch_type =
150 label->IsSmiLiteral() ? SwitchStatement::SMI_SWITCH :
151 label->IsStringLiteral() ? SwitchStatement::STRING_SWITCH :
152 SwitchStatement::GENERIC_SWITCH;
153 if (switch_type == SwitchStatement::UNKNOWN_SWITCH)
154 switch_type = label_switch_type;
155 else if (switch_type != label_switch_type)
156 switch_type = SwitchStatement::GENERIC_SWITCH;
157 }
158 CHECK_ALIVE(VisitStatements(clause->statements()));
159 }
160 if (switch_type == SwitchStatement::UNKNOWN_SWITCH)
161 switch_type = SwitchStatement::GENERIC_SWITCH;
162 stmt->set_switch_type(switch_type);
163
164 // TODO(rossberg): can we eliminate this special case and extra loop?
165 if (switch_type == SwitchStatement::SMI_SWITCH) {
166 for (int i = 0; i < clauses->length(); ++i) {
167 CaseClause* clause = clauses->at(i);
168 if (!clause->is_default())
169 clause->RecordTypeFeedback(oracle());
170 }
171 }
172 }
173
174
175 void AstTyper::VisitDoWhileStatement(DoWhileStatement* stmt) {
176 ASSERT(!HasStackOverflow());
177 CHECK_ALIVE(Visit(stmt->body()));
178 CHECK_ALIVE(Visit(stmt->cond()));
179
180 if (!stmt->cond()->ToBooleanIsTrue()) {
181 stmt->cond()->RecordToBooleanTypeFeedback(oracle());
182 }
183 }
184
185
186 void AstTyper::VisitWhileStatement(WhileStatement* stmt) {
187 ASSERT(!HasStackOverflow());
188 CHECK_ALIVE(Visit(stmt->cond()));
189 CHECK_ALIVE(Visit(stmt->body()));
190
191 if (!stmt->cond()->ToBooleanIsTrue()) {
192 stmt->cond()->RecordToBooleanTypeFeedback(oracle());
193 }
194 }
195
196
197 void AstTyper::VisitForStatement(ForStatement* stmt) {
198 ASSERT(!HasStackOverflow());
199 if (stmt->init() != NULL) {
200 CHECK_ALIVE(Visit(stmt->init()));
201 }
202 if (stmt->cond() != NULL) {
203 CHECK_ALIVE(Visit(stmt->cond()));
204
205 stmt->cond()->RecordToBooleanTypeFeedback(oracle());
206 }
207 CHECK_ALIVE(Visit(stmt->body()));
208 if (stmt->next() != NULL) {
209 CHECK_ALIVE(Visit(stmt->next()));
210 }
211 }
212
213
214 void AstTyper::VisitForInStatement(ForInStatement* stmt) {
215 ASSERT(!HasStackOverflow());
216 CHECK_ALIVE(Visit(stmt->enumerable()));
217 CHECK_ALIVE(Visit(stmt->body()));
218
219 stmt->RecordTypeFeedback(oracle());
220 }
221
222
223 void AstTyper::VisitTryCatchStatement(TryCatchStatement* stmt) {
224 ASSERT(!HasStackOverflow());
225 CHECK_ALIVE(Visit(stmt->try_block()));
226 CHECK_ALIVE(Visit(stmt->catch_block()));
227 }
228
229
230 void AstTyper::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
231 ASSERT(!HasStackOverflow());
232 CHECK_ALIVE(Visit(stmt->try_block()));
233 CHECK_ALIVE(Visit(stmt->finally_block()));
234 }
235
236
237 void AstTyper::VisitDebuggerStatement(DebuggerStatement* stmt) {
238 ASSERT(!HasStackOverflow());
239 }
240
241
242 void AstTyper::VisitFunctionLiteral(FunctionLiteral* expr) {
243 ASSERT(!HasStackOverflow());
244 }
245
246
247 void AstTyper::VisitSharedFunctionInfoLiteral(SharedFunctionInfoLiteral* expr) {
248 ASSERT(!HasStackOverflow());
249 }
250
251
252 void AstTyper::VisitConditional(Conditional* expr) {
253 ASSERT(!HasStackOverflow());
254 CHECK_ALIVE(Visit(expr->condition()));
255 CHECK_ALIVE(Visit(expr->then_expression()));
256 CHECK_ALIVE(Visit(expr->else_expression()));
257
258 expr->condition()->RecordToBooleanTypeFeedback(oracle());
259 }
260
261
262 void AstTyper::VisitVariableProxy(VariableProxy* expr) {
263 ASSERT(!HasStackOverflow());
264 }
265
266
267 void AstTyper::VisitLiteral(Literal* expr) {
268 ASSERT(!HasStackOverflow());
269 }
270
271
272 void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) {
273 ASSERT(!HasStackOverflow());
274 }
275
276
277 void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) {
278 ASSERT(!HasStackOverflow());
279 ZoneList<ObjectLiteral::Property*>* properties = expr->properties();
280 for (int i = 0; i < properties->length(); ++i) {
281 ObjectLiteral::Property* prop = properties->at(i);
282 CHECK_ALIVE(Visit(prop->value()));
283
284 if ((prop->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL &&
285 !CompileTimeValue::IsCompileTimeValue(prop->value())) ||
286 prop->kind() == ObjectLiteral::Property::COMPUTED) {
287 if (prop->key()->handle()->IsInternalizedString() && prop->emit_store())
288 prop->RecordTypeFeedback(oracle());
289 }
290 }
291 }
292
293
294 void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) {
295 ASSERT(!HasStackOverflow());
296 ZoneList<Expression*>* values = expr->values();
297 for (int i = 0; i < values->length(); ++i) {
298 Expression* value = values->at(i);
299 CHECK_ALIVE(Visit(value));
300 }
301 }
302
303
304 void AstTyper::VisitAssignment(Assignment* expr) {
305 ASSERT(!HasStackOverflow());
306 CHECK_ALIVE(Visit(expr->target()));
307 CHECK_ALIVE(Visit(expr->value()));
308
309 // TODO(rossberg): Can we clean this up?
310 if (expr->is_compound()) {
311 CHECK_ALIVE(Visit(expr->binary_operation()));
312
313 Expression* target = expr->target();
314 Property* prop = target->AsProperty();
315 if (prop != NULL) {
316 prop->RecordTypeFeedback(oracle(), zone());
317 if (!prop->key()->IsPropertyName()) // i.e., keyed
318 expr->RecordTypeFeedback(oracle(), zone());
319 }
320 return;
321 }
322 if (expr->target()->AsProperty())
323 expr->RecordTypeFeedback(oracle(), zone());
324 }
325
326
327 void AstTyper::VisitYield(Yield* expr) {
328 ASSERT(!HasStackOverflow());
329 CHECK_ALIVE(Visit(expr->generator_object()));
330 CHECK_ALIVE(Visit(expr->expression()));
331 }
332
333
334 void AstTyper::VisitThrow(Throw* expr) {
335 ASSERT(!HasStackOverflow());
336 CHECK_ALIVE(Visit(expr->exception()));
337 }
338
339
340 void AstTyper::VisitProperty(Property* expr) {
341 ASSERT(!HasStackOverflow());
342 CHECK_ALIVE(Visit(expr->obj()));
343 CHECK_ALIVE(Visit(expr->key()));
344
345 expr->RecordTypeFeedback(oracle(), zone());
346 }
347
348
349 void AstTyper::VisitCall(Call* expr) {
350 ASSERT(!HasStackOverflow());
351 CHECK_ALIVE(Visit(expr->expression()));
352 ZoneList<Expression*>* args = expr->arguments();
353 for (int i = 0; i < args->length(); ++i) {
354 Expression* arg = args->at(i);
355 CHECK_ALIVE(Visit(arg));
356 }
357
358 Expression* callee = expr->expression();
359 Property* prop = callee->AsProperty();
360 if (prop != NULL) {
361 if (prop->key()->IsPropertyName())
362 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD);
363 } else {
364 expr->RecordTypeFeedback(oracle(), CALL_AS_FUNCTION);
365 }
366 }
367
368
369 void AstTyper::VisitCallNew(CallNew* expr) {
370 ASSERT(!HasStackOverflow());
371 CHECK_ALIVE(Visit(expr->expression()));
372 ZoneList<Expression*>* args = expr->arguments();
373 for (int i = 0; i < args->length(); ++i) {
374 Expression* arg = args->at(i);
375 CHECK_ALIVE(Visit(arg));
376 }
377
378 expr->RecordTypeFeedback(oracle());
379 }
380
381
382 void AstTyper::VisitCallRuntime(CallRuntime* expr) {
383 ASSERT(!HasStackOverflow());
384 ZoneList<Expression*>* args = expr->arguments();
385 for (int i = 0; i < args->length(); ++i) {
386 Expression* arg = args->at(i);
387 CHECK_ALIVE(Visit(arg));
388 }
389 }
390
391
392 void AstTyper::VisitUnaryOperation(UnaryOperation* expr) {
393 ASSERT(!HasStackOverflow());
394 CHECK_ALIVE(Visit(expr->expression()));
395
396 expr->RecordTypeFeedback(oracle());
397 if (expr->op() == Token::NOT) {
398 // TODO(rossberg): only do in test or value context.
399 expr->expression()->RecordToBooleanTypeFeedback(oracle());
400 }
401 }
402
403
404 void AstTyper::VisitCountOperation(CountOperation* expr) {
405 ASSERT(!HasStackOverflow());
406 CHECK_ALIVE(Visit(expr->expression()));
407
408 expr->RecordTypeFeedback(oracle(), zone());
409 Property* prop = expr->expression()->AsProperty();
410 if (prop != NULL) {
411 prop->RecordTypeFeedback(oracle(), zone());
412 }
413 }
414
415
416 void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
417 ASSERT(!HasStackOverflow());
418 CHECK_ALIVE(Visit(expr->left()));
419 CHECK_ALIVE(Visit(expr->right()));
420
421 expr->RecordTypeFeedback(oracle());
422 if (expr->op() == Token::OR || expr->op() == Token::AND) {
423 expr->left()->RecordToBooleanTypeFeedback(oracle());
424 }
425 }
426
427
428 void AstTyper::VisitCompareOperation(CompareOperation* expr) {
429 ASSERT(!HasStackOverflow());
430 CHECK_ALIVE(Visit(expr->left()));
431 CHECK_ALIVE(Visit(expr->right()));
432
433 expr->RecordTypeFeedback(oracle());
434 }
435
436
437 void AstTyper::VisitThisFunction(ThisFunction* expr) {
438 ASSERT(!HasStackOverflow());
439 }
440
441
442 void AstTyper::VisitDeclarations(ZoneList<Declaration*>* decls) {
443 ASSERT(!HasStackOverflow());
444 for (int i = 0; i < decls->length(); ++i) {
445 Declaration* decl = decls->at(i);
446 CHECK_ALIVE(Visit(decl));
447 }
448 }
449
450
451 void AstTyper::VisitVariableDeclaration(VariableDeclaration* declaration) {
452 ASSERT(!HasStackOverflow());
453 }
454
455
456 void AstTyper::VisitFunctionDeclaration(FunctionDeclaration* declaration) {
457 ASSERT(!HasStackOverflow());
458 CHECK_ALIVE(Visit(declaration->fun()));
459 }
460
461
462 void AstTyper::VisitModuleDeclaration(ModuleDeclaration* declaration) {
463 ASSERT(!HasStackOverflow());
464 CHECK_ALIVE(Visit(declaration->module()));
465 }
466
467
468 void AstTyper::VisitImportDeclaration(ImportDeclaration* declaration) {
469 ASSERT(!HasStackOverflow());
470 CHECK_ALIVE(Visit(declaration->module()));
471 }
472
473
474 void AstTyper::VisitExportDeclaration(ExportDeclaration* declaration) {
475 ASSERT(!HasStackOverflow());
476 }
477
478
479 void AstTyper::VisitModuleLiteral(ModuleLiteral* module) {
480 ASSERT(!HasStackOverflow());
481 CHECK_ALIVE(Visit(module->body()));
482 }
483
484
485 void AstTyper::VisitModuleVariable(ModuleVariable* module) {
486 ASSERT(!HasStackOverflow());
487 }
488
489
490 void AstTyper::VisitModulePath(ModulePath* module) {
491 ASSERT(!HasStackOverflow());
492 CHECK_ALIVE(Visit(module->module()));
493 }
494
495
496 void AstTyper::VisitModuleUrl(ModuleUrl* module) {
497 ASSERT(!HasStackOverflow());
498 }
499
500
501 void AstTyper::VisitModuleStatement(ModuleStatement* stmt) {
502 ASSERT(!HasStackOverflow());
503 CHECK_ALIVE(Visit(stmt->body()));
504 }
505
506
507 } } // namespace v8::internal
OLDNEW
« src/typing.h ('K') | « src/typing.h ('k') | tools/gyp/v8.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698