Just add slots that point to to-space objects back to the store buffer.
BUG= Review URL: https://codereview.chromium.org/946973008 Cr-Commit-Position: refs/heads/master@{#26844}
This commit is contained in:
parent
6a42682975
commit
fd35be4065
@ -378,27 +378,41 @@ void StoreBuffer::GCEpilogue() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void StoreBuffer::ProcessOldToNewSlot(Address slot_address,
|
||||||
|
ObjectSlotCallback slot_callback,
|
||||||
|
bool clear_maps) {
|
||||||
|
Object** slot = reinterpret_cast<Object**>(slot_address);
|
||||||
|
Object* object = reinterpret_cast<Object*>(
|
||||||
|
base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(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<HeapObject*>(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<HeapObject**>(slot), heap_object);
|
||||||
|
object = reinterpret_cast<Object*>(
|
||||||
|
base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(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<Address>(slot));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void StoreBuffer::FindPointersToNewSpaceInRegion(
|
void StoreBuffer::FindPointersToNewSpaceInRegion(
|
||||||
Address start, Address end, ObjectSlotCallback slot_callback,
|
Address start, Address end, ObjectSlotCallback slot_callback,
|
||||||
bool clear_maps) {
|
bool clear_maps) {
|
||||||
for (Address slot_address = start; slot_address < end;
|
for (Address slot_address = start; slot_address < end;
|
||||||
slot_address += kPointerSize) {
|
slot_address += kPointerSize) {
|
||||||
Object** slot = reinterpret_cast<Object**>(slot_address);
|
ProcessOldToNewSlot(slot_address, slot_callback, clear_maps);
|
||||||
Object* object = reinterpret_cast<Object*>(
|
|
||||||
base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot)));
|
|
||||||
if (heap_->InNewSpace(object)) {
|
|
||||||
HeapObject* heap_object = reinterpret_cast<HeapObject*>(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<HeapObject**>(slot), heap_object);
|
|
||||||
object = reinterpret_cast<Object*>(
|
|
||||||
base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot)));
|
|
||||||
if (heap_->InNewSpace(object)) {
|
|
||||||
EnterDirectlyIntoStoreBuffer(slot_address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,21 +427,7 @@ void StoreBuffer::IteratePointersInStoreBuffer(ObjectSlotCallback slot_callback,
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Address* saved_top = old_top_;
|
Address* saved_top = old_top_;
|
||||||
#endif
|
#endif
|
||||||
Object** slot = reinterpret_cast<Object**>(*current);
|
ProcessOldToNewSlot(*current, slot_callback, clear_maps);
|
||||||
Object* object = reinterpret_cast<Object*>(
|
|
||||||
base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot)));
|
|
||||||
if (heap_->InFromSpace(object)) {
|
|
||||||
HeapObject* heap_object = reinterpret_cast<HeapObject*>(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<HeapObject**>(slot), heap_object);
|
|
||||||
object = reinterpret_cast<Object*>(
|
|
||||||
base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot)));
|
|
||||||
if (heap_->InNewSpace(object)) {
|
|
||||||
EnterDirectlyIntoStoreBuffer(reinterpret_cast<Address>(slot));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DCHECK(old_top_ == saved_top + 1 || old_top_ == saved_top);
|
DCHECK(old_top_ == saved_top + 1 || old_top_ == saved_top);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,6 +148,9 @@ class StoreBuffer {
|
|||||||
// Set the map field of the object to NULL if contains a map.
|
// Set the map field of the object to NULL if contains a map.
|
||||||
inline void ClearDeadObject(HeapObject* object);
|
inline void ClearDeadObject(HeapObject* object);
|
||||||
|
|
||||||
|
void ProcessOldToNewSlot(Address slot_address,
|
||||||
|
ObjectSlotCallback slot_callback, bool clear_maps);
|
||||||
|
|
||||||
void IteratePointersToNewSpace(ObjectSlotCallback callback, bool clear_maps);
|
void IteratePointersToNewSpace(ObjectSlotCallback callback, bool clear_maps);
|
||||||
|
|
||||||
void FindPointersToNewSpaceInRegion(Address start, Address end,
|
void FindPointersToNewSpaceInRegion(Address start, Address end,
|
||||||
|
Loading…
Reference in New Issue
Block a user