From 908fc3c89c5dddd2fd83c9057179b49a29f7e542 Mon Sep 17 00:00:00 2001 From: Michael Lippautz Date: Mon, 6 Feb 2023 15:54:47 +0100 Subject: [PATCH] [heap] MinorMC: Split up PageMarkingItem further MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PageMarkingItem is used to process OLD_TO_NEW regular and typed slots sets. These slot sets are disjoint and do not share state that needs to be modified, i.e., can be processed in parallel. Rework PageMarkingItem to allows for parallel processing of slot sets on a single page. Remove the lock as it should not be necessary. The CL does not change the cost function for computing tasks. Drive-by: Optimize marking a single object on filtering. Bug: v8:12612 Change-Id: I6595d857d6df23d9d427bcdf5ecb3c9ea1c3c9ad Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4224451 Reviewed-by: Dominik Inführ Commit-Queue: Michael Lippautz Cr-Commit-Position: refs/heads/main@{#85694} --- src/heap/incremental-marking.cc | 14 +++++++++-- src/heap/mark-compact.cc | 41 ++++++++++++++++++++------------- src/heap/mark-compact.h | 8 ++++--- 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/src/heap/incremental-marking.cc b/src/heap/incremental-marking.cc index e220e722bc..484917c537 100644 --- a/src/heap/incremental-marking.cc +++ b/src/heap/incremental-marking.cc @@ -275,8 +275,18 @@ void IncrementalMarking::MarkRoots() { std::vector marking_items; RememberedSet::IterateMemoryChunks( - heap_, [&marking_items](MemoryChunk* chunk) { - marking_items.emplace_back(chunk); + heap(), [&marking_items](MemoryChunk* chunk) { + if (chunk->slot_set()) { + marking_items.emplace_back( + chunk, PageMarkingItem::SlotsType::kRegularSlots); + } else { + chunk->ReleaseInvalidatedSlots(); + } + + if (chunk->typed_slot_set()) { + marking_items.emplace_back(chunk, + PageMarkingItem::SlotsType::kTypedSlots); + } }); V8::GetCurrentPlatform() diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc index e1d3ffb6bf..e53441ea78 100644 --- a/src/heap/mark-compact.cc +++ b/src/heap/mark-compact.cc @@ -6097,9 +6097,7 @@ class YoungGenerationMarkingTask { marking_state_(heap->marking_state()), visitor_(isolate, marking_state_, marking_worklists_local()) {} - void MarkObject(Object object) { - if (!Heap::InYoungGeneration(object)) return; - HeapObject heap_object = HeapObject::cast(object); + void MarkYoungObject(HeapObject heap_object) { if (marking_state_->WhiteToGrey(heap_object)) { visitor_.Visit(heap_object); // Objects transition to black when visited. @@ -6130,13 +6128,17 @@ class YoungGenerationMarkingTask { }; void PageMarkingItem::Process(YoungGenerationMarkingTask* task) { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.gc"), "PageMarkingItem::Process"); base::MutexGuard guard(chunk_->mutex()); - MarkUntypedPointers(task); - MarkTypedPointers(task); + if (slots_type_ == SlotsType::kRegularSlots) { + MarkUntypedPointers(task); + } else { + MarkTypedPointers(task); + } } void PageMarkingItem::MarkUntypedPointers(YoungGenerationMarkingTask* task) { + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.gc"), + "PageMarkingItem::MarkUntypedPointers"); InvalidatedSlotsFilter filter = InvalidatedSlotsFilter::OldToNew( chunk_, InvalidatedSlotsFilter::LivenessCheck::kNo); RememberedSet::Iterate( @@ -6152,6 +6154,8 @@ void PageMarkingItem::MarkUntypedPointers(YoungGenerationMarkingTask* task) { } void PageMarkingItem::MarkTypedPointers(YoungGenerationMarkingTask* task) { + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.gc"), + "PageMarkingItem::MarkTypedPointers"); RememberedSet::IterateTyped( chunk_, [this, task](SlotType slot_type, Address slot) { return UpdateTypedSlotHelper::UpdateTypedSlot( @@ -6169,15 +6173,10 @@ V8_INLINE SlotCallbackResult PageMarkingItem::CheckAndMarkObject( std::is_same::value, "Only FullMaybeObjectSlot and MaybeObjectSlot are expected here"); MaybeObject object = *slot; - if (Heap::InYoungGeneration(object)) { - // Marking happens before flipping the young generation, so the object - // has to be in a to page. - DCHECK(Heap::InToPage(object)); - HeapObject heap_object; - bool success = object.GetHeapObject(&heap_object); - USE(success); - DCHECK(success); - task->MarkObject(heap_object); + HeapObject heap_object; + if (object.GetHeapObject(&heap_object) && + Heap::InYoungGeneration(heap_object)) { + task->MarkYoungObject(heap_object); return KEEP_SLOT; } return REMOVE_SLOT; @@ -6298,7 +6297,17 @@ void MinorMarkCompactCollector::MarkLiveObjectsInParallel( // Create items for each page. RememberedSet::IterateMemoryChunks( heap(), [&marking_items](MemoryChunk* chunk) { - marking_items.emplace_back(chunk); + if (chunk->slot_set()) { + marking_items.emplace_back( + chunk, PageMarkingItem::SlotsType::kRegularSlots); + } else { + chunk->ReleaseInvalidatedSlots(); + } + + if (chunk->typed_slot_set()) { + marking_items.emplace_back( + chunk, PageMarkingItem::SlotsType::kTypedSlots); + } }); } } diff --git a/src/heap/mark-compact.h b/src/heap/mark-compact.h index 0742a62971..c2c69af431 100644 --- a/src/heap/mark-compact.h +++ b/src/heap/mark-compact.h @@ -754,7 +754,10 @@ class MinorMarkCompactCollector final : public CollectorBase { class PageMarkingItem : public ParallelWorkItem { public: - explicit PageMarkingItem(MemoryChunk* chunk) : chunk_(chunk) {} + enum class SlotsType { kRegularSlots, kTypedSlots }; + + PageMarkingItem(MemoryChunk* chunk, SlotsType slots_type) + : chunk_(chunk), slots_type_(slots_type) {} ~PageMarkingItem() = default; void Process(YoungGenerationMarkingTask* task); @@ -763,14 +766,13 @@ class PageMarkingItem : public ParallelWorkItem { inline Heap* heap() { return chunk_->heap(); } void MarkUntypedPointers(YoungGenerationMarkingTask* task); - void MarkTypedPointers(YoungGenerationMarkingTask* task); - template V8_INLINE SlotCallbackResult CheckAndMarkObject(YoungGenerationMarkingTask* task, TSlot slot); MemoryChunk* chunk_; + const SlotsType slots_type_; }; enum class YoungMarkingJobType { kAtomic, kIncremental };