| 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;
|
|
|