Index: src/heap/mark-compact.cc |
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc |
index ee04ee846d68b76a35c8b7cae2bcb790ad0252eb..5be69a10d1fcddc6cfba672954111ef8d672784c 100644 |
--- a/src/heap/mark-compact.cc |
+++ b/src/heap/mark-compact.cc |
@@ -321,7 +321,7 @@ void MarkCompactCollector::CollectGarbage() { |
} |
#endif |
- SweepSpaces(); |
+ StartSweepSpaces(); |
EvacuateNewSpaceAndCandidates(); |
@@ -451,22 +451,20 @@ void MarkCompactCollector::Sweeper::StartSweeping() { |
std::sort(sweeping_list_[space].begin(), sweeping_list_[space].end(), |
[](Page* a, Page* b) { return a->LiveBytes() < b->LiveBytes(); }); |
}); |
- if (FLAG_concurrent_sweeping) { |
+} |
+ |
+void MarkCompactCollector::Sweeper::StartSweeperTasks() { |
+ if (FLAG_concurrent_sweeping && sweeping_in_progress_) { |
ForAllSweepingSpaces([this](AllocationSpace space) { |
if (space == NEW_SPACE) return; |
- StartSweepingHelper(space); |
+ num_sweeping_tasks_.Increment(1); |
+ V8::GetCurrentPlatform()->CallOnBackgroundThread( |
+ new SweeperTask(this, &pending_sweeper_tasks_semaphore_, space), |
+ v8::Platform::kShortRunningTask); |
}); |
} |
} |
-void MarkCompactCollector::Sweeper::StartSweepingHelper( |
- AllocationSpace space_to_start) { |
- num_sweeping_tasks_.Increment(1); |
- V8::GetCurrentPlatform()->CallOnBackgroundThread( |
- new SweeperTask(this, &pending_sweeper_tasks_semaphore_, space_to_start), |
- v8::Platform::kShortRunningTask); |
-} |
- |
void MarkCompactCollector::Sweeper::SweepOrWaitUntilSweepingCompleted( |
Page* page) { |
if (!page->SweepingDone()) { |
@@ -481,7 +479,8 @@ void MarkCompactCollector::Sweeper::SweepOrWaitUntilSweepingCompleted( |
} |
void MarkCompactCollector::SweepAndRefill(CompactionSpace* space) { |
- if (FLAG_concurrent_sweeping && !sweeper().IsSweepingCompleted()) { |
+ if (FLAG_concurrent_sweeping && |
+ !sweeper().IsSweepingCompleted(space->identity())) { |
sweeper().ParallelSweepSpace(space->identity(), 0); |
space->RefillFreeList(); |
} |
@@ -501,10 +500,11 @@ void MarkCompactCollector::Sweeper::EnsureCompleted() { |
// If sweeping is not completed or not running at all, we try to complete it |
// here. |
- if (!FLAG_concurrent_sweeping || !IsSweepingCompleted()) { |
- ForAllSweepingSpaces( |
- [this](AllocationSpace space) { ParallelSweepSpace(space, 0); }); |
- } |
+ ForAllSweepingSpaces([this](AllocationSpace space) { |
+ if (!FLAG_concurrent_sweeping || !this->IsSweepingCompleted(space)) { |
+ ParallelSweepSpace(space, 0); |
+ } |
+ }); |
if (FLAG_concurrent_sweeping) { |
while (num_sweeping_tasks_.Value() > 0) { |
@@ -519,13 +519,12 @@ void MarkCompactCollector::Sweeper::EnsureCompleted() { |
} |
DCHECK(sweeping_list_[space].empty()); |
}); |
- late_pages_ = false; |
sweeping_in_progress_ = false; |
} |
void MarkCompactCollector::Sweeper::EnsureNewSpaceCompleted() { |
if (!sweeping_in_progress_) return; |
- if (!FLAG_concurrent_sweeping || !IsSweepingCompleted()) { |
+ if (!FLAG_concurrent_sweeping || !IsSweepingCompleted(NEW_SPACE)) { |
for (Page* p : *heap_->new_space()) { |
SweepOrWaitUntilSweepingCompleted(p); |
} |
@@ -547,13 +546,20 @@ void MarkCompactCollector::EnsureSweepingCompleted() { |
#endif |
} |
-bool MarkCompactCollector::Sweeper::IsSweepingCompleted() { |
+bool MarkCompactCollector::Sweeper::AreSweeperTasksRunning() { |
DCHECK(FLAG_concurrent_sweeping); |
while (pending_sweeper_tasks_semaphore_.WaitFor( |
base::TimeDelta::FromSeconds(0))) { |
num_sweeping_tasks_.Increment(-1); |
} |
- return num_sweeping_tasks_.Value() == 0; |
+ return num_sweeping_tasks_.Value() != 0; |
+} |
+ |
+bool MarkCompactCollector::Sweeper::IsSweepingCompleted(AllocationSpace space) { |
+ DCHECK(FLAG_concurrent_sweeping); |
+ if (AreSweeperTasksRunning()) return false; |
+ base::LockGuard<base::Mutex> guard(&mutex_); |
+ return sweeping_list_[space].empty(); |
} |
const char* AllocationSpaceName(AllocationSpace space) { |
@@ -832,11 +838,7 @@ void MarkCompactCollector::Prepare() { |
void MarkCompactCollector::Finish() { |
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_FINISH); |
- if (sweeper().contains_late_pages() && FLAG_concurrent_sweeping) { |
- // If we added some more pages during MC, we need to start at least one |
- // more task as all other tasks might already be finished. |
- sweeper().StartSweepingHelper(OLD_SPACE); |
- } |
+ sweeper().StartSweeperTasks(); |
// The hashing of weak_object_to_code_table is no longer valid. |
heap()->weak_object_to_code_table()->Rehash( |
@@ -3173,17 +3175,15 @@ int MarkCompactCollector::NumberOfParallelCompactionTasks(int pages, |
// |
// The number of parallel compaction tasks is limited by: |
// - #evacuation pages |
- // - (#cores - 1) |
+ // - #cores |
const double kTargetCompactionTimeInMs = .5; |
- const int kNumSweepingTasks = 3; |
double compaction_speed = |
heap()->tracer()->CompactionSpeedInBytesPerMillisecond(); |
const int available_cores = Max( |
1, static_cast<int>( |
- V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads()) - |
- kNumSweepingTasks - 1); |
+ V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads())); |
int tasks; |
if (compaction_speed > 0) { |
tasks = 1 + static_cast<int>(live_bytes / compaction_speed / |
@@ -3543,12 +3543,12 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { |
for (Page* p : newspace_evacuation_candidates_) { |
if (p->IsFlagSet(Page::PAGE_NEW_NEW_PROMOTION)) { |
p->ClearFlag(Page::PAGE_NEW_NEW_PROMOTION); |
- sweeper().AddLatePage(p->owner()->identity(), p); |
+ sweeper().AddPage(p->owner()->identity(), p); |
} else if (p->IsFlagSet(Page::PAGE_NEW_OLD_PROMOTION)) { |
p->ClearFlag(Page::PAGE_NEW_OLD_PROMOTION); |
p->ForAllFreeListCategories( |
[](FreeListCategory* category) { DCHECK(!category->is_linked()); }); |
- sweeper().AddLatePage(p->owner()->identity(), p); |
+ sweeper().AddPage(p->owner()->identity(), p); |
} |
} |
newspace_evacuation_candidates_.Rewind(0); |
@@ -3560,7 +3560,7 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { |
SkipList* list = p->skip_list(); |
if (list != NULL) list->Clear(); |
if (p->IsFlagSet(Page::COMPACTION_WAS_ABORTED)) { |
- sweeper().AddLatePage(p->owner()->identity(), p); |
+ sweeper().AddPage(p->owner()->identity(), p); |
p->ClearFlag(Page::COMPACTION_WAS_ABORTED); |
} |
} |
@@ -3862,19 +3862,11 @@ int MarkCompactCollector::Sweeper::ParallelSweepPage(Page* page, |
} |
void MarkCompactCollector::Sweeper::AddPage(AllocationSpace space, Page* page) { |
- DCHECK(!sweeping_in_progress_); |
+ DCHECK(!FLAG_concurrent_sweeping || !AreSweeperTasksRunning()); |
PrepareToBeSweptPage(space, page); |
sweeping_list_[space].push_back(page); |
} |
-void MarkCompactCollector::Sweeper::AddLatePage(AllocationSpace space, |
- Page* page) { |
- DCHECK(sweeping_in_progress_); |
- PrepareToBeSweptPage(space, page); |
- late_pages_ = true; |
- AddSweepingPageSafe(space, page); |
-} |
- |
void MarkCompactCollector::Sweeper::PrepareToBeSweptPage(AllocationSpace space, |
Page* page) { |
page->concurrent_sweeping_state().SetValue(Page::kSweepingPending); |
@@ -3955,8 +3947,7 @@ void MarkCompactCollector::StartSweepSpace(PagedSpace* space) { |
} |
} |
- |
-void MarkCompactCollector::SweepSpaces() { |
+void MarkCompactCollector::StartSweepSpaces() { |
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_SWEEP); |
#ifdef DEBUG |
state_ = SWEEP_SPACES; |