Reviewers: danno, Michael Starzinger, titzer, ulan,

Description:
Implemented lazy sweeping of new space.

BUG=

Please review this at https://codereview.chromium.org/18998004/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/heap.cc
  M src/mark-compact.cc
  M src/store-buffer.h
  M src/store-buffer.cc


Index: src/heap.cc
diff --git a/src/heap.cc b/src/heap.cc
index ebf1487e1487a7aea99d4fa5e11c8c4b285ec4a6..f8737c45b98acde1af9393e035efc09f47048d49 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -1375,7 +1375,7 @@ void Heap::Scavenge() {
     StoreBufferRebuildScope scope(this,
                                   store_buffer(),
                                   &ScavengeStoreBufferCallback);
-    store_buffer()->IteratePointersToNewSpace(&ScavengeObject);
+    store_buffer()->IteratePointersToNewSpace(&ScavengeObject, false);
   }

   // Copy objects reachable from simple cells by scavenging cell values
Index: src/mark-compact.cc
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index 980c039792652b442045708b8e2c9d12502594af..62c980e3076d93908cb8ef4278500b94efabcf16 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -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,7 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
     StoreBufferRebuildScope scope(heap_,
                                   heap_->store_buffer(),
                                   &Heap::ScavengeStoreBufferCallback);
-    heap_->store_buffer()->IteratePointersToNewSpace(&UpdatePointer);
+    heap_->store_buffer()->IteratePointersToNewSpace(&UpdatePointer, true);
   }

   { GCTracer::Scope gc_scope(tracer_,
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());
+      // 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;
+        }
         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);
         }
       }
     }
Index: src/store-buffer.h
diff --git a/src/store-buffer.h b/src/store-buffer.h
index 520cbc01626b698607928dbd83638ba220096fb2..ca92a6a7b31e15731e7f2102e47c095b394f0336 100644
--- a/src/store-buffer.h
+++ b/src/store-buffer.h
@@ -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.
@@ -81,7 +83,7 @@ class StoreBuffer {
// Iterates over all pointers that go from old space to new space. It will
   // delete the store buffer as it starts so the callback should reenter
   // surviving old-to-new pointers into the store buffer to rebuild it.
-  void IteratePointersToNewSpace(ObjectSlotCallback callback);
+ void IteratePointersToNewSpace(ObjectSlotCallback callback, bool clear_maps);

   static const int kStoreBufferOverflowBit = 1 << (14 + kPointerSizeLog2);
   static const int kStoreBufferSize = kStoreBufferOverflowBit;
@@ -166,7 +168,8 @@ class StoreBuffer {

   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 +185,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);


--
--
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.


Reply via email to