Index: src/heap/mark-compact.cc |
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc |
index 5be69a10d1fcddc6cfba672954111ef8d672784c..ee04ee846d68b76a35c8b7cae2bcb790ad0252eb 100644 |
--- a/src/heap/mark-compact.cc |
+++ b/src/heap/mark-compact.cc |
@@ -321,7 +321,7 @@ |
} |
#endif |
- StartSweepSpaces(); |
+ SweepSpaces(); |
EvacuateNewSpaceAndCandidates(); |
@@ -451,18 +451,20 @@ |
std::sort(sweeping_list_[space].begin(), sweeping_list_[space].end(), |
[](Page* a, Page* b) { return a->LiveBytes() < b->LiveBytes(); }); |
}); |
-} |
- |
-void MarkCompactCollector::Sweeper::StartSweeperTasks() { |
- if (FLAG_concurrent_sweeping && sweeping_in_progress_) { |
+ if (FLAG_concurrent_sweeping) { |
ForAllSweepingSpaces([this](AllocationSpace space) { |
if (space == NEW_SPACE) return; |
- num_sweeping_tasks_.Increment(1); |
- V8::GetCurrentPlatform()->CallOnBackgroundThread( |
- new SweeperTask(this, &pending_sweeper_tasks_semaphore_, space), |
- v8::Platform::kShortRunningTask); |
+ StartSweepingHelper(space); |
}); |
} |
+} |
+ |
+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( |
@@ -479,8 +481,7 @@ |
} |
void MarkCompactCollector::SweepAndRefill(CompactionSpace* space) { |
- if (FLAG_concurrent_sweeping && |
- !sweeper().IsSweepingCompleted(space->identity())) { |
+ if (FLAG_concurrent_sweeping && !sweeper().IsSweepingCompleted()) { |
sweeper().ParallelSweepSpace(space->identity(), 0); |
space->RefillFreeList(); |
} |
@@ -500,11 +501,10 @@ |
// If sweeping is not completed or not running at all, we try to complete it |
// here. |
- ForAllSweepingSpaces([this](AllocationSpace space) { |
- if (!FLAG_concurrent_sweeping || !this->IsSweepingCompleted(space)) { |
- ParallelSweepSpace(space, 0); |
- } |
- }); |
+ if (!FLAG_concurrent_sweeping || !IsSweepingCompleted()) { |
+ ForAllSweepingSpaces( |
+ [this](AllocationSpace space) { ParallelSweepSpace(space, 0); }); |
+ } |
if (FLAG_concurrent_sweeping) { |
while (num_sweeping_tasks_.Value() > 0) { |
@@ -519,12 +519,13 @@ |
} |
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(NEW_SPACE)) { |
+ if (!FLAG_concurrent_sweeping || !IsSweepingCompleted()) { |
for (Page* p : *heap_->new_space()) { |
SweepOrWaitUntilSweepingCompleted(p); |
} |
@@ -546,20 +547,13 @@ |
#endif |
} |
-bool MarkCompactCollector::Sweeper::AreSweeperTasksRunning() { |
+bool MarkCompactCollector::Sweeper::IsSweepingCompleted() { |
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; |
-} |
- |
-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(); |
+ return num_sweeping_tasks_.Value() == 0; |
} |
const char* AllocationSpaceName(AllocationSpace space) { |
@@ -838,7 +832,11 @@ |
void MarkCompactCollector::Finish() { |
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_FINISH); |
- sweeper().StartSweeperTasks(); |
+ 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); |
+ } |
// The hashing of weak_object_to_code_table is no longer valid. |
heap()->weak_object_to_code_table()->Rehash( |
@@ -3175,15 +3173,17 @@ |
// |
// The number of parallel compaction tasks is limited by: |
// - #evacuation pages |
- // - #cores |
+ // - (#cores - 1) |
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())); |
+ V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads()) - |
+ kNumSweepingTasks - 1); |
int tasks; |
if (compaction_speed > 0) { |
tasks = 1 + static_cast<int>(live_bytes / compaction_speed / |
@@ -3543,12 +3543,12 @@ |
for (Page* p : newspace_evacuation_candidates_) { |
if (p->IsFlagSet(Page::PAGE_NEW_NEW_PROMOTION)) { |
p->ClearFlag(Page::PAGE_NEW_NEW_PROMOTION); |
- sweeper().AddPage(p->owner()->identity(), p); |
+ sweeper().AddLatePage(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().AddPage(p->owner()->identity(), p); |
+ sweeper().AddLatePage(p->owner()->identity(), p); |
} |
} |
newspace_evacuation_candidates_.Rewind(0); |
@@ -3560,7 +3560,7 @@ |
SkipList* list = p->skip_list(); |
if (list != NULL) list->Clear(); |
if (p->IsFlagSet(Page::COMPACTION_WAS_ABORTED)) { |
- sweeper().AddPage(p->owner()->identity(), p); |
+ sweeper().AddLatePage(p->owner()->identity(), p); |
p->ClearFlag(Page::COMPACTION_WAS_ABORTED); |
} |
} |
@@ -3862,9 +3862,17 @@ |
} |
void MarkCompactCollector::Sweeper::AddPage(AllocationSpace space, Page* page) { |
- DCHECK(!FLAG_concurrent_sweeping || !AreSweeperTasksRunning()); |
+ DCHECK(!sweeping_in_progress_); |
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, |
@@ -3947,7 +3955,8 @@ |
} |
} |
-void MarkCompactCollector::StartSweepSpaces() { |
+ |
+void MarkCompactCollector::SweepSpaces() { |
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_SWEEP); |
#ifdef DEBUG |
state_ = SWEEP_SPACES; |