diff --git a/src/heap/store-buffer.cc b/src/heap/store-buffer.cc index 591d28fe9f..6c8a457af8 100644 --- a/src/heap/store-buffer.cc +++ b/src/heap/store-buffer.cc @@ -378,27 +378,41 @@ void StoreBuffer::GCEpilogue() { } +void StoreBuffer::ProcessOldToNewSlot(Address slot_address, + ObjectSlotCallback slot_callback, + bool clear_maps) { + Object** slot = reinterpret_cast(slot_address); + Object* object = reinterpret_cast( + base::NoBarrier_Load(reinterpret_cast(slot))); + + // If the object is not in from space, it must be a duplicate store buffer + // entry and the slot was already updated. + if (heap_->InFromSpace(object)) { + HeapObject* heap_object = reinterpret_cast(object); + DCHECK(heap_object->IsHeapObject()); + // The new space object was not promoted if it still contains a map + // pointer. Clear the map field now lazily (during full GC). + if (clear_maps) ClearDeadObject(heap_object); + slot_callback(reinterpret_cast(slot), heap_object); + object = reinterpret_cast( + base::NoBarrier_Load(reinterpret_cast(slot))); + // If the object was in from space before and is after executing the + // callback in to space, the object is still live. + // Unfortunately, we do not know about the slot. It could be in a + // just freed free space object. + if (heap_->InToSpace(object)) { + EnterDirectlyIntoStoreBuffer(reinterpret_cast
(slot)); + } + } +} + + void StoreBuffer::FindPointersToNewSpaceInRegion( Address start, Address end, ObjectSlotCallback slot_callback, bool clear_maps) { for (Address slot_address = start; slot_address < end; slot_address += kPointerSize) { - Object** slot = reinterpret_cast(slot_address); - Object* object = reinterpret_cast( - base::NoBarrier_Load(reinterpret_cast(slot))); - if (heap_->InNewSpace(object)) { - HeapObject* heap_object = reinterpret_cast(object); - DCHECK(heap_object->IsHeapObject()); - // The new space object was not promoted if it still contains a map - // pointer. Clear the map field now lazily. - if (clear_maps) ClearDeadObject(heap_object); - slot_callback(reinterpret_cast(slot), heap_object); - object = reinterpret_cast( - base::NoBarrier_Load(reinterpret_cast(slot))); - if (heap_->InNewSpace(object)) { - EnterDirectlyIntoStoreBuffer(slot_address); - } - } + ProcessOldToNewSlot(slot_address, slot_callback, clear_maps); } } @@ -413,21 +427,7 @@ void StoreBuffer::IteratePointersInStoreBuffer(ObjectSlotCallback slot_callback, #ifdef DEBUG Address* saved_top = old_top_; #endif - Object** slot = reinterpret_cast(*current); - Object* object = reinterpret_cast( - base::NoBarrier_Load(reinterpret_cast(slot))); - if (heap_->InFromSpace(object)) { - HeapObject* heap_object = reinterpret_cast(object); - // The new space object was not promoted if it still contains a map - // pointer. Clear the map field now lazily. - if (clear_maps) ClearDeadObject(heap_object); - slot_callback(reinterpret_cast(slot), heap_object); - object = reinterpret_cast( - base::NoBarrier_Load(reinterpret_cast(slot))); - if (heap_->InNewSpace(object)) { - EnterDirectlyIntoStoreBuffer(reinterpret_cast
(slot)); - } - } + ProcessOldToNewSlot(*current, slot_callback, clear_maps); DCHECK(old_top_ == saved_top + 1 || old_top_ == saved_top); } } diff --git a/src/heap/store-buffer.h b/src/heap/store-buffer.h index 5efd6922bc..30ef18f54f 100644 --- a/src/heap/store-buffer.h +++ b/src/heap/store-buffer.h @@ -148,6 +148,9 @@ class StoreBuffer { // Set the map field of the object to NULL if contains a map. inline void ClearDeadObject(HeapObject* object); + void ProcessOldToNewSlot(Address slot_address, + ObjectSlotCallback slot_callback, bool clear_maps); + void IteratePointersToNewSpace(ObjectSlotCallback callback, bool clear_maps); void FindPointersToNewSpaceInRegion(Address start, Address end,