Don't filter store buffer after sweeping.
authorhpayer <hpayer@chromium.org>
Thu, 20 Aug 2015 15:33:06 +0000 (08:33 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 20 Aug 2015 15:33:20 +0000 (15:33 +0000)
Additionally, this CL moves a bit of code around to free up more memory before compaction starts.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#30275}

src/heap/heap.cc
src/heap/heap.h
src/heap/mark-compact.cc
src/heap/spaces.cc
src/heap/spaces.h

index 3ae38f5..1586a00 100644 (file)
@@ -6663,7 +6663,7 @@ void Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) {
 }
 
 
-void Heap::FreeQueuedChunks() {
+void Heap::FilterStoreBufferEntriesOnAboutToBeFreedPages() {
   if (chunks_queued_for_free_ == NULL) return;
   MemoryChunk* next;
   MemoryChunk* chunk;
@@ -6673,6 +6673,12 @@ void Heap::FreeQueuedChunks() {
   }
   isolate_->heap()->store_buffer()->Compact();
   isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED);
+}
+
+
+void Heap::FreeQueuedChunks() {
+  MemoryChunk* next;
+  MemoryChunk* chunk;
   for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) {
     next = chunk->next_chunk();
     isolate_->memory_allocator()->Free(chunk);
index d424807..a4268e5 100644 (file)
@@ -1429,6 +1429,7 @@ class Heap {
   inline bool OldGenerationAllocationLimitReached();
 
   void QueueMemoryChunkForFree(MemoryChunk* chunk);
+  void FilterStoreBufferEntriesOnAboutToBeFreedPages();
   void FreeQueuedChunks();
 
   int gc_count() const { return gc_count_; }
index 6a0c9d5..ab00782 100644 (file)
@@ -3760,6 +3760,7 @@ void MarkCompactCollector::ReleaseEvacuationCandidates() {
   }
   evacuation_candidates_.Rewind(0);
   compacting_ = false;
+  heap()->FilterStoreBufferEntriesOnAboutToBeFreedPages();
   heap()->FreeQueuedChunks();
 }
 
@@ -4312,9 +4313,6 @@ void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
     PrintF("SweepSpace: %s (%d pages swept)\n",
            AllocationSpaceName(space->identity()), pages_swept);
   }
-
-  // Give pages that are queued to be freed back to the OS.
-  heap()->FreeQueuedChunks();
 }
 
 
@@ -4331,11 +4329,6 @@ void MarkCompactCollector::SweepSpaces() {
 
   MoveEvacuationCandidatesToEndOfPagesList();
 
-  // Noncompacting collections simply sweep the spaces to clear the mark
-  // bits and free the nonlive blocks (for old and map spaces).  We sweep
-  // the map space last because freeing non-live maps overwrites them and
-  // the other spaces rely on possibly non-live maps to get the sizes for
-  // non-live objects.
   {
     {
       GCTracer::Scope sweep_scope(heap()->tracer(),
@@ -4358,12 +4351,19 @@ void MarkCompactCollector::SweepSpaces() {
     }
   }
 
-  EvacuateNewSpaceAndCandidates();
+  // Deallocate unmarked large objects.
+  heap_->lo_space()->FreeUnmarkedObjects();
+
+  // Give pages that are queued to be freed back to the OS. Invalid store
+  // buffer entries are already filter out. We can just release the memory.
+  heap()->FreeQueuedChunks();
 
   heap()->FreeDeadArrayBuffers(false);
 
-  // Deallocate unmarked objects and clear marked bits for marked objects.
-  heap_->lo_space()->FreeUnmarkedObjects();
+  EvacuateNewSpaceAndCandidates();
+
+  // Clear the marking state of live large objects.
+  heap_->lo_space()->ClearMarkingStateOfLiveObjects();
 
   // Deallocate evacuated candidate pages.
   ReleaseEvacuationCandidates();
index e66fd39..1f81945 100644 (file)
@@ -2933,19 +2933,27 @@ LargePage* LargeObjectSpace::FindPage(Address a) {
 }
 
 
+void LargeObjectSpace::ClearMarkingStateOfLiveObjects() {
+  LargePage* current = first_page_;
+  while (current != NULL) {
+    HeapObject* object = current->GetObject();
+    MarkBit mark_bit = Marking::MarkBitFrom(object);
+    DCHECK(Marking::IsBlackOrGrey(mark_bit));
+    Marking::BlackToWhite(mark_bit);
+    Page::FromAddress(object->address())->ResetProgressBar();
+    Page::FromAddress(object->address())->ResetLiveBytes();
+    current = current->next_page();
+  }
+}
+
+
 void LargeObjectSpace::FreeUnmarkedObjects() {
   LargePage* previous = NULL;
   LargePage* current = first_page_;
   while (current != NULL) {
     HeapObject* object = current->GetObject();
-    // Can this large page contain pointers to non-trivial objects.  No other
-    // pointer object is this big.
-    bool is_pointer_object = object->IsFixedArray();
     MarkBit mark_bit = Marking::MarkBitFrom(object);
     if (Marking::IsBlackOrGrey(mark_bit)) {
-      Marking::BlackToWhite(mark_bit);
-      Page::FromAddress(object->address())->ResetProgressBar();
-      Page::FromAddress(object->address())->ResetLiveBytes();
       previous = current;
       current = current->next_page();
     } else {
@@ -2976,14 +2984,9 @@ void LargeObjectSpace::FreeUnmarkedObjects() {
                           static_cast<uint32_t>(key));
       }
 
-      if (is_pointer_object) {
-        heap()->QueueMemoryChunkForFree(page);
-      } else {
-        heap()->isolate()->memory_allocator()->Free(page);
-      }
+      heap()->QueueMemoryChunkForFree(page);
     }
   }
-  heap()->FreeQueuedChunks();
 }
 
 
index 2ea2e90..c00a84f 100644 (file)
@@ -2744,6 +2744,9 @@ class LargeObjectSpace : public Space {
   // if such a page doesn't exist.
   LargePage* FindPage(Address a);
 
+  // Clears the marking state of live objects.
+  void ClearMarkingStateOfLiveObjects();
+
   // Frees unmarked objects.
   void FreeUnmarkedObjects();