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

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

Issue 1991843003: Refactor PointerUpdatingVisitor. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 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 | « no previous file | no next file » | 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 b328393da00c13e916d4eed730ab472adf239b48..d410797bdf7b71fae2b8c54464c7d2048784963b 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -2799,42 +2799,138 @@ void MarkCompactCollector::RecordRelocSlot(Code* host, RelocInfo* rinfo,
}
}
-static inline void UpdateTypedSlot(Isolate* isolate, ObjectVisitor* v,
- SlotType slot_type, Address addr) {
+static inline SlotCallbackResult UpdateSlot(Object** slot) {
+ Object* obj = reinterpret_cast<Object*>(
+ base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot)));
+
+ if (obj->IsHeapObject()) {
+ HeapObject* heap_obj = HeapObject::cast(obj);
+ MapWord map_word = heap_obj->map_word();
+ if (map_word.IsForwardingAddress()) {
+ DCHECK(heap_obj->GetHeap()->InFromSpace(heap_obj) ||
+ MarkCompactCollector::IsOnEvacuationCandidate(heap_obj) ||
+ Page::FromAddress(heap_obj->address())
+ ->IsFlagSet(Page::COMPACTION_WAS_ABORTED));
+ HeapObject* target = map_word.ToForwardingAddress();
+ base::NoBarrier_CompareAndSwap(
+ reinterpret_cast<base::AtomicWord*>(slot),
+ reinterpret_cast<base::AtomicWord>(obj),
+ reinterpret_cast<base::AtomicWord>(target));
+ DCHECK(!heap_obj->GetHeap()->InFromSpace(target) &&
+ !MarkCompactCollector::IsOnEvacuationCandidate(target));
+ }
+ }
+ return REMOVE_SLOT;
+}
+
+// Updates a cell slot using an untyped slot callback.
+// The callback accepts (Heap*, Object**) and returns SlotCallbackResult.
+template <typename Callback>
+static SlotCallbackResult UpdateCell(RelocInfo* rinfo, Callback callback) {
+ DCHECK(rinfo->rmode() == RelocInfo::CELL);
+ Object* cell = rinfo->target_cell();
+ Object* old_cell = cell;
+ SlotCallbackResult result = callback(&cell);
+ if (cell != old_cell) {
+ rinfo->set_target_cell(reinterpret_cast<Cell*>(cell));
+ }
+ return result;
+}
+
+// Updates a code entry slot using an untyped slot callback.
+// The callback accepts (Heap*, Object**) and returns SlotCallbackResult.
+template <typename Callback>
+static SlotCallbackResult UpdateCodeEntry(Address entry_address,
+ Callback callback) {
+ Object* code = Code::GetObjectFromEntryAddress(entry_address);
+ Object* old_code = code;
+ SlotCallbackResult result = callback(&code);
+ if (code != old_code) {
+ Memory::Address_at(entry_address) = reinterpret_cast<Code*>(code)->entry();
+ }
+ return result;
+}
+
+// Updates a code target slot using an untyped slot callback.
+// The callback accepts (Heap*, Object**) and returns SlotCallbackResult.
+template <typename Callback>
+static SlotCallbackResult UpdateCodeTarget(RelocInfo* rinfo,
+ Callback callback) {
+ DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode()));
+ Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
+ Object* old_target = target;
+ SlotCallbackResult result = callback(&target);
+ if (target != old_target) {
+ rinfo->set_target_address(Code::cast(target)->instruction_start());
+ }
+ return result;
+}
+
+// Updates an embedded pointer slot using an untyped slot callback.
+// The callback accepts (Heap*, Object**) and returns SlotCallbackResult.
+template <typename Callback>
+static SlotCallbackResult UpdateEmbeddedPointer(RelocInfo* rinfo,
+ Callback callback) {
+ DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
+ Object* target = rinfo->target_object();
+ Object* old_target = target;
+ SlotCallbackResult result = callback(&target);
+ if (target != old_target) {
+ rinfo->set_target_object(target);
+ }
+ return result;
+}
+
+// Updates a debug target slot using an untyped slot callback.
+// The callback accepts (Heap*, Object**) and returns SlotCallbackResult.
+template <typename Callback>
+static SlotCallbackResult UpdateDebugTarget(RelocInfo* rinfo,
+ Callback callback) {
+ DCHECK(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
+ rinfo->IsPatchedDebugBreakSlotSequence());
+ Object* target = Code::GetCodeFromTargetAddress(rinfo->debug_call_address());
+ SlotCallbackResult result = callback(&target);
+ rinfo->set_debug_call_address(Code::cast(target)->instruction_start());
+ return result;
+}
+
+// Updates a typed slot using an untyped slot callback.
+// The callback accepts (Heap*, Object**) and returns SlotCallbackResult.
+template <typename Callback>
+static SlotCallbackResult UpdateTypedSlot(Isolate* isolate, SlotType slot_type,
+ Address addr, Callback callback) {
switch (slot_type) {
case CODE_TARGET_SLOT: {
RelocInfo rinfo(isolate, addr, RelocInfo::CODE_TARGET, 0, NULL);
- rinfo.Visit(isolate, v);
- break;
+ return UpdateCodeTarget(&rinfo, callback);
}
case CELL_TARGET_SLOT: {
RelocInfo rinfo(isolate, addr, RelocInfo::CELL, 0, NULL);
- rinfo.Visit(isolate, v);
- break;
+ return UpdateCell(&rinfo, callback);
}
case CODE_ENTRY_SLOT: {
- v->VisitCodeEntry(addr);
- break;
+ return UpdateCodeEntry(addr, callback);
}
case DEBUG_TARGET_SLOT: {
RelocInfo rinfo(isolate, addr, RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION, 0,
NULL);
- if (rinfo.IsPatchedDebugBreakSlotSequence()) rinfo.Visit(isolate, v);
- break;
+ if (rinfo.IsPatchedDebugBreakSlotSequence()) {
+ return UpdateDebugTarget(&rinfo, callback);
+ }
+ return REMOVE_SLOT;
}
case EMBEDDED_OBJECT_SLOT: {
RelocInfo rinfo(isolate, addr, RelocInfo::EMBEDDED_OBJECT, 0, NULL);
- rinfo.Visit(isolate, v);
- break;
+ return UpdateEmbeddedPointer(&rinfo, callback);
}
case OBJECT_SLOT: {
- v->VisitPointer(reinterpret_cast<Object**>(addr));
- break;
+ return callback(reinterpret_cast<Object**>(addr));
}
- default:
- UNREACHABLE();
+ case NUMBER_OF_SLOT_TYPES:
break;
}
+ UNREACHABLE();
+ return REMOVE_SLOT;
}
@@ -2842,103 +2938,29 @@ static inline void UpdateTypedSlot(Isolate* isolate, ObjectVisitor* v,
// It does not expect to encounter pointers to dead objects.
class PointersUpdatingVisitor : public ObjectVisitor {
public:
- explicit PointersUpdatingVisitor(Heap* heap) : heap_(heap) {}
-
- void VisitPointer(Object** p) override { UpdatePointer(p); }
+ void VisitPointer(Object** p) override { UpdateSlot(p); }
void VisitPointers(Object** start, Object** end) override {
- for (Object** p = start; p < end; p++) UpdatePointer(p);
+ for (Object** p = start; p < end; p++) UpdateSlot(p);
}
- void VisitCell(RelocInfo* rinfo) override {
- DCHECK(rinfo->rmode() == RelocInfo::CELL);
- Object* cell = rinfo->target_cell();
- Object* old_cell = cell;
- VisitPointer(&cell);
- if (cell != old_cell) {
- rinfo->set_target_cell(reinterpret_cast<Cell*>(cell));
- }
- }
+ void VisitCell(RelocInfo* rinfo) override { UpdateCell(rinfo, UpdateSlot); }
void VisitEmbeddedPointer(RelocInfo* rinfo) override {
- DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
- Object* target = rinfo->target_object();
- Object* old_target = target;
- VisitPointer(&target);
- // Avoid unnecessary changes that might unnecessary flush the instruction
- // cache.
- if (target != old_target) {
- rinfo->set_target_object(target);
- }
+ UpdateEmbeddedPointer(rinfo, UpdateSlot);
}
void VisitCodeTarget(RelocInfo* rinfo) override {
- DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode()));
- Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
- Object* old_target = target;
- VisitPointer(&target);
- if (target != old_target) {
- rinfo->set_target_address(Code::cast(target)->instruction_start());
- }
- }
-
- void VisitCodeAgeSequence(RelocInfo* rinfo) override {
- DCHECK(RelocInfo::IsCodeAgeSequence(rinfo->rmode()));
- Object* stub = rinfo->code_age_stub();
- DCHECK(stub != NULL);
- VisitPointer(&stub);
- if (stub != rinfo->code_age_stub()) {
- rinfo->set_code_age_stub(Code::cast(stub));
- }
+ UpdateCodeTarget(rinfo, UpdateSlot);
}
void VisitCodeEntry(Address entry_address) override {
- Object* code = Code::GetObjectFromEntryAddress(entry_address);
- Object* old_code = code;
- VisitPointer(&code);
- if (code != old_code) {
- Memory::Address_at(entry_address) =
- reinterpret_cast<Code*>(code)->entry();
- }
+ UpdateCodeEntry(entry_address, UpdateSlot);
}
void VisitDebugTarget(RelocInfo* rinfo) override {
- DCHECK(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
- rinfo->IsPatchedDebugBreakSlotSequence());
- Object* target =
- Code::GetCodeFromTargetAddress(rinfo->debug_call_address());
- VisitPointer(&target);
- rinfo->set_debug_call_address(Code::cast(target)->instruction_start());
- }
-
- static inline void UpdateSlot(Heap* heap, Object** slot) {
- Object* obj = reinterpret_cast<Object*>(
- base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot)));
-
- if (!obj->IsHeapObject()) return;
-
- HeapObject* heap_obj = HeapObject::cast(obj);
-
- MapWord map_word = heap_obj->map_word();
- if (map_word.IsForwardingAddress()) {
- DCHECK(heap->InFromSpace(heap_obj) ||
- MarkCompactCollector::IsOnEvacuationCandidate(heap_obj) ||
- Page::FromAddress(heap_obj->address())
- ->IsFlagSet(Page::COMPACTION_WAS_ABORTED));
- HeapObject* target = map_word.ToForwardingAddress();
- base::NoBarrier_CompareAndSwap(
- reinterpret_cast<base::AtomicWord*>(slot),
- reinterpret_cast<base::AtomicWord>(obj),
- reinterpret_cast<base::AtomicWord>(target));
- DCHECK(!heap->InFromSpace(target) &&
- !MarkCompactCollector::IsOnEvacuationCandidate(target));
- }
+ UpdateDebugTarget(rinfo, UpdateSlot);
}
-
- private:
- inline void UpdatePointer(Object** p) { UpdateSlot(heap_, p); }
-
- Heap* heap_;
};
static String* UpdateReferenceInExternalStringTableEntry(Heap* heap,
@@ -3629,12 +3651,12 @@ template <PointerDirection direction>
class PointerUpdateJobTraits {
public:
typedef int PerPageData; // Per page data is not used in this job.
- typedef PointersUpdatingVisitor* PerTaskData;
+ typedef int PerTaskData; // Per task data is not used in this job.
- static bool ProcessPageInParallel(Heap* heap, PerTaskData visitor,
- MemoryChunk* chunk, PerPageData) {
+ static bool ProcessPageInParallel(Heap* heap, PerTaskData, MemoryChunk* chunk,
+ PerPageData) {
UpdateUntypedPointers(heap, chunk);
- UpdateTypedPointers(heap, chunk, visitor);
+ UpdateTypedPointers(heap, chunk);
return true;
}
static const bool NeedSequentialFinalization = false;
@@ -3647,22 +3669,18 @@ class PointerUpdateJobTraits {
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;
+ RememberedSet<OLD_TO_OLD>::Iterate(chunk, [](Address slot) {
+ return UpdateSlot(reinterpret_cast<Object**>(slot));
});
}
}
- static void UpdateTypedPointers(Heap* heap, MemoryChunk* chunk,
- PointersUpdatingVisitor* visitor) {
+ static void UpdateTypedPointers(Heap* heap, MemoryChunk* chunk) {
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;
+ chunk, [isolate](SlotType type, Address slot) {
+ return UpdateTypedSlot(isolate, type, slot, UpdateSlot);
});
}
}
@@ -3691,10 +3709,9 @@ void UpdatePointersInParallel(Heap* heap) {
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; });
+ job.Run(num_tasks, [](int i) { return 0; });
}
class ToSpacePointerUpdateJobTraits {
@@ -3731,7 +3748,7 @@ void UpdateToSpacePointersInParallel(Heap* heap) {
Address end = page->Contains(space_end) ? space_end : page->area_end();
job.AddPage(page, std::make_pair(start, end));
}
- PointersUpdatingVisitor visitor(heap);
+ PointersUpdatingVisitor visitor;
int num_tasks = FLAG_parallel_pointer_update ? job.NumberOfPages() : 1;
job.Run(num_tasks, [&visitor](int i) { return &visitor; });
}
@@ -3739,7 +3756,7 @@ void UpdateToSpacePointersInParallel(Heap* heap) {
void MarkCompactCollector::UpdatePointersAfterEvacuation() {
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS);
- PointersUpdatingVisitor updating_visitor(heap());
+ PointersUpdatingVisitor updating_visitor;
{
TRACE_GC(heap()->tracer(),
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698