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 |