Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Unified Diff: src/heap/mark-compact.cc

Issue 1775003003: Implement parallel pointer updates after evacuation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/flag-definitions.h ('k') | src/heap/page-parallel-job.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/heap/mark-compact.cc
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index 4032c55592e7130d19653bfb7751d560f225f0ca..438bb4abf2ea076e48da074548eb28129f280260 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,22 +2789,6 @@ class PointersUpdatingVisitor : public ObjectVisitor {
Heap* heap_;
};
-
-static void UpdatePointer(HeapObject** address, HeapObject* object) {
- 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
- // these pointers here.
- DCHECK(map_word.IsForwardingAddress() ||
- !object->GetHeap()->old_space()->Contains(
- reinterpret_cast<Address>(address)));
- if (map_word.IsForwardingAddress()) {
- // Update the corresponding slot.
- *address = map_word.ToForwardingAddress();
- }
-}
-
-
static String* UpdateReferenceInExternalStringTableEntry(Heap* heap,
Object** p) {
MapWord map_word = HeapObject::cast(*p)->map_word();
@@ -3158,8 +3143,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>(
+ V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads()) -
+ kNumSweepingTasks - 1);
int tasks;
if (compaction_speed > 0) {
tasks = 1 + static_cast<int>(static_cast<double>(live_bytes) /
@@ -3585,6 +3572,81 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
#endif
}
+template <PointerDirection direction>
+class PointerUpdateJobTraits {
+ public:
+ typedef int PerPageData; // Per page data is not used in this job.
+ typedef PointersUpdatingVisitor* PerTaskData;
+
+ static bool ProcessPageInParallel(Heap* heap, PerTaskData visitor,
+ 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;
+ });
+ }
+ }
+
+ static void UpdateOldToNewSlot(HeapObject** address, HeapObject* object) {
+ 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
+ // these pointers here.
+ DCHECK(map_word.IsForwardingAddress() ||
+ !object->GetHeap()->old_space()->Contains(
+ reinterpret_cast<Address>(address)));
+ if (map_word.IsForwardingAddress()) {
+ // Update the corresponding slot.
+ *address = map_word.ToForwardingAddress();
+ }
+ }
+};
+
+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 +3668,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 +3676,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_);
}
{
« no previous file with comments | « src/flag-definitions.h ('k') | src/heap/page-parallel-job.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698