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); |
} |
} |
} |