| Index: src/store-buffer.cc
|
| diff --git a/src/store-buffer.cc b/src/store-buffer.cc
|
| index 0386280de65b0948c22c54638cbba4c0e3646457..9705b60489800feb74d8d09d1a72ca85cf9f0a4b 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,7 +413,10 @@ 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) {
|
| @@ -420,6 +424,9 @@ void StoreBuffer::FindPointersToNewSpaceInRegion(
|
| if (heap_->InNewSpace(*slot)) {
|
| HeapObject* object = reinterpret_cast<HeapObject*>(*slot);
|
| ASSERT(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(object);
|
| slot_callback(reinterpret_cast<HeapObject**>(slot), object);
|
| if (heap_->InNewSpace(*slot)) {
|
| EnterDirectlyIntoStoreBuffer(slot_address);
|
| @@ -446,7 +453,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 +468,8 @@ void StoreBuffer::FindPointersToNewSpaceInMaps(
|
|
|
| FindPointersToNewSpaceInRegion(pointer_fields_start,
|
| pointer_fields_end,
|
| - slot_callback);
|
| + slot_callback,
|
| + clear_maps);
|
| map_address += Map::kSize;
|
| }
|
| }
|
| @@ -469,7 +478,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 +488,8 @@ void StoreBuffer::FindPointersToNewSpaceInMapsRegion(
|
|
|
| FindPointersToNewSpaceInMaps(map_aligned_start,
|
| map_aligned_end,
|
| - slot_callback);
|
| + slot_callback,
|
| + clear_maps);
|
| }
|
|
|
|
|
| @@ -500,7 +511,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 +532,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 +564,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 +585,9 @@ void StoreBuffer::IteratePointersInStoreBuffer(
|
| Object* object = *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);
|
| if (heap_->InNewSpace(*slot)) {
|
| EnterDirectlyIntoStoreBuffer(reinterpret_cast<Address>(slot));
|
| @@ -582,6 +600,18 @@ void StoreBuffer::IteratePointersInStoreBuffer(
|
|
|
|
|
| void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback) {
|
| + IteratePointersToNewSpace(slot_callback, false);
|
| +}
|
| +
|
| +
|
| +void StoreBuffer::IteratePointersToNewSpaceAndClearMaps(
|
| + ObjectSlotCallback slot_callback) {
|
| + IteratePointersToNewSpace(slot_callback, true);
|
| +}
|
| +
|
| +
|
| +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 +620,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 +649,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 +659,8 @@ void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback) {
|
| (owner == heap_->map_space() ?
|
| &StoreBuffer::FindPointersToNewSpaceInMapsRegion :
|
| &StoreBuffer::FindPointersToNewSpaceInRegion),
|
| - slot_callback);
|
| + slot_callback,
|
| + clear_maps);
|
| }
|
| }
|
| }
|
|
|