Commit 19bc589d authored by Dominik Inführ's avatar Dominik Inführ Committed by V8 LUCI CQ

[heap] Keep OLD_TO_SHARED slots across GCs

So far all OLD_TO_SHARED slots were deleted after a shared GC. The
remembered set was rebuilt in the next shared GC from scratch. This CL
changes this behavior to only remove slots that don't point into the
shared heap anymore.

We still need to remove the full OLD_TO_SHARED slot set for young
generation pages though. During a shared GC we use the OLD_TO_SHARED
remembered set to cache references into the shared heap even for
pages in the young generation to avoid the second new space object
iteration.

Bug: v8:11708
Change-Id: If92fca25e8fe7e7bf5fc5562c974b0d4c121cb02
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3790967
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82078}
parent 9a7e151f
...@@ -3579,6 +3579,26 @@ static inline void UpdateSlot(PtrComprCageBase cage_base, TSlot slot) { ...@@ -3579,6 +3579,26 @@ static inline void UpdateSlot(PtrComprCageBase cage_base, TSlot slot) {
} }
} }
static inline SlotCallbackResult UpdateOldToSharedSlot(
PtrComprCageBase cage_base, MaybeObjectSlot slot) {
MaybeObject obj = slot.Relaxed_Load(cage_base);
HeapObject heap_obj;
if (obj.GetHeapObject(&heap_obj)) {
if (obj.IsWeak()) {
UpdateSlot<AccessMode::NON_ATOMIC, HeapObjectReferenceType::WEAK>(
cage_base, slot, obj, heap_obj);
} else {
UpdateSlot<AccessMode::NON_ATOMIC, HeapObjectReferenceType::STRONG>(
cage_base, slot, obj, heap_obj);
}
return heap_obj.InSharedWritableHeap() ? KEEP_SLOT : REMOVE_SLOT;
} else {
return REMOVE_SLOT;
}
}
template <AccessMode access_mode, typename TSlot> template <AccessMode access_mode, typename TSlot>
static inline void UpdateStrongSlot(PtrComprCageBase cage_base, TSlot slot) { static inline void UpdateStrongSlot(PtrComprCageBase cage_base, TSlot slot) {
typename TSlot::TObject obj = slot.Relaxed_Load(cage_base); typename TSlot::TObject obj = slot.Relaxed_Load(cage_base);
...@@ -3590,6 +3610,20 @@ static inline void UpdateStrongSlot(PtrComprCageBase cage_base, TSlot slot) { ...@@ -3590,6 +3610,20 @@ static inline void UpdateStrongSlot(PtrComprCageBase cage_base, TSlot slot) {
} }
} }
static inline SlotCallbackResult UpdateStrongOldToSharedSlot(
PtrComprCageBase cage_base, FullMaybeObjectSlot slot) {
MaybeObject obj = slot.Relaxed_Load(cage_base);
DCHECK(!HAS_WEAK_HEAP_OBJECT_TAG(obj.ptr()));
HeapObject heap_obj;
if (obj.GetHeapObject(&heap_obj)) {
UpdateSlot<AccessMode::NON_ATOMIC, HeapObjectReferenceType::STRONG>(
cage_base, slot, obj, heap_obj);
return heap_obj.InSharedWritableHeap() ? KEEP_SLOT : REMOVE_SLOT;
}
return REMOVE_SLOT;
}
template <AccessMode access_mode> template <AccessMode access_mode>
static inline void UpdateStrongCodeSlot(HeapObject host, static inline void UpdateStrongCodeSlot(HeapObject host,
PtrComprCageBase cage_base, PtrComprCageBase cage_base,
...@@ -5003,12 +5037,12 @@ void MarkCompactCollector::UpdatePointersInClientHeap(Isolate* client) { ...@@ -5003,12 +5037,12 @@ void MarkCompactCollector::UpdatePointersInClientHeap(Isolate* client) {
chunk, chunk,
[cage_base, &filter](MaybeObjectSlot slot) { [cage_base, &filter](MaybeObjectSlot slot) {
if (!filter.IsValid(slot.address())) return REMOVE_SLOT; if (!filter.IsValid(slot.address())) return REMOVE_SLOT;
UpdateSlot<AccessMode::NON_ATOMIC>(cage_base, slot); return UpdateOldToSharedSlot(cage_base, slot);
return REMOVE_SLOT;
}, },
SlotSet::FREE_EMPTY_BUCKETS); SlotSet::FREE_EMPTY_BUCKETS);
chunk->ReleaseInvalidatedSlots<OLD_TO_SHARED>(); chunk->ReleaseInvalidatedSlots<OLD_TO_SHARED>();
if (chunk->InYoungGeneration()) chunk->ReleaseSlotSet<OLD_TO_SHARED>();
RememberedSet<OLD_TO_SHARED>::IterateTyped(chunk, [this](SlotType slot_type, RememberedSet<OLD_TO_SHARED>::IterateTyped(chunk, [this](SlotType slot_type,
Address slot) { Address slot) {
...@@ -5017,10 +5051,10 @@ void MarkCompactCollector::UpdatePointersInClientHeap(Isolate* client) { ...@@ -5017,10 +5051,10 @@ void MarkCompactCollector::UpdatePointersInClientHeap(Isolate* client) {
PtrComprCageBase cage_base = heap_->isolate(); PtrComprCageBase cage_base = heap_->isolate();
return UpdateTypedSlotHelper::UpdateTypedSlot( return UpdateTypedSlotHelper::UpdateTypedSlot(
heap_, slot_type, slot, [cage_base](FullMaybeObjectSlot slot) { heap_, slot_type, slot, [cage_base](FullMaybeObjectSlot slot) {
UpdateStrongSlot<AccessMode::NON_ATOMIC>(cage_base, slot); return UpdateStrongOldToSharedSlot(cage_base, slot);
return REMOVE_SLOT;
}); });
}); });
if (chunk->InYoungGeneration()) chunk->ReleaseTypedSlotSet<OLD_TO_SHARED>();
} }
#ifdef VERIFY_HEAP #ifdef VERIFY_HEAP
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment