Revision: 15616
Author: [email protected]
Date: Thu Jul 11 02:17:03 2013
Log: Implemented lazy sweeping of new space.
BUG=
[email protected]
Review URL: https://codereview.chromium.org/18998004
http://code.google.com/p/v8/source/detail?r=15616
Modified:
/branches/bleeding_edge/src/mark-compact.cc
/branches/bleeding_edge/src/store-buffer-inl.h
/branches/bleeding_edge/src/store-buffer.cc
/branches/bleeding_edge/src/store-buffer.h
=======================================
--- /branches/bleeding_edge/src/mark-compact.cc Tue Jul 9 01:40:34 2013
+++ /branches/bleeding_edge/src/mark-compact.cc Thu Jul 11 02:17:03 2013
@@ -2930,9 +2930,6 @@
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 @@
StoreBufferRebuildScope scope(heap_,
heap_->store_buffer(),
&Heap::ScavengeStoreBufferCallback);
- heap_->store_buffer()->IteratePointersToNewSpace(&UpdatePointer);
+ heap_->store_buffer()->IteratePointersToNewSpaceAndClearMaps(
+ &UpdatePointer);
}
{ GCTracer::Scope gc_scope(tracer_,
=======================================
--- /branches/bleeding_edge/src/store-buffer-inl.h Thu Oct 13 04:50:00 2011
+++ /branches/bleeding_edge/src/store-buffer-inl.h Thu Jul 11 02:17:03 2013
@@ -72,6 +72,14 @@
}
}
}
+
+
+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
=======================================
--- /branches/bleeding_edge/src/store-buffer.cc Thu Jun 20 04:47:58 2013
+++ /branches/bleeding_edge/src/store-buffer.cc Thu Jul 11 02:17:03 2013
@@ -364,7 +364,8 @@
reinterpret_cast<PagedSpace*>(page->owner()),
page,
region_callback,
- &DummyScavengePointer);
+ &DummyScavengePointer,
+ false);
}
}
@@ -412,7 +413,10 @@
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 @@
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 @@
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 @@
FindPointersToNewSpaceInRegion(pointer_fields_start,
pointer_fields_end,
- slot_callback);
+ slot_callback,
+ clear_maps);
map_address += Map::kSize;
}
}
@@ -469,7 +478,8 @@
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 @@
FindPointersToNewSpaceInMaps(map_aligned_start,
map_aligned_end,
- slot_callback);
+ slot_callback,
+ clear_maps);
}
@@ -500,7 +511,8 @@
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 @@
// 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 @@
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 @@
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::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 @@
// 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 @@
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 @@
(owner == heap_->map_space() ?
&StoreBuffer::FindPointersToNewSpaceInMapsRegion :
&StoreBuffer::FindPointersToNewSpaceInRegion),
- slot_callback);
+ slot_callback,
+ clear_maps);
}
}
}
=======================================
--- /branches/bleeding_edge/src/store-buffer.h Wed Jun 12 06:14:35 2013
+++ /branches/bleeding_edge/src/store-buffer.h Thu Jul 11 02:17:03 2013
@@ -43,8 +43,10 @@
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 @@
// 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 @@
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 @@
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);
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.