Commit aba185a7 authored by Dominik Inführ's avatar Dominik Inführ Committed by Commit Bot

[heap] Remove slots when shrinking objects

Immediately remove recorded old-to-new slots when shrinking objects.
This operation needs to drain the store buffer, however the store buffer
is supposed to be removed anyway.

Also do not remove slots when left-trimming since this isn't needed for
correctness.

Bug: v8:9454
Change-Id: I751baf2dcd03c87aee9cb1ebd168e05bf373a738
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1762012Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63271}
parent fe7b0974
...@@ -2986,7 +2986,7 @@ FixedArrayBase Heap::LeftTrimFixedArray(FixedArrayBase object, ...@@ -2986,7 +2986,7 @@ FixedArrayBase Heap::LeftTrimFixedArray(FixedArrayBase object,
// debug mode which iterates through the heap), but to play safer // debug mode which iterates through the heap), but to play safer
// we still do it. // we still do it.
HeapObject filler = HeapObject filler =
CreateFillerObjectAt(old_start, bytes_to_trim, ClearRecordedSlots::kYes); CreateFillerObjectAt(old_start, bytes_to_trim, ClearRecordedSlots::kNo);
// Initialize header of the trimmed array. Since left trimming is only // Initialize header of the trimmed array. Since left trimming is only
// performed on pages which are not concurrently swept creating a filler // performed on pages which are not concurrently swept creating a filler
...@@ -2998,11 +2998,6 @@ FixedArrayBase Heap::LeftTrimFixedArray(FixedArrayBase object, ...@@ -2998,11 +2998,6 @@ FixedArrayBase Heap::LeftTrimFixedArray(FixedArrayBase object,
FixedArrayBase new_object = FixedArrayBase new_object =
FixedArrayBase::cast(HeapObject::FromAddress(new_start)); FixedArrayBase::cast(HeapObject::FromAddress(new_start));
// Remove recorded slots for the new map and length offset.
ClearRecordedSlot(new_object, new_object.RawField(0));
ClearRecordedSlot(new_object,
new_object.RawField(FixedArrayBase::kLengthOffset));
// Handle invalidated old-to-old slots. // Handle invalidated old-to-old slots.
if (incremental_marking()->IsCompacting() && if (incremental_marking()->IsCompacting() &&
MayContainRecordedSlots(new_object)) { MayContainRecordedSlots(new_object)) {
...@@ -3088,6 +3083,12 @@ void Heap::CreateFillerForArray(T object, int elements_to_trim, ...@@ -3088,6 +3083,12 @@ void Heap::CreateFillerForArray(T object, int elements_to_trim,
Address old_end = object.address() + old_size; Address old_end = object.address() + old_size;
Address new_end = old_end - bytes_to_trim; Address new_end = old_end - bytes_to_trim;
// Remove recorded old-to-new slots in right-trimmed area.
if (MayContainRecordedSlots(object)) {
int new_size = old_size - bytes_to_trim;
RemoveRecordedSlotsAfterObjectShrinking(object, new_size, old_size);
}
// Register the array as an object with invalidated old-to-old slots. We // Register the array as an object with invalidated old-to-old slots. We
// cannot use NotifyObjectLayoutChange as it would mark the array black, // cannot use NotifyObjectLayoutChange as it would mark the array black,
// which is not safe for left-trimming because left-trimming re-pushes // which is not safe for left-trimming because left-trimming re-pushes
...@@ -4143,6 +4144,18 @@ void Heap::VerifyCountersBeforeConcurrentSweeping() { ...@@ -4143,6 +4144,18 @@ void Heap::VerifyCountersBeforeConcurrentSweeping() {
} }
#endif #endif
void Heap::RemoveRecordedSlotsAfterObjectShrinking(HeapObject object,
int new_size, int old_size) {
DCHECK_LE(new_size, old_size);
if (new_size == old_size) return;
store_buffer()->MoveAllEntriesToRememberedSet();
MemoryChunk* chunk = MemoryChunk::FromHeapObject(object);
Address free_start = object.address() + new_size;
Address free_end = object.address() + old_size;
RememberedSet<OLD_TO_NEW>::RemoveRange(chunk, free_start, free_end,
SlotSet::KEEP_EMPTY_BUCKETS);
}
void Heap::ZapFromSpace() { void Heap::ZapFromSpace() {
if (!new_space_->IsFromSpaceCommitted()) return; if (!new_space_->IsFromSpaceCommitted()) return;
for (Page* page : PageRange(new_space_->from_space().first_page(), nullptr)) { for (Page* page : PageRange(new_space_->from_space().first_page(), nullptr)) {
......
...@@ -439,6 +439,8 @@ class Heap { ...@@ -439,6 +439,8 @@ class Heap {
V8_EXPORT_PRIVATE void RightTrimFixedArray(FixedArrayBase obj, V8_EXPORT_PRIVATE void RightTrimFixedArray(FixedArrayBase obj,
int elements_to_trim); int elements_to_trim);
void RightTrimWeakFixedArray(WeakFixedArray obj, int elements_to_trim); void RightTrimWeakFixedArray(WeakFixedArray obj, int elements_to_trim);
void RemoveRecordedSlotsAfterObjectShrinking(HeapObject object, int new_size,
int old_size);
// Converts the given boolean condition to JavaScript boolean value. // Converts the given boolean condition to JavaScript boolean value.
inline Oddball ToBoolean(bool condition); inline Oddball ToBoolean(bool condition);
......
...@@ -2820,7 +2820,9 @@ void MigrateFastToFast(Isolate* isolate, Handle<JSObject> object, ...@@ -2820,7 +2820,9 @@ void MigrateFastToFast(Isolate* isolate, Handle<JSObject> object,
if (instance_size_delta > 0) { if (instance_size_delta > 0) {
Address address = object->address(); Address address = object->address();
heap->CreateFillerObjectAt(address + new_instance_size, instance_size_delta, heap->CreateFillerObjectAt(address + new_instance_size, instance_size_delta,
ClearRecordedSlots::kYes); ClearRecordedSlots::kNo);
heap->RemoveRecordedSlotsAfterObjectShrinking(*object, new_instance_size,
old_instance_size);
} }
// We are storing the new map using release store after creating a filler for // We are storing the new map using release store after creating a filler for
...@@ -2905,7 +2907,9 @@ void MigrateFastToSlow(Isolate* isolate, Handle<JSObject> object, ...@@ -2905,7 +2907,9 @@ void MigrateFastToSlow(Isolate* isolate, Handle<JSObject> object,
if (instance_size_delta > 0) { if (instance_size_delta > 0) {
heap->CreateFillerObjectAt(object->address() + new_instance_size, heap->CreateFillerObjectAt(object->address() + new_instance_size,
instance_size_delta, ClearRecordedSlots::kYes); instance_size_delta, ClearRecordedSlots::kNo);
heap->RemoveRecordedSlotsAfterObjectShrinking(*object, new_instance_size,
old_instance_size);
} }
// We are storing the new map using release store after creating a filler for // We are storing the new map using release store after creating a filler for
......
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