blob: dd6ce4a6027214f59a0c83a49f74535c66060b8b [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();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000223 ReserveFeedbackSlots(node);
224 node->set_base_id(ReserveIdRange(Yield::num_ids()));
225 Visit(node->generator_object());
226 Visit(node->expression());
227}
228
229
230void AstNumberingVisitor::VisitThrow(Throw* node) {
231 IncrementNodeCount();
232 node->set_base_id(ReserveIdRange(Throw::num_ids()));
233 Visit(node->exception());
234}
235
236
237void AstNumberingVisitor::VisitUnaryOperation(UnaryOperation* node) {
238 IncrementNodeCount();
239 node->set_base_id(ReserveIdRange(UnaryOperation::num_ids()));
240 Visit(node->expression());
241}
242
243
244void AstNumberingVisitor::VisitCountOperation(CountOperation* node) {
245 IncrementNodeCount();
246 node->set_base_id(ReserveIdRange(CountOperation::num_ids()));
247 Visit(node->expression());
248 ReserveFeedbackSlots(node);
249}
250
251
252void AstNumberingVisitor::VisitBlock(Block* node) {
253 IncrementNodeCount();
254 node->set_base_id(ReserveIdRange(Block::num_ids()));
255 if (node->scope() != NULL) VisitDeclarations(node->scope()->declarations());
256 VisitStatements(node->statements());
257}
258
259
260void AstNumberingVisitor::VisitFunctionDeclaration(FunctionDeclaration* node) {
261 IncrementNodeCount();
262 VisitVariableProxy(node->proxy());
263 VisitFunctionLiteral(node->fun());
264}
265
266
267void AstNumberingVisitor::VisitCallRuntime(CallRuntime* node) {
268 IncrementNodeCount();
269 ReserveFeedbackSlots(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000270 node->set_base_id(ReserveIdRange(CallRuntime::num_ids()));
271 VisitArguments(node->arguments());
272}
273
274
275void AstNumberingVisitor::VisitWithStatement(WithStatement* node) {
276 IncrementNodeCount();
277 DisableCrankshaft(kWithStatement);
278 node->set_base_id(ReserveIdRange(WithStatement::num_ids()));
279 Visit(node->expression());
280 Visit(node->statement());
281}
282
283
284void AstNumberingVisitor::VisitDoWhileStatement(DoWhileStatement* node) {
285 IncrementNodeCount();
286 DisableSelfOptimization();
287 node->set_base_id(ReserveIdRange(DoWhileStatement::num_ids()));
Ben Murdochc5610432016-08-08 18:44:38 +0100288 node->set_first_yield_id(yield_count_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000289 Visit(node->body());
290 Visit(node->cond());
Ben Murdochc5610432016-08-08 18:44:38 +0100291 node->set_yield_count(yield_count_ - node->first_yield_id());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000292}
293
294
295void AstNumberingVisitor::VisitWhileStatement(WhileStatement* node) {
296 IncrementNodeCount();
297 DisableSelfOptimization();
298 node->set_base_id(ReserveIdRange(WhileStatement::num_ids()));
Ben Murdochc5610432016-08-08 18:44:38 +0100299 node->set_first_yield_id(yield_count_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000300 Visit(node->cond());
301 Visit(node->body());
Ben Murdochc5610432016-08-08 18:44:38 +0100302 node->set_yield_count(yield_count_ - node->first_yield_id());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000303}
304
305
306void AstNumberingVisitor::VisitTryCatchStatement(TryCatchStatement* node) {
307 IncrementNodeCount();
Ben Murdoch61f157c2016-09-16 13:49:30 +0100308 DisableCrankshaft(kTryCatchStatement);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000309 Visit(node->try_block());
310 Visit(node->catch_block());
311}
312
313
314void AstNumberingVisitor::VisitTryFinallyStatement(TryFinallyStatement* node) {
315 IncrementNodeCount();
Ben Murdoch61f157c2016-09-16 13:49:30 +0100316 DisableCrankshaft(kTryFinallyStatement);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000317 Visit(node->try_block());
318 Visit(node->finally_block());
319}
320
321
322void AstNumberingVisitor::VisitPropertyReference(Property* node) {
323 IncrementNodeCount();
324 node->set_base_id(ReserveIdRange(Property::num_ids()));
325 Visit(node->key());
326 Visit(node->obj());
327}
328
329
330void AstNumberingVisitor::VisitReference(Expression* expr) {
331 DCHECK(expr->IsProperty() || expr->IsVariableProxy());
332 if (expr->IsProperty()) {
333 VisitPropertyReference(expr->AsProperty());
334 } else {
335 VisitVariableProxyReference(expr->AsVariableProxy());
336 }
337}
338
339
340void AstNumberingVisitor::VisitProperty(Property* node) {
341 VisitPropertyReference(node);
342 ReserveFeedbackSlots(node);
343}
344
345
346void AstNumberingVisitor::VisitAssignment(Assignment* node) {
347 IncrementNodeCount();
348 node->set_base_id(ReserveIdRange(Assignment::num_ids()));
349
350 if (node->is_compound()) VisitBinaryOperation(node->binary_operation());
351 VisitReference(node->target());
352 Visit(node->value());
353 ReserveFeedbackSlots(node);
354}
355
356
357void AstNumberingVisitor::VisitBinaryOperation(BinaryOperation* node) {
358 IncrementNodeCount();
359 node->set_base_id(ReserveIdRange(BinaryOperation::num_ids()));
360 Visit(node->left());
361 Visit(node->right());
362}
363
364
365void AstNumberingVisitor::VisitCompareOperation(CompareOperation* node) {
366 IncrementNodeCount();
367 node->set_base_id(ReserveIdRange(CompareOperation::num_ids()));
368 Visit(node->left());
369 Visit(node->right());
370}
371
372
Ben Murdoch097c5b22016-05-18 11:27:45 +0100373void AstNumberingVisitor::VisitSpread(Spread* node) { UNREACHABLE(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000374
375
376void AstNumberingVisitor::VisitEmptyParentheses(EmptyParentheses* node) {
377 UNREACHABLE();
378}
379
380
381void AstNumberingVisitor::VisitForInStatement(ForInStatement* node) {
382 IncrementNodeCount();
383 DisableSelfOptimization();
384 node->set_base_id(ReserveIdRange(ForInStatement::num_ids()));
Ben Murdochc5610432016-08-08 18:44:38 +0100385 Visit(node->enumerable()); // Not part of loop.
386 node->set_first_yield_id(yield_count_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000387 Visit(node->each());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000388 Visit(node->body());
Ben Murdochc5610432016-08-08 18:44:38 +0100389 node->set_yield_count(yield_count_ - node->first_yield_id());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000390 ReserveFeedbackSlots(node);
391}
392
393
394void AstNumberingVisitor::VisitForOfStatement(ForOfStatement* node) {
395 IncrementNodeCount();
396 DisableCrankshaft(kForOfStatement);
397 node->set_base_id(ReserveIdRange(ForOfStatement::num_ids()));
Ben Murdochc5610432016-08-08 18:44:38 +0100398 Visit(node->assign_iterator()); // Not part of loop.
399 node->set_first_yield_id(yield_count_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000400 Visit(node->next_result());
401 Visit(node->result_done());
402 Visit(node->assign_each());
403 Visit(node->body());
Ben Murdochc5610432016-08-08 18:44:38 +0100404 node->set_yield_count(yield_count_ - node->first_yield_id());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000405 ReserveFeedbackSlots(node);
406}
407
408
409void AstNumberingVisitor::VisitConditional(Conditional* node) {
410 IncrementNodeCount();
411 node->set_base_id(ReserveIdRange(Conditional::num_ids()));
412 Visit(node->condition());
413 Visit(node->then_expression());
414 Visit(node->else_expression());
415}
416
417
418void AstNumberingVisitor::VisitIfStatement(IfStatement* node) {
419 IncrementNodeCount();
420 node->set_base_id(ReserveIdRange(IfStatement::num_ids()));
421 Visit(node->condition());
422 Visit(node->then_statement());
423 if (node->HasElseStatement()) {
424 Visit(node->else_statement());
425 }
426}
427
428
429void AstNumberingVisitor::VisitSwitchStatement(SwitchStatement* node) {
430 IncrementNodeCount();
431 node->set_base_id(ReserveIdRange(SwitchStatement::num_ids()));
432 Visit(node->tag());
433 ZoneList<CaseClause*>* cases = node->cases();
434 for (int i = 0; i < cases->length(); i++) {
435 VisitCaseClause(cases->at(i));
436 }
437}
438
439
440void AstNumberingVisitor::VisitCaseClause(CaseClause* node) {
441 IncrementNodeCount();
442 node->set_base_id(ReserveIdRange(CaseClause::num_ids()));
443 if (!node->is_default()) Visit(node->label());
444 VisitStatements(node->statements());
445}
446
447
448void AstNumberingVisitor::VisitForStatement(ForStatement* node) {
449 IncrementNodeCount();
450 DisableSelfOptimization();
451 node->set_base_id(ReserveIdRange(ForStatement::num_ids()));
Ben Murdochc5610432016-08-08 18:44:38 +0100452 if (node->init() != NULL) Visit(node->init()); // Not part of loop.
453 node->set_first_yield_id(yield_count_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000454 if (node->cond() != NULL) Visit(node->cond());
455 if (node->next() != NULL) Visit(node->next());
456 Visit(node->body());
Ben Murdochc5610432016-08-08 18:44:38 +0100457 node->set_yield_count(yield_count_ - node->first_yield_id());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000458}
459
460
461void AstNumberingVisitor::VisitClassLiteral(ClassLiteral* node) {
462 IncrementNodeCount();
463 DisableCrankshaft(kClassLiteral);
464 node->set_base_id(ReserveIdRange(node->num_ids()));
465 if (node->extends()) Visit(node->extends());
466 if (node->constructor()) Visit(node->constructor());
467 if (node->class_variable_proxy()) {
468 VisitVariableProxy(node->class_variable_proxy());
469 }
470 for (int i = 0; i < node->properties()->length(); i++) {
471 VisitObjectLiteralProperty(node->properties()->at(i));
472 }
473 ReserveFeedbackSlots(node);
474}
475
476
477void AstNumberingVisitor::VisitObjectLiteral(ObjectLiteral* node) {
478 IncrementNodeCount();
479 node->set_base_id(ReserveIdRange(node->num_ids()));
480 for (int i = 0; i < node->properties()->length(); i++) {
481 VisitObjectLiteralProperty(node->properties()->at(i));
482 }
483 node->BuildConstantProperties(isolate_);
484 // Mark all computed expressions that are bound to a key that
485 // is shadowed by a later occurrence of the same key. For the
486 // marked expressions, no store code will be is emitted.
487 node->CalculateEmitStore(zone_);
488 ReserveFeedbackSlots(node);
489}
490
491
492void AstNumberingVisitor::VisitObjectLiteralProperty(
493 ObjectLiteralProperty* node) {
494 if (node->is_computed_name()) DisableCrankshaft(kComputedPropertyName);
495 Visit(node->key());
496 Visit(node->value());
497}
498
499
500void AstNumberingVisitor::VisitArrayLiteral(ArrayLiteral* node) {
501 IncrementNodeCount();
502 node->set_base_id(ReserveIdRange(node->num_ids()));
503 for (int i = 0; i < node->values()->length(); i++) {
504 Visit(node->values()->at(i));
505 }
506 node->BuildConstantElements(isolate_);
507 ReserveFeedbackSlots(node);
508}
509
510
511void AstNumberingVisitor::VisitCall(Call* node) {
512 IncrementNodeCount();
513 ReserveFeedbackSlots(node);
514 node->set_base_id(ReserveIdRange(Call::num_ids()));
515 Visit(node->expression());
516 VisitArguments(node->arguments());
517}
518
519
520void AstNumberingVisitor::VisitCallNew(CallNew* node) {
521 IncrementNodeCount();
522 ReserveFeedbackSlots(node);
523 node->set_base_id(ReserveIdRange(CallNew::num_ids()));
524 Visit(node->expression());
525 VisitArguments(node->arguments());
526}
527
528
529void AstNumberingVisitor::VisitStatements(ZoneList<Statement*>* statements) {
530 if (statements == NULL) return;
531 for (int i = 0; i < statements->length(); i++) {
532 Visit(statements->at(i));
533 }
534}
535
536
537void AstNumberingVisitor::VisitDeclarations(
538 ZoneList<Declaration*>* declarations) {
539 for (int i = 0; i < declarations->length(); i++) {
540 Visit(declarations->at(i));
541 }
542}
543
544
545void AstNumberingVisitor::VisitArguments(ZoneList<Expression*>* arguments) {
546 for (int i = 0; i < arguments->length(); i++) {
547 Visit(arguments->at(i));
548 }
549}
550
551
552void AstNumberingVisitor::VisitFunctionLiteral(FunctionLiteral* node) {
553 IncrementNodeCount();
554 node->set_base_id(ReserveIdRange(FunctionLiteral::num_ids()));
555 // We don't recurse into the declarations or body of the function literal:
556 // you have to separately Renumber() each FunctionLiteral that you compile.
557}
558
559
Ben Murdoch097c5b22016-05-18 11:27:45 +0100560void AstNumberingVisitor::VisitRewritableExpression(
561 RewritableExpression* node) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000562 IncrementNodeCount();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100563 node->set_base_id(ReserveIdRange(RewritableExpression::num_ids()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000564 Visit(node->expression());
565}
566
567
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000568bool AstNumberingVisitor::Renumber(FunctionLiteral* node) {
569 Scope* scope = node->scope();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000570 if (scope->new_target_var()) DisableCrankshaft(kSuperReference);
571 if (scope->calls_eval()) DisableOptimization(kFunctionCallsEval);
572 if (scope->arguments() != NULL && !scope->arguments()->IsStackAllocated()) {
573 DisableCrankshaft(kContextAllocatedArguments);
574 }
575
576 int rest_index;
577 if (scope->rest_parameter(&rest_index)) {
578 DisableCrankshaft(kRestParameter);
579 }
580
Ben Murdoch61f157c2016-09-16 13:49:30 +0100581 if (IsGeneratorFunction(node->kind()) || IsAsyncFunction(node->kind())) {
582 // TODO(neis): We may want to allow Turbofan optimization here if
583 // --turbo-from-bytecode is set and we know that Ignition is used.
584 // Unfortunately we can't express that here.
585 DisableOptimization(kGenerator);
586 }
587
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000588 VisitDeclarations(scope->declarations());
589 VisitStatements(node->body());
590
Ben Murdochc5610432016-08-08 18:44:38 +0100591 node->set_ast_properties(&properties_);
592 node->set_dont_optimize_reason(dont_optimize_reason());
593 node->set_yield_count(yield_count_);
594 return !HasStackOverflow();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000595}
596
597
598bool AstNumbering::Renumber(Isolate* isolate, Zone* zone,
599 FunctionLiteral* function) {
600 AstNumberingVisitor visitor(isolate, zone);
601 return visitor.Renumber(function);
602}
603} // namespace internal
604} // namespace v8