Index: src/heap/mark-compact.cc |
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc |
index 2eb9a1b79195f3c38e9b2c1df6f5daf84dac66f1..c92e1b0015a1976a5a9f24fd2fc49b18376c201e 100644 |
--- a/src/heap/mark-compact.cc |
+++ b/src/heap/mark-compact.cc |
@@ -1834,41 +1834,48 @@ class MarkCompactCollector::EvacuateNewSpaceVisitor final |
base::HashMap* local_pretenuring_feedback_; |
}; |
+template <PageEvacuationMode mode> |
class MarkCompactCollector::EvacuateNewSpacePageVisitor final |
: public MarkCompactCollector::HeapObjectVisitor { |
public: |
- explicit EvacuateNewSpacePageVisitor(Heap* heap) |
- : heap_(heap), promoted_size_(0), semispace_copied_size_(0) {} |
- |
- static void MoveToOldSpace(Page* page, PagedSpace* owner) { |
- page->Unlink(); |
- Page* new_page = Page::ConvertNewToOld(page, owner); |
- new_page->SetFlag(Page::PAGE_NEW_OLD_PROMOTION); |
- } |
+ explicit EvacuateNewSpacePageVisitor( |
+ Heap* heap, base::HashMap* local_pretenuring_feedback) |
+ : heap_(heap), |
+ moved_bytes_(0), |
+ local_pretenuring_feedback_(local_pretenuring_feedback) {} |
- static void MoveToToSpace(Page* page) { |
- page->heap()->new_space()->MovePageFromSpaceToSpace(page); |
- page->SetFlag(Page::PAGE_NEW_NEW_PROMOTION); |
+ static void Move(Page* page) { |
+ switch (mode) { |
+ case NEW_TO_NEW: |
+ page->heap()->new_space()->MovePageFromSpaceToSpace(page); |
+ page->SetFlag(Page::PAGE_NEW_NEW_PROMOTION); |
+ break; |
+ case NEW_TO_OLD: { |
+ page->Unlink(); |
+ Page* new_page = Page::ConvertNewToOld(page); |
+ new_page->SetFlag(Page::PAGE_NEW_OLD_PROMOTION); |
+ break; |
+ } |
+ } |
} |
inline bool Visit(HeapObject* object) { |
- RecordMigratedSlotVisitor visitor(heap_->mark_compact_collector()); |
- object->IterateBodyFast(&visitor); |
- promoted_size_ += object->Size(); |
+ heap_->UpdateAllocationSite<Heap::kCached>(object, |
+ local_pretenuring_feedback_); |
+ if (mode == NEW_TO_OLD) { |
+ RecordMigratedSlotVisitor visitor(heap_->mark_compact_collector()); |
+ object->IterateBodyFast(&visitor); |
+ } |
return true; |
} |
- intptr_t promoted_size() { return promoted_size_; } |
- intptr_t semispace_copied_size() { return semispace_copied_size_; } |
- |
- void account_semispace_copied(intptr_t copied) { |
- semispace_copied_size_ += copied; |
- } |
+ intptr_t moved_bytes() { return moved_bytes_; } |
+ void account_moved_bytes(intptr_t bytes) { moved_bytes_ += bytes; } |
private: |
Heap* heap_; |
- intptr_t promoted_size_; |
- intptr_t semispace_copied_size_; |
+ intptr_t moved_bytes_; |
+ base::HashMap* local_pretenuring_feedback_; |
}; |
class MarkCompactCollector::EvacuateOldSpaceVisitor final |
@@ -2925,7 +2932,11 @@ class MarkCompactCollector::Evacuator : public Malloced { |
local_pretenuring_feedback_(kInitialLocalPretenuringFeedbackCapacity), |
new_space_visitor_(collector->heap(), &compaction_spaces_, |
&local_pretenuring_feedback_), |
- new_space_page_visitor(collector->heap()), |
+ new_to_new_page_visitor_(collector->heap(), |
+ &local_pretenuring_feedback_), |
+ new_to_old_page_visitor_(collector->heap(), |
+ &local_pretenuring_feedback_), |
+ |
old_space_visitor_(collector->heap(), &compaction_spaces_), |
duration_(0.0), |
bytes_compacted_(0) {} |
@@ -2956,7 +2967,10 @@ class MarkCompactCollector::Evacuator : public Malloced { |
// Visitors for the corresponding spaces. |
EvacuateNewSpaceVisitor new_space_visitor_; |
- EvacuateNewSpacePageVisitor new_space_page_visitor; |
+ EvacuateNewSpacePageVisitor<PageEvacuationMode::NEW_TO_NEW> |
+ new_to_new_page_visitor_; |
+ EvacuateNewSpacePageVisitor<PageEvacuationMode::NEW_TO_OLD> |
+ new_to_old_page_visitor_; |
EvacuateOldSpaceVisitor old_space_visitor_; |
// Book keeping info. |
@@ -2977,20 +2991,23 @@ bool MarkCompactCollector::Evacuator::EvacuatePage(Page* page) { |
case kObjectsNewToOld: |
success = collector_->VisitLiveObjects(page, &new_space_visitor_, |
kClearMarkbits); |
+ DCHECK(success); |
ArrayBufferTracker::ProcessBuffers( |
page, ArrayBufferTracker::kUpdateForwardedRemoveOthers); |
- DCHECK(success); |
break; |
case kPageNewToOld: |
- success = collector_->VisitLiveObjects(page, &new_space_page_visitor, |
+ success = collector_->VisitLiveObjects(page, &new_to_old_page_visitor_, |
kKeepMarking); |
- // ArrayBufferTracker will be updated during sweeping. |
DCHECK(success); |
+ new_to_old_page_visitor_.account_moved_bytes(page->LiveBytes()); |
+ // ArrayBufferTracker will be updated during sweeping. |
break; |
case kPageNewToNew: |
- new_space_page_visitor.account_semispace_copied(page->LiveBytes()); |
+ success = collector_->VisitLiveObjects(page, &new_to_new_page_visitor_, |
+ kKeepMarking); |
+ DCHECK(success); |
+ new_to_new_page_visitor_.account_moved_bytes(page->LiveBytes()); |
// ArrayBufferTracker will be updated during sweeping. |
- success = true; |
break; |
case kObjectsOldToOld: |
success = collector_->VisitLiveObjects(page, &old_space_visitor_, |
@@ -3015,8 +3032,6 @@ bool MarkCompactCollector::Evacuator::EvacuatePage(Page* page) { |
page, ArrayBufferTracker::kUpdateForwardedRemoveOthers); |
} |
break; |
- default: |
- UNREACHABLE(); |
} |
} |
ReportCompactionProgress(evacuation_time, saved_live_bytes); |
@@ -3042,15 +3057,15 @@ void MarkCompactCollector::Evacuator::Finalize() { |
compaction_spaces_.Get(CODE_SPACE)); |
heap()->tracer()->AddCompactionEvent(duration_, bytes_compacted_); |
heap()->IncrementPromotedObjectsSize(new_space_visitor_.promoted_size() + |
- new_space_page_visitor.promoted_size()); |
+ new_to_old_page_visitor_.moved_bytes()); |
heap()->IncrementSemiSpaceCopiedObjectSize( |
new_space_visitor_.semispace_copied_size() + |
- new_space_page_visitor.semispace_copied_size()); |
+ new_to_new_page_visitor_.moved_bytes()); |
heap()->IncrementYoungSurvivorsCounter( |
new_space_visitor_.promoted_size() + |
new_space_visitor_.semispace_copied_size() + |
- new_space_page_visitor.promoted_size() + |
- new_space_page_visitor.semispace_copied_size()); |
+ new_to_old_page_visitor_.moved_bytes() + |
+ new_to_new_page_visitor_.moved_bytes()); |
heap()->MergeAllocationSitePretenuringFeedback(local_pretenuring_feedback_); |
} |
@@ -3147,9 +3162,9 @@ void MarkCompactCollector::EvacuatePagesInParallel() { |
(page->LiveBytes() > Evacuator::PageEvacuationThreshold()) && |
!page->Contains(age_mark)) { |
if (page->IsFlagSet(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK)) { |
- EvacuateNewSpacePageVisitor::MoveToOldSpace(page, heap()->old_space()); |
+ EvacuateNewSpacePageVisitor<NEW_TO_OLD>::Move(page); |
} else { |
- EvacuateNewSpacePageVisitor::MoveToToSpace(page); |
+ EvacuateNewSpacePageVisitor<NEW_TO_NEW>::Move(page); |
} |
} |