Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/ast/ast-numbering.h" | 5 #include "src/ast/ast-numbering.h" |
| 6 | 6 |
| 7 #include "src/ast/ast.h" | 7 #include "src/ast/ast.h" |
| 8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| 11 namespace internal { | 11 namespace internal { |
| 12 | 12 |
| 13 class AstNumberingVisitor final : public AstVisitor { | 13 class AstNumberingVisitor final : public AstVisitor { |
| 14 public: | 14 public: |
| 15 AstNumberingVisitor(Isolate* isolate, Zone* zone) | 15 AstNumberingVisitor(Isolate* isolate, Zone* zone) |
| 16 : AstVisitor(), | 16 : AstVisitor(), |
| 17 isolate_(isolate), | 17 isolate_(isolate), |
| 18 zone_(zone), | 18 zone_(zone), |
| 19 next_id_(BailoutId::FirstUsable().ToInt()), | 19 next_id_(BailoutId::FirstUsable().ToInt()), |
| 20 yield_count_(0), | |
| 20 properties_(zone), | 21 properties_(zone), |
| 21 slot_cache_(zone), | 22 slot_cache_(zone), |
| 22 dont_optimize_reason_(kNoReason) { | 23 dont_optimize_reason_(kNoReason) { |
| 23 InitializeAstVisitor(isolate); | 24 InitializeAstVisitor(isolate); |
| 24 } | 25 } |
| 25 | 26 |
| 26 bool Renumber(FunctionLiteral* node); | 27 bool Renumber(FunctionLiteral* node); |
| 27 | 28 |
| 28 private: | 29 private: |
| 29 // AST node visitor interface. | 30 // AST node visitor interface. |
| 30 #define DEFINE_VISIT(type) void Visit##type(type* node) override; | 31 #define DEFINE_VISIT(type) void Visit##type(type* node) override; |
| 31 AST_NODE_LIST(DEFINE_VISIT) | 32 AST_NODE_LIST(DEFINE_VISIT) |
| 32 #undef DEFINE_VISIT | 33 #undef DEFINE_VISIT |
| 33 | 34 |
| 34 bool Finish(FunctionLiteral* node); | |
| 35 | |
| 36 void VisitVariableProxyReference(VariableProxy* node); | 35 void VisitVariableProxyReference(VariableProxy* node); |
| 37 void VisitPropertyReference(Property* node); | 36 void VisitPropertyReference(Property* node); |
| 38 void VisitReference(Expression* expr); | 37 void VisitReference(Expression* expr); |
| 39 | 38 |
| 40 void VisitStatements(ZoneList<Statement*>* statements) override; | 39 void VisitStatements(ZoneList<Statement*>* statements) override; |
| 41 void VisitDeclarations(ZoneList<Declaration*>* declarations) override; | 40 void VisitDeclarations(ZoneList<Declaration*>* declarations) override; |
| 42 void VisitArguments(ZoneList<Expression*>* arguments); | 41 void VisitArguments(ZoneList<Expression*>* arguments); |
| 43 void VisitObjectLiteralProperty(ObjectLiteralProperty* property); | 42 void VisitObjectLiteralProperty(ObjectLiteralProperty* property); |
| 44 | 43 |
| 45 int ReserveIdRange(int n) { | 44 int ReserveIdRange(int n) { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 66 } | 65 } |
| 67 | 66 |
| 68 template <typename Node> | 67 template <typename Node> |
| 69 void ReserveFeedbackSlots(Node* node) { | 68 void ReserveFeedbackSlots(Node* node) { |
| 70 node->AssignFeedbackVectorSlots(isolate_, properties_.get_spec(), | 69 node->AssignFeedbackVectorSlots(isolate_, properties_.get_spec(), |
| 71 &slot_cache_); | 70 &slot_cache_); |
| 72 } | 71 } |
| 73 | 72 |
| 74 BailoutReason dont_optimize_reason() const { return dont_optimize_reason_; } | 73 BailoutReason dont_optimize_reason() const { return dont_optimize_reason_; } |
| 75 | 74 |
| 75 int GetAndResetYieldCount() { | |
| 76 int old_yield_count = yield_count_; | |
| 77 yield_count_ = 0; | |
| 78 return old_yield_count; | |
| 79 } | |
| 80 | |
| 81 void StoreAndUpdateYieldCount(IterationStatement* node, int old_yield_count) { | |
| 82 node->set_yield_count(yield_count_); | |
| 83 yield_count_ += old_yield_count; | |
| 84 } | |
| 85 | |
| 76 Isolate* isolate_; | 86 Isolate* isolate_; |
| 77 Zone* zone_; | 87 Zone* zone_; |
| 78 int next_id_; | 88 int next_id_; |
| 89 int yield_count_; | |
| 79 AstProperties properties_; | 90 AstProperties properties_; |
| 80 // The slot cache allows us to reuse certain feedback vector slots. | 91 // The slot cache allows us to reuse certain feedback vector slots. |
| 81 FeedbackVectorSlotCache slot_cache_; | 92 FeedbackVectorSlotCache slot_cache_; |
| 82 BailoutReason dont_optimize_reason_; | 93 BailoutReason dont_optimize_reason_; |
| 83 | 94 |
| 84 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); | 95 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); |
| 85 DISALLOW_COPY_AND_ASSIGN(AstNumberingVisitor); | 96 DISALLOW_COPY_AND_ASSIGN(AstNumberingVisitor); |
| 86 }; | 97 }; |
| 87 | 98 |
| 88 | 99 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 210 } | 221 } |
| 211 | 222 |
| 212 | 223 |
| 213 void AstNumberingVisitor::VisitReturnStatement(ReturnStatement* node) { | 224 void AstNumberingVisitor::VisitReturnStatement(ReturnStatement* node) { |
| 214 IncrementNodeCount(); | 225 IncrementNodeCount(); |
| 215 Visit(node->expression()); | 226 Visit(node->expression()); |
| 216 } | 227 } |
| 217 | 228 |
| 218 | 229 |
| 219 void AstNumberingVisitor::VisitYield(Yield* node) { | 230 void AstNumberingVisitor::VisitYield(Yield* node) { |
| 231 yield_count_++; | |
| 220 IncrementNodeCount(); | 232 IncrementNodeCount(); |
| 221 DisableOptimization(kYield); | 233 DisableOptimization(kYield); |
| 222 ReserveFeedbackSlots(node); | 234 ReserveFeedbackSlots(node); |
| 223 node->set_base_id(ReserveIdRange(Yield::num_ids())); | 235 node->set_base_id(ReserveIdRange(Yield::num_ids())); |
| 224 Visit(node->generator_object()); | 236 Visit(node->generator_object()); |
| 225 Visit(node->expression()); | 237 Visit(node->expression()); |
| 226 } | 238 } |
| 227 | 239 |
| 228 | 240 |
| 229 void AstNumberingVisitor::VisitThrow(Throw* node) { | 241 void AstNumberingVisitor::VisitThrow(Throw* node) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 277 node->set_base_id(ReserveIdRange(WithStatement::num_ids())); | 289 node->set_base_id(ReserveIdRange(WithStatement::num_ids())); |
| 278 Visit(node->expression()); | 290 Visit(node->expression()); |
| 279 Visit(node->statement()); | 291 Visit(node->statement()); |
| 280 } | 292 } |
| 281 | 293 |
| 282 | 294 |
| 283 void AstNumberingVisitor::VisitDoWhileStatement(DoWhileStatement* node) { | 295 void AstNumberingVisitor::VisitDoWhileStatement(DoWhileStatement* node) { |
| 284 IncrementNodeCount(); | 296 IncrementNodeCount(); |
| 285 DisableSelfOptimization(); | 297 DisableSelfOptimization(); |
| 286 node->set_base_id(ReserveIdRange(DoWhileStatement::num_ids())); | 298 node->set_base_id(ReserveIdRange(DoWhileStatement::num_ids())); |
| 299 int old_yield_count = GetAndResetYieldCount(); | |
| 287 Visit(node->body()); | 300 Visit(node->body()); |
| 288 Visit(node->cond()); | 301 Visit(node->cond()); |
| 302 StoreAndUpdateYieldCount(node, old_yield_count); | |
| 289 } | 303 } |
| 290 | 304 |
| 291 | 305 |
| 292 void AstNumberingVisitor::VisitWhileStatement(WhileStatement* node) { | 306 void AstNumberingVisitor::VisitWhileStatement(WhileStatement* node) { |
| 293 IncrementNodeCount(); | 307 IncrementNodeCount(); |
| 294 DisableSelfOptimization(); | 308 DisableSelfOptimization(); |
| 295 node->set_base_id(ReserveIdRange(WhileStatement::num_ids())); | 309 node->set_base_id(ReserveIdRange(WhileStatement::num_ids())); |
| 310 int old_yield_count = GetAndResetYieldCount(); | |
| 296 Visit(node->cond()); | 311 Visit(node->cond()); |
| 297 Visit(node->body()); | 312 Visit(node->body()); |
| 313 StoreAndUpdateYieldCount(node, old_yield_count); | |
| 298 } | 314 } |
| 299 | 315 |
| 300 | 316 |
| 301 void AstNumberingVisitor::VisitTryCatchStatement(TryCatchStatement* node) { | 317 void AstNumberingVisitor::VisitTryCatchStatement(TryCatchStatement* node) { |
| 302 IncrementNodeCount(); | 318 IncrementNodeCount(); |
| 303 DisableCrankshaft(kTryCatchStatement); | 319 DisableCrankshaft(kTryCatchStatement); |
| 304 Visit(node->try_block()); | 320 Visit(node->try_block()); |
| 305 Visit(node->catch_block()); | 321 Visit(node->catch_block()); |
| 306 } | 322 } |
| 307 | 323 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 370 | 386 |
| 371 void AstNumberingVisitor::VisitEmptyParentheses(EmptyParentheses* node) { | 387 void AstNumberingVisitor::VisitEmptyParentheses(EmptyParentheses* node) { |
| 372 UNREACHABLE(); | 388 UNREACHABLE(); |
| 373 } | 389 } |
| 374 | 390 |
| 375 | 391 |
| 376 void AstNumberingVisitor::VisitForInStatement(ForInStatement* node) { | 392 void AstNumberingVisitor::VisitForInStatement(ForInStatement* node) { |
| 377 IncrementNodeCount(); | 393 IncrementNodeCount(); |
| 378 DisableSelfOptimization(); | 394 DisableSelfOptimization(); |
| 379 node->set_base_id(ReserveIdRange(ForInStatement::num_ids())); | 395 node->set_base_id(ReserveIdRange(ForInStatement::num_ids())); |
| 396 Visit(node->enumerable()); // Not part of loop. | |
|
neis
2016/04/13 09:54:27
Here I'm changing the order of visits, for conveni
| |
| 397 int old_yield_count = GetAndResetYieldCount(); | |
| 380 Visit(node->each()); | 398 Visit(node->each()); |
| 381 Visit(node->enumerable()); | |
| 382 Visit(node->body()); | 399 Visit(node->body()); |
| 400 StoreAndUpdateYieldCount(node, old_yield_count); | |
| 383 ReserveFeedbackSlots(node); | 401 ReserveFeedbackSlots(node); |
| 384 } | 402 } |
| 385 | 403 |
| 386 | 404 |
| 387 void AstNumberingVisitor::VisitForOfStatement(ForOfStatement* node) { | 405 void AstNumberingVisitor::VisitForOfStatement(ForOfStatement* node) { |
| 388 IncrementNodeCount(); | 406 IncrementNodeCount(); |
| 389 DisableCrankshaft(kForOfStatement); | 407 DisableCrankshaft(kForOfStatement); |
| 390 node->set_base_id(ReserveIdRange(ForOfStatement::num_ids())); | 408 node->set_base_id(ReserveIdRange(ForOfStatement::num_ids())); |
| 391 Visit(node->assign_iterator()); | 409 Visit(node->assign_iterator()); // Not part of loop. |
| 410 int old_yield_count = GetAndResetYieldCount(); | |
| 392 Visit(node->next_result()); | 411 Visit(node->next_result()); |
| 393 Visit(node->result_done()); | 412 Visit(node->result_done()); |
| 394 Visit(node->assign_each()); | 413 Visit(node->assign_each()); |
| 395 Visit(node->body()); | 414 Visit(node->body()); |
| 415 StoreAndUpdateYieldCount(node, old_yield_count); | |
| 396 ReserveFeedbackSlots(node); | 416 ReserveFeedbackSlots(node); |
| 397 } | 417 } |
| 398 | 418 |
| 399 | 419 |
| 400 void AstNumberingVisitor::VisitConditional(Conditional* node) { | 420 void AstNumberingVisitor::VisitConditional(Conditional* node) { |
| 401 IncrementNodeCount(); | 421 IncrementNodeCount(); |
| 402 node->set_base_id(ReserveIdRange(Conditional::num_ids())); | 422 node->set_base_id(ReserveIdRange(Conditional::num_ids())); |
| 403 Visit(node->condition()); | 423 Visit(node->condition()); |
| 404 Visit(node->then_expression()); | 424 Visit(node->then_expression()); |
| 405 Visit(node->else_expression()); | 425 Visit(node->else_expression()); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 433 node->set_base_id(ReserveIdRange(CaseClause::num_ids())); | 453 node->set_base_id(ReserveIdRange(CaseClause::num_ids())); |
| 434 if (!node->is_default()) Visit(node->label()); | 454 if (!node->is_default()) Visit(node->label()); |
| 435 VisitStatements(node->statements()); | 455 VisitStatements(node->statements()); |
| 436 } | 456 } |
| 437 | 457 |
| 438 | 458 |
| 439 void AstNumberingVisitor::VisitForStatement(ForStatement* node) { | 459 void AstNumberingVisitor::VisitForStatement(ForStatement* node) { |
| 440 IncrementNodeCount(); | 460 IncrementNodeCount(); |
| 441 DisableSelfOptimization(); | 461 DisableSelfOptimization(); |
| 442 node->set_base_id(ReserveIdRange(ForStatement::num_ids())); | 462 node->set_base_id(ReserveIdRange(ForStatement::num_ids())); |
| 443 if (node->init() != NULL) Visit(node->init()); | 463 if (node->init() != NULL) Visit(node->init()); // Not part of loop. |
| 464 int old_yield_count = GetAndResetYieldCount(); | |
| 444 if (node->cond() != NULL) Visit(node->cond()); | 465 if (node->cond() != NULL) Visit(node->cond()); |
| 445 if (node->next() != NULL) Visit(node->next()); | 466 if (node->next() != NULL) Visit(node->next()); |
| 446 Visit(node->body()); | 467 Visit(node->body()); |
| 468 StoreAndUpdateYieldCount(node, old_yield_count); | |
| 447 } | 469 } |
| 448 | 470 |
| 449 | 471 |
| 450 void AstNumberingVisitor::VisitClassLiteral(ClassLiteral* node) { | 472 void AstNumberingVisitor::VisitClassLiteral(ClassLiteral* node) { |
| 451 IncrementNodeCount(); | 473 IncrementNodeCount(); |
| 452 DisableCrankshaft(kClassLiteral); | 474 DisableCrankshaft(kClassLiteral); |
| 453 node->set_base_id(ReserveIdRange(node->num_ids())); | 475 node->set_base_id(ReserveIdRange(node->num_ids())); |
| 454 if (node->extends()) Visit(node->extends()); | 476 if (node->extends()) Visit(node->extends()); |
| 455 if (node->constructor()) Visit(node->constructor()); | 477 if (node->constructor()) Visit(node->constructor()); |
| 456 if (node->class_variable_proxy()) { | 478 if (node->class_variable_proxy()) { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 547 | 569 |
| 548 | 570 |
| 549 void AstNumberingVisitor::VisitRewritableExpression( | 571 void AstNumberingVisitor::VisitRewritableExpression( |
| 550 RewritableExpression* node) { | 572 RewritableExpression* node) { |
| 551 IncrementNodeCount(); | 573 IncrementNodeCount(); |
| 552 node->set_base_id(ReserveIdRange(RewritableExpression::num_ids())); | 574 node->set_base_id(ReserveIdRange(RewritableExpression::num_ids())); |
| 553 Visit(node->expression()); | 575 Visit(node->expression()); |
| 554 } | 576 } |
| 555 | 577 |
| 556 | 578 |
| 557 bool AstNumberingVisitor::Finish(FunctionLiteral* node) { | |
| 558 node->set_ast_properties(&properties_); | |
| 559 node->set_dont_optimize_reason(dont_optimize_reason()); | |
| 560 return !HasStackOverflow(); | |
| 561 } | |
| 562 | |
| 563 | |
| 564 bool AstNumberingVisitor::Renumber(FunctionLiteral* node) { | 579 bool AstNumberingVisitor::Renumber(FunctionLiteral* node) { |
| 565 Scope* scope = node->scope(); | 580 Scope* scope = node->scope(); |
| 566 if (scope->new_target_var()) DisableCrankshaft(kSuperReference); | 581 if (scope->new_target_var()) DisableCrankshaft(kSuperReference); |
| 567 if (scope->calls_eval()) DisableOptimization(kFunctionCallsEval); | 582 if (scope->calls_eval()) DisableOptimization(kFunctionCallsEval); |
| 568 if (scope->arguments() != NULL && !scope->arguments()->IsStackAllocated()) { | 583 if (scope->arguments() != NULL && !scope->arguments()->IsStackAllocated()) { |
| 569 DisableCrankshaft(kContextAllocatedArguments); | 584 DisableCrankshaft(kContextAllocatedArguments); |
| 570 } | 585 } |
| 571 | 586 |
| 572 int rest_index; | 587 int rest_index; |
| 573 if (scope->rest_parameter(&rest_index)) { | 588 if (scope->rest_parameter(&rest_index)) { |
| 574 DisableCrankshaft(kRestParameter); | 589 DisableCrankshaft(kRestParameter); |
| 575 } | 590 } |
| 576 | 591 |
| 577 VisitDeclarations(scope->declarations()); | 592 VisitDeclarations(scope->declarations()); |
| 578 VisitStatements(node->body()); | 593 VisitStatements(node->body()); |
| 579 | 594 |
| 580 return Finish(node); | 595 node->set_ast_properties(&properties_); |
| 596 node->set_dont_optimize_reason(dont_optimize_reason()); | |
| 597 node->set_yield_count(yield_count_); | |
| 598 return !HasStackOverflow(); | |
| 581 } | 599 } |
| 582 | 600 |
| 583 | 601 |
| 584 bool AstNumbering::Renumber(Isolate* isolate, Zone* zone, | 602 bool AstNumbering::Renumber(Isolate* isolate, Zone* zone, |
| 585 FunctionLiteral* function) { | 603 FunctionLiteral* function) { |
| 586 AstNumberingVisitor visitor(isolate, zone); | 604 AstNumberingVisitor visitor(isolate, zone); |
| 587 return visitor.Renumber(function); | 605 return visitor.Renumber(function); |
| 588 } | 606 } |
| 589 } // namespace internal | 607 } // namespace internal |
| 590 } // namespace v8 | 608 } // namespace v8 |
| OLD | NEW |