[heap] MinorMC: Split up PageMarkingItem further
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 <dinfuehr@chromium.org> Commit-Queue: Michael Lippautz <mlippautz@chromium.org> Cr-Commit-Position: refs/heads/main@{#85694}
This commit is contained in:
parent
2262ba881c
commit
908fc3c89c
@ -275,8 +275,18 @@ void IncrementalMarking::MarkRoots() {
|
|||||||
|
|
||||||
std::vector<PageMarkingItem> marking_items;
|
std::vector<PageMarkingItem> marking_items;
|
||||||
RememberedSet<OLD_TO_NEW>::IterateMemoryChunks(
|
RememberedSet<OLD_TO_NEW>::IterateMemoryChunks(
|
||||||
heap_, [&marking_items](MemoryChunk* chunk) {
|
heap(), [&marking_items](MemoryChunk* chunk) {
|
||||||
marking_items.emplace_back(chunk);
|
if (chunk->slot_set<OLD_TO_NEW>()) {
|
||||||
|
marking_items.emplace_back(
|
||||||
|
chunk, PageMarkingItem::SlotsType::kRegularSlots);
|
||||||
|
} else {
|
||||||
|
chunk->ReleaseInvalidatedSlots<OLD_TO_NEW>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chunk->typed_slot_set<OLD_TO_NEW>()) {
|
||||||
|
marking_items.emplace_back(chunk,
|
||||||
|
PageMarkingItem::SlotsType::kTypedSlots);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
V8::GetCurrentPlatform()
|
V8::GetCurrentPlatform()
|
||||||
|
@ -6097,9 +6097,7 @@ class YoungGenerationMarkingTask {
|
|||||||
marking_state_(heap->marking_state()),
|
marking_state_(heap->marking_state()),
|
||||||
visitor_(isolate, marking_state_, marking_worklists_local()) {}
|
visitor_(isolate, marking_state_, marking_worklists_local()) {}
|
||||||
|
|
||||||
void MarkObject(Object object) {
|
void MarkYoungObject(HeapObject heap_object) {
|
||||||
if (!Heap::InYoungGeneration(object)) return;
|
|
||||||
HeapObject heap_object = HeapObject::cast(object);
|
|
||||||
if (marking_state_->WhiteToGrey(heap_object)) {
|
if (marking_state_->WhiteToGrey(heap_object)) {
|
||||||
visitor_.Visit(heap_object);
|
visitor_.Visit(heap_object);
|
||||||
// Objects transition to black when visited.
|
// Objects transition to black when visited.
|
||||||
@ -6130,13 +6128,17 @@ class YoungGenerationMarkingTask {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void PageMarkingItem::Process(YoungGenerationMarkingTask* task) {
|
void PageMarkingItem::Process(YoungGenerationMarkingTask* task) {
|
||||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.gc"), "PageMarkingItem::Process");
|
|
||||||
base::MutexGuard guard(chunk_->mutex());
|
base::MutexGuard guard(chunk_->mutex());
|
||||||
MarkUntypedPointers(task);
|
if (slots_type_ == SlotsType::kRegularSlots) {
|
||||||
MarkTypedPointers(task);
|
MarkUntypedPointers(task);
|
||||||
|
} else {
|
||||||
|
MarkTypedPointers(task);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageMarkingItem::MarkUntypedPointers(YoungGenerationMarkingTask* task) {
|
void PageMarkingItem::MarkUntypedPointers(YoungGenerationMarkingTask* task) {
|
||||||
|
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.gc"),
|
||||||
|
"PageMarkingItem::MarkUntypedPointers");
|
||||||
InvalidatedSlotsFilter filter = InvalidatedSlotsFilter::OldToNew(
|
InvalidatedSlotsFilter filter = InvalidatedSlotsFilter::OldToNew(
|
||||||
chunk_, InvalidatedSlotsFilter::LivenessCheck::kNo);
|
chunk_, InvalidatedSlotsFilter::LivenessCheck::kNo);
|
||||||
RememberedSet<OLD_TO_NEW>::Iterate(
|
RememberedSet<OLD_TO_NEW>::Iterate(
|
||||||
@ -6152,6 +6154,8 @@ void PageMarkingItem::MarkUntypedPointers(YoungGenerationMarkingTask* task) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PageMarkingItem::MarkTypedPointers(YoungGenerationMarkingTask* task) {
|
void PageMarkingItem::MarkTypedPointers(YoungGenerationMarkingTask* task) {
|
||||||
|
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.gc"),
|
||||||
|
"PageMarkingItem::MarkTypedPointers");
|
||||||
RememberedSet<OLD_TO_NEW>::IterateTyped(
|
RememberedSet<OLD_TO_NEW>::IterateTyped(
|
||||||
chunk_, [this, task](SlotType slot_type, Address slot) {
|
chunk_, [this, task](SlotType slot_type, Address slot) {
|
||||||
return UpdateTypedSlotHelper::UpdateTypedSlot(
|
return UpdateTypedSlotHelper::UpdateTypedSlot(
|
||||||
@ -6169,15 +6173,10 @@ V8_INLINE SlotCallbackResult PageMarkingItem::CheckAndMarkObject(
|
|||||||
std::is_same<TSlot, MaybeObjectSlot>::value,
|
std::is_same<TSlot, MaybeObjectSlot>::value,
|
||||||
"Only FullMaybeObjectSlot and MaybeObjectSlot are expected here");
|
"Only FullMaybeObjectSlot and MaybeObjectSlot are expected here");
|
||||||
MaybeObject object = *slot;
|
MaybeObject object = *slot;
|
||||||
if (Heap::InYoungGeneration(object)) {
|
HeapObject heap_object;
|
||||||
// Marking happens before flipping the young generation, so the object
|
if (object.GetHeapObject(&heap_object) &&
|
||||||
// has to be in a to page.
|
Heap::InYoungGeneration(heap_object)) {
|
||||||
DCHECK(Heap::InToPage(object));
|
task->MarkYoungObject(heap_object);
|
||||||
HeapObject heap_object;
|
|
||||||
bool success = object.GetHeapObject(&heap_object);
|
|
||||||
USE(success);
|
|
||||||
DCHECK(success);
|
|
||||||
task->MarkObject(heap_object);
|
|
||||||
return KEEP_SLOT;
|
return KEEP_SLOT;
|
||||||
}
|
}
|
||||||
return REMOVE_SLOT;
|
return REMOVE_SLOT;
|
||||||
@ -6298,7 +6297,17 @@ void MinorMarkCompactCollector::MarkLiveObjectsInParallel(
|
|||||||
// Create items for each page.
|
// Create items for each page.
|
||||||
RememberedSet<OLD_TO_NEW>::IterateMemoryChunks(
|
RememberedSet<OLD_TO_NEW>::IterateMemoryChunks(
|
||||||
heap(), [&marking_items](MemoryChunk* chunk) {
|
heap(), [&marking_items](MemoryChunk* chunk) {
|
||||||
marking_items.emplace_back(chunk);
|
if (chunk->slot_set<OLD_TO_NEW>()) {
|
||||||
|
marking_items.emplace_back(
|
||||||
|
chunk, PageMarkingItem::SlotsType::kRegularSlots);
|
||||||
|
} else {
|
||||||
|
chunk->ReleaseInvalidatedSlots<OLD_TO_NEW>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chunk->typed_slot_set<OLD_TO_NEW>()) {
|
||||||
|
marking_items.emplace_back(
|
||||||
|
chunk, PageMarkingItem::SlotsType::kTypedSlots);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -754,7 +754,10 @@ class MinorMarkCompactCollector final : public CollectorBase {
|
|||||||
|
|
||||||
class PageMarkingItem : public ParallelWorkItem {
|
class PageMarkingItem : public ParallelWorkItem {
|
||||||
public:
|
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;
|
~PageMarkingItem() = default;
|
||||||
|
|
||||||
void Process(YoungGenerationMarkingTask* task);
|
void Process(YoungGenerationMarkingTask* task);
|
||||||
@ -763,14 +766,13 @@ class PageMarkingItem : public ParallelWorkItem {
|
|||||||
inline Heap* heap() { return chunk_->heap(); }
|
inline Heap* heap() { return chunk_->heap(); }
|
||||||
|
|
||||||
void MarkUntypedPointers(YoungGenerationMarkingTask* task);
|
void MarkUntypedPointers(YoungGenerationMarkingTask* task);
|
||||||
|
|
||||||
void MarkTypedPointers(YoungGenerationMarkingTask* task);
|
void MarkTypedPointers(YoungGenerationMarkingTask* task);
|
||||||
|
|
||||||
template <typename TSlot>
|
template <typename TSlot>
|
||||||
V8_INLINE SlotCallbackResult
|
V8_INLINE SlotCallbackResult
|
||||||
CheckAndMarkObject(YoungGenerationMarkingTask* task, TSlot slot);
|
CheckAndMarkObject(YoungGenerationMarkingTask* task, TSlot slot);
|
||||||
|
|
||||||
MemoryChunk* chunk_;
|
MemoryChunk* chunk_;
|
||||||
|
const SlotsType slots_type_;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class YoungMarkingJobType { kAtomic, kIncremental };
|
enum class YoungMarkingJobType { kAtomic, kIncremental };
|
||||||
|
Loading…
Reference in New Issue
Block a user