[heap] Also remove OLD_TO_SHARED slots in trimmed memory

Slots in free memory need to be removed. After a GC the JS application can create additional free memory by either left- or right-trimming
of heap objects. The sweeper might discover memory that was freed
because of such operations.

In case the sweeper discovers free memory, there can't be any
recorded slots in it. Otherwise subsequent allocations might store
untagged values in those slots and the next deref would most
likely crash.

Remove OLD_TO_SHARED slots in freed memory when left-trimming, right-
trimming and for DeleteObjectPropertyFast.

Also full GC was right-trimming objects which now needs to remove
slots in OLD_TO_SHARED.

Bug: v8:11708
Change-Id: I5761336e103704929fbd455d74bdbb499ae23f61
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3905144
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83314}
This commit is contained in:
Dominik Inführ 2022-09-19 19:30:52 +02:00 committed by V8 LUCI CQ
parent c400af48b5
commit ec4b480e46
2 changed files with 10 additions and 0 deletions

View File

@ -3601,6 +3601,7 @@ void Heap::CreateFillerForArray(T object, int elements_to_trim,
if (MayContainRecordedSlots(object)) { if (MayContainRecordedSlots(object)) {
MemoryChunk* chunk = MemoryChunk::FromHeapObject(object); MemoryChunk* chunk = MemoryChunk::FromHeapObject(object);
DCHECK(!chunk->RegisteredObjectWithInvalidatedSlots<OLD_TO_NEW>(object)); DCHECK(!chunk->RegisteredObjectWithInvalidatedSlots<OLD_TO_NEW>(object));
DCHECK(!chunk->RegisteredObjectWithInvalidatedSlots<OLD_TO_SHARED>(object));
DCHECK(!chunk->RegisteredObjectWithInvalidatedSlots<OLD_TO_OLD>(object)); DCHECK(!chunk->RegisteredObjectWithInvalidatedSlots<OLD_TO_OLD>(object));
} }
#endif #endif
@ -6145,6 +6146,7 @@ void Heap::ClearRecordedSlot(HeapObject object, ObjectSlot slot) {
// No need to update old-to-old here since that remembered set is gone // No need to update old-to-old here since that remembered set is gone
// after a full GC and not re-recorded until sweeping is finished. // after a full GC and not re-recorded until sweeping is finished.
RememberedSet<OLD_TO_NEW>::Remove(page, slot.address()); RememberedSet<OLD_TO_NEW>::Remove(page, slot.address());
RememberedSet<OLD_TO_SHARED>::Remove(page, slot.address());
} }
} }
#endif #endif
@ -6175,6 +6177,7 @@ void Heap::VerifySlotRangeHasNoRecordedSlots(Address start, Address end) {
#ifndef V8_DISABLE_WRITE_BARRIERS #ifndef V8_DISABLE_WRITE_BARRIERS
Page* page = Page::FromAddress(start); Page* page = Page::FromAddress(start);
RememberedSet<OLD_TO_NEW>::CheckNoneInRange(page, start, end); RememberedSet<OLD_TO_NEW>::CheckNoneInRange(page, start, end);
RememberedSet<OLD_TO_SHARED>::CheckNoneInRange(page, start, end);
#endif #endif
} }
#endif #endif
@ -6189,6 +6192,8 @@ void Heap::ClearRecordedSlotRange(Address start, Address end) {
if (!page->SweepingDone()) { if (!page->SweepingDone()) {
RememberedSet<OLD_TO_NEW>::RemoveRange(page, start, end, RememberedSet<OLD_TO_NEW>::RemoveRange(page, start, end,
SlotSet::KEEP_EMPTY_BUCKETS); SlotSet::KEEP_EMPTY_BUCKETS);
RememberedSet<OLD_TO_SHARED>::RemoveRange(page, start, end,
SlotSet::KEEP_EMPTY_BUCKETS);
} }
} }
#endif #endif

View File

@ -3201,6 +3201,9 @@ void MarkCompactCollector::FlushBytecodeFromSFI(
RememberedSet<OLD_TO_NEW>::RemoveRange( RememberedSet<OLD_TO_NEW>::RemoveRange(
chunk, compiled_data_start, compiled_data_start + compiled_data_size, chunk, compiled_data_start, compiled_data_start + compiled_data_size,
SlotSet::FREE_EMPTY_BUCKETS); SlotSet::FREE_EMPTY_BUCKETS);
RememberedSet<OLD_TO_SHARED>::RemoveRange(
chunk, compiled_data_start, compiled_data_start + compiled_data_size,
SlotSet::FREE_EMPTY_BUCKETS);
RememberedSet<OLD_TO_OLD>::RemoveRange( RememberedSet<OLD_TO_OLD>::RemoveRange(
chunk, compiled_data_start, compiled_data_start + compiled_data_size, chunk, compiled_data_start, compiled_data_start + compiled_data_size,
SlotSet::FREE_EMPTY_BUCKETS); SlotSet::FREE_EMPTY_BUCKETS);
@ -3456,6 +3459,8 @@ void MarkCompactCollector::RightTrimDescriptorArray(DescriptorArray array,
MemoryChunk* chunk = MemoryChunk::FromHeapObject(array); MemoryChunk* chunk = MemoryChunk::FromHeapObject(array);
RememberedSet<OLD_TO_NEW>::RemoveRange(chunk, start, end, RememberedSet<OLD_TO_NEW>::RemoveRange(chunk, start, end,
SlotSet::FREE_EMPTY_BUCKETS); SlotSet::FREE_EMPTY_BUCKETS);
RememberedSet<OLD_TO_SHARED>::RemoveRange(chunk, start, end,
SlotSet::FREE_EMPTY_BUCKETS);
RememberedSet<OLD_TO_OLD>::RemoveRange(chunk, start, end, RememberedSet<OLD_TO_OLD>::RemoveRange(chunk, start, end,
SlotSet::FREE_EMPTY_BUCKETS); SlotSet::FREE_EMPTY_BUCKETS);
if (V8_COMPRESS_POINTERS_8GB_BOOL) { if (V8_COMPRESS_POINTERS_8GB_BOOL) {