Chromium Code Reviews| Index: src/heap/mark-compact.cc |
| diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc |
| index 198aa04f7835ae941774b31339069ab99d49273b..7cd6ed173ff8bb5baf914ff7819929eb440b7bd4 100644 |
| --- a/src/heap/mark-compact.cc |
| +++ b/src/heap/mark-compact.cc |
| @@ -21,6 +21,7 @@ |
| #include "src/heap/object-stats.h" |
| #include "src/heap/objects-visiting-inl.h" |
| #include "src/heap/objects-visiting.h" |
| +#include "src/heap/page-parallel-job.h" |
| #include "src/heap/spaces-inl.h" |
| #include "src/ic/ic.h" |
| #include "src/ic/stub-cache.h" |
| @@ -2788,8 +2789,7 @@ class PointersUpdatingVisitor : public ObjectVisitor { |
| Heap* heap_; |
| }; |
| - |
| -static void UpdatePointer(HeapObject** address, HeapObject* object) { |
| +static void UpdateOldToNewSlot(HeapObject** address, HeapObject* object) { |
|
Michael Lippautz
2016/03/09 09:48:53
If its only use is within PointerUpdateJobTraits,
|
| MapWord map_word = object->map_word(); |
| // Since we only filter invalid slots in old space, the store buffer can |
| // still contain stale pointers in large object and in map spaces. Ignore |
| @@ -3158,8 +3158,10 @@ int MarkCompactCollector::NumberOfParallelCompactionTasks(int pages, |
| intptr_t compaction_speed = |
| heap()->tracer()->CompactionSpeedInBytesPerMillisecond(); |
| - const int available_cores = |
| - Max(1, base::SysInfo::NumberOfProcessors() - kNumSweepingTasks - 1); |
| + const int available_cores = Max( |
| + 1, static_cast<int>( |
|
Michael Lippautz
2016/03/09 09:48:53
Thanks for the drive-by-fix ;)
ulan
2016/03/09 17:34:18
Done.
|
| + V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads()) - |
| + kNumSweepingTasks - 1); |
| int tasks; |
| if (compaction_speed > 0) { |
| tasks = 1 + static_cast<int>(static_cast<double>(live_bytes) / |
| @@ -3585,6 +3587,68 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { |
| #endif |
| } |
| +template <PointerDirection direction> |
| +class PointerUpdateJobTraits { |
| + public: |
| + typedef int PerPageData; |
|
Michael Lippautz
2016/03/09 09:48:53
Maybe add a comment that PerPageData is unused for
ulan
2016/03/09 17:34:18
Done.
|
| + typedef PointersUpdatingVisitor* PerTaskData; |
| + |
| + static bool ProcessPageInParallel(Heap* heap, |
| + PointersUpdatingVisitor* visitor, |
|
Michael Lippautz
2016/03/09 09:48:53
Not sure if the equivalent version of the decl
s
ulan
2016/03/09 17:34:18
Done. It is shorter :)
|
| + MemoryChunk* chunk, PerPageData) { |
| + UpdateUntypedPointers(heap, chunk); |
| + UpdateTypedPointers(heap, chunk, visitor); |
| + return true; |
| + } |
| + static const bool NeedSequentialFinalization = false; |
| + static void FinalizePageSequentially(Heap*, MemoryChunk*, bool, PerPageData) { |
| + } |
| + |
| + private: |
| + static void UpdateUntypedPointers(Heap* heap, MemoryChunk* chunk) { |
| + if (direction == OLD_TO_NEW) { |
| + RememberedSet<OLD_TO_NEW>::IterateWithWrapper(heap, chunk, |
| + UpdateOldToNewSlot); |
| + } else { |
| + RememberedSet<OLD_TO_OLD>::Iterate(chunk, [heap](Address slot) { |
| + PointersUpdatingVisitor::UpdateSlot(heap, |
| + reinterpret_cast<Object**>(slot)); |
| + return REMOVE_SLOT; |
| + }); |
| + } |
| + } |
| + |
| + static void UpdateTypedPointers(Heap* heap, MemoryChunk* chunk, |
| + PointersUpdatingVisitor* visitor) { |
| + if (direction == OLD_TO_OLD) { |
| + Isolate* isolate = heap->isolate(); |
| + RememberedSet<OLD_TO_OLD>::IterateTyped( |
| + chunk, [isolate, visitor](SlotType type, Address slot) { |
| + UpdateTypedSlot(isolate, visitor, type, slot); |
| + return REMOVE_SLOT; |
| + }); |
| + } |
| + } |
| +}; |
| + |
| +int NumberOfPointerUpdateTasks(int pages) { |
| + if (!FLAG_parallel_pointer_update) return 1; |
| + const int kMaxTasks = 4; |
| + const int kPagesPerTask = 4; |
| + return Min(kMaxTasks, (pages + kPagesPerTask - 1) / kPagesPerTask); |
| +} |
| + |
| +template <PointerDirection direction> |
| +void UpdatePointersInParallel(Heap* heap) { |
| + PageParallelJob<PointerUpdateJobTraits<direction> > job( |
| + heap, heap->isolate()->cancelable_task_manager()); |
| + RememberedSet<direction>::IterateMemoryChunks( |
| + heap, [&job](MemoryChunk* chunk) { job.AddPage(chunk, 0); }); |
| + PointersUpdatingVisitor visitor(heap); |
| + int num_pages = job.NumberOfPages(); |
| + int num_tasks = NumberOfPointerUpdateTasks(num_pages); |
| + job.Run(num_tasks, [&visitor](int i) { return &visitor; }); |
| +} |
| void MarkCompactCollector::UpdatePointersAfterEvacuation() { |
| GCTracer::Scope gc_scope(heap()->tracer(), |
| @@ -3606,7 +3670,7 @@ void MarkCompactCollector::UpdatePointersAfterEvacuation() { |
| // Update roots. |
| heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE); |
| - RememberedSet<OLD_TO_NEW>::IterateWithWrapper(heap_, UpdatePointer); |
| + UpdatePointersInParallel<OLD_TO_NEW>(heap_); |
| } |
| { |
| @@ -3614,19 +3678,7 @@ void MarkCompactCollector::UpdatePointersAfterEvacuation() { |
| GCTracer::Scope gc_scope( |
| heap->tracer(), |
| GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_TO_EVACUATED); |
| - |
| - RememberedSet<OLD_TO_OLD>::Iterate(heap, [heap](Address slot) { |
| - PointersUpdatingVisitor::UpdateSlot(heap, |
| - reinterpret_cast<Object**>(slot)); |
| - return REMOVE_SLOT; |
| - }); |
| - Isolate* isolate = heap->isolate(); |
| - PointersUpdatingVisitor* visitor = &updating_visitor; |
| - RememberedSet<OLD_TO_OLD>::IterateTyped( |
| - heap, [isolate, visitor](SlotType type, Address slot) { |
| - UpdateTypedSlot(isolate, visitor, type, slot); |
| - return REMOVE_SLOT; |
| - }); |
| + UpdatePointersInParallel<OLD_TO_OLD>(heap_); |
| } |
| { |