[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 <ulan@chromium.org> Reviewed-by: Hannes Payer <hpayer@chromium.org> Commit-Queue: Michael Lippautz <mlippautz@chromium.org> Cr-Commit-Position: refs/heads/master@{#43378}
This commit is contained in:
parent
b008f27f02
commit
e800933eee
@ -550,6 +550,8 @@ void GCTracer::PrintNVP() const {
|
|||||||
"evacuate.candidates=%.1f "
|
"evacuate.candidates=%.1f "
|
||||||
"evacuate.clean_up=%.1f "
|
"evacuate.clean_up=%.1f "
|
||||||
"evacuate.copy=%.1f "
|
"evacuate.copy=%.1f "
|
||||||
|
"evacuate.prologue=%.1f "
|
||||||
|
"evacuate.epilogue=%.1f "
|
||||||
"evacuate.rebalance=%.1f "
|
"evacuate.rebalance=%.1f "
|
||||||
"evacuate.update_pointers=%.1f "
|
"evacuate.update_pointers=%.1f "
|
||||||
"evacuate.update_pointers.to_evacuated=%.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_CANDIDATES],
|
||||||
current_.scopes[Scope::MC_EVACUATE_CLEAN_UP],
|
current_.scopes[Scope::MC_EVACUATE_CLEAN_UP],
|
||||||
current_.scopes[Scope::MC_EVACUATE_COPY],
|
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_REBALANCE],
|
||||||
current_.scopes[Scope::MC_EVACUATE_UPDATE_POINTERS],
|
current_.scopes[Scope::MC_EVACUATE_UPDATE_POINTERS],
|
||||||
current_.scopes[Scope::MC_EVACUATE_UPDATE_POINTERS_TO_EVACUATED],
|
current_.scopes[Scope::MC_EVACUATE_UPDATE_POINTERS_TO_EVACUATED],
|
||||||
|
@ -56,6 +56,8 @@ enum ScavengeSpeedMode { kForAllObjects, kForSurvivedObjects };
|
|||||||
F(MC_EVACUATE_CANDIDATES) \
|
F(MC_EVACUATE_CANDIDATES) \
|
||||||
F(MC_EVACUATE_CLEAN_UP) \
|
F(MC_EVACUATE_CLEAN_UP) \
|
||||||
F(MC_EVACUATE_COPY) \
|
F(MC_EVACUATE_COPY) \
|
||||||
|
F(MC_EVACUATE_EPILOGUE) \
|
||||||
|
F(MC_EVACUATE_PROLOGUE) \
|
||||||
F(MC_EVACUATE_REBALANCE) \
|
F(MC_EVACUATE_REBALANCE) \
|
||||||
F(MC_EVACUATE_UPDATE_POINTERS) \
|
F(MC_EVACUATE_UPDATE_POINTERS) \
|
||||||
F(MC_EVACUATE_UPDATE_POINTERS_TO_EVACUATED) \
|
F(MC_EVACUATE_UPDATE_POINTERS_TO_EVACUATED) \
|
||||||
|
@ -2994,14 +2994,26 @@ static String* UpdateReferenceInExternalStringTableEntry(Heap* heap,
|
|||||||
return String::cast(*p);
|
return String::cast(*p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MarkCompactCollector::EvacuateNewSpacePrologue() {
|
void MarkCompactCollector::EvacuatePrologue() {
|
||||||
|
// New space.
|
||||||
NewSpace* new_space = heap()->new_space();
|
NewSpace* new_space = heap()->new_space();
|
||||||
// Append the list of new space pages to be processed.
|
// Append the list of new space pages to be processed.
|
||||||
for (Page* p : PageRange(new_space->bottom(), new_space->top())) {
|
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->Flip();
|
||||||
new_space->ResetAllocationInfo();
|
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 {
|
class MarkCompactCollector::Evacuator : public Malloced {
|
||||||
@ -3255,14 +3267,14 @@ void MarkCompactCollector::EvacuatePagesInParallel() {
|
|||||||
|
|
||||||
int abandoned_pages = 0;
|
int abandoned_pages = 0;
|
||||||
intptr_t live_bytes = 0;
|
intptr_t live_bytes = 0;
|
||||||
for (Page* page : evacuation_candidates_) {
|
for (Page* page : old_space_evacuation_pages_) {
|
||||||
live_bytes += page->LiveBytes();
|
live_bytes += page->LiveBytes();
|
||||||
job.AddPage(page, &abandoned_pages);
|
job.AddPage(page, &abandoned_pages);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool reduce_memory = heap()->ShouldReduceMemory();
|
const bool reduce_memory = heap()->ShouldReduceMemory();
|
||||||
const Address age_mark = heap()->new_space()->age_mark();
|
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();
|
live_bytes += page->LiveBytes();
|
||||||
if (!reduce_memory && !page->NeverEvacuate() &&
|
if (!reduce_memory && !page->NeverEvacuate() &&
|
||||||
(page->LiveBytes() > Evacuator::PageEvacuationThreshold()) &&
|
(page->LiveBytes() > Evacuator::PageEvacuationThreshold()) &&
|
||||||
@ -3556,13 +3568,15 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
|
|||||||
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE);
|
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE);
|
||||||
Heap::RelocationLock relocation_lock(heap());
|
Heap::RelocationLock relocation_lock(heap());
|
||||||
|
|
||||||
|
{
|
||||||
|
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_PROLOGUE);
|
||||||
|
EvacuatePrologue();
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_COPY);
|
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_COPY);
|
||||||
EvacuationScope evacuation_scope(this);
|
EvacuationScope evacuation_scope(this);
|
||||||
|
|
||||||
EvacuateNewSpacePrologue();
|
|
||||||
EvacuatePagesInParallel();
|
EvacuatePagesInParallel();
|
||||||
heap()->new_space()->set_age_mark(heap()->new_space()->top());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdatePointersAfterEvacuation();
|
UpdatePointersAfterEvacuation();
|
||||||
@ -3583,7 +3597,7 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
|
|||||||
{
|
{
|
||||||
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_CLEAN_UP);
|
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)) {
|
if (p->IsFlagSet(Page::PAGE_NEW_NEW_PROMOTION)) {
|
||||||
p->ClearFlag(Page::PAGE_NEW_NEW_PROMOTION);
|
p->ClearFlag(Page::PAGE_NEW_NEW_PROMOTION);
|
||||||
sweeper().AddPage(p->owner()->identity(), p);
|
sweeper().AddPage(p->owner()->identity(), p);
|
||||||
@ -3594,9 +3608,9 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
|
|||||||
sweeper().AddPage(p->owner()->identity(), p);
|
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
|
// Important: skip list should be cleared only after roots were updated
|
||||||
// because root iteration traverses the stack and might have to find
|
// because root iteration traverses the stack and might have to find
|
||||||
// code objects from non-updated pc pointing into evacuation candidate.
|
// code objects from non-updated pc pointing into evacuation candidate.
|
||||||
@ -3607,9 +3621,11 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
|
|||||||
p->ClearFlag(Page::COMPACTION_WAS_ABORTED);
|
p->ClearFlag(Page::COMPACTION_WAS_ABORTED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Deallocate evacuated candidate pages.
|
{
|
||||||
ReleaseEvacuationCandidates();
|
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_EPILOGUE);
|
||||||
|
EvacuateEpilogue();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef VERIFY_HEAP
|
#ifdef VERIFY_HEAP
|
||||||
@ -3836,14 +3852,14 @@ void MarkCompactCollector::UpdatePointersAfterEvacuation() {
|
|||||||
|
|
||||||
|
|
||||||
void MarkCompactCollector::ReleaseEvacuationCandidates() {
|
void MarkCompactCollector::ReleaseEvacuationCandidates() {
|
||||||
for (Page* p : evacuation_candidates_) {
|
for (Page* p : old_space_evacuation_pages_) {
|
||||||
if (!p->IsEvacuationCandidate()) continue;
|
if (!p->IsEvacuationCandidate()) continue;
|
||||||
PagedSpace* space = static_cast<PagedSpace*>(p->owner());
|
PagedSpace* space = static_cast<PagedSpace*>(p->owner());
|
||||||
p->ResetLiveBytes();
|
p->ResetLiveBytes();
|
||||||
CHECK(p->SweepingDone());
|
CHECK(p->SweepingDone());
|
||||||
space->ReleasePage(p);
|
space->ReleasePage(p);
|
||||||
}
|
}
|
||||||
evacuation_candidates_.Rewind(0);
|
old_space_evacuation_pages_.Rewind(0);
|
||||||
compacting_ = false;
|
compacting_ = false;
|
||||||
heap()->memory_allocator()->unmapper()->FreeQueuedChunks();
|
heap()->memory_allocator()->unmapper()->FreeQueuedChunks();
|
||||||
}
|
}
|
||||||
|
@ -754,8 +754,8 @@ class MarkCompactCollector {
|
|||||||
void StartSweepSpaces();
|
void StartSweepSpaces();
|
||||||
void StartSweepSpace(PagedSpace* space);
|
void StartSweepSpace(PagedSpace* space);
|
||||||
|
|
||||||
void EvacuateNewSpacePrologue();
|
void EvacuatePrologue();
|
||||||
|
void EvacuateEpilogue();
|
||||||
void EvacuatePagesInParallel();
|
void EvacuatePagesInParallel();
|
||||||
|
|
||||||
// The number of parallel compaction tasks, including the main thread.
|
// The number of parallel compaction tasks, including the main thread.
|
||||||
@ -819,8 +819,11 @@ class MarkCompactCollector {
|
|||||||
|
|
||||||
CodeFlusher* code_flusher_;
|
CodeFlusher* code_flusher_;
|
||||||
|
|
||||||
|
// Candidates for pages that should be evacuated.
|
||||||
List<Page*> evacuation_candidates_;
|
List<Page*> evacuation_candidates_;
|
||||||
List<Page*> newspace_evacuation_candidates_;
|
// Pages that are actually processed during evacuation.
|
||||||
|
List<Page*> old_space_evacuation_pages_;
|
||||||
|
List<Page*> new_space_evacuation_pages_;
|
||||||
|
|
||||||
Sweeper sweeper_;
|
Sweeper sweeper_;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user