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

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

Issue 2801073006: Decouple root visitors from object visitors. (Closed)
Patch Set: rebase Created 3 years, 8 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/heap/mark-compact.h ('k') | src/heap/object-stats.cc » ('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 2a464744e20cf120a90196bca277b66e6dac03a8..468a0e8bfdd57a0399c749cf9fa677f36b272672 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -51,7 +51,7 @@ STATIC_ASSERT(Heap::kMinObjectSizeInWords >= 2);
#ifdef VERIFY_HEAP
namespace {
-class MarkingVerifier : public ObjectVisitor {
+class MarkingVerifier : public ObjectVisitor, public RootVisitor {
public:
virtual void Run() = 0;
@@ -60,6 +60,16 @@ class MarkingVerifier : public ObjectVisitor {
virtual MarkingState marking_state(MemoryChunk* chunk) = 0;
+ virtual void VerifyPointers(Object** start, Object** end) = 0;
+
+ void VisitPointers(Object** start, Object** end) override {
+ VerifyPointers(start, end);
+ }
+
+ void VisitRootPointers(Root root, Object** start, Object** end) override {
+ VerifyPointers(start, end);
+ }
+
void VerifyRoots(VisitMode mode);
void VerifyMarkingOnPage(const Page& page, const MarkingState& state,
Address start, Address end);
@@ -152,7 +162,7 @@ class FullMarkingVerifier : public MarkingVerifier {
return MarkingState::Internal(object);
}
- void VisitPointers(Object** start, Object** end) override {
+ void VerifyPointers(Object** start, Object** end) override {
for (Object** current = start; current < end; current++) {
if ((*current)->IsHeapObject()) {
HeapObject* object = HeapObject::cast(*current);
@@ -195,7 +205,7 @@ class YoungGenerationMarkingVerifier : public MarkingVerifier {
VerifyMarking(heap_->new_space());
}
- void VisitPointers(Object** start, Object** end) override {
+ void VerifyPointers(Object** start, Object** end) override {
for (Object** current = start; current < end; current++) {
if ((*current)->IsHeapObject()) {
HeapObject* object = HeapObject::cast(*current);
@@ -206,11 +216,22 @@ class YoungGenerationMarkingVerifier : public MarkingVerifier {
}
};
-class EvacuationVerifier : public ObjectVisitor {
+class EvacuationVerifier : public ObjectVisitor, public RootVisitor {
public:
virtual void Run() = 0;
void VisitPointers(Object** start, Object** end) override {
+ VerifyPointers(start, end);
+ }
+
+ void VisitRootPointers(Root root, Object** start, Object** end) override {
+ VerifyPointers(start, end);
+ }
+
+ protected:
+ explicit EvacuationVerifier(Heap* heap) : heap_(heap) {}
+
+ void VerifyPointers(Object** start, Object** end) {
for (Object** current = start; current < end; current++) {
if ((*current)->IsHeapObject()) {
HeapObject* object = HeapObject::cast(*current);
@@ -219,9 +240,6 @@ class EvacuationVerifier : public ObjectVisitor {
}
}
- protected:
- explicit EvacuationVerifier(Heap* heap) : heap_(heap) {}
-
void VerifyRoots(VisitMode mode);
void VerifyEvacuationOnPage(Address start, Address end);
void VerifyEvacuation(NewSpace* new_space);
@@ -1357,17 +1375,26 @@ class CodeMarkingVisitor : public ThreadVisitor {
MarkCompactCollector* collector_;
};
-
-class SharedFunctionInfoMarkingVisitor : public ObjectVisitor {
+class SharedFunctionInfoMarkingVisitor : public ObjectVisitor,
+ public RootVisitor {
public:
explicit SharedFunctionInfoMarkingVisitor(MarkCompactCollector* collector)
: collector_(collector) {}
void VisitPointers(Object** start, Object** end) override {
- for (Object** p = start; p < end; p++) VisitPointer(p);
+ for (Object** p = start; p < end; p++) MarkObject(p);
+ }
+
+ void VisitPointer(Object** slot) override { MarkObject(slot); }
+
+ void VisitRootPointers(Root root, Object** start, Object** end) override {
+ for (Object** p = start; p < end; p++) MarkObject(p);
}
- void VisitPointer(Object** slot) override {
+ void VisitRootPointer(Root root, Object** slot) override { MarkObject(slot); }
+
+ private:
+ void MarkObject(Object** slot) {
Object* obj = *slot;
if (obj->IsSharedFunctionInfo()) {
SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(obj);
@@ -1375,8 +1402,6 @@ class SharedFunctionInfoMarkingVisitor : public ObjectVisitor {
collector_->MarkObject(shared);
}
}
-
- private:
MarkCompactCollector* collector_;
};
@@ -1421,21 +1446,19 @@ void MarkCompactCollector::PrepareForCodeFlushing() {
ProcessMarkingDeque();
}
-class MinorMarkCompactCollector::RootMarkingVisitor : public ObjectVisitor {
+class MinorMarkCompactCollector::RootMarkingVisitor : public RootVisitor {
public:
explicit RootMarkingVisitor(MinorMarkCompactCollector* collector)
: collector_(collector) {}
- void VisitPointer(Object** p) override { MarkObjectByPointer(p); }
+ void VisitRootPointer(Root root, Object** p) override {
+ MarkObjectByPointer(p);
+ }
- void VisitPointers(Object** start, Object** end) override {
+ void VisitRootPointers(Root root, Object** start, Object** end) override {
for (Object** p = start; p < end; p++) MarkObjectByPointer(p);
}
- // Skip the weak next code link in a code object, which is visited in
- // ProcessTopOptimizedFrame.
- void VisitNextCodeLink(Object** p) override {}
-
private:
void MarkObjectByPointer(Object** p) {
if (!(*p)->IsHeapObject()) return;
@@ -1460,7 +1483,10 @@ class MinorMarkCompactCollector::RootMarkingVisitor : public ObjectVisitor {
};
// Visitor class for marking heap roots.
-class MarkCompactCollector::RootMarkingVisitor : public ObjectVisitor {
+// TODO(ulan): Remove ObjectVisitor base class after fixing marking of
+// the string table and the top optimized code.
+class MarkCompactCollector::RootMarkingVisitor : public ObjectVisitor,
+ public RootVisitor {
public:
explicit RootMarkingVisitor(Heap* heap)
: collector_(heap->mark_compact_collector()) {}
@@ -1471,6 +1497,14 @@ class MarkCompactCollector::RootMarkingVisitor : public ObjectVisitor {
for (Object** p = start; p < end; p++) MarkObjectByPointer(p);
}
+ void VisitRootPointer(Root root, Object** p) override {
+ MarkObjectByPointer(p);
+ }
+
+ void VisitRootPointers(Root root, Object** start, Object** end) override {
+ for (Object** p = start; p < end; p++) MarkObjectByPointer(p);
+ }
+
// Skip the weak next code link in a code object, which is visited in
// ProcessTopOptimizedFrame.
void VisitNextCodeLink(Object** p) override {}
@@ -1502,38 +1536,25 @@ class MarkCompactCollector::RootMarkingVisitor : public ObjectVisitor {
MarkCompactCollector* collector_;
};
-
-// Helper class for pruning the string table.
-template <bool finalize_external_strings, bool record_slots>
-class StringTableCleaner : public ObjectVisitor {
+class InternalizedStringTableCleaner : public ObjectVisitor {
public:
- StringTableCleaner(Heap* heap, HeapObject* table)
- : heap_(heap), pointers_removed_(0), table_(table) {
- DCHECK(!record_slots || table != nullptr);
- }
+ InternalizedStringTableCleaner(Heap* heap, HeapObject* table)
+ : heap_(heap), pointers_removed_(0), table_(table) {}
void VisitPointers(Object** start, Object** end) override {
// Visit all HeapObject pointers in [start, end).
MarkCompactCollector* collector = heap_->mark_compact_collector();
+ Object* the_hole = heap_->the_hole_value();
for (Object** p = start; p < end; p++) {
Object* o = *p;
if (o->IsHeapObject()) {
HeapObject* heap_object = HeapObject::cast(o);
if (ObjectMarking::IsWhite(heap_object,
MarkingState::Internal(heap_object))) {
- if (finalize_external_strings) {
- if (o->IsExternalString()) {
- heap_->FinalizeExternalString(String::cast(*p));
- } else {
- // The original external string may have been internalized.
- DCHECK(o->IsThinString());
- }
- } else {
- pointers_removed_++;
- }
+ pointers_removed_++;
// Set the entry to the_hole_value (as deleted).
- *p = heap_->the_hole_value();
- } else if (record_slots) {
+ *p = the_hole;
+ } else {
// StringTable contains only old space strings.
DCHECK(!heap_->InNewSpace(o));
collector->RecordSlot(table_, p, o);
@@ -1543,7 +1564,6 @@ class StringTableCleaner : public ObjectVisitor {
}
int PointersRemoved() {
- DCHECK(!finalize_external_strings);
return pointers_removed_;
}
@@ -1553,8 +1573,35 @@ class StringTableCleaner : public ObjectVisitor {
HeapObject* table_;
};
-typedef StringTableCleaner<false, true> InternalizedStringTableCleaner;
-typedef StringTableCleaner<true, false> ExternalStringTableCleaner;
+class ExternalStringTableCleaner : public RootVisitor {
+ public:
+ explicit ExternalStringTableCleaner(Heap* heap) : heap_(heap) {}
+
+ void VisitRootPointers(Root root, Object** start, Object** end) override {
+ // Visit all HeapObject pointers in [start, end).
+ Object* the_hole = heap_->the_hole_value();
+ for (Object** p = start; p < end; p++) {
+ Object* o = *p;
+ if (o->IsHeapObject()) {
+ HeapObject* heap_object = HeapObject::cast(o);
+ if (ObjectMarking::IsWhite(heap_object,
+ MarkingState::Internal(heap_object))) {
+ if (o->IsExternalString()) {
+ heap_->FinalizeExternalString(String::cast(*p));
+ } else {
+ // The original external string may have been internalized.
+ DCHECK(o->IsThinString());
+ }
+ // Set the entry to the_hole_value (as deleted).
+ *p = the_hole;
+ }
+ }
+ }
+ }
+
+ private:
+ Heap* heap_;
+};
// Implementation of WeakObjectRetainer for mark compact GCs. All marked objects
// are retained.
@@ -2151,7 +2198,7 @@ void MarkCompactCollector::ProcessMarkingDeque() {
// Mark all objects reachable (transitively) from objects on the marking
// stack including references only considered in the atomic marking pause.
void MarkCompactCollector::ProcessEphemeralMarking(
- ObjectVisitor* visitor, bool only_process_harmony_weak_collections) {
+ bool only_process_harmony_weak_collections) {
DCHECK(marking_deque()->IsEmpty() && !marking_deque()->overflowed());
bool work_to_do = true;
while (work_to_do) {
@@ -2179,7 +2226,8 @@ void MarkCompactCollector::ProcessEphemeralMarking(
CHECK_EQ(0, heap()->local_embedder_heap_tracer()->NumberOfWrappersToTrace());
}
-void MarkCompactCollector::ProcessTopOptimizedFrame(ObjectVisitor* visitor) {
+void MarkCompactCollector::ProcessTopOptimizedFrame(
+ RootMarkingVisitor* visitor) {
for (StackFrameIterator it(isolate(), isolate()->thread_local_top());
!it.done(); it.Advance()) {
if (it.frame()->type() == StackFrame::JAVA_SCRIPT) {
@@ -2409,7 +2457,7 @@ void MinorMarkCompactCollector::MarkLiveObjects() {
{
TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_WEAK);
- heap()->VisitEncounteredWeakCollections(&root_visitor);
+ heap()->IterateEncounteredWeakCollections(&root_visitor);
ProcessMarkingDeque();
}
@@ -2510,7 +2558,7 @@ void MarkCompactCollector::MarkLiveObjects() {
{
TRACE_GC(heap()->tracer(),
GCTracer::Scope::MC_MARK_WEAK_CLOSURE_EPHEMERAL);
- ProcessEphemeralMarking(&root_visitor, false);
+ ProcessEphemeralMarking(false);
}
// The objects reachable from the roots, weak maps or object groups
@@ -2543,7 +2591,7 @@ void MarkCompactCollector::MarkLiveObjects() {
// processed and no weakly reachable node can discover new objects groups.
{
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WEAK_CLOSURE_HARMONY);
- ProcessEphemeralMarking(&root_visitor, true);
+ ProcessEphemeralMarking(true);
{
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WRAPPER_EPILOGUE);
heap()->local_embedder_heap_tracer()->TraceEpilogue();
@@ -2567,7 +2615,7 @@ void MarkCompactCollector::ClearNonLiveReferences() {
string_table->IterateElements(&internalized_visitor);
string_table->ElementsRemoved(internalized_visitor.PointersRemoved());
- ExternalStringTableCleaner external_visitor(heap(), nullptr);
+ ExternalStringTableCleaner external_visitor(heap());
heap()->external_string_table_.IterateAll(&external_visitor);
heap()->external_string_table_.CleanUpAll();
}
@@ -3038,9 +3086,11 @@ static inline SlotCallbackResult UpdateSlot(Object** slot) {
return REMOVE_SLOT;
}
-// Visitor for updating pointers from live objects in old spaces to new space.
+// Visitor for updating root pointers and to-space pointers.
// It does not expect to encounter pointers to dead objects.
-class PointersUpdatingVisitor : public ObjectVisitor {
+// TODO(ulan): Remove code object specific functions. This visitor
+// nevers visits code objects.
+class PointersUpdatingVisitor : public ObjectVisitor, public RootVisitor {
public:
void VisitPointer(Object** p) override { UpdateSlot(p); }
@@ -3048,6 +3098,12 @@ class PointersUpdatingVisitor : public ObjectVisitor {
for (Object** p = start; p < end; p++) UpdateSlot(p);
}
+ void VisitRootPointer(Root root, Object** p) override { UpdateSlot(p); }
+
+ void VisitRootPointers(Root root, Object** start, Object** end) override {
+ for (Object** p = start; p < end; p++) UpdateSlot(p);
+ }
+
void VisitCell(RelocInfo* rinfo) override {
UpdateTypedSlotHelper::UpdateCell(rinfo, UpdateSlot);
}
@@ -3909,13 +3965,13 @@ void UpdateToSpacePointersInParallel(Heap* heap, base::Semaphore* semaphore) {
void MarkCompactCollector::UpdatePointersAfterEvacuation() {
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS);
- PointersUpdatingVisitor updating_visitor;
{
TRACE_GC(heap()->tracer(),
GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_TO_NEW);
UpdateToSpacePointersInParallel(heap_, &page_parallel_job_semaphore_);
// Update roots.
+ PointersUpdatingVisitor updating_visitor;
heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE);
UpdatePointersInParallel<OLD_TO_NEW>(heap_, &page_parallel_job_semaphore_);
}
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/object-stats.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698