Chromium Code Reviews| Index: src/store-buffer.cc |
| diff --git a/src/store-buffer.cc b/src/store-buffer.cc |
| index 0386280de65b0948c22c54638cbba4c0e3646457..0649bc72b772bb2be5e32c63124472510e610278 100644 |
| --- a/src/store-buffer.cc |
| +++ b/src/store-buffer.cc |
| @@ -364,7 +364,8 @@ void StoreBuffer::VerifyPointers(PagedSpace* space, |
| reinterpret_cast<PagedSpace*>(page->owner()), |
| page, |
| region_callback, |
| - &DummyScavengePointer); |
| + &DummyScavengePointer, |
| + false); |
| } |
| } |
| @@ -412,13 +413,22 @@ void StoreBuffer::GCEpilogue() { |
| void StoreBuffer::FindPointersToNewSpaceInRegion( |
| - Address start, Address end, ObjectSlotCallback slot_callback) { |
| + 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<Object**>(slot_address); |
| if (heap_->InNewSpace(*slot)) { |
| HeapObject* object = reinterpret_cast<HeapObject*>(*slot); |
| + Address& map_field = Memory::Address_at(object->address()); |
|
titzer
2013/07/10 17:06:35
I'm a little dedup, short and stout. Rip me over a
Hannes Payer (out of office)
2013/07/11 07:30:40
Done.
|
| + // The new space object was not promoted if it still contains a map |
| + // pointer. Clear the map field now lazily. |
| + if (clear_maps && heap_->map_space()->Contains(map_field)) { |
| + map_field = NULL; |
| + } |
| ASSERT(object->IsHeapObject()); |
| slot_callback(reinterpret_cast<HeapObject**>(slot), object); |
| if (heap_->InNewSpace(*slot)) { |
| @@ -446,7 +456,8 @@ static inline Address MapEndAlign(Address addr) { |
| void StoreBuffer::FindPointersToNewSpaceInMaps( |
| Address start, |
| Address end, |
| - ObjectSlotCallback slot_callback) { |
| + ObjectSlotCallback slot_callback, |
| + bool clear_maps) { |
| ASSERT(MapStartAlign(start) == start); |
| ASSERT(MapEndAlign(end) == end); |
| @@ -460,7 +471,8 @@ void StoreBuffer::FindPointersToNewSpaceInMaps( |
| FindPointersToNewSpaceInRegion(pointer_fields_start, |
| pointer_fields_end, |
| - slot_callback); |
| + slot_callback, |
| + clear_maps); |
| map_address += Map::kSize; |
| } |
| } |
| @@ -469,7 +481,8 @@ void StoreBuffer::FindPointersToNewSpaceInMaps( |
| void StoreBuffer::FindPointersToNewSpaceInMapsRegion( |
| Address start, |
| Address end, |
| - ObjectSlotCallback slot_callback) { |
| + ObjectSlotCallback slot_callback, |
| + bool clear_maps) { |
| Address map_aligned_start = MapStartAlign(start); |
| Address map_aligned_end = MapEndAlign(end); |
| @@ -478,7 +491,8 @@ void StoreBuffer::FindPointersToNewSpaceInMapsRegion( |
| FindPointersToNewSpaceInMaps(map_aligned_start, |
| map_aligned_end, |
| - slot_callback); |
| + slot_callback, |
| + clear_maps); |
| } |
| @@ -500,7 +514,8 @@ void StoreBuffer::FindPointersToNewSpaceOnPage( |
| PagedSpace* space, |
| Page* page, |
| RegionCallback region_callback, |
| - ObjectSlotCallback slot_callback) { |
| + ObjectSlotCallback slot_callback, |
| + bool clear_maps) { |
| Address visitable_start = page->area_start(); |
| Address end_of_page = page->area_end(); |
| @@ -520,7 +535,8 @@ void StoreBuffer::FindPointersToNewSpaceOnPage( |
| // After calling this the special garbage section may have moved. |
| (this->*region_callback)(visitable_start, |
| visitable_end, |
| - slot_callback); |
| + slot_callback, |
| + clear_maps); |
| if (visitable_end >= space->top() && visitable_end < space->limit()) { |
| visitable_end = space->limit(); |
| visitable_start = visitable_end; |
| @@ -551,13 +567,15 @@ void StoreBuffer::FindPointersToNewSpaceOnPage( |
| if (visitable_start != visitable_end) { |
| (this->*region_callback)(visitable_start, |
| visitable_end, |
| - slot_callback); |
| + slot_callback, |
| + clear_maps); |
| } |
| } |
| void StoreBuffer::IteratePointersInStoreBuffer( |
| - ObjectSlotCallback slot_callback) { |
| + ObjectSlotCallback slot_callback, |
| + bool clear_maps) { |
| Address* limit = old_top_; |
| old_top_ = old_start_; |
| { |
| @@ -570,6 +588,12 @@ void StoreBuffer::IteratePointersInStoreBuffer( |
| Object* object = *slot; |
| if (heap_->InFromSpace(object)) { |
| HeapObject* heap_object = reinterpret_cast<HeapObject*>(object); |
| + Address& map_field = Memory::Address_at(heap_object->address()); |
| + // The new space object was not promoted if it still contains a map |
| + // pointer. Clear the map field now lazily. |
| + if (clear_maps && heap_->map_space()->Contains(map_field)) { |
| + map_field = NULL; |
| + } |
|
titzer
2013/07/10 17:06:35
BTW, do you still want to call the slot callback i
Hannes Payer (out of office)
2013/07/11 07:30:40
As soon as we clear the todo in the callback, we c
|
| slot_callback(reinterpret_cast<HeapObject**>(slot), heap_object); |
| if (heap_->InNewSpace(*slot)) { |
| EnterDirectlyIntoStoreBuffer(reinterpret_cast<Address>(slot)); |
| @@ -581,7 +605,8 @@ void StoreBuffer::IteratePointersInStoreBuffer( |
| } |
| -void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback) { |
| +void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback, |
| + bool clear_maps) { |
| // We do not sort or remove duplicated entries from the store buffer because |
| // we expect that callback will rebuild the store buffer thus removing |
| // all duplicates and pointers to old space. |
| @@ -590,7 +615,7 @@ void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback) { |
| // TODO(gc): we want to skip slots on evacuation candidates |
| // but we can't simply figure that out from slot address |
| // because slot can belong to a large object. |
| - IteratePointersInStoreBuffer(slot_callback); |
| + IteratePointersInStoreBuffer(slot_callback, clear_maps); |
| // We are done scanning all the pointers that were in the store buffer, but |
| // there may be some pages marked scan_on_scavenge that have pointers to new |
| @@ -619,7 +644,7 @@ void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback) { |
| ASSERT(array->IsFixedArray()); |
| Address start = array->address(); |
| Address end = start + array->Size(); |
| - FindPointersToNewSpaceInRegion(start, end, slot_callback); |
| + FindPointersToNewSpaceInRegion(start, end, slot_callback, clear_maps); |
| } else { |
| Page* page = reinterpret_cast<Page*>(chunk); |
| PagedSpace* owner = reinterpret_cast<PagedSpace*>(page->owner()); |
| @@ -629,7 +654,8 @@ void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback) { |
| (owner == heap_->map_space() ? |
| &StoreBuffer::FindPointersToNewSpaceInMapsRegion : |
| &StoreBuffer::FindPointersToNewSpaceInRegion), |
| - slot_callback); |
| + slot_callback, |
| + clear_maps); |
| } |
| } |
| } |