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/heap/heap.h" | 5 #include "src/heap/heap.h" |
6 | 6 |
7 #include <unordered_map> | 7 #include <unordered_map> |
8 #include <unordered_set> | 8 #include <unordered_set> |
9 | 9 |
10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 | 547 |
548 ~PretenuringScope() { | 548 ~PretenuringScope() { |
549 delete heap_->global_pretenuring_feedback_; | 549 delete heap_->global_pretenuring_feedback_; |
550 heap_->global_pretenuring_feedback_ = nullptr; | 550 heap_->global_pretenuring_feedback_ = nullptr; |
551 } | 551 } |
552 | 552 |
553 private: | 553 private: |
554 Heap* heap_; | 554 Heap* heap_; |
555 }; | 555 }; |
556 | 556 |
| 557 namespace { |
| 558 inline bool MakePretenureDecision( |
| 559 AllocationSite* site, AllocationSite::PretenureDecision current_decision, |
| 560 double ratio, bool maximum_size_scavenge) { |
| 561 // Here we just allow state transitions from undecided or maybe tenure |
| 562 // to don't tenure, maybe tenure, or tenure. |
| 563 if ((current_decision == AllocationSite::kUndecided || |
| 564 current_decision == AllocationSite::kMaybeTenure)) { |
| 565 if (ratio >= AllocationSite::kPretenureRatio) { |
| 566 // We just transition into tenure state when the semi-space was at |
| 567 // maximum capacity. |
| 568 if (maximum_size_scavenge) { |
| 569 site->set_deopt_dependent_code(true); |
| 570 site->set_pretenure_decision(AllocationSite::kTenure); |
| 571 // Currently we just need to deopt when we make a state transition to |
| 572 // tenure. |
| 573 return true; |
| 574 } |
| 575 site->set_pretenure_decision(AllocationSite::kMaybeTenure); |
| 576 } else { |
| 577 site->set_pretenure_decision(AllocationSite::kDontTenure); |
| 578 } |
| 579 } |
| 580 return false; |
| 581 } |
| 582 |
| 583 inline bool DigestPretenuringFeedback(Isolate* isolate, AllocationSite* site, |
| 584 bool maximum_size_scavenge) { |
| 585 bool deopt = false; |
| 586 int create_count = site->memento_create_count(); |
| 587 int found_count = site->memento_found_count(); |
| 588 bool minimum_mementos_created = |
| 589 create_count >= AllocationSite::kPretenureMinimumCreated; |
| 590 double ratio = minimum_mementos_created || FLAG_trace_pretenuring_statistics |
| 591 ? static_cast<double>(found_count) / create_count |
| 592 : 0.0; |
| 593 AllocationSite::PretenureDecision current_decision = |
| 594 site->pretenure_decision(); |
| 595 |
| 596 if (minimum_mementos_created) { |
| 597 deopt = MakePretenureDecision(site, current_decision, ratio, |
| 598 maximum_size_scavenge); |
| 599 } |
| 600 |
| 601 if (FLAG_trace_pretenuring_statistics) { |
| 602 PrintIsolate(isolate, |
| 603 "pretenuring: AllocationSite(%p): (created, found, ratio) " |
| 604 "(%d, %d, %f) %s => %s\n", |
| 605 static_cast<void*>(site), create_count, found_count, ratio, |
| 606 site->PretenureDecisionName(current_decision), |
| 607 site->PretenureDecisionName(site->pretenure_decision())); |
| 608 } |
| 609 |
| 610 // Clear feedback calculation fields until the next gc. |
| 611 site->set_memento_found_count(0); |
| 612 site->set_memento_create_count(0); |
| 613 return deopt; |
| 614 } |
| 615 } // namespace |
557 | 616 |
558 void Heap::ProcessPretenuringFeedback() { | 617 void Heap::ProcessPretenuringFeedback() { |
559 bool trigger_deoptimization = false; | 618 bool trigger_deoptimization = false; |
560 if (FLAG_allocation_site_pretenuring) { | 619 if (FLAG_allocation_site_pretenuring) { |
561 int tenure_decisions = 0; | 620 int tenure_decisions = 0; |
562 int dont_tenure_decisions = 0; | 621 int dont_tenure_decisions = 0; |
563 int allocation_mementos_found = 0; | 622 int allocation_mementos_found = 0; |
564 int allocation_sites = 0; | 623 int allocation_sites = 0; |
565 int active_allocation_sites = 0; | 624 int active_allocation_sites = 0; |
566 | 625 |
567 AllocationSite* site = nullptr; | 626 AllocationSite* site = nullptr; |
568 | 627 |
569 // Step 1: Digest feedback for recorded allocation sites. | 628 // Step 1: Digest feedback for recorded allocation sites. |
570 bool maximum_size_scavenge = MaximumSizeScavenge(); | 629 bool maximum_size_scavenge = MaximumSizeScavenge(); |
571 for (base::HashMap::Entry* e = global_pretenuring_feedback_->Start(); | 630 for (base::HashMap::Entry* e = global_pretenuring_feedback_->Start(); |
572 e != nullptr; e = global_pretenuring_feedback_->Next(e)) { | 631 e != nullptr; e = global_pretenuring_feedback_->Next(e)) { |
573 allocation_sites++; | 632 allocation_sites++; |
574 site = reinterpret_cast<AllocationSite*>(e->key); | 633 site = reinterpret_cast<AllocationSite*>(e->key); |
575 int found_count = site->memento_found_count(); | 634 int found_count = site->memento_found_count(); |
576 // An entry in the storage does not imply that the count is > 0 because | 635 // An entry in the storage does not imply that the count is > 0 because |
577 // allocation sites might have been reset due to too many objects dying | 636 // allocation sites might have been reset due to too many objects dying |
578 // in old space. | 637 // in old space. |
579 if (found_count > 0) { | 638 if (found_count > 0) { |
580 DCHECK(site->IsAllocationSite()); | 639 DCHECK(site->IsAllocationSite()); |
581 active_allocation_sites++; | 640 active_allocation_sites++; |
582 allocation_mementos_found += found_count; | 641 allocation_mementos_found += found_count; |
583 if (site->DigestPretenuringFeedback(maximum_size_scavenge)) { | 642 if (DigestPretenuringFeedback(isolate_, site, maximum_size_scavenge)) { |
584 trigger_deoptimization = true; | 643 trigger_deoptimization = true; |
585 } | 644 } |
586 if (site->GetPretenureMode() == TENURED) { | 645 if (site->GetPretenureMode() == TENURED) { |
587 tenure_decisions++; | 646 tenure_decisions++; |
588 } else { | 647 } else { |
589 dont_tenure_decisions++; | 648 dont_tenure_decisions++; |
590 } | 649 } |
591 } | 650 } |
592 } | 651 } |
593 | 652 |
(...skipping 6125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6719 return dst == src && type == CODE_TYPE; | 6778 return dst == src && type == CODE_TYPE; |
6720 case MAP_SPACE: | 6779 case MAP_SPACE: |
6721 case LO_SPACE: | 6780 case LO_SPACE: |
6722 return false; | 6781 return false; |
6723 } | 6782 } |
6724 UNREACHABLE(); | 6783 UNREACHABLE(); |
6725 } | 6784 } |
6726 | 6785 |
6727 } // namespace internal | 6786 } // namespace internal |
6728 } // namespace v8 | 6787 } // namespace v8 |
OLD | NEW |