| Index: src/heap/mark-compact.cc
|
| diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
|
| index 87e1b34f5c021acd57af14d222a5f107620a5e47..d090de066932274a5c344eaee91cf03c0d73fc6f 100644
|
| --- a/src/heap/mark-compact.cc
|
| +++ b/src/heap/mark-compact.cc
|
| @@ -6,6 +6,7 @@
|
|
|
| #include "src/base/atomicops.h"
|
| #include "src/base/bits.h"
|
| +#include "src/base/sys-info.h"
|
| #include "src/code-stubs.h"
|
| #include "src/compilation-cache.h"
|
| #include "src/cpu-profiler.h"
|
| @@ -572,7 +573,6 @@ void MarkCompactCollector::EnsureSweepingCompleted() {
|
| heap()->paged_space(OLD_SPACE)->ResetUnsweptFreeBytes();
|
| heap()->paged_space(CODE_SPACE)->ResetUnsweptFreeBytes();
|
| heap()->paged_space(MAP_SPACE)->ResetUnsweptFreeBytes();
|
| -
|
| #ifdef VERIFY_HEAP
|
| if (FLAG_verify_heap && !evacuation()) {
|
| VerifyEvacuation(heap_);
|
| @@ -593,7 +593,6 @@ bool MarkCompactCollector::IsSweepingCompleted() {
|
|
|
| void MarkCompactCollector::RefillFreeList(PagedSpace* space) {
|
| FreeList* free_list;
|
| -
|
| if (space == heap()->old_space()) {
|
| free_list = free_list_old_space_.get();
|
| } else if (space == heap()->code_space()) {
|
| @@ -3370,52 +3369,57 @@ bool MarkCompactCollector::EvacuateLiveObjectsFromPage(
|
| }
|
|
|
|
|
| +int MarkCompactCollector::NumberOfParallelCompactionTasks() {
|
| + if (!FLAG_parallel_compaction) return 1;
|
| + // We cap the number of parallel compaction tasks by
|
| + // - (#cores - 1)
|
| + // - a value depending on the list of evacuation candidates
|
| + // - a hard limit
|
| + const int kPagesPerCompactionTask = 4;
|
| + const int kMaxCompactionTasks = 8;
|
| + return Min(kMaxCompactionTasks,
|
| + Min(1 + evacuation_candidates_.length() / kPagesPerCompactionTask,
|
| + Max(1, base::SysInfo::NumberOfProcessors() - 1)));
|
| +}
|
| +
|
| +
|
| void MarkCompactCollector::EvacuatePagesInParallel() {
|
| if (evacuation_candidates_.length() == 0) return;
|
|
|
| - int num_tasks = 1;
|
| - if (FLAG_parallel_compaction) {
|
| - num_tasks = NumberOfParallelCompactionTasks();
|
| - }
|
| + const int num_tasks = NumberOfParallelCompactionTasks();
|
|
|
| // Set up compaction spaces.
|
| - CompactionSpaceCollection** compaction_spaces_for_tasks =
|
| + CompactionSpaceCollection** spaces_for_tasks =
|
| new CompactionSpaceCollection*[num_tasks];
|
| for (int i = 0; i < num_tasks; i++) {
|
| - compaction_spaces_for_tasks[i] = new CompactionSpaceCollection(heap());
|
| + spaces_for_tasks[i] = new CompactionSpaceCollection(heap());
|
| }
|
| -
|
| - compaction_spaces_for_tasks[0]->Get(OLD_SPACE)->MoveOverFreeMemory(
|
| - heap()->old_space());
|
| - compaction_spaces_for_tasks[0]
|
| - ->Get(CODE_SPACE)
|
| - ->MoveOverFreeMemory(heap()->code_space());
|
| + heap()->old_space()->DivideMemory(spaces_for_tasks, num_tasks, 1 * MB);
|
| + heap()->code_space()->DivideMemory(spaces_for_tasks, num_tasks, 1 * MB);
|
|
|
| compaction_in_progress_ = true;
|
| // Kick off parallel tasks.
|
| for (int i = 1; i < num_tasks; i++) {
|
| concurrent_compaction_tasks_active_++;
|
| V8::GetCurrentPlatform()->CallOnBackgroundThread(
|
| - new CompactionTask(heap(), compaction_spaces_for_tasks[i]),
|
| + new CompactionTask(heap(), spaces_for_tasks[i]),
|
| v8::Platform::kShortRunningTask);
|
| }
|
|
|
| - // Contribute in main thread. Counter and signal are in principal not needed.
|
| - concurrent_compaction_tasks_active_++;
|
| - EvacuatePages(compaction_spaces_for_tasks[0], &migration_slots_buffer_);
|
| - pending_compaction_tasks_semaphore_.Signal();
|
| + // Perform compaction on the main thread.
|
| + EvacuatePages(spaces_for_tasks[0], &migration_slots_buffer_);
|
|
|
| WaitUntilCompactionCompleted();
|
|
|
| // Merge back memory (compacted and unused) from compaction spaces.
|
| for (int i = 0; i < num_tasks; i++) {
|
| heap()->old_space()->MergeCompactionSpace(
|
| - compaction_spaces_for_tasks[i]->Get(OLD_SPACE));
|
| + spaces_for_tasks[i]->Get(OLD_SPACE));
|
| heap()->code_space()->MergeCompactionSpace(
|
| - compaction_spaces_for_tasks[i]->Get(CODE_SPACE));
|
| - delete compaction_spaces_for_tasks[i];
|
| + spaces_for_tasks[i]->Get(CODE_SPACE));
|
| + delete spaces_for_tasks[i];
|
| }
|
| - delete[] compaction_spaces_for_tasks;
|
| + delete[] spaces_for_tasks;
|
|
|
| // Finalize sequentially.
|
| const int num_pages = evacuation_candidates_.length();
|
|
|