Commit 4e8b60af authored by Leon Bettscheider's avatar Leon Bettscheider Committed by V8 LUCI CQ

[heap] Introduce CollectorBase class

This CL is part of an effort to enable concurrent marking in MinorMC.

For this purpose we plan to reuse the IncrementalMarking class which
already implements a part of the concurrent marking code for MajorMC
(and is currently coupled with MarkCompactCollector).

We plan to parameterize IncrementalMarking with CollectorBase, which
can be either MinorMarkCompactCollector or MarkCompactCollector, in
a subsequent CL.

Bug: v8:13012
Change-Id: I595bfdcb6e1abaa270d8037d889620433f26a416
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3749183
Commit-Queue: Leon Bettscheider <bettscheider@google.com>
Reviewed-by: 's avatarOmer Katz <omerkatz@chromium.org>
Reviewed-by: 's avatarDominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81797}
parent 263db307
...@@ -2641,6 +2641,7 @@ void Heap::MinorMarkCompact() { ...@@ -2641,6 +2641,7 @@ void Heap::MinorMarkCompact() {
CppHeap::PauseConcurrentMarkingScope pause_cpp_marking( CppHeap::PauseConcurrentMarkingScope pause_cpp_marking(
CppHeap::From(cpp_heap_)); CppHeap::From(cpp_heap_));
minor_mark_compact_collector_->Prepare();
minor_mark_compact_collector_->CollectGarbage(); minor_mark_compact_collector_->CollectGarbage();
SetGCState(NOT_IN_GC); SetGCState(NOT_IN_GC);
......
...@@ -43,7 +43,7 @@ void MarkCompactCollector::MarkRootObject(Root root, HeapObject obj) { ...@@ -43,7 +43,7 @@ void MarkCompactCollector::MarkRootObject(Root root, HeapObject obj) {
void MinorMarkCompactCollector::MarkRootObject(HeapObject obj) { void MinorMarkCompactCollector::MarkRootObject(HeapObject obj) {
if (Heap::InYoungGeneration(obj) && if (Heap::InYoungGeneration(obj) &&
non_atomic_marking_state_.WhiteToBlack(obj)) { non_atomic_marking_state_.WhiteToBlack(obj)) {
main_thread_worklists_local_->Push(obj); local_marking_worklists_->Push(obj);
} }
} }
...@@ -279,8 +279,7 @@ typename LiveObjectRange<mode>::iterator LiveObjectRange<mode>::end() { ...@@ -279,8 +279,7 @@ typename LiveObjectRange<mode>::iterator LiveObjectRange<mode>::end() {
return iterator(chunk_, bitmap_, end_); return iterator(chunk_, bitmap_, end_);
} }
Isolate* MarkCompactCollector::isolate() { return heap()->isolate(); } Isolate* CollectorBase::isolate() { return heap()->isolate(); }
Isolate* MinorMarkCompactCollector::isolate() { return heap()->isolate(); }
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -476,17 +476,26 @@ int NumberOfParallelCompactionTasks(Heap* heap) { ...@@ -476,17 +476,26 @@ int NumberOfParallelCompactionTasks(Heap* heap) {
} }
return tasks; return tasks;
} }
} // namespace } // namespace
MarkCompactCollector::MarkCompactCollector(Heap* heap) CollectorBase::CollectorBase(Heap* heap, GarbageCollector collector)
: heap_(heap), : heap_(heap),
garbage_collector_(collector),
marking_state_(heap->isolate()),
non_atomic_marking_state_(heap->isolate()) {
DCHECK_NE(GarbageCollector::SCAVENGER, garbage_collector_);
}
bool CollectorBase::IsMajorMC() {
return !heap_->IsYoungGenerationCollector(garbage_collector_);
}
MarkCompactCollector::MarkCompactCollector(Heap* heap)
: CollectorBase(heap, GarbageCollector::MARK_COMPACTOR),
#ifdef DEBUG #ifdef DEBUG
state_(IDLE), state_(IDLE),
#endif #endif
is_shared_heap_(heap->IsShared()), is_shared_heap_(heap->IsShared()),
marking_state_(heap->isolate()),
non_atomic_marking_state_(heap->isolate()),
sweeper_(new Sweeper(heap, non_atomic_marking_state())) { sweeper_(new Sweeper(heap, non_atomic_marking_state())) {
} }
...@@ -2346,9 +2355,8 @@ void MarkCompactCollector::MarkTransitiveClosureLinear() { ...@@ -2346,9 +2355,8 @@ void MarkCompactCollector::MarkTransitiveClosureLinear() {
GCTracer::Scope::MC_MARK_WEAK_CLOSURE_EPHEMERON_MARKING); GCTracer::Scope::MC_MARK_WEAK_CLOSURE_EPHEMERON_MARKING);
// Drain marking worklist and push all discovered objects into // Drain marking worklist and push all discovered objects into
// newly_discovered. // newly_discovered.
ProcessMarkingWorklist< ProcessMarkingWorklist(
MarkCompactCollector::MarkingWorklistProcessingMode:: 0, MarkingWorklistProcessingMode::kTrackNewlyDiscoveredObjects);
kTrackNewlyDiscoveredObjects>(0);
} }
while (local_weak_objects()->discovered_ephemerons_local.Pop(&ephemeron)) { while (local_weak_objects()->discovered_ephemerons_local.Pop(&ephemeron)) {
...@@ -2426,9 +2434,14 @@ void MarkCompactCollector::PerformWrapperTracing() { ...@@ -2426,9 +2434,14 @@ void MarkCompactCollector::PerformWrapperTracing() {
} }
} }
template <MarkCompactCollector::MarkingWorklistProcessingMode mode>
std::pair<size_t, size_t> MarkCompactCollector::ProcessMarkingWorklist( std::pair<size_t, size_t> MarkCompactCollector::ProcessMarkingWorklist(
size_t bytes_to_process) { size_t bytes_to_process) {
return ProcessMarkingWorklist(bytes_to_process,
MarkingWorklistProcessingMode::kDefault);
}
std::pair<size_t, size_t> MarkCompactCollector::ProcessMarkingWorklist(
size_t bytes_to_process, MarkingWorklistProcessingMode mode) {
HeapObject object; HeapObject object;
size_t bytes_processed = 0; size_t bytes_processed = 0;
size_t objects_processed = 0; size_t objects_processed = 0;
...@@ -2485,14 +2498,6 @@ std::pair<size_t, size_t> MarkCompactCollector::ProcessMarkingWorklist( ...@@ -2485,14 +2498,6 @@ std::pair<size_t, size_t> MarkCompactCollector::ProcessMarkingWorklist(
return std::make_pair(bytes_processed, objects_processed); return std::make_pair(bytes_processed, objects_processed);
} }
// Generate definitions for use in other files.
template std::pair<size_t, size_t> MarkCompactCollector::ProcessMarkingWorklist<
MarkCompactCollector::MarkingWorklistProcessingMode::kDefault>(
size_t bytes_to_process);
template std::pair<size_t, size_t> MarkCompactCollector::ProcessMarkingWorklist<
MarkCompactCollector::MarkingWorklistProcessingMode::
kTrackNewlyDiscoveredObjects>(size_t bytes_to_process);
bool MarkCompactCollector::ProcessEphemeron(HeapObject key, HeapObject value) { bool MarkCompactCollector::ProcessEphemeron(HeapObject key, HeapObject value) {
if (marking_state()->IsBlackOrGrey(key)) { if (marking_state()->IsBlackOrGrey(key)) {
if (marking_state()->WhiteToGrey(value)) { if (marking_state()->WhiteToGrey(value)) {
...@@ -5470,11 +5475,16 @@ void MinorMarkCompactCollector::TearDown() {} ...@@ -5470,11 +5475,16 @@ void MinorMarkCompactCollector::TearDown() {}
constexpr size_t MinorMarkCompactCollector::kMaxParallelTasks; constexpr size_t MinorMarkCompactCollector::kMaxParallelTasks;
MinorMarkCompactCollector::MinorMarkCompactCollector(Heap* heap) MinorMarkCompactCollector::MinorMarkCompactCollector(Heap* heap)
: heap_(heap), : CollectorBase(heap, GarbageCollector::MINOR_MARK_COMPACTOR),
marking_state_(heap->isolate()),
non_atomic_marking_state_(heap->isolate()),
page_parallel_job_semaphore_(0) {} page_parallel_job_semaphore_(0) {}
std::pair<size_t, size_t> MinorMarkCompactCollector::ProcessMarkingWorklist(
size_t bytes_to_process) {
// TODO(v8:13012): Implement this later. It should be similar to
// MinorMarkCompactCollector::DrainMarkingWorklist.
return std::pair<size_t, size_t>(0, 0);
}
void MinorMarkCompactCollector::CleanupPromotedPages() { void MinorMarkCompactCollector::CleanupPromotedPages() {
for (Page* p : promoted_pages_) { for (Page* p : promoted_pages_) {
p->ClearFlag(Page::PAGE_NEW_NEW_PROMOTION); p->ClearFlag(Page::PAGE_NEW_NEW_PROMOTION);
...@@ -5494,7 +5504,18 @@ void MinorMarkCompactCollector::CleanupPromotedPages() { ...@@ -5494,7 +5504,18 @@ void MinorMarkCompactCollector::CleanupPromotedPages() {
promoted_large_pages_.clear(); promoted_large_pages_.clear();
} }
void MinorMarkCompactCollector::VisitObject(HeapObject obj) {
main_marking_visitor_->Visit(obj.map(), obj);
}
void MinorMarkCompactCollector::RevisitObject(HeapObject obj) {
// TODO(v8:13012): Implement.
UNREACHABLE();
}
void MinorMarkCompactCollector::SweepArrayBufferExtensions() { void MinorMarkCompactCollector::SweepArrayBufferExtensions() {
TRACE_GC(heap()->tracer(),
GCTracer::Scope::MINOR_MC_FINISH_SWEEP_ARRAY_BUFFERS);
heap_->array_buffer_sweeper()->RequestSweep( heap_->array_buffer_sweeper()->RequestSweep(
ArrayBufferSweeper::SweepingType::kYoung); ArrayBufferSweeper::SweepingType::kYoung);
} }
...@@ -5654,6 +5675,27 @@ class MinorMarkCompactCollector::RootMarkingVisitor : public RootVisitor { ...@@ -5654,6 +5675,27 @@ class MinorMarkCompactCollector::RootMarkingVisitor : public RootVisitor {
MinorMarkCompactCollector* const collector_; MinorMarkCompactCollector* const collector_;
}; };
void MinorMarkCompactCollector::Prepare() {
// Probably requires more.
if (!heap()->incremental_marking()->IsMarking()) {
StartMarking();
}
}
void MinorMarkCompactCollector::StartMarking() {
local_marking_worklists_ =
std::make_unique<MarkingWorklists::Local>(&marking_worklists_);
main_marking_visitor_ = std::make_unique<YoungGenerationMarkingVisitor>(
heap()->isolate(), marking_state(), local_marking_worklists());
}
void MinorMarkCompactCollector::Finish() {
TRACE_GC(heap()->tracer(),
GCTracer::Scope::MINOR_MC_FINISH);
local_marking_worklists_.reset();
main_marking_visitor_.reset();
}
void MinorMarkCompactCollector::CollectGarbage() { void MinorMarkCompactCollector::CollectGarbage() {
DCHECK(!heap()->mark_compact_collector()->in_use()); DCHECK(!heap()->mark_compact_collector()->in_use());
#ifdef VERIFY_HEAP #ifdef VERIFY_HEAP
...@@ -5676,6 +5718,8 @@ void MinorMarkCompactCollector::CollectGarbage() { ...@@ -5676,6 +5718,8 @@ void MinorMarkCompactCollector::CollectGarbage() {
#endif // VERIFY_HEAP #endif // VERIFY_HEAP
Evacuate(); Evacuate();
Finish();
#ifdef VERIFY_HEAP #ifdef VERIFY_HEAP
if (FLAG_verify_heap) { if (FLAG_verify_heap) {
YoungGenerationEvacuationVerifier verifier(heap()); YoungGenerationEvacuationVerifier verifier(heap());
...@@ -6080,15 +6124,16 @@ void MinorMarkCompactCollector::MarkRootSetInParallel( ...@@ -6080,15 +6124,16 @@ void MinorMarkCompactCollector::MarkRootSetInParallel(
// The main thread might hold local items, while GlobalPoolSize() == // The main thread might hold local items, while GlobalPoolSize() ==
// 0. Flush to ensure these items are visible globally and picked up // 0. Flush to ensure these items are visible globally and picked up
// by the job. // by the job.
main_thread_worklists_local_->Publish(); local_marking_worklists_->Publish();
TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_ROOTS); TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_ROOTS);
V8::GetCurrentPlatform() V8::GetCurrentPlatform()
->PostJob(v8::TaskPriority::kUserBlocking, ->PostJob(v8::TaskPriority::kUserBlocking,
std::make_unique<YoungGenerationMarkingJob>( std::make_unique<YoungGenerationMarkingJob>(
isolate(), this, worklists(), std::move(marking_items))) isolate(), this, marking_worklists(),
std::move(marking_items)))
->Join(); ->Join();
DCHECK(main_thread_worklists_local_->IsEmpty()); DCHECK(local_marking_worklists_->IsEmpty());
} }
} }
} }
...@@ -6096,10 +6141,8 @@ void MinorMarkCompactCollector::MarkRootSetInParallel( ...@@ -6096,10 +6141,8 @@ void MinorMarkCompactCollector::MarkRootSetInParallel(
void MinorMarkCompactCollector::MarkLiveObjects() { void MinorMarkCompactCollector::MarkLiveObjects() {
TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK); TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK);
main_thread_worklists_local_ = DCHECK_NOT_NULL(local_marking_worklists_);
std::make_unique<MarkingWorklists::Local>(&worklists_); DCHECK_NOT_NULL(main_marking_visitor_);
main_marking_visitor_ = std::make_unique<YoungGenerationMarkingVisitor>(
heap()->isolate(), marking_state(), main_thread_worklists_local());
PostponeInterruptsScope postpone(isolate()); PostponeInterruptsScope postpone(isolate());
...@@ -6123,22 +6166,19 @@ void MinorMarkCompactCollector::MarkLiveObjects() { ...@@ -6123,22 +6166,19 @@ void MinorMarkCompactCollector::MarkLiveObjects() {
if (FLAG_minor_mc_trace_fragmentation) { if (FLAG_minor_mc_trace_fragmentation) {
TraceFragmentation(); TraceFragmentation();
} }
main_thread_worklists_local_.reset();
main_marking_visitor_.reset();
} }
void MinorMarkCompactCollector::DrainMarkingWorklist() { void MinorMarkCompactCollector::DrainMarkingWorklist() {
PtrComprCageBase cage_base(isolate()); PtrComprCageBase cage_base(isolate());
HeapObject object; HeapObject object;
while (main_thread_worklists_local_->Pop(&object)) { while (local_marking_worklists_->Pop(&object)) {
DCHECK(!object.IsFreeSpaceOrFiller(cage_base)); DCHECK(!object.IsFreeSpaceOrFiller(cage_base));
DCHECK(object.IsHeapObject()); DCHECK(object.IsHeapObject());
DCHECK(heap()->Contains(object)); DCHECK(heap()->Contains(object));
DCHECK(non_atomic_marking_state()->IsBlack(object)); DCHECK(non_atomic_marking_state()->IsBlack(object));
main_marking_visitor_->Visit(object); main_marking_visitor_->Visit(object);
} }
DCHECK(main_thread_worklists_local_->IsEmpty()); DCHECK(local_marking_worklists_->IsEmpty());
} }
void MinorMarkCompactCollector::TraceFragmentation() { void MinorMarkCompactCollector::TraceFragmentation() {
......
This diff is collapsed.
...@@ -612,6 +612,8 @@ ...@@ -612,6 +612,8 @@
F(MINOR_MC_EVACUATE_UPDATE_POINTERS_SLOTS) \ F(MINOR_MC_EVACUATE_UPDATE_POINTERS_SLOTS) \
F(MINOR_MC_EVACUATE_UPDATE_POINTERS_TO_NEW_ROOTS) \ F(MINOR_MC_EVACUATE_UPDATE_POINTERS_TO_NEW_ROOTS) \
F(MINOR_MC_EVACUATE_UPDATE_POINTERS_WEAK) \ F(MINOR_MC_EVACUATE_UPDATE_POINTERS_WEAK) \
F(MINOR_MC_FINISH) \
F(MINOR_MC_FINISH_SWEEP_ARRAY_BUFFERS) \
F(MINOR_MC_MARK) \ F(MINOR_MC_MARK) \
F(MINOR_MC_MARK_GLOBAL_HANDLES) \ F(MINOR_MC_MARK_GLOBAL_HANDLES) \
F(MINOR_MC_MARK_PARALLEL) \ F(MINOR_MC_MARK_PARALLEL) \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment