From: hpayer Date: Thu, 20 Aug 2015 15:33:06 +0000 (-0700) Subject: Don't filter store buffer after sweeping. X-Git-Tag: upstream/4.7.83~765 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=267381d9789419922c959d6ea44bbd1b17641e1f;p=platform%2Fupstream%2Fv8.git Don't filter store buffer after sweeping. 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} --- diff --git a/src/heap/heap.cc b/src/heap/heap.cc index 3ae38f5..1586a00 100644 --- a/src/heap/heap.cc +++ b/src/heap/heap.cc @@ -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); diff --git a/src/heap/heap.h b/src/heap/heap.h index d424807..a4268e5 100644 --- a/src/heap/heap.h +++ b/src/heap/heap.h @@ -1429,6 +1429,7 @@ class Heap { inline bool OldGenerationAllocationLimitReached(); void QueueMemoryChunkForFree(MemoryChunk* chunk); + void FilterStoreBufferEntriesOnAboutToBeFreedPages(); void FreeQueuedChunks(); int gc_count() const { return gc_count_; } diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc index 6a0c9d5..ab00782 100644 --- a/src/heap/mark-compact.cc +++ b/src/heap/mark-compact.cc @@ -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(); diff --git a/src/heap/spaces.cc b/src/heap/spaces.cc index e66fd39..1f81945 100644 --- a/src/heap/spaces.cc +++ b/src/heap/spaces.cc @@ -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(key)); } - if (is_pointer_object) { - heap()->QueueMemoryChunkForFree(page); - } else { - heap()->isolate()->memory_allocator()->Free(page); - } + heap()->QueueMemoryChunkForFree(page); } } - heap()->FreeQueuedChunks(); } diff --git a/src/heap/spaces.h b/src/heap/spaces.h index 2ea2e90..c00a84f 100644 --- a/src/heap/spaces.h +++ b/src/heap/spaces.h @@ -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();