From e800933eee938161cc53edbd5e8dd3fae66c8453 Mon Sep 17 00:00:00 2001 From: Michael Lippautz Date: Wed, 22 Feb 2017 14:52:53 +0100 Subject: [PATCH] [heap] Refactor evacuation routine Have clear prologue and epilogue steps. For a minor MC we can then templatize the prologue without changing the actual evacuation routine. BUG=chromium:651354 Change-Id: Ia238748e90bc6b616cd813d31198de182fe11498 Reviewed-on: https://chromium-review.googlesource.com/445898 Reviewed-by: Ulan Degenbaev Reviewed-by: Hannes Payer Commit-Queue: Michael Lippautz Cr-Commit-Position: refs/heads/master@{#43378} --- src/heap/gc-tracer.cc | 4 ++++ src/heap/gc-tracer.h | 2 ++ src/heap/mark-compact.cc | 44 +++++++++++++++++++++++++++------------- src/heap/mark-compact.h | 9 +++++--- 4 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/heap/gc-tracer.cc b/src/heap/gc-tracer.cc index 8dbb3fd44f..2c1024f09a 100644 --- a/src/heap/gc-tracer.cc +++ b/src/heap/gc-tracer.cc @@ -550,6 +550,8 @@ void GCTracer::PrintNVP() const { "evacuate.candidates=%.1f " "evacuate.clean_up=%.1f " "evacuate.copy=%.1f " + "evacuate.prologue=%.1f " + "evacuate.epilogue=%.1f " "evacuate.rebalance=%.1f " "evacuate.update_pointers=%.1f " "evacuate.update_pointers.to_evacuated=%.1f " @@ -634,6 +636,8 @@ void GCTracer::PrintNVP() const { current_.scopes[Scope::MC_EVACUATE_CANDIDATES], current_.scopes[Scope::MC_EVACUATE_CLEAN_UP], current_.scopes[Scope::MC_EVACUATE_COPY], + current_.scopes[Scope::MC_EVACUATE_PROLOGUE], + current_.scopes[Scope::MC_EVACUATE_EPILOGUE], current_.scopes[Scope::MC_EVACUATE_REBALANCE], current_.scopes[Scope::MC_EVACUATE_UPDATE_POINTERS], current_.scopes[Scope::MC_EVACUATE_UPDATE_POINTERS_TO_EVACUATED], diff --git a/src/heap/gc-tracer.h b/src/heap/gc-tracer.h index a461f0f638..b206286168 100644 --- a/src/heap/gc-tracer.h +++ b/src/heap/gc-tracer.h @@ -56,6 +56,8 @@ enum ScavengeSpeedMode { kForAllObjects, kForSurvivedObjects }; F(MC_EVACUATE_CANDIDATES) \ F(MC_EVACUATE_CLEAN_UP) \ F(MC_EVACUATE_COPY) \ + F(MC_EVACUATE_EPILOGUE) \ + F(MC_EVACUATE_PROLOGUE) \ F(MC_EVACUATE_REBALANCE) \ F(MC_EVACUATE_UPDATE_POINTERS) \ F(MC_EVACUATE_UPDATE_POINTERS_TO_EVACUATED) \ diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc index ae65d1f06e..adfdd4709b 100644 --- a/src/heap/mark-compact.cc +++ b/src/heap/mark-compact.cc @@ -2994,14 +2994,26 @@ static String* UpdateReferenceInExternalStringTableEntry(Heap* heap, return String::cast(*p); } -void MarkCompactCollector::EvacuateNewSpacePrologue() { +void MarkCompactCollector::EvacuatePrologue() { + // New space. NewSpace* new_space = heap()->new_space(); // Append the list of new space pages to be processed. for (Page* p : PageRange(new_space->bottom(), new_space->top())) { - newspace_evacuation_candidates_.Add(p); + new_space_evacuation_pages_.Add(p); } new_space->Flip(); new_space->ResetAllocationInfo(); + + // Old space. + CHECK(old_space_evacuation_pages_.is_empty()); + old_space_evacuation_pages_.Swap(&evacuation_candidates_); +} + +void MarkCompactCollector::EvacuateEpilogue() { + // New space. + heap()->new_space()->set_age_mark(heap()->new_space()->top()); + // Old space. Deallocate evacuated candidate pages. + ReleaseEvacuationCandidates(); } class MarkCompactCollector::Evacuator : public Malloced { @@ -3255,14 +3267,14 @@ void MarkCompactCollector::EvacuatePagesInParallel() { int abandoned_pages = 0; intptr_t live_bytes = 0; - for (Page* page : evacuation_candidates_) { + for (Page* page : old_space_evacuation_pages_) { live_bytes += page->LiveBytes(); job.AddPage(page, &abandoned_pages); } const bool reduce_memory = heap()->ShouldReduceMemory(); const Address age_mark = heap()->new_space()->age_mark(); - for (Page* page : newspace_evacuation_candidates_) { + for (Page* page : new_space_evacuation_pages_) { live_bytes += page->LiveBytes(); if (!reduce_memory && !page->NeverEvacuate() && (page->LiveBytes() > Evacuator::PageEvacuationThreshold()) && @@ -3556,13 +3568,15 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE); Heap::RelocationLock relocation_lock(heap()); + { + TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_PROLOGUE); + EvacuatePrologue(); + } + { TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_COPY); EvacuationScope evacuation_scope(this); - - EvacuateNewSpacePrologue(); EvacuatePagesInParallel(); - heap()->new_space()->set_age_mark(heap()->new_space()->top()); } UpdatePointersAfterEvacuation(); @@ -3583,7 +3597,7 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { { TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_CLEAN_UP); - for (Page* p : newspace_evacuation_candidates_) { + for (Page* p : new_space_evacuation_pages_) { if (p->IsFlagSet(Page::PAGE_NEW_NEW_PROMOTION)) { p->ClearFlag(Page::PAGE_NEW_NEW_PROMOTION); sweeper().AddPage(p->owner()->identity(), p); @@ -3594,9 +3608,9 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { sweeper().AddPage(p->owner()->identity(), p); } } - newspace_evacuation_candidates_.Rewind(0); + new_space_evacuation_pages_.Rewind(0); - for (Page* p : evacuation_candidates_) { + for (Page* p : old_space_evacuation_pages_) { // Important: skip list should be cleared only after roots were updated // because root iteration traverses the stack and might have to find // code objects from non-updated pc pointing into evacuation candidate. @@ -3607,9 +3621,11 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { p->ClearFlag(Page::COMPACTION_WAS_ABORTED); } } + } - // Deallocate evacuated candidate pages. - ReleaseEvacuationCandidates(); + { + TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_EPILOGUE); + EvacuateEpilogue(); } #ifdef VERIFY_HEAP @@ -3836,14 +3852,14 @@ void MarkCompactCollector::UpdatePointersAfterEvacuation() { void MarkCompactCollector::ReleaseEvacuationCandidates() { - for (Page* p : evacuation_candidates_) { + for (Page* p : old_space_evacuation_pages_) { if (!p->IsEvacuationCandidate()) continue; PagedSpace* space = static_cast(p->owner()); p->ResetLiveBytes(); CHECK(p->SweepingDone()); space->ReleasePage(p); } - evacuation_candidates_.Rewind(0); + old_space_evacuation_pages_.Rewind(0); compacting_ = false; heap()->memory_allocator()->unmapper()->FreeQueuedChunks(); } diff --git a/src/heap/mark-compact.h b/src/heap/mark-compact.h index 41804f916a..86d0b9616b 100644 --- a/src/heap/mark-compact.h +++ b/src/heap/mark-compact.h @@ -754,8 +754,8 @@ class MarkCompactCollector { void StartSweepSpaces(); void StartSweepSpace(PagedSpace* space); - void EvacuateNewSpacePrologue(); - + void EvacuatePrologue(); + void EvacuateEpilogue(); void EvacuatePagesInParallel(); // The number of parallel compaction tasks, including the main thread. @@ -819,8 +819,11 @@ class MarkCompactCollector { CodeFlusher* code_flusher_; + // Candidates for pages that should be evacuated. List evacuation_candidates_; - List newspace_evacuation_candidates_; + // Pages that are actually processed during evacuation. + List old_space_evacuation_pages_; + List new_space_evacuation_pages_; Sweeper sweeper_;