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.


Reply via email to