Commit 02ce4453 authored by hpayer's avatar hpayer Committed by Commit bot

Remove lazy sweeping of new space and corresponding complicated pointer updating logic.

We can do that now since we have the invariant that the store buffer always has valid slots after marking.

BUG=

Review URL: https://codereview.chromium.org/991853002

Cr-Commit-Position: refs/heads/master@{#27105}
parent 0fd9bf8f
...@@ -3008,19 +3008,15 @@ void PointersUpdatingVisitor::CheckLayoutDescriptorAndDie(Heap* heap, ...@@ -3008,19 +3008,15 @@ void PointersUpdatingVisitor::CheckLayoutDescriptorAndDie(Heap* heap,
static void UpdatePointer(HeapObject** address, HeapObject* object) { static void UpdatePointer(HeapObject** address, HeapObject* object) {
Address new_addr = Memory::Address_at(object->address()); MapWord map_word = object->map_word();
// The store buffer can still contain stale pointers in dead large objects.
// The new space sweep will overwrite the map word of dead objects // Ignore these pointers here.
// with NULL. In this case we do not need to transfer this entry to DCHECK(map_word.IsForwardingAddress() ||
// the store buffer which we are rebuilding. object->GetHeap()->lo_space()->FindPage(
// We perform the pointer update with a no barrier compare-and-swap. The reinterpret_cast<Address>(address)) != NULL);
// compare and swap may fail in the case where the pointer update tries to if (map_word.IsForwardingAddress()) {
// update garbage memory which was concurrently accessed by the sweeper. // Update the corresponding slot.
if (new_addr != NULL) { *address = map_word.ToForwardingAddress();
base::NoBarrier_CompareAndSwap(
reinterpret_cast<base::AtomicWord*>(address),
reinterpret_cast<base::AtomicWord>(object),
reinterpret_cast<base::AtomicWord>(HeapObject::FromAddress(new_addr)));
} }
} }
...@@ -3652,8 +3648,7 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { ...@@ -3652,8 +3648,7 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
GCTracer::Scope::MC_UPDATE_OLD_TO_NEW_POINTERS); GCTracer::Scope::MC_UPDATE_OLD_TO_NEW_POINTERS);
StoreBufferRebuildScope scope(heap_, heap_->store_buffer(), StoreBufferRebuildScope scope(heap_, heap_->store_buffer(),
&Heap::ScavengeStoreBufferCallback); &Heap::ScavengeStoreBufferCallback);
heap_->store_buffer()->IteratePointersToNewSpaceAndClearMaps( heap_->store_buffer()->IteratePointersToNewSpace(&UpdatePointer);
&UpdatePointer);
} }
{ {
......
...@@ -49,14 +49,6 @@ void StoreBuffer::EnterDirectlyIntoStoreBuffer(Address addr) { ...@@ -49,14 +49,6 @@ void StoreBuffer::EnterDirectlyIntoStoreBuffer(Address addr) {
} }
} }
} }
void StoreBuffer::ClearDeadObject(HeapObject* object) {
Address& map_field = Memory::Address_at(object->address());
if (heap_->map_space()->Contains(map_field)) {
map_field = NULL;
}
}
} }
} // namespace v8::internal } // namespace v8::internal
......
...@@ -379,8 +379,7 @@ void StoreBuffer::GCEpilogue() { ...@@ -379,8 +379,7 @@ void StoreBuffer::GCEpilogue() {
void StoreBuffer::ProcessOldToNewSlot(Address slot_address, void StoreBuffer::ProcessOldToNewSlot(Address slot_address,
ObjectSlotCallback slot_callback, ObjectSlotCallback slot_callback) {
bool clear_maps) {
Object** slot = reinterpret_cast<Object**>(slot_address); Object** slot = reinterpret_cast<Object**>(slot_address);
Object* object = reinterpret_cast<Object*>( Object* object = reinterpret_cast<Object*>(
base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot))); base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot)));
...@@ -390,9 +389,6 @@ void StoreBuffer::ProcessOldToNewSlot(Address slot_address, ...@@ -390,9 +389,6 @@ void StoreBuffer::ProcessOldToNewSlot(Address slot_address,
if (heap_->InFromSpace(object)) { if (heap_->InFromSpace(object)) {
HeapObject* heap_object = reinterpret_cast<HeapObject*>(object); HeapObject* heap_object = reinterpret_cast<HeapObject*>(object);
DCHECK(heap_object->IsHeapObject()); 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); slot_callback(reinterpret_cast<HeapObject**>(slot), heap_object);
object = reinterpret_cast<Object*>( object = reinterpret_cast<Object*>(
base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot))); base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot)));
...@@ -408,17 +404,16 @@ void StoreBuffer::ProcessOldToNewSlot(Address slot_address, ...@@ -408,17 +404,16 @@ void StoreBuffer::ProcessOldToNewSlot(Address slot_address,
void StoreBuffer::FindPointersToNewSpaceInRegion( 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; for (Address slot_address = start; slot_address < end;
slot_address += kPointerSize) { slot_address += kPointerSize) {
ProcessOldToNewSlot(slot_address, slot_callback, clear_maps); ProcessOldToNewSlot(slot_address, slot_callback);
} }
} }
void StoreBuffer::IteratePointersInStoreBuffer(ObjectSlotCallback slot_callback, void StoreBuffer::IteratePointersInStoreBuffer(
bool clear_maps) { ObjectSlotCallback slot_callback) {
Address* limit = old_top_; Address* limit = old_top_;
old_top_ = old_start_; old_top_ = old_start_;
{ {
...@@ -427,7 +422,7 @@ void StoreBuffer::IteratePointersInStoreBuffer(ObjectSlotCallback slot_callback, ...@@ -427,7 +422,7 @@ void StoreBuffer::IteratePointersInStoreBuffer(ObjectSlotCallback slot_callback,
#ifdef DEBUG #ifdef DEBUG
Address* saved_top = old_top_; Address* saved_top = old_top_;
#endif #endif
ProcessOldToNewSlot(*current, slot_callback, clear_maps); ProcessOldToNewSlot(*current, slot_callback);
DCHECK(old_top_ == saved_top + 1 || old_top_ == saved_top); DCHECK(old_top_ == saved_top + 1 || old_top_ == saved_top);
} }
} }
...@@ -478,18 +473,6 @@ void StoreBuffer::VerifyValidStoreBufferEntries() { ...@@ -478,18 +473,6 @@ void StoreBuffer::VerifyValidStoreBufferEntries() {
void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback) { 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 do not sort or remove duplicated entries from the store buffer because
// we expect that callback will rebuild the store buffer thus removing // we expect that callback will rebuild the store buffer thus removing
// all duplicates and pointers to old space. // all duplicates and pointers to old space.
...@@ -498,7 +481,7 @@ void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback, ...@@ -498,7 +481,7 @@ void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback,
// TODO(gc): we want to skip slots on evacuation candidates // TODO(gc): we want to skip slots on evacuation candidates
// but we can't simply figure that out from slot address // but we can't simply figure that out from slot address
// because slot can belong to a large object. // because slot can belong to a large object.
IteratePointersInStoreBuffer(slot_callback, clear_maps); IteratePointersInStoreBuffer(slot_callback);
// We are done scanning all the pointers that were in the store buffer, but // 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 // there may be some pages marked scan_on_scavenge that have pointers to new
...@@ -527,7 +510,7 @@ void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback, ...@@ -527,7 +510,7 @@ void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback,
DCHECK(array->IsFixedArray()); DCHECK(array->IsFixedArray());
Address start = array->address(); Address start = array->address();
Address end = start + array->Size(); Address end = start + array->Size();
FindPointersToNewSpaceInRegion(start, end, slot_callback, clear_maps); FindPointersToNewSpaceInRegion(start, end, slot_callback);
} else { } else {
Page* page = reinterpret_cast<Page*>(chunk); Page* page = reinterpret_cast<Page*>(chunk);
PagedSpace* owner = reinterpret_cast<PagedSpace*>(page->owner()); PagedSpace* owner = reinterpret_cast<PagedSpace*>(page->owner());
...@@ -542,7 +525,7 @@ void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback, ...@@ -542,7 +525,7 @@ void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback,
FindPointersToNewSpaceInRegion( FindPointersToNewSpaceInRegion(
heap_object->address() + Map::kPointerFieldsBeginOffset, heap_object->address() + Map::kPointerFieldsBeginOffset,
heap_object->address() + Map::kPointerFieldsEndOffset, heap_object->address() + Map::kPointerFieldsEndOffset,
slot_callback, clear_maps); slot_callback);
} }
} }
} else { } else {
...@@ -577,8 +560,7 @@ void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback, ...@@ -577,8 +560,7 @@ void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback,
&end_of_region_offset)) { &end_of_region_offset)) {
FindPointersToNewSpaceInRegion( FindPointersToNewSpaceInRegion(
obj_address + offset, obj_address + offset,
obj_address + end_of_region_offset, slot_callback, obj_address + end_of_region_offset, slot_callback);
clear_maps);
} }
offset = end_of_region_offset; offset = end_of_region_offset;
} }
...@@ -588,7 +570,7 @@ void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback, ...@@ -588,7 +570,7 @@ void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback,
Address end_address = obj_address + end_offset; Address end_address = obj_address + end_offset;
// Object has only tagged fields. // Object has only tagged fields.
FindPointersToNewSpaceInRegion(start_address, end_address, FindPointersToNewSpaceInRegion(start_address, end_address,
slot_callback, clear_maps); slot_callback);
#if V8_DOUBLE_FIELDS_UNBOXING #if V8_DOUBLE_FIELDS_UNBOXING
} }
#endif #endif
......
...@@ -20,8 +20,7 @@ class StoreBuffer; ...@@ -20,8 +20,7 @@ class StoreBuffer;
typedef void (*ObjectSlotCallback)(HeapObject** from, HeapObject* to); typedef void (*ObjectSlotCallback)(HeapObject** from, HeapObject* to);
typedef void (StoreBuffer::*RegionCallback)(Address start, Address end, typedef void (StoreBuffer::*RegionCallback)(Address start, Address end,
ObjectSlotCallback slot_callback, ObjectSlotCallback slot_callback);
bool clear_maps);
// Used to implement the write barrier by collecting addresses of pointers // Used to implement the write barrier by collecting addresses of pointers
// between spaces. // between spaces.
...@@ -60,10 +59,6 @@ class StoreBuffer { ...@@ -60,10 +59,6 @@ class StoreBuffer {
// surviving old-to-new pointers into the store buffer to rebuild it. // surviving old-to-new pointers into the store buffer to rebuild it.
void IteratePointersToNewSpace(ObjectSlotCallback callback); void IteratePointersToNewSpace(ObjectSlotCallback callback);
// Same as IteratePointersToNewSpace but additonally clears maps in objects
// referenced from the store buffer that do not contain a forwarding pointer.
void IteratePointersToNewSpaceAndClearMaps(ObjectSlotCallback callback);
static const int kStoreBufferOverflowBit = 1 << (14 + kPointerSizeLog2); static const int kStoreBufferOverflowBit = 1 << (14 + kPointerSizeLog2);
static const int kStoreBufferSize = kStoreBufferOverflowBit; static const int kStoreBufferSize = kStoreBufferOverflowBit;
static const int kStoreBufferLength = kStoreBufferSize / sizeof(Address); static const int kStoreBufferLength = kStoreBufferSize / sizeof(Address);
...@@ -152,17 +147,11 @@ class StoreBuffer { ...@@ -152,17 +147,11 @@ class StoreBuffer {
void Uniq(); void Uniq();
void ExemptPopularPages(int prime_sample_step, int threshold); void ExemptPopularPages(int prime_sample_step, int threshold);
// Set the map field of the object to NULL if contains a map.
inline void ClearDeadObject(HeapObject* object);
void ProcessOldToNewSlot(Address slot_address, void ProcessOldToNewSlot(Address slot_address,
ObjectSlotCallback slot_callback, bool clear_maps); ObjectSlotCallback slot_callback);
void IteratePointersToNewSpace(ObjectSlotCallback callback, bool clear_maps);
void FindPointersToNewSpaceInRegion(Address start, Address end, void FindPointersToNewSpaceInRegion(Address start, Address end,
ObjectSlotCallback slot_callback, ObjectSlotCallback slot_callback);
bool clear_maps);
// For each region of pointers on a page in use from an old space call // For each region of pointers on a page in use from an old space call
// visit_pointer_region callback. // visit_pointer_region callback.
...@@ -173,8 +162,7 @@ class StoreBuffer { ...@@ -173,8 +162,7 @@ class StoreBuffer {
RegionCallback region_callback, RegionCallback region_callback,
ObjectSlotCallback slot_callback); ObjectSlotCallback slot_callback);
void IteratePointersInStoreBuffer(ObjectSlotCallback slot_callback, void IteratePointersInStoreBuffer(ObjectSlotCallback slot_callback);
bool clear_maps);
#ifdef VERIFY_HEAP #ifdef VERIFY_HEAP
void VerifyPointers(LargeObjectSpace* space); void VerifyPointers(LargeObjectSpace* space);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment