| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/heap/mark-compact.h" | 5 #include "src/heap/mark-compact.h" |
| 6 | 6 |
| 7 #include "src/base/atomicops.h" | 7 #include "src/base/atomicops.h" |
| 8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
| 9 #include "src/base/sys-info.h" | |
| 10 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 11 #include "src/compilation-cache.h" | 10 #include "src/compilation-cache.h" |
| 12 #include "src/cpu-profiler.h" | 11 #include "src/cpu-profiler.h" |
| 13 #include "src/deoptimizer.h" | 12 #include "src/deoptimizer.h" |
| 14 #include "src/execution.h" | 13 #include "src/execution.h" |
| 15 #include "src/frames-inl.h" | 14 #include "src/frames-inl.h" |
| 16 #include "src/gdb-jit.h" | 15 #include "src/gdb-jit.h" |
| 17 #include "src/global-handles.h" | 16 #include "src/global-handles.h" |
| 18 #include "src/heap/array-buffer-tracker.h" | 17 #include "src/heap/array-buffer-tracker.h" |
| 19 #include "src/heap/gc-tracer.h" | 18 #include "src/heap/gc-tracer.h" |
| (...skipping 3341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3361 } | 3360 } |
| 3362 | 3361 |
| 3363 // Clear marking bits for current cell. | 3362 // Clear marking bits for current cell. |
| 3364 *cell = 0; | 3363 *cell = 0; |
| 3365 } | 3364 } |
| 3366 p->ResetLiveBytes(); | 3365 p->ResetLiveBytes(); |
| 3367 return true; | 3366 return true; |
| 3368 } | 3367 } |
| 3369 | 3368 |
| 3370 | 3369 |
| 3371 int MarkCompactCollector::NumberOfParallelCompactionTasks() { | |
| 3372 if (!FLAG_parallel_compaction) return 1; | |
| 3373 // We cap the number of parallel compaction tasks by | |
| 3374 // - (#cores - 1) | |
| 3375 // - a value depending on the list of evacuation candidates | |
| 3376 // - a hard limit | |
| 3377 const int kPagesPerCompactionTask = 4; | |
| 3378 const int kMaxCompactionTasks = 8; | |
| 3379 return Min(kMaxCompactionTasks, | |
| 3380 Min(1 + evacuation_candidates_.length() / kPagesPerCompactionTask, | |
| 3381 Max(1, base::SysInfo::NumberOfProcessors() - 1))); | |
| 3382 } | |
| 3383 | |
| 3384 | |
| 3385 void MarkCompactCollector::EvacuatePagesInParallel() { | 3370 void MarkCompactCollector::EvacuatePagesInParallel() { |
| 3386 if (evacuation_candidates_.length() == 0) return; | 3371 if (evacuation_candidates_.length() == 0) return; |
| 3387 | 3372 |
| 3388 const int num_tasks = NumberOfParallelCompactionTasks(); | 3373 int num_tasks = 1; |
| 3374 if (FLAG_parallel_compaction) { |
| 3375 num_tasks = NumberOfParallelCompactionTasks(); |
| 3376 } |
| 3389 | 3377 |
| 3390 // Set up compaction spaces. | 3378 // Set up compaction spaces. |
| 3391 CompactionSpaceCollection** compaction_spaces_for_tasks = | 3379 CompactionSpaceCollection** compaction_spaces_for_tasks = |
| 3392 new CompactionSpaceCollection*[num_tasks]; | 3380 new CompactionSpaceCollection*[num_tasks]; |
| 3393 FreeList** free_lists = new FreeList*[2 * num_tasks]; | |
| 3394 for (int i = 0; i < num_tasks; i++) { | 3381 for (int i = 0; i < num_tasks; i++) { |
| 3395 compaction_spaces_for_tasks[i] = new CompactionSpaceCollection(heap()); | 3382 compaction_spaces_for_tasks[i] = new CompactionSpaceCollection(heap()); |
| 3396 free_lists[i] = compaction_spaces_for_tasks[i]->Get(OLD_SPACE)->free_list(); | |
| 3397 free_lists[i + num_tasks] = | |
| 3398 compaction_spaces_for_tasks[i]->Get(CODE_SPACE)->free_list(); | |
| 3399 } | 3383 } |
| 3400 heap()->old_space()->DivideFreeLists(free_lists, num_tasks, 1 * MB); | 3384 |
| 3401 heap()->code_space()->DivideFreeLists(&free_lists[num_tasks], num_tasks, | 3385 compaction_spaces_for_tasks[0]->Get(OLD_SPACE)->MoveOverFreeMemory( |
| 3402 1 * MB); | 3386 heap()->old_space()); |
| 3403 delete[] free_lists; | 3387 compaction_spaces_for_tasks[0] |
| 3388 ->Get(CODE_SPACE) |
| 3389 ->MoveOverFreeMemory(heap()->code_space()); |
| 3404 | 3390 |
| 3405 compaction_in_progress_ = true; | 3391 compaction_in_progress_ = true; |
| 3406 // Kick off parallel tasks. | 3392 // Kick off parallel tasks. |
| 3407 for (int i = 1; i < num_tasks; i++) { | 3393 for (int i = 1; i < num_tasks; i++) { |
| 3408 concurrent_compaction_tasks_active_++; | 3394 concurrent_compaction_tasks_active_++; |
| 3409 V8::GetCurrentPlatform()->CallOnBackgroundThread( | 3395 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
| 3410 new CompactionTask(heap(), compaction_spaces_for_tasks[i]), | 3396 new CompactionTask(heap(), compaction_spaces_for_tasks[i]), |
| 3411 v8::Platform::kShortRunningTask); | 3397 v8::Platform::kShortRunningTask); |
| 3412 } | 3398 } |
| 3413 | 3399 |
| 3414 // Perform compaction on the main thread. | 3400 // Contribute in main thread. Counter and signal are in principal not needed. |
| 3401 concurrent_compaction_tasks_active_++; |
| 3415 EvacuatePages(compaction_spaces_for_tasks[0], &migration_slots_buffer_); | 3402 EvacuatePages(compaction_spaces_for_tasks[0], &migration_slots_buffer_); |
| 3403 pending_compaction_tasks_semaphore_.Signal(); |
| 3416 | 3404 |
| 3417 WaitUntilCompactionCompleted(); | 3405 WaitUntilCompactionCompleted(); |
| 3418 | 3406 |
| 3419 // Merge back memory (compacted and unused) from compaction spaces. | 3407 // Merge back memory (compacted and unused) from compaction spaces. |
| 3420 for (int i = 0; i < num_tasks; i++) { | 3408 for (int i = 0; i < num_tasks; i++) { |
| 3421 heap()->old_space()->MergeCompactionSpace( | 3409 heap()->old_space()->MergeCompactionSpace( |
| 3422 compaction_spaces_for_tasks[i]->Get(OLD_SPACE)); | 3410 compaction_spaces_for_tasks[i]->Get(OLD_SPACE)); |
| 3423 heap()->code_space()->MergeCompactionSpace( | 3411 heap()->code_space()->MergeCompactionSpace( |
| 3424 compaction_spaces_for_tasks[i]->Get(CODE_SPACE)); | 3412 compaction_spaces_for_tasks[i]->Get(CODE_SPACE)); |
| 3425 delete compaction_spaces_for_tasks[i]; | 3413 delete compaction_spaces_for_tasks[i]; |
| (...skipping 1172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4598 MarkBit mark_bit = Marking::MarkBitFrom(host); | 4586 MarkBit mark_bit = Marking::MarkBitFrom(host); |
| 4599 if (Marking::IsBlack(mark_bit)) { | 4587 if (Marking::IsBlack(mark_bit)) { |
| 4600 RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host); | 4588 RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host); |
| 4601 RecordRelocSlot(&rinfo, target); | 4589 RecordRelocSlot(&rinfo, target); |
| 4602 } | 4590 } |
| 4603 } | 4591 } |
| 4604 } | 4592 } |
| 4605 | 4593 |
| 4606 } // namespace internal | 4594 } // namespace internal |
| 4607 } // namespace v8 | 4595 } // namespace v8 |
| OLD | NEW |