Commit c518bee5 authored by hpayer@chromium.org's avatar hpayer@chromium.org

Implemented lazy sweeping of new space.

BUG=
R=titzer@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15616 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c294a40e
......@@ -2930,9 +2930,6 @@ void MarkCompactCollector::EvacuateNewSpace() {
object->address(),
size,
NEW_SPACE);
} else {
// Mark dead objects in the new space with null in their map field.
Memory::Address_at(object->address()) = NULL;
}
}
......@@ -3354,7 +3351,8 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
StoreBufferRebuildScope scope(heap_,
heap_->store_buffer(),
&Heap::ScavengeStoreBufferCallback);
heap_->store_buffer()->IteratePointersToNewSpace(&UpdatePointer);
heap_->store_buffer()->IteratePointersToNewSpaceAndClearMaps(
&UpdatePointer);
}
{ GCTracer::Scope gc_scope(tracer_,
......
......@@ -74,6 +74,14 @@ 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
#endif // V8_STORE_BUFFER_INL_H_
......@@ -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);
}
}
}
......
......@@ -43,8 +43,10 @@ class StoreBuffer;
typedef void (*ObjectSlotCallback)(HeapObject** from, HeapObject* to);
typedef void (StoreBuffer::*RegionCallback)(
Address start, Address end, ObjectSlotCallback slot_callback);
typedef void (StoreBuffer::*RegionCallback)(Address start,
Address end,
ObjectSlotCallback slot_callback,
bool clear_maps);
// Used to implement the write barrier by collecting addresses of pointers
// between spaces.
......@@ -83,6 +85,10 @@ class StoreBuffer {
// surviving old-to-new pointers into the store buffer to rebuild it.
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 kStoreBufferSize = kStoreBufferOverflowBit;
static const int kStoreBufferLength = kStoreBufferSize / sizeof(Address);
......@@ -164,9 +170,15 @@ class StoreBuffer {
void Uniq();
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 IteratePointersToNewSpace(ObjectSlotCallback callback, bool clear_maps);
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
// visit_pointer_region callback.
......@@ -182,20 +194,24 @@ class StoreBuffer {
void FindPointersToNewSpaceInMaps(
Address start,
Address end,
ObjectSlotCallback slot_callback);
ObjectSlotCallback slot_callback,
bool clear_maps);
void FindPointersToNewSpaceInMapsRegion(
Address start,
Address end,
ObjectSlotCallback slot_callback);
ObjectSlotCallback slot_callback,
bool clear_maps);
void FindPointersToNewSpaceOnPage(
PagedSpace* space,
Page* page,
RegionCallback region_callback,
ObjectSlotCallback slot_callback);
ObjectSlotCallback slot_callback,
bool clear_maps);
void IteratePointersInStoreBuffer(ObjectSlotCallback slot_callback);
void IteratePointersInStoreBuffer(ObjectSlotCallback slot_callback,
bool clear_maps);
#ifdef VERIFY_HEAP
void VerifyPointers(PagedSpace* space, RegionCallback region_callback);
......
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