blob: bd960264149e46013c621c06ee1c16612ce8ea8a [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2012 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/ast/ast-numbering.h"
6
7#include "src/ast/ast.h"
8#include "src/ast/scopes.h"
9
10namespace v8 {
11namespace internal {
12
13class AstNumberingVisitor final : public AstVisitor {
14 public:
15 AstNumberingVisitor(Isolate* isolate, Zone* zone)
16 : AstVisitor(),
17 isolate_(isolate),
18 zone_(zone),
19 next_id_(BailoutId::FirstUsable().ToInt()),
Ben Murdochc5610432016-08-08 18:44:38 +010020 yield_count_(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000021 properties_(zone),
22 slot_cache_(zone),
23 dont_optimize_reason_(kNoReason) {
24 InitializeAstVisitor(isolate);
25 }
26
27 bool Renumber(FunctionLiteral* node);
28
29 private:
30// AST node visitor interface.
31#define DEFINE_VISIT(type) void Visit##type(type* node) override;
32 AST_NODE_LIST(DEFINE_VISIT)
33#undef DEFINE_VISIT
34
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000035 void VisitVariableProxyReference(VariableProxy* node);
36 void VisitPropertyReference(Property* node);
37 void VisitReference(Expression* expr);
38
39 void VisitStatements(ZoneList<Statement*>* statements) override;
40 void VisitDeclarations(ZoneList<Declaration*>* declarations) override;
41 void VisitArguments(ZoneList<Expression*>* arguments);
42 void VisitObjectLiteralProperty(ObjectLiteralProperty* property);
43
44 int ReserveIdRange(int n) {
45 int tmp = next_id_;
46 next_id_ += n;
47 return tmp;
48 }
49
50 void IncrementNodeCount() { properties_.add_node_count(1); }
51 void DisableSelfOptimization() {
52 properties_.flags() |= AstProperties::kDontSelfOptimize;
53 }
54 void DisableOptimization(BailoutReason reason) {
55 dont_optimize_reason_ = reason;
56 DisableSelfOptimization();
57 }
58 void DisableCrankshaft(BailoutReason reason) {
59 if (FLAG_turbo_shipping) {
60 properties_.flags() |= AstProperties::kDontCrankshaft;
61 } else {
62 dont_optimize_reason_ = reason;
63 DisableSelfOptimization();
64 }
65 }
66
67 template <typename Node>
68 void ReserveFeedbackSlots(Node* node) {
69 node->AssignFeedbackVectorSlots(isolate_, properties_.get_spec(),
70 &slot_cache_);
71 }
72
73 BailoutReason dont_optimize_reason() const { return dont_optimize_reason_; }
74
75 Isolate* isolate_;
76 Zone* zone_;
77 int next_id_;
Ben Murdochc5610432016-08-08 18:44:38 +010078 int yield_count_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000079 AstProperties properties_;
80 // The slot cache allows us to reuse certain feedback vector slots.
81 FeedbackVectorSlotCache slot_cache_;
82 BailoutReason dont_optimize_reason_;
83
84 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
85 DISALLOW_COPY_AND_ASSIGN(AstNumberingVisitor);
86};
87
88
89void AstNumberingVisitor::VisitVariableDeclaration(VariableDeclaration* node) {
90 IncrementNodeCount();
91 VisitVariableProxy(node->proxy());
92}
93
94
95void AstNumberingVisitor::VisitExportDeclaration(ExportDeclaration* node) {
96 IncrementNodeCount();
97 DisableOptimization(kExportDeclaration);
98 VisitVariableProxy(node->proxy());
99}
100
101
102void AstNumberingVisitor::VisitEmptyStatement(EmptyStatement* node) {
103 IncrementNodeCount();
104}
105
106
107void AstNumberingVisitor::VisitSloppyBlockFunctionStatement(
108 SloppyBlockFunctionStatement* node) {
109 IncrementNodeCount();
110 Visit(node->statement());
111}
112
113
114void AstNumberingVisitor::VisitContinueStatement(ContinueStatement* node) {
115 IncrementNodeCount();
116}
117
118
119void AstNumberingVisitor::VisitBreakStatement(BreakStatement* node) {
120 IncrementNodeCount();
121}
122
123
124void AstNumberingVisitor::VisitDebuggerStatement(DebuggerStatement* node) {
125 IncrementNodeCount();
126 DisableOptimization(kDebuggerStatement);
127 node->set_base_id(ReserveIdRange(DebuggerStatement::num_ids()));
128}
129
130
131void AstNumberingVisitor::VisitNativeFunctionLiteral(
132 NativeFunctionLiteral* node) {
133 IncrementNodeCount();
134 DisableOptimization(kNativeFunctionLiteral);
135 node->set_base_id(ReserveIdRange(NativeFunctionLiteral::num_ids()));
136}
137
138
139void AstNumberingVisitor::VisitDoExpression(DoExpression* node) {
140 IncrementNodeCount();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000141 node->set_base_id(ReserveIdRange(DoExpression::num_ids()));
142 Visit(node->block());
143 Visit(node->result());
144}
145
146
147void AstNumberingVisitor::VisitLiteral(Literal* node) {
148 IncrementNodeCount();
149 node->set_base_id(ReserveIdRange(Literal::num_ids()));
150}
151
152
153void AstNumberingVisitor::VisitRegExpLiteral(RegExpLiteral* node) {
154 IncrementNodeCount();
155 node->set_base_id(ReserveIdRange(RegExpLiteral::num_ids()));
156}
157
158
159void AstNumberingVisitor::VisitVariableProxyReference(VariableProxy* node) {
160 IncrementNodeCount();
161 if (node->var()->IsLookupSlot()) {
162 DisableCrankshaft(kReferenceToAVariableWhichRequiresDynamicLookup);
163 }
164 node->set_base_id(ReserveIdRange(VariableProxy::num_ids()));
165}
166
167
168void AstNumberingVisitor::VisitVariableProxy(VariableProxy* node) {
169 VisitVariableProxyReference(node);
170 ReserveFeedbackSlots(node);
171}
172
173
174void AstNumberingVisitor::VisitThisFunction(ThisFunction* node) {
175 IncrementNodeCount();
176 node->set_base_id(ReserveIdRange(ThisFunction::num_ids()));
177}
178
179
180void AstNumberingVisitor::VisitSuperPropertyReference(
181 SuperPropertyReference* node) {
182 IncrementNodeCount();
183 DisableCrankshaft(kSuperReference);
184 node->set_base_id(ReserveIdRange(SuperPropertyReference::num_ids()));
185 Visit(node->this_var());
186 Visit(node->home_object());
187}
188
189
190void AstNumberingVisitor::VisitSuperCallReference(SuperCallReference* node) {
191 IncrementNodeCount();
192 DisableCrankshaft(kSuperReference);
193 node->set_base_id(ReserveIdRange(SuperCallReference::num_ids()));
194 Visit(node->this_var());
195 Visit(node->new_target_var());
196 Visit(node->this_function_var());
197}
198
199
200void AstNumberingVisitor::VisitImportDeclaration(ImportDeclaration* node) {
201 IncrementNodeCount();
202 DisableOptimization(kImportDeclaration);
203 VisitVariableProxy(node->proxy());
204}
205
206
207void AstNumberingVisitor::VisitExpressionStatement(ExpressionStatement* node) {
208 IncrementNodeCount();
209 Visit(node->expression());
210}
211
212
213void AstNumberingVisitor::VisitReturnStatement(ReturnStatement* node) {
214 IncrementNodeCount();
215 Visit(node->expression());
216}
217
218
219void AstNumberingVisitor::VisitYield(Yield* node) {
Ben Murdochc5610432016-08-08 18:44:38 +0100220 node->set_yield_id(yield_count_);
221 yield_count_++;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000222 IncrementNodeCount();
223 DisableOptimization(kYield);
224 ReserveFeedbackSlots(node);
225 node->set_base_id(ReserveIdRange(Yield::num_ids()));
226 Visit(node->generator_object());
227 Visit(node->expression());
228}
229
230
231void AstNumberingVisitor::VisitThrow(Throw* node) {
232 IncrementNodeCount();
233 node->set_base_id(ReserveIdRange(Throw::num_ids()));
234 Visit(node->exception());
235}
236
237
238void AstNumberingVisitor::VisitUnaryOperation(UnaryOperation* node) {
239 IncrementNodeCount();
240 node->set_base_id(ReserveIdRange(UnaryOperation::num_ids()));
241 Visit(node->expression());
242}
243
244
245void AstNumberingVisitor::VisitCountOperation(CountOperation* node) {
246 IncrementNodeCount();
247 node->set_base_id(ReserveIdRange(CountOperation::num_ids()));
248 Visit(node->expression());
249 ReserveFeedbackSlots(node);
250}
251
252
253void AstNumberingVisitor::VisitBlock(Block* node) {
254 IncrementNodeCount();
255 node->set_base_id(ReserveIdRange(Block::num_ids()));
256 if (node->scope() != NULL) VisitDeclarations(node->scope()->declarations());
257 VisitStatements(node->statements());
258}
259
260
261void AstNumberingVisitor::VisitFunctionDeclaration(FunctionDeclaration* node) {
262 IncrementNodeCount();
263 VisitVariableProxy(node->proxy());
264 VisitFunctionLiteral(node->fun());
265}
266
267
268void AstNumberingVisitor::VisitCallRuntime(CallRuntime* node) {
269 IncrementNodeCount();
270 ReserveFeedbackSlots(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000271 node->set_base_id(ReserveIdRange(CallRuntime::num_ids()));
272 VisitArguments(node->arguments());
273}
274
275
276void AstNumberingVisitor::VisitWithStatement(WithStatement* node) {
277 IncrementNodeCount();
278 DisableCrankshaft(kWithStatement);
279 node->set_base_id(ReserveIdRange(WithStatement::num_ids()));
280 Visit(node->expression());
281 Visit(node->statement());
282}
283
284
285void AstNumberingVisitor::VisitDoWhileStatement(DoWhileStatement* node) {
286 IncrementNodeCount();
287 DisableSelfOptimization();
288 node->set_base_id(ReserveIdRange(DoWhileStatement::num_ids()));
Ben Murdochc5610432016-08-08 18:44:38 +0100289 node->set_first_yield_id(yield_count_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000290 Visit(node->body());
291 Visit(node->cond());
Ben Murdochc5610432016-08-08 18:44:38 +0100292 node->set_yield_count(yield_count_ - node->first_yield_id());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000293}
294
295
296void AstNumberingVisitor::VisitWhileStatement(WhileStatement* node) {
297 IncrementNodeCount();
298 DisableSelfOptimization();
299 node->set_base_id(ReserveIdRange(WhileStatement::num_ids()));
Ben Murdochc5610432016-08-08 18:44:38 +0100300 node->set_first_yield_id(yield_count_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000301 Visit(node->cond());
302 Visit(node->body());
Ben Murdochc5610432016-08-08 18:44:38 +0100303 node->set_yield_count(yield_count_ - node->first_yield_id());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000304}
305
306
307void AstNumberingVisitor::VisitTryCatchStatement(TryCatchStatement* node) {
308 IncrementNodeCount();
309 DisableOptimization(kTryCatchStatement);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000310 Visit(node->try_block());
311 Visit(node->catch_block());
312}
313
314
315void AstNumberingVisitor::VisitTryFinallyStatement(TryFinallyStatement* node) {
316 IncrementNodeCount();
317 DisableOptimization(kTryFinallyStatement);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000318 Visit(node->try_block());
319 Visit(node->finally_block());
320}
321
322
323void AstNumberingVisitor::VisitPropertyReference(Property* node) {
324 IncrementNodeCount();
325 node->set_base_id(ReserveIdRange(Property::num_ids()));
326 Visit(node->key());
327 Visit(node->obj());
328}
329
330
331void AstNumberingVisitor::VisitReference(Expression* expr) {
332 DCHECK(expr->IsProperty() || expr->IsVariableProxy());
333 if (expr->IsProperty()) {
334 VisitPropertyReference(expr->AsProperty());
335 } else {
336 VisitVariableProxyReference(expr->AsVariableProxy());
337 }
338}
339
340
341void AstNumberingVisitor::VisitProperty(Property* node) {
342 VisitPropertyReference(node);
343 ReserveFeedbackSlots(node);
344}
345
346
347void AstNumberingVisitor::VisitAssignment(Assignment* node) {
348 IncrementNodeCount();
349 node->set_base_id(ReserveIdRange(Assignment::num_ids()));
350
351 if (node->is_compound()) VisitBinaryOperation(node->binary_operation());
352 VisitReference(node->target());
353 Visit(node->value());
354 ReserveFeedbackSlots(node);
355}
356
357
358void AstNumberingVisitor::VisitBinaryOperation(BinaryOperation* node) {
359 IncrementNodeCount();
360 node->set_base_id(ReserveIdRange(BinaryOperation::num_ids()));
361 Visit(node->left());
362 Visit(node->right());
363}
364
365
366void AstNumberingVisitor::VisitCompareOperation(CompareOperation* node) {
367 IncrementNodeCount();
368 node->set_base_id(ReserveIdRange(CompareOperation::num_ids()));
369 Visit(node->left());
370 Visit(node->right());
371}
372
373
Ben Murdoch097c5b22016-05-18 11:27:45 +0100374void AstNumberingVisitor::VisitSpread(Spread* node) { UNREACHABLE(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000375
376
377void AstNumberingVisitor::VisitEmptyParentheses(EmptyParentheses* node) {
378 UNREACHABLE();
379}
380
381
382void AstNumberingVisitor::VisitForInStatement(ForInStatement* node) {
383 IncrementNodeCount();
384 DisableSelfOptimization();
385 node->set_base_id(ReserveIdRange(ForInStatement::num_ids()));
Ben Murdochc5610432016-08-08 18:44:38 +0100386 Visit(node->enumerable()); // Not part of loop.
387 node->set_first_yield_id(yield_count_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000388 Visit(node->each());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000389 Visit(node->body());
Ben Murdochc5610432016-08-08 18:44:38 +0100390 node->set_yield_count(yield_count_ - node->first_yield_id());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000391 ReserveFeedbackSlots(node);
392}
393
394
395void AstNumberingVisitor::VisitForOfStatement(ForOfStatement* node) {
396 IncrementNodeCount();
397 DisableCrankshaft(kForOfStatement);
398 node->set_base_id(ReserveIdRange(ForOfStatement::num_ids()));
Ben Murdochc5610432016-08-08 18:44:38 +0100399 Visit(node->assign_iterator()); // Not part of loop.
400 node->set_first_yield_id(yield_count_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000401 Visit(node->next_result());
402 Visit(node->result_done());
403 Visit(node->assign_each());
404 Visit(node->body());
Ben Murdochc5610432016-08-08 18:44:38 +0100405 node->set_yield_count(yield_count_ - node->first_yield_id());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000406 ReserveFeedbackSlots(node);
407}
408
409
410void AstNumberingVisitor::VisitConditional(Conditional* node) {
411 IncrementNodeCount();
412 node->set_base_id(ReserveIdRange(Conditional::num_ids()));
413 Visit(node->condition());
414 Visit(node->then_expression());
415 Visit(node->else_expression());
416}
417
418
419void AstNumberingVisitor::VisitIfStatement(IfStatement* node) {
420 IncrementNodeCount();
421 node->set_base_id(ReserveIdRange(IfStatement::num_ids()));
422 Visit(node->condition());
423 Visit(node->then_statement());
424 if (node->HasElseStatement()) {
425 Visit(node->else_statement());
426 }
427}
428
429
430void AstNumberingVisitor::VisitSwitchStatement(SwitchStatement* node) {
431 IncrementNodeCount();
432 node->set_base_id(ReserveIdRange(SwitchStatement::num_ids()));
433 Visit(node->tag());
434 ZoneList<CaseClause*>* cases = node->cases();
435 for (int i = 0; i < cases->length(); i++) {
436 VisitCaseClause(cases->at(i));
437 }
438}
439
440
441void AstNumberingVisitor::VisitCaseClause(CaseClause* node) {
442 IncrementNodeCount();
443 node->set_base_id(ReserveIdRange(CaseClause::num_ids()));
444 if (!node->is_default()) Visit(node->label());
445 VisitStatements(node->statements());
446}
447
448
449void AstNumberingVisitor::VisitForStatement(ForStatement* node) {
450 IncrementNodeCount();
451 DisableSelfOptimization();
452 node->set_base_id(ReserveIdRange(ForStatement::num_ids()));
Ben Murdochc5610432016-08-08 18:44:38 +0100453 if (node->init() != NULL) Visit(node->init()); // Not part of loop.
454 node->set_first_yield_id(yield_count_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000455 if (node->cond() != NULL) Visit(node->cond());
456 if (node->next() != NULL) Visit(node->next());
457 Visit(node->body());
Ben Murdochc5610432016-08-08 18:44:38 +0100458 node->set_yield_count(yield_count_ - node->first_yield_id());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000459}
460
461
462void AstNumberingVisitor::VisitClassLiteral(ClassLiteral* node) {
463 IncrementNodeCount();
464 DisableCrankshaft(kClassLiteral);
465 node->set_base_id(ReserveIdRange(node->num_ids()));
466 if (node->extends()) Visit(node->extends());
467 if (node->constructor()) Visit(node->constructor());
468 if (node->class_variable_proxy()) {
469 VisitVariableProxy(node->class_variable_proxy());
470 }
471 for (int i = 0; i < node->properties()->length(); i++) {
472 VisitObjectLiteralProperty(node->properties()->at(i));
473 }
474 ReserveFeedbackSlots(node);
475}
476
477
478void AstNumberingVisitor::VisitObjectLiteral(ObjectLiteral* node) {
479 IncrementNodeCount();
480 node->set_base_id(ReserveIdRange(node->num_ids()));
481 for (int i = 0; i < node->properties()->length(); i++) {
482 VisitObjectLiteralProperty(node->properties()->at(i));
483 }
484 node->BuildConstantProperties(isolate_);
485 // Mark all computed expressions that are bound to a key that
486 // is shadowed by a later occurrence of the same key. For the
487 // marked expressions, no store code will be is emitted.
488 node->CalculateEmitStore(zone_);
489 ReserveFeedbackSlots(node);
490}
491
492
493void AstNumberingVisitor::VisitObjectLiteralProperty(
494 ObjectLiteralProperty* node) {
495 if (node->is_computed_name()) DisableCrankshaft(kComputedPropertyName);
496 Visit(node->key());
497 Visit(node->value());
498}
499
500
501void AstNumberingVisitor::VisitArrayLiteral(ArrayLiteral* node) {
502 IncrementNodeCount();
503 node->set_base_id(ReserveIdRange(node->num_ids()));
504 for (int i = 0; i < node->values()->length(); i++) {
505 Visit(node->values()->at(i));
506 }
507 node->BuildConstantElements(isolate_);
508 ReserveFeedbackSlots(node);
509}
510
511
512void AstNumberingVisitor::VisitCall(Call* node) {
513 IncrementNodeCount();
514 ReserveFeedbackSlots(node);
515 node->set_base_id(ReserveIdRange(Call::num_ids()));
516 Visit(node->expression());
517 VisitArguments(node->arguments());
518}
519
520
521void AstNumberingVisitor::VisitCallNew(CallNew* node) {
522 IncrementNodeCount();
523 ReserveFeedbackSlots(node);
524 node->set_base_id(ReserveIdRange(CallNew::num_ids()));
525 Visit(node->expression());
526 VisitArguments(node->arguments());
527}
528
529
530void AstNumberingVisitor::VisitStatements(ZoneList<Statement*>* statements) {
531 if (statements == NULL) return;
532 for (int i = 0; i < statements->length(); i++) {
533 Visit(statements->at(i));
534 }
535}
536
537
538void AstNumberingVisitor::VisitDeclarations(
539 ZoneList<Declaration*>* declarations) {
540 for (int i = 0; i < declarations->length(); i++) {
541 Visit(declarations->at(i));
542 }
543}
544
545
546void AstNumberingVisitor::VisitArguments(ZoneList<Expression*>* arguments) {
547 for (int i = 0; i < arguments->length(); i++) {
548 Visit(arguments->at(i));
549 }
550}
551
552
553void AstNumberingVisitor::VisitFunctionLiteral(FunctionLiteral* node) {
554 IncrementNodeCount();
555 node->set_base_id(ReserveIdRange(FunctionLiteral::num_ids()));
556 // We don't recurse into the declarations or body of the function literal:
557 // you have to separately Renumber() each FunctionLiteral that you compile.
558}
559
560
Ben Murdoch097c5b22016-05-18 11:27:45 +0100561void AstNumberingVisitor::VisitRewritableExpression(
562 RewritableExpression* node) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000563 IncrementNodeCount();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100564 node->set_base_id(ReserveIdRange(RewritableExpression::num_ids()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000565 Visit(node->expression());
566}
567
568
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000569bool AstNumberingVisitor::Renumber(FunctionLiteral* node) {
570 Scope* scope = node->scope();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000571 if (scope->new_target_var()) DisableCrankshaft(kSuperReference);
572 if (scope->calls_eval()) DisableOptimization(kFunctionCallsEval);
573 if (scope->arguments() != NULL && !scope->arguments()->IsStackAllocated()) {
574 DisableCrankshaft(kContextAllocatedArguments);
575 }
576
577 int rest_index;
578 if (scope->rest_parameter(&rest_index)) {
579 DisableCrankshaft(kRestParameter);
580 }
581
582 VisitDeclarations(scope->declarations());
583 VisitStatements(node->body());
584
Ben Murdochc5610432016-08-08 18:44:38 +0100585 node->set_ast_properties(&properties_);
586 node->set_dont_optimize_reason(dont_optimize_reason());
587 node->set_yield_count(yield_count_);
588 return !HasStackOverflow();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000589}
590
591
592bool AstNumbering::Renumber(Isolate* isolate, Zone* zone,
593 FunctionLiteral* function) {
594 AstNumberingVisitor visitor(isolate, zone);
595 return visitor.Renumber(function);
596}
597} // namespace internal
598} // namespace v8