ast-numbering.cc 16.1 KB
Newer Older
1 2 3 4 5
// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/ast-numbering.h"
6 7

#include "src/ast.h"
8 9 10 11 12
#include "src/scopes.h"

namespace v8 {
namespace internal {

13
class 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()),
20
        properties_(zone),
21
        slot_cache_(zone),
22
        dont_optimize_reason_(kNoReason) {
23
    InitializeAstVisitor(isolate);
24 25
  }

26
  bool Renumber(FunctionLiteral* node);
27 28 29

 private:
// AST node visitor interface.
30
#define DEFINE_VISIT(type) void Visit##type(type* node) override;
31 32 33
  AST_NODE_LIST(DEFINE_VISIT)
#undef DEFINE_VISIT

34 35
  bool Finish(FunctionLiteral* node);

36 37 38 39
  void VisitVariableProxyReference(VariableProxy* node);
  void VisitPropertyReference(Property* node);
  void VisitReference(Expression* expr);

40 41
  void VisitStatements(ZoneList<Statement*>* statements) override;
  void VisitDeclarations(ZoneList<Declaration*>* declarations) override;
42 43 44 45 46 47 48 49 50
  void VisitArguments(ZoneList<Expression*>* arguments);
  void VisitObjectLiteralProperty(ObjectLiteralProperty* property);

  int ReserveIdRange(int n) {
    int tmp = next_id_;
    next_id_ += n;
    return tmp;
  }

51
  void IncrementNodeCount() { properties_.add_node_count(1); }
52
  void DisableSelfOptimization() {
53
    properties_.flags() |= AstProperties::kDontSelfOptimize;
54
  }
55 56 57 58
  void DisableOptimization(BailoutReason reason) {
    dont_optimize_reason_ = reason;
    DisableSelfOptimization();
  }
59 60
  void DisableCrankshaft(BailoutReason reason) {
    if (FLAG_turbo_shipping) {
61 62 63 64
      properties_.flags() |= AstProperties::kDontCrankshaft;
    } else {
      dont_optimize_reason_ = reason;
      DisableSelfOptimization();
65 66
    }
  }
67

68 69
  template <typename Node>
  void ReserveFeedbackSlots(Node* node) {
70
    node->AssignFeedbackVectorSlots(isolate_, properties_.get_spec(),
71
                                    &slot_cache_);
72 73
  }

74
  BailoutReason dont_optimize_reason() const { return dont_optimize_reason_; }
75

76
  Isolate* isolate_;
77
  Zone* zone_;
78
  int next_id_;
79
  AstProperties properties_;
80 81
  // The slot cache allows us to reuse certain feedback vector slots.
  FeedbackVectorSlotCache slot_cache_;
82
  BailoutReason dont_optimize_reason_;
83 84 85 86 87 88 89

  DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
  DISALLOW_COPY_AND_ASSIGN(AstNumberingVisitor);
};


void AstNumberingVisitor::VisitVariableDeclaration(VariableDeclaration* node) {
90
  IncrementNodeCount();
91 92 93 94 95
  VisitVariableProxy(node->proxy());
}


void AstNumberingVisitor::VisitExportDeclaration(ExportDeclaration* node) {
96
  IncrementNodeCount();
97
  DisableOptimization(kExportDeclaration);
98 99 100 101
  VisitVariableProxy(node->proxy());
}


102 103 104
void AstNumberingVisitor::VisitEmptyStatement(EmptyStatement* node) {
  IncrementNodeCount();
}
105 106


107 108 109 110 111 112 113
void AstNumberingVisitor::VisitSloppyBlockFunctionStatement(
    SloppyBlockFunctionStatement* node) {
  IncrementNodeCount();
  Visit(node->statement());
}


114 115 116
void AstNumberingVisitor::VisitContinueStatement(ContinueStatement* node) {
  IncrementNodeCount();
}
117 118


119 120 121
void AstNumberingVisitor::VisitBreakStatement(BreakStatement* node) {
  IncrementNodeCount();
}
122 123 124


void AstNumberingVisitor::VisitDebuggerStatement(DebuggerStatement* node) {
125
  IncrementNodeCount();
126
  DisableOptimization(kDebuggerStatement);
127 128 129 130 131 132
  node->set_base_id(ReserveIdRange(DebuggerStatement::num_ids()));
}


void AstNumberingVisitor::VisitNativeFunctionLiteral(
    NativeFunctionLiteral* node) {
133
  IncrementNodeCount();
134
  DisableOptimization(kNativeFunctionLiteral);
135 136 137 138
  node->set_base_id(ReserveIdRange(NativeFunctionLiteral::num_ids()));
}


139 140 141 142 143 144 145 146 147
void AstNumberingVisitor::VisitDoExpression(DoExpression* node) {
  IncrementNodeCount();
  DisableCrankshaft(kDoExpression);
  node->set_base_id(ReserveIdRange(DoExpression::num_ids()));
  Visit(node->block());
  Visit(node->result());
}


148
void AstNumberingVisitor::VisitLiteral(Literal* node) {
149
  IncrementNodeCount();
150 151 152 153 154
  node->set_base_id(ReserveIdRange(Literal::num_ids()));
}


void AstNumberingVisitor::VisitRegExpLiteral(RegExpLiteral* node) {
155
  IncrementNodeCount();
156 157 158 159
  node->set_base_id(ReserveIdRange(RegExpLiteral::num_ids()));
}


160
void AstNumberingVisitor::VisitVariableProxyReference(VariableProxy* node) {
161
  IncrementNodeCount();
162
  if (node->var()->IsLookupSlot()) {
163
    DisableCrankshaft(kReferenceToAVariableWhichRequiresDynamicLookup);
164
  }
165 166 167 168
  node->set_base_id(ReserveIdRange(VariableProxy::num_ids()));
}


169 170 171 172 173 174
void AstNumberingVisitor::VisitVariableProxy(VariableProxy* node) {
  VisitVariableProxyReference(node);
  ReserveFeedbackSlots(node);
}


175
void AstNumberingVisitor::VisitThisFunction(ThisFunction* node) {
176
  IncrementNodeCount();
177 178 179 180
  node->set_base_id(ReserveIdRange(ThisFunction::num_ids()));
}


181 182
void AstNumberingVisitor::VisitSuperPropertyReference(
    SuperPropertyReference* node) {
183
  IncrementNodeCount();
184
  DisableOptimization(kSuperReference);
185
  node->set_base_id(ReserveIdRange(SuperPropertyReference::num_ids()));
186
  Visit(node->this_var());
187
  Visit(node->home_object());
188 189 190
}


191 192 193 194 195 196 197 198 199 200
void AstNumberingVisitor::VisitSuperCallReference(SuperCallReference* node) {
  IncrementNodeCount();
  DisableOptimization(kSuperReference);
  node->set_base_id(ReserveIdRange(SuperCallReference::num_ids()));
  Visit(node->this_var());
  Visit(node->new_target_var());
  Visit(node->this_function_var());
}


201
void AstNumberingVisitor::VisitImportDeclaration(ImportDeclaration* node) {
202
  IncrementNodeCount();
203
  DisableOptimization(kImportDeclaration);
204 205 206 207 208
  VisitVariableProxy(node->proxy());
}


void AstNumberingVisitor::VisitExpressionStatement(ExpressionStatement* node) {
209
  IncrementNodeCount();
210 211 212 213 214
  Visit(node->expression());
}


void AstNumberingVisitor::VisitReturnStatement(ReturnStatement* node) {
215
  IncrementNodeCount();
216 217 218 219 220
  Visit(node->expression());
}


void AstNumberingVisitor::VisitYield(Yield* node) {
221
  IncrementNodeCount();
222
  DisableOptimization(kYield);
223
  ReserveFeedbackSlots(node);
224 225 226 227 228 229 230
  node->set_base_id(ReserveIdRange(Yield::num_ids()));
  Visit(node->generator_object());
  Visit(node->expression());
}


void AstNumberingVisitor::VisitThrow(Throw* node) {
231
  IncrementNodeCount();
232 233 234 235 236 237
  node->set_base_id(ReserveIdRange(Throw::num_ids()));
  Visit(node->exception());
}


void AstNumberingVisitor::VisitUnaryOperation(UnaryOperation* node) {
238
  IncrementNodeCount();
239 240 241 242 243 244
  node->set_base_id(ReserveIdRange(UnaryOperation::num_ids()));
  Visit(node->expression());
}


void AstNumberingVisitor::VisitCountOperation(CountOperation* node) {
245
  IncrementNodeCount();
246 247
  node->set_base_id(ReserveIdRange(CountOperation::num_ids()));
  Visit(node->expression());
248
  ReserveFeedbackSlots(node);
249 250 251 252
}


void AstNumberingVisitor::VisitBlock(Block* node) {
253
  IncrementNodeCount();
254 255 256 257 258 259 260
  node->set_base_id(ReserveIdRange(Block::num_ids()));
  if (node->scope() != NULL) VisitDeclarations(node->scope()->declarations());
  VisitStatements(node->statements());
}


void AstNumberingVisitor::VisitFunctionDeclaration(FunctionDeclaration* node) {
261
  IncrementNodeCount();
262 263 264 265 266 267
  VisitVariableProxy(node->proxy());
  VisitFunctionLiteral(node->fun());
}


void AstNumberingVisitor::VisitCallRuntime(CallRuntime* node) {
268
  IncrementNodeCount();
269
  ReserveFeedbackSlots(node);
270 271
  if (node->is_jsruntime()) {
    // Don't try to optimize JS runtime calls because we bailout on them.
272
    DisableOptimization(kCallToAJavaScriptRuntimeFunction);
273
  }
274 275 276 277 278 279
  node->set_base_id(ReserveIdRange(CallRuntime::num_ids()));
  VisitArguments(node->arguments());
}


void AstNumberingVisitor::VisitWithStatement(WithStatement* node) {
280
  IncrementNodeCount();
281
  DisableCrankshaft(kWithStatement);
282
  node->set_base_id(ReserveIdRange(WithStatement::num_ids()));
283 284 285 286 287 288
  Visit(node->expression());
  Visit(node->statement());
}


void AstNumberingVisitor::VisitDoWhileStatement(DoWhileStatement* node) {
289
  IncrementNodeCount();
290
  DisableSelfOptimization();
291 292 293 294 295 296 297
  node->set_base_id(ReserveIdRange(DoWhileStatement::num_ids()));
  Visit(node->body());
  Visit(node->cond());
}


void AstNumberingVisitor::VisitWhileStatement(WhileStatement* node) {
298
  IncrementNodeCount();
299
  DisableSelfOptimization();
300 301 302 303 304 305 306
  node->set_base_id(ReserveIdRange(WhileStatement::num_ids()));
  Visit(node->cond());
  Visit(node->body());
}


void AstNumberingVisitor::VisitTryCatchStatement(TryCatchStatement* node) {
307
  IncrementNodeCount();
308
  DisableOptimization(kTryCatchStatement);
309
  node->set_base_id(ReserveIdRange(TryCatchStatement::num_ids()));
310 311 312 313 314 315
  Visit(node->try_block());
  Visit(node->catch_block());
}


void AstNumberingVisitor::VisitTryFinallyStatement(TryFinallyStatement* node) {
316
  IncrementNodeCount();
317
  DisableOptimization(kTryFinallyStatement);
318
  node->set_base_id(ReserveIdRange(TryFinallyStatement::num_ids()));
319 320 321 322 323
  Visit(node->try_block());
  Visit(node->finally_block());
}


324
void AstNumberingVisitor::VisitPropertyReference(Property* node) {
325
  IncrementNodeCount();
326 327 328 329 330 331
  node->set_base_id(ReserveIdRange(Property::num_ids()));
  Visit(node->key());
  Visit(node->obj());
}


332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
void AstNumberingVisitor::VisitReference(Expression* expr) {
  DCHECK(expr->IsProperty() || expr->IsVariableProxy());
  if (expr->IsProperty()) {
    VisitPropertyReference(expr->AsProperty());
  } else {
    VisitVariableProxyReference(expr->AsVariableProxy());
  }
}


void AstNumberingVisitor::VisitProperty(Property* node) {
  VisitPropertyReference(node);
  ReserveFeedbackSlots(node);
}


348
void AstNumberingVisitor::VisitAssignment(Assignment* node) {
349
  IncrementNodeCount();
350 351
  node->set_base_id(ReserveIdRange(Assignment::num_ids()));
  if (node->is_compound()) VisitBinaryOperation(node->binary_operation());
352
  VisitReference(node->target());
353
  Visit(node->value());
354
  ReserveFeedbackSlots(node);
355 356 357 358
}


void AstNumberingVisitor::VisitBinaryOperation(BinaryOperation* node) {
359
  IncrementNodeCount();
360 361 362 363 364 365 366
  node->set_base_id(ReserveIdRange(BinaryOperation::num_ids()));
  Visit(node->left());
  Visit(node->right());
}


void AstNumberingVisitor::VisitCompareOperation(CompareOperation* node) {
367
  IncrementNodeCount();
368 369 370 371 372 373
  node->set_base_id(ReserveIdRange(CompareOperation::num_ids()));
  Visit(node->left());
  Visit(node->right());
}


arv's avatar
arv committed
374 375
void AstNumberingVisitor::VisitSpread(Spread* node) {
  IncrementNodeCount();
376
  DisableCrankshaft(kSpread);
arv's avatar
arv committed
377 378
  Visit(node->expression());
}
379 380


381 382 383 384 385
void AstNumberingVisitor::VisitEmptyParentheses(EmptyParentheses* node) {
  UNREACHABLE();
}


386
void AstNumberingVisitor::VisitForInStatement(ForInStatement* node) {
387
  IncrementNodeCount();
388
  DisableSelfOptimization();
389 390 391 392
  node->set_base_id(ReserveIdRange(ForInStatement::num_ids()));
  Visit(node->each());
  Visit(node->enumerable());
  Visit(node->body());
393
  ReserveFeedbackSlots(node);
394 395 396 397
}


void AstNumberingVisitor::VisitForOfStatement(ForOfStatement* node) {
398
  IncrementNodeCount();
399
  DisableCrankshaft(kForOfStatement);
400 401 402 403 404 405
  node->set_base_id(ReserveIdRange(ForOfStatement::num_ids()));
  Visit(node->assign_iterator());
  Visit(node->next_result());
  Visit(node->result_done());
  Visit(node->assign_each());
  Visit(node->body());
406
  ReserveFeedbackSlots(node);
407 408 409 410
}


void AstNumberingVisitor::VisitConditional(Conditional* node) {
411
  IncrementNodeCount();
412 413 414 415 416 417 418 419
  node->set_base_id(ReserveIdRange(Conditional::num_ids()));
  Visit(node->condition());
  Visit(node->then_expression());
  Visit(node->else_expression());
}


void AstNumberingVisitor::VisitIfStatement(IfStatement* node) {
420
  IncrementNodeCount();
421 422 423 424 425 426 427 428 429 430
  node->set_base_id(ReserveIdRange(IfStatement::num_ids()));
  Visit(node->condition());
  Visit(node->then_statement());
  if (node->HasElseStatement()) {
    Visit(node->else_statement());
  }
}


void AstNumberingVisitor::VisitSwitchStatement(SwitchStatement* node) {
431
  IncrementNodeCount();
432 433 434 435 436 437 438 439 440 441
  node->set_base_id(ReserveIdRange(SwitchStatement::num_ids()));
  Visit(node->tag());
  ZoneList<CaseClause*>* cases = node->cases();
  for (int i = 0; i < cases->length(); i++) {
    VisitCaseClause(cases->at(i));
  }
}


void AstNumberingVisitor::VisitCaseClause(CaseClause* node) {
442
  IncrementNodeCount();
443 444 445 446 447 448 449
  node->set_base_id(ReserveIdRange(CaseClause::num_ids()));
  if (!node->is_default()) Visit(node->label());
  VisitStatements(node->statements());
}


void AstNumberingVisitor::VisitForStatement(ForStatement* node) {
450
  IncrementNodeCount();
451
  DisableSelfOptimization();
452 453 454 455 456 457 458 459 460
  node->set_base_id(ReserveIdRange(ForStatement::num_ids()));
  if (node->init() != NULL) Visit(node->init());
  if (node->cond() != NULL) Visit(node->cond());
  if (node->next() != NULL) Visit(node->next());
  Visit(node->body());
}


void AstNumberingVisitor::VisitClassLiteral(ClassLiteral* node) {
461
  IncrementNodeCount();
462
  DisableCrankshaft(kClassLiteral);
463
  node->set_base_id(ReserveIdRange(node->num_ids()));
464 465
  if (node->extends()) Visit(node->extends());
  if (node->constructor()) Visit(node->constructor());
466 467 468
  if (node->class_variable_proxy()) {
    VisitVariableProxy(node->class_variable_proxy());
  }
469 470 471
  for (int i = 0; i < node->properties()->length(); i++) {
    VisitObjectLiteralProperty(node->properties()->at(i));
  }
472
  ReserveFeedbackSlots(node);
473 474 475 476
}


void AstNumberingVisitor::VisitObjectLiteral(ObjectLiteral* node) {
477
  IncrementNodeCount();
478
  node->set_base_id(ReserveIdRange(node->num_ids()));
479 480 481
  for (int i = 0; i < node->properties()->length(); i++) {
    VisitObjectLiteralProperty(node->properties()->at(i));
  }
482
  node->BuildConstantProperties(isolate_);
483 484 485
  // Mark all computed expressions that are bound to a key that
  // is shadowed by a later occurrence of the same key. For the
  // marked expressions, no store code will be is emitted.
486
  node->CalculateEmitStore(zone_);
487
  ReserveFeedbackSlots(node);
488 489 490 491 492
}


void AstNumberingVisitor::VisitObjectLiteralProperty(
    ObjectLiteralProperty* node) {
493
  if (node->is_computed_name()) DisableCrankshaft(kComputedPropertyName);
494 495 496 497 498 499
  Visit(node->key());
  Visit(node->value());
}


void AstNumberingVisitor::VisitArrayLiteral(ArrayLiteral* node) {
500
  IncrementNodeCount();
501 502 503 504
  node->set_base_id(ReserveIdRange(node->num_ids()));
  for (int i = 0; i < node->values()->length(); i++) {
    Visit(node->values()->at(i));
  }
505
  node->BuildConstantElements(isolate_);
506
  ReserveFeedbackSlots(node);
507 508 509 510
}


void AstNumberingVisitor::VisitCall(Call* node) {
511
  IncrementNodeCount();
512
  ReserveFeedbackSlots(node);
513 514 515 516 517 518 519
  node->set_base_id(ReserveIdRange(Call::num_ids()));
  Visit(node->expression());
  VisitArguments(node->arguments());
}


void AstNumberingVisitor::VisitCallNew(CallNew* node) {
520
  IncrementNodeCount();
521
  ReserveFeedbackSlots(node);
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551
  node->set_base_id(ReserveIdRange(CallNew::num_ids()));
  Visit(node->expression());
  VisitArguments(node->arguments());
}


void AstNumberingVisitor::VisitStatements(ZoneList<Statement*>* statements) {
  if (statements == NULL) return;
  for (int i = 0; i < statements->length(); i++) {
    Visit(statements->at(i));
  }
}


void AstNumberingVisitor::VisitDeclarations(
    ZoneList<Declaration*>* declarations) {
  for (int i = 0; i < declarations->length(); i++) {
    Visit(declarations->at(i));
  }
}


void AstNumberingVisitor::VisitArguments(ZoneList<Expression*>* arguments) {
  for (int i = 0; i < arguments->length(); i++) {
    Visit(arguments->at(i));
  }
}


void AstNumberingVisitor::VisitFunctionLiteral(FunctionLiteral* node) {
552
  IncrementNodeCount();
553 554 555 556 557 558
  node->set_base_id(ReserveIdRange(FunctionLiteral::num_ids()));
  // We don't recurse into the declarations or body of the function literal:
  // you have to separately Renumber() each FunctionLiteral that you compile.
}


559 560 561 562 563 564
bool AstNumberingVisitor::Finish(FunctionLiteral* node) {
  node->set_ast_properties(&properties_);
  node->set_dont_optimize_reason(dont_optimize_reason());
  return !HasStackOverflow();
}

565

566
bool AstNumberingVisitor::Renumber(FunctionLiteral* node) {
567
  Scope* scope = node->scope();
568 569

  if (scope->HasIllegalRedeclaration()) {
570
    Visit(scope->GetIllegalRedeclaration());
571
    DisableOptimization(kFunctionWithIllegalRedeclaration);
572 573
    return Finish(node);
  }
574
  if (scope->calls_eval()) DisableOptimization(kFunctionCallsEval);
575
  if (scope->arguments() != NULL && !scope->arguments()->IsStackAllocated()) {
576
    DisableCrankshaft(kContextAllocatedArguments);
577 578
  }

579 580
  VisitDeclarations(scope->declarations());
  VisitStatements(node->body());
581

582
  return Finish(node);
583 584 585
}


586 587 588
bool AstNumbering::Renumber(Isolate* isolate, Zone* zone,
                            FunctionLiteral* function) {
  AstNumberingVisitor visitor(isolate, zone);
589
  return visitor.Renumber(function);
590
}
591 592
}  // namespace internal
}  // namespace v8