Chromium Code Reviews| 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" | 9 #include "src/base/sys-info.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 328 } | 328 } |
| 329 }; | 329 }; |
| 330 | 330 |
| 331 } // namespace | 331 } // namespace |
| 332 #endif // VERIFY_HEAP | 332 #endif // VERIFY_HEAP |
| 333 | 333 |
| 334 // ============================================================================= | 334 // ============================================================================= |
| 335 // MarkCompactCollectorBase, MinorMarkCompactCollector, MarkCompactCollector | 335 // MarkCompactCollectorBase, MinorMarkCompactCollector, MarkCompactCollector |
| 336 // ============================================================================= | 336 // ============================================================================= |
| 337 | 337 |
| 338 int MarkCompactCollectorBase::NumberOfParallelCompactionTasks( | 338 int MarkCompactCollectorBase::NumberOfParallelCompactionTasks(int pages) { |
| 339 int pages, intptr_t live_bytes) { | |
| 340 if (!FLAG_parallel_compaction) return 1; | 339 if (!FLAG_parallel_compaction) return 1; |
| 341 // Compute the number of needed tasks based on a target compaction time, the | |
| 342 // profiled compaction speed and marked live memory. | |
| 343 // | |
| 344 // The number of parallel compaction tasks is limited by: | |
| 345 // - #evacuation pages | |
| 346 // - #cores | |
| 347 const double kTargetCompactionTimeInMs = .5; | |
| 348 | |
| 349 double compaction_speed = | |
| 350 heap()->tracer()->CompactionSpeedInBytesPerMillisecond(); | |
|
Michael Lippautz
2017/05/10 14:38:40
I will get rid of this one if we decide to keep it
| |
| 351 | |
| 352 const int available_cores = Max( | 340 const int available_cores = Max( |
| 353 1, static_cast<int>( | 341 1, static_cast<int>( |
| 354 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads())); | 342 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads())); |
| 355 int tasks; | 343 return Min(available_cores, pages); |
| 356 if (compaction_speed > 0) { | 344 } |
| 357 tasks = 1 + static_cast<int>(live_bytes / compaction_speed / | 345 |
| 358 kTargetCompactionTimeInMs); | 346 int MarkCompactCollectorBase::NumberOfPointerUpdateTasks(int pages) { |
| 359 } else { | 347 if (!FLAG_parallel_pointer_update) return 1; |
| 360 tasks = pages; | 348 const int available_cores = Max( |
| 361 } | 349 1, static_cast<int>( |
| 362 const int tasks_capped_pages = Min(pages, tasks); | 350 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads())); |
| 363 return Min(available_cores, tasks_capped_pages); | 351 return Min(available_cores, pages); |
| 364 } | 352 } |
| 365 | 353 |
| 366 MarkCompactCollector::MarkCompactCollector(Heap* heap) | 354 MarkCompactCollector::MarkCompactCollector(Heap* heap) |
| 367 : MarkCompactCollectorBase(heap), | 355 : MarkCompactCollectorBase(heap), |
| 368 page_parallel_job_semaphore_(0), | 356 page_parallel_job_semaphore_(0), |
| 369 #ifdef DEBUG | 357 #ifdef DEBUG |
| 370 state_(IDLE), | 358 state_(IDLE), |
| 371 #endif | 359 #endif |
| 372 was_marked_incrementally_(false), | 360 was_marked_incrementally_(false), |
| 373 evacuation_(false), | 361 evacuation_(false), |
| (...skipping 3363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3737 compaction_speed = heap()->tracer()->CompactionSpeedInBytesPerMillisecond(); | 3725 compaction_speed = heap()->tracer()->CompactionSpeedInBytesPerMillisecond(); |
| 3738 } | 3726 } |
| 3739 | 3727 |
| 3740 const bool profiling = | 3728 const bool profiling = |
| 3741 heap()->isolate()->is_profiling() || | 3729 heap()->isolate()->is_profiling() || |
| 3742 heap()->isolate()->logger()->is_logging_code_events() || | 3730 heap()->isolate()->logger()->is_logging_code_events() || |
| 3743 heap()->isolate()->heap_profiler()->is_tracking_object_moves(); | 3731 heap()->isolate()->heap_profiler()->is_tracking_object_moves(); |
| 3744 ProfilingMigrationObserver profiling_observer(heap()); | 3732 ProfilingMigrationObserver profiling_observer(heap()); |
| 3745 | 3733 |
| 3746 const int wanted_num_tasks = | 3734 const int wanted_num_tasks = |
| 3747 NumberOfParallelCompactionTasks(job->NumberOfPages(), live_bytes); | 3735 NumberOfParallelCompactionTasks(job->NumberOfPages()); |
| 3748 Evacuator** evacuators = new Evacuator*[wanted_num_tasks]; | 3736 Evacuator** evacuators = new Evacuator*[wanted_num_tasks]; |
| 3749 for (int i = 0; i < wanted_num_tasks; i++) { | 3737 for (int i = 0; i < wanted_num_tasks; i++) { |
| 3750 evacuators[i] = new Evacuator(collector, record_visitor); | 3738 evacuators[i] = new Evacuator(collector, record_visitor); |
| 3751 if (profiling) evacuators[i]->AddObserver(&profiling_observer); | 3739 if (profiling) evacuators[i]->AddObserver(&profiling_observer); |
| 3752 if (migration_observer != nullptr) | 3740 if (migration_observer != nullptr) |
| 3753 evacuators[i]->AddObserver(migration_observer); | 3741 evacuators[i]->AddObserver(migration_observer); |
| 3754 } | 3742 } |
| 3755 job->Run(wanted_num_tasks, [evacuators](int i) { return evacuators[i]; }); | 3743 job->Run(wanted_num_tasks, [evacuators](int i) { return evacuators[i]; }); |
| 3756 const Address top = heap()->new_space()->top(); | 3744 const Address top = heap()->new_space()->top(); |
| 3757 for (int i = 0; i < wanted_num_tasks; i++) { | 3745 for (int i = 0; i < wanted_num_tasks; i++) { |
| (...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4255 if (ObjectMarking::IsBlack(heap_object, | 4243 if (ObjectMarking::IsBlack(heap_object, |
| 4256 collector->marking_state(heap_object))) | 4244 collector->marking_state(heap_object))) |
| 4257 return KEEP_SLOT; | 4245 return KEEP_SLOT; |
| 4258 } else { | 4246 } else { |
| 4259 DCHECK(!heap->InNewSpace(slot_reference)); | 4247 DCHECK(!heap->InNewSpace(slot_reference)); |
| 4260 } | 4248 } |
| 4261 return REMOVE_SLOT; | 4249 return REMOVE_SLOT; |
| 4262 } | 4250 } |
| 4263 }; | 4251 }; |
| 4264 | 4252 |
| 4265 int NumberOfPointerUpdateTasks(int pages) { | |
| 4266 if (!FLAG_parallel_pointer_update) return 1; | |
| 4267 const int available_cores = Max( | |
| 4268 1, static_cast<int>( | |
| 4269 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads())); | |
| 4270 const int kPagesPerTask = 4; | |
| 4271 return Min(available_cores, (pages + kPagesPerTask - 1) / kPagesPerTask); | |
| 4272 } | |
| 4273 | |
| 4274 template <RememberedSetType type> | 4253 template <RememberedSetType type> |
| 4275 void UpdatePointersInParallel(Heap* heap, base::Semaphore* semaphore, | 4254 void UpdatePointersInParallel(Heap* heap, base::Semaphore* semaphore, |
| 4276 const MarkCompactCollectorBase* collector) { | 4255 const MarkCompactCollectorBase* collector) { |
| 4277 PageParallelJob<PointerUpdateJobTraits<type> > job( | 4256 PageParallelJob<PointerUpdateJobTraits<type> > job( |
| 4278 heap, heap->isolate()->cancelable_task_manager(), semaphore); | 4257 heap, heap->isolate()->cancelable_task_manager(), semaphore); |
| 4279 RememberedSet<type>::IterateMemoryChunks( | 4258 RememberedSet<type>::IterateMemoryChunks( |
| 4280 heap, [&job](MemoryChunk* chunk) { job.AddPage(chunk, 0); }); | 4259 heap, [&job](MemoryChunk* chunk) { job.AddPage(chunk, 0); }); |
| 4281 int num_pages = job.NumberOfPages(); | 4260 int num_pages = job.NumberOfPages(); |
| 4282 int num_tasks = NumberOfPointerUpdateTasks(num_pages); | 4261 int num_tasks = NumberOfPointerUpdateTasks(num_pages); |
| 4283 job.Run(num_tasks, [collector](int i) { return collector; }); | 4262 job.Run(num_tasks, [collector](int i) { return collector; }); |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4638 // The target is always in old space, we don't have to record the slot in | 4617 // The target is always in old space, we don't have to record the slot in |
| 4639 // the old-to-new remembered set. | 4618 // the old-to-new remembered set. |
| 4640 DCHECK(!heap()->InNewSpace(target)); | 4619 DCHECK(!heap()->InNewSpace(target)); |
| 4641 RecordRelocSlot(host, &rinfo, target); | 4620 RecordRelocSlot(host, &rinfo, target); |
| 4642 } | 4621 } |
| 4643 } | 4622 } |
| 4644 } | 4623 } |
| 4645 | 4624 |
| 4646 } // namespace internal | 4625 } // namespace internal |
| 4647 } // namespace v8 | 4626 } // namespace v8 |
| OLD | NEW |