Commit c26dd2e3 authored by Michael Lippautz's avatar Michael Lippautz Committed by V8 LUCI CQ

[heap] Simplify incremental marking

In preparation for removing the finalization step, simplify
incremental marking logic.

Change-Id: I929034e389edb0c9da78cd39fd497d5783aff7c4
Bug: v8:12775
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3704509Reviewed-by: 's avatarDominik Inführ <dinfuehr@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81155}
parent e9d0a5a5
...@@ -1526,13 +1526,11 @@ void Heap::HandleGCRequest() { ...@@ -1526,13 +1526,11 @@ void Heap::HandleGCRequest() {
CollectAllGarbage(NEW_SPACE, GarbageCollectionReason::kTesting); CollectAllGarbage(NEW_SPACE, GarbageCollectionReason::kTesting);
stress_scavenge_observer_->RequestedGCDone(); stress_scavenge_observer_->RequestedGCDone();
} else if (HighMemoryPressure()) { } else if (HighMemoryPressure()) {
incremental_marking()->reset_request_type();
CheckMemoryPressure(); CheckMemoryPressure();
} else if (CollectionRequested()) { } else if (CollectionRequested()) {
CheckCollectionRequested(); CheckCollectionRequested();
} else if (incremental_marking()->request_type() == } else if (incremental_marking()->request_type() ==
IncrementalMarking::GCRequestType::COMPLETE_MARKING) { IncrementalMarking::GCRequestType::COMPLETE_MARKING) {
incremental_marking()->reset_request_type();
CollectAllGarbage(current_gc_flags_, CollectAllGarbage(current_gc_flags_,
GarbageCollectionReason::kFinalizeMarkingViaStackGuard, GarbageCollectionReason::kFinalizeMarkingViaStackGuard,
current_gc_callback_flags_); current_gc_callback_flags_);
...@@ -1540,7 +1538,6 @@ void Heap::HandleGCRequest() { ...@@ -1540,7 +1538,6 @@ void Heap::HandleGCRequest() {
IncrementalMarking::GCRequestType::FINALIZATION && IncrementalMarking::GCRequestType::FINALIZATION &&
incremental_marking()->IsMarking() && incremental_marking()->IsMarking() &&
!incremental_marking()->finalize_marking_completed()) { !incremental_marking()->finalize_marking_completed()) {
incremental_marking()->reset_request_type();
FinalizeIncrementalMarkingIncrementally( FinalizeIncrementalMarkingIncrementally(
GarbageCollectionReason::kFinalizeMarkingViaStackGuard); GarbageCollectionReason::kFinalizeMarkingViaStackGuard);
} }
...@@ -1732,7 +1729,8 @@ void Heap::ReportExternalMemoryPressure() { ...@@ -1732,7 +1729,8 @@ void Heap::ReportExternalMemoryPressure() {
current_gc_callback_flags_ = static_cast<GCCallbackFlags>( current_gc_callback_flags_ = static_cast<GCCallbackFlags>(
current_gc_callback_flags_ | kGCCallbackFlagsForExternalMemory); current_gc_callback_flags_ | kGCCallbackFlagsForExternalMemory);
incremental_marking()->AdvanceWithDeadline( incremental_marking()->AdvanceWithDeadline(
deadline, IncrementalMarking::GC_VIA_STACK_GUARD, StepOrigin::kV8); deadline, IncrementalMarking::CompletionAction::kGcViaStackGuard,
StepOrigin::kV8);
} }
} }
...@@ -2662,8 +2660,6 @@ void Heap::MarkCompactEpilogue() { ...@@ -2662,8 +2660,6 @@ void Heap::MarkCompactEpilogue() {
isolate_->counters()->objs_since_last_full()->Set(0); isolate_->counters()->objs_since_last_full()->Set(0);
incremental_marking()->Epilogue(); incremental_marking()->Epilogue();
DCHECK(incremental_marking()->IsStopped());
} }
void Heap::MarkCompactPrologue() { void Heap::MarkCompactPrologue() {
...@@ -4093,7 +4089,7 @@ bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, ...@@ -4093,7 +4089,7 @@ bool Heap::PerformIdleTimeAction(GCIdleTimeAction action,
break; break;
case GCIdleTimeAction::kIncrementalStep: { case GCIdleTimeAction::kIncrementalStep: {
incremental_marking()->AdvanceWithDeadline( incremental_marking()->AdvanceWithDeadline(
deadline_in_ms, IncrementalMarking::NO_GC_VIA_STACK_GUARD, deadline_in_ms, IncrementalMarking::CompletionAction::kGCViaTask,
StepOrigin::kTask); StepOrigin::kTask);
FinalizeIncrementalMarkingIfComplete( FinalizeIncrementalMarkingIfComplete(
GarbageCollectionReason::kFinalizeMarkingViaTask); GarbageCollectionReason::kFinalizeMarkingViaTask);
......
...@@ -1079,8 +1079,6 @@ class Heap { ...@@ -1079,8 +1079,6 @@ class Heap {
return reinterpret_cast<Address*>(&is_marking_flag_); return reinterpret_cast<Address*>(&is_marking_flag_);
} }
void SetIsMarkingFlag(uint8_t flag) { is_marking_flag_ = flag; }
void ClearRecordedSlot(HeapObject object, ObjectSlot slot); void ClearRecordedSlot(HeapObject object, ObjectSlot slot);
void ClearRecordedSlotRange(Address start, Address end); void ClearRecordedSlotRange(Address start, Address end);
static int InsertIntoRememberedSetFromCode(MemoryChunk* chunk, Address slot); static int InsertIntoRememberedSetFromCode(MemoryChunk* chunk, Address slot);
...@@ -2146,6 +2144,10 @@ class Heap { ...@@ -2146,6 +2144,10 @@ class Heap {
bool IsStressingScavenge(); bool IsStressingScavenge();
void SetIsMarkingFlag(bool value) {
is_marking_flag_ = static_cast<uint8_t>(value);
}
ExternalMemoryAccounting external_memory_; ExternalMemoryAccounting external_memory_;
// This can be calculated directly from a pointer to the heap; however, it is // This can be calculated directly from a pointer to the heap; however, it is
......
...@@ -86,7 +86,7 @@ StepResult IncrementalMarkingJob::Task::Step(Heap* heap) { ...@@ -86,7 +86,7 @@ StepResult IncrementalMarkingJob::Task::Step(Heap* heap) {
double deadline = double deadline =
heap->MonotonicallyIncreasingTimeInMs() + kIncrementalMarkingDelayMs; heap->MonotonicallyIncreasingTimeInMs() + kIncrementalMarkingDelayMs;
StepResult result = heap->incremental_marking()->AdvanceWithDeadline( StepResult result = heap->incremental_marking()->AdvanceWithDeadline(
deadline, i::IncrementalMarking::NO_GC_VIA_STACK_GUARD, deadline, i::IncrementalMarking::CompletionAction::kGCViaTask,
i::StepOrigin::kTask); i::StepOrigin::kTask);
heap->FinalizeIncrementalMarkingIfComplete( heap->FinalizeIncrementalMarkingIfComplete(
GarbageCollectionReason::kFinalizeMarkingViaTask); GarbageCollectionReason::kFinalizeMarkingViaTask);
......
...@@ -564,7 +564,7 @@ void IncrementalMarking::FinalizeMarking(CompletionAction action) { ...@@ -564,7 +564,7 @@ void IncrementalMarking::FinalizeMarking(CompletionAction action) {
"marking.\n"); "marking.\n");
} }
request_type_ = GCRequestType::FINALIZATION; request_type_ = GCRequestType::FINALIZATION;
if (action == GC_VIA_STACK_GUARD) { if (action == CompletionAction::kGcViaStackGuard) {
heap_->isolate()->stack_guard()->RequestGC(); heap_->isolate()->stack_guard()->RequestGC();
} }
} }
...@@ -585,7 +585,7 @@ void IncrementalMarking::MarkingComplete(CompletionAction action) { ...@@ -585,7 +585,7 @@ void IncrementalMarking::MarkingComplete(CompletionAction action) {
// marking was fast. // marking was fast.
constexpr double kMinOvershootMs = 50; constexpr double kMinOvershootMs = 50;
if (action == GC_VIA_STACK_GUARD) { if (action == CompletionAction::kGcViaStackGuard) {
if (time_to_force_completion_ == 0.0) { if (time_to_force_completion_ == 0.0) {
const double now = heap_->MonotonicallyIncreasingTimeInMs(); const double now = heap_->MonotonicallyIncreasingTimeInMs();
const double overshoot_ms = const double overshoot_ms =
...@@ -634,14 +634,17 @@ void IncrementalMarking::MarkingComplete(CompletionAction action) { ...@@ -634,14 +634,17 @@ void IncrementalMarking::MarkingComplete(CompletionAction action) {
"[IncrementalMarking] Complete (normal).\n"); "[IncrementalMarking] Complete (normal).\n");
} }
request_type_ = GCRequestType::COMPLETE_MARKING; request_type_ = GCRequestType::COMPLETE_MARKING;
if (action == GC_VIA_STACK_GUARD) { if (action == CompletionAction::kGcViaStackGuard) {
heap_->isolate()->stack_guard()->RequestGC(); heap_->isolate()->stack_guard()->RequestGC();
} }
} }
void IncrementalMarking::Epilogue() { void IncrementalMarking::Epilogue() {
DCHECK(IsStopped());
was_activated_ = false; was_activated_ = false;
finalize_marking_completed_ = false; finalize_marking_completed_ = false;
request_type_ = GCRequestType::NONE;
} }
bool IncrementalMarking::ShouldDoEmbedderStep() { bool IncrementalMarking::ShouldDoEmbedderStep() {
...@@ -814,7 +817,7 @@ void IncrementalMarking::AdvanceOnAllocation() { ...@@ -814,7 +817,7 @@ void IncrementalMarking::AdvanceOnAllocation() {
TRACE_GC_EPOCH(heap_->tracer(), GCTracer::Scope::MC_INCREMENTAL, TRACE_GC_EPOCH(heap_->tracer(), GCTracer::Scope::MC_INCREMENTAL,
ThreadKind::kMain); ThreadKind::kMain);
ScheduleBytesToMarkBasedOnAllocation(); ScheduleBytesToMarkBasedOnAllocation();
Step(kMaxStepSizeInMs, GC_VIA_STACK_GUARD, StepOrigin::kV8); Step(kMaxStepSizeInMs, CompletionAction::kGcViaStackGuard, StepOrigin::kV8);
} }
StepResult IncrementalMarking::Step(double max_step_size_in_ms, StepResult IncrementalMarking::Step(double max_step_size_in_ms,
......
...@@ -31,7 +31,12 @@ class V8_EXPORT_PRIVATE IncrementalMarking final { ...@@ -31,7 +31,12 @@ class V8_EXPORT_PRIVATE IncrementalMarking final {
public: public:
enum State : uint8_t { STOPPED, MARKING, COMPLETE }; enum State : uint8_t { STOPPED, MARKING, COMPLETE };
enum CompletionAction { GC_VIA_STACK_GUARD, NO_GC_VIA_STACK_GUARD }; // How to complete a GC when invoking a step.
// - kGCViaTask: No action to finish the GC synchronously is performed.
// Instead, a task to finish the GC is scheduled.
// - kGcViaStackGuard: Upon determining that there's no more work to do, a GC
// is triggered via stack guard.
enum class CompletionAction { kGcViaStackGuard, kGCViaTask };
enum class GCRequestType { NONE, COMPLETE_MARKING, FINALIZATION }; enum class GCRequestType { NONE, COMPLETE_MARKING, FINALIZATION };
...@@ -97,11 +102,6 @@ class V8_EXPORT_PRIVATE IncrementalMarking final { ...@@ -97,11 +102,6 @@ class V8_EXPORT_PRIVATE IncrementalMarking final {
V8_INLINE void TransferColor(HeapObject from, HeapObject to); V8_INLINE void TransferColor(HeapObject from, HeapObject to);
State state() const {
DCHECK(state_ == STOPPED || FLAG_incremental_marking);
return state_;
}
bool finalize_marking_completed() const { bool finalize_marking_completed() const {
return finalize_marking_completed_; return finalize_marking_completed_;
} }
...@@ -110,11 +110,9 @@ class V8_EXPORT_PRIVATE IncrementalMarking final { ...@@ -110,11 +110,9 @@ class V8_EXPORT_PRIVATE IncrementalMarking final {
finalize_marking_completed_ = val; finalize_marking_completed_ = val;
} }
inline bool IsStopped() const { return state() == STOPPED; } bool IsStopped() const { return state() == STOPPED; }
bool IsMarking() const { return state() >= MARKING; }
inline bool IsMarking() const { return state() >= MARKING; } bool IsComplete() const { return state() == COMPLETE; }
inline bool IsComplete() const { return state() == COMPLETE; }
inline bool IsReadyToOverApproximateWeakClosure() const { inline bool IsReadyToOverApproximateWeakClosure() const {
return request_type_ == GCRequestType::FINALIZATION && return request_type_ == GCRequestType::FINALIZATION &&
...@@ -128,10 +126,7 @@ class V8_EXPORT_PRIVATE IncrementalMarking final { ...@@ -128,10 +126,7 @@ class V8_EXPORT_PRIVATE IncrementalMarking final {
GCRequestType request_type() const { return request_type_; } GCRequestType request_type() const { return request_type_; }
void reset_request_type() { request_type_ = GCRequestType::NONE; }
bool CanBeActivated(); bool CanBeActivated();
bool WasActivated(); bool WasActivated();
void Start(GarbageCollectionReason gc_reason); void Start(GarbageCollectionReason gc_reason);
...@@ -262,6 +257,11 @@ class V8_EXPORT_PRIVATE IncrementalMarking final { ...@@ -262,6 +257,11 @@ class V8_EXPORT_PRIVATE IncrementalMarking final {
void AdvanceOnAllocation(); void AdvanceOnAllocation();
State state() const {
DCHECK_IMPLIES(state_ != STOPPED, FLAG_incremental_marking);
return state_;
}
void SetState(State s) { void SetState(State s) {
state_ = s; state_ = s;
heap_->SetIsMarkingFlag(s >= MARKING); heap_->SetIsMarkingFlag(s >= MARKING);
...@@ -285,10 +285,10 @@ class V8_EXPORT_PRIVATE IncrementalMarking final { ...@@ -285,10 +285,10 @@ class V8_EXPORT_PRIVATE IncrementalMarking final {
// bytes_marked_ahead_of_schedule_ with contribution of concurrent marking. // bytes_marked_ahead_of_schedule_ with contribution of concurrent marking.
size_t bytes_marked_concurrently_ = 0; size_t bytes_marked_concurrently_ = 0;
// Must use SetState() above to update state_ // Must use `SetState()` above to update `state_`.
// Atomic since main thread can complete marking (= changing state), while a // Atomic since main thread can complete marking while a background thread's
// background thread's slow allocation path will check whether incremental // slow allocation path will check whether incremental marking is currently
// marking is currently running. // running.
std::atomic<State> state_; std::atomic<State> state_;
bool is_compacting_ = false; bool is_compacting_ = false;
......
...@@ -88,7 +88,7 @@ void MemoryReducer::NotifyTimer(const Event& event) { ...@@ -88,7 +88,7 @@ void MemoryReducer::NotifyTimer(const Event& event) {
double deadline = heap()->MonotonicallyIncreasingTimeInMs() + double deadline = heap()->MonotonicallyIncreasingTimeInMs() +
kIncrementalMarkingDelayMs; kIncrementalMarkingDelayMs;
heap()->incremental_marking()->AdvanceWithDeadline( heap()->incremental_marking()->AdvanceWithDeadline(
deadline, IncrementalMarking::NO_GC_VIA_STACK_GUARD, deadline, IncrementalMarking::CompletionAction::kGCViaTask,
StepOrigin::kTask); StepOrigin::kTask);
heap()->FinalizeIncrementalMarkingIfComplete( heap()->FinalizeIncrementalMarkingIfComplete(
GarbageCollectionReason::kFinalizeMarkingViaTask); GarbageCollectionReason::kFinalizeMarkingViaTask);
......
...@@ -196,7 +196,8 @@ void SimulateIncrementalMarking(i::Heap* heap, bool force_completion) { ...@@ -196,7 +196,8 @@ void SimulateIncrementalMarking(i::Heap* heap, bool force_completion) {
if (!force_completion) return; if (!force_completion) return;
while (!marking->IsComplete()) { while (!marking->IsComplete()) {
marking->Step(kStepSizeInMs, i::IncrementalMarking::NO_GC_VIA_STACK_GUARD, marking->Step(kStepSizeInMs,
i::IncrementalMarking::CompletionAction::kGCViaTask,
i::StepOrigin::kV8); i::StepOrigin::kV8);
if (marking->IsReadyToOverApproximateWeakClosure()) { if (marking->IsReadyToOverApproximateWeakClosure()) {
SafepointScope scope(heap); SafepointScope scope(heap);
......
...@@ -2361,7 +2361,8 @@ TEST(InstanceOfStubWriteBarrier) { ...@@ -2361,7 +2361,8 @@ TEST(InstanceOfStubWriteBarrier) {
while (!marking_state->IsBlack(f->code()) && !marking->IsStopped()) { while (!marking_state->IsBlack(f->code()) && !marking->IsStopped()) {
// Discard any pending GC requests otherwise we will get GC when we enter // Discard any pending GC requests otherwise we will get GC when we enter
// code below. // code below.
marking->Step(kStepSizeInMs, IncrementalMarking::NO_GC_VIA_STACK_GUARD, marking->Step(kStepSizeInMs,
IncrementalMarking::CompletionAction::kGCViaTask,
StepOrigin::kV8); StepOrigin::kV8);
} }
...@@ -2456,7 +2457,8 @@ TEST(IdleNotificationFinishMarking) { ...@@ -2456,7 +2457,8 @@ TEST(IdleNotificationFinishMarking) {
const double kStepSizeInMs = 100; const double kStepSizeInMs = 100;
do { do {
marking->Step(kStepSizeInMs, IncrementalMarking::NO_GC_VIA_STACK_GUARD, marking->Step(kStepSizeInMs,
IncrementalMarking::CompletionAction::kGCViaTask,
StepOrigin::kV8); StepOrigin::kV8);
} while (!CcTest::heap() } while (!CcTest::heap()
->mark_compact_collector() ->mark_compact_collector()
...@@ -5702,7 +5704,7 @@ TEST(Regress598319) { ...@@ -5702,7 +5704,7 @@ TEST(Regress598319) {
const double kSmallStepSizeInMs = 0.1; const double kSmallStepSizeInMs = 0.1;
while (!marking->IsComplete()) { while (!marking->IsComplete()) {
marking->Step(kSmallStepSizeInMs, marking->Step(kSmallStepSizeInMs,
i::IncrementalMarking::NO_GC_VIA_STACK_GUARD, i::IncrementalMarking::CompletionAction::kGCViaTask,
StepOrigin::kV8); StepOrigin::kV8);
ProgressBar& progress_bar = page->ProgressBar(); ProgressBar& progress_bar = page->ProgressBar();
if (progress_bar.IsEnabled() && progress_bar.Value() > 0) { if (progress_bar.IsEnabled() && progress_bar.Value() > 0) {
...@@ -5723,7 +5725,7 @@ TEST(Regress598319) { ...@@ -5723,7 +5725,7 @@ TEST(Regress598319) {
const double kLargeStepSizeInMs = 1000; const double kLargeStepSizeInMs = 1000;
while (!marking->IsComplete()) { while (!marking->IsComplete()) {
marking->Step(kLargeStepSizeInMs, marking->Step(kLargeStepSizeInMs,
i::IncrementalMarking::NO_GC_VIA_STACK_GUARD, i::IncrementalMarking::CompletionAction::kGCViaTask,
StepOrigin::kV8); StepOrigin::kV8);
if (marking->IsReadyToOverApproximateWeakClosure()) { if (marking->IsReadyToOverApproximateWeakClosure()) {
SafepointScope safepoint_scope(heap); SafepointScope safepoint_scope(heap);
...@@ -5817,7 +5819,8 @@ TEST(Regress615489) { ...@@ -5817,7 +5819,8 @@ TEST(Regress615489) {
} }
const double kStepSizeInMs = 100; const double kStepSizeInMs = 100;
while (!marking->IsComplete()) { while (!marking->IsComplete()) {
marking->Step(kStepSizeInMs, i::IncrementalMarking::NO_GC_VIA_STACK_GUARD, marking->Step(kStepSizeInMs,
i::IncrementalMarking::CompletionAction::kGCViaTask,
StepOrigin::kV8); StepOrigin::kV8);
if (marking->IsReadyToOverApproximateWeakClosure()) { if (marking->IsReadyToOverApproximateWeakClosure()) {
SafepointScope safepoint_scope(heap); SafepointScope safepoint_scope(heap);
...@@ -5880,7 +5883,8 @@ TEST(Regress631969) { ...@@ -5880,7 +5883,8 @@ TEST(Regress631969) {
const double kStepSizeInMs = 100; const double kStepSizeInMs = 100;
IncrementalMarking* marking = heap->incremental_marking(); IncrementalMarking* marking = heap->incremental_marking();
while (!marking->IsComplete()) { while (!marking->IsComplete()) {
marking->Step(kStepSizeInMs, i::IncrementalMarking::NO_GC_VIA_STACK_GUARD, marking->Step(kStepSizeInMs,
i::IncrementalMarking::CompletionAction::kGCViaTask,
StepOrigin::kV8); StepOrigin::kV8);
if (marking->IsReadyToOverApproximateWeakClosure()) { if (marking->IsReadyToOverApproximateWeakClosure()) {
SafepointScope safepoint_scope(heap); SafepointScope safepoint_scope(heap);
...@@ -6497,7 +6501,8 @@ HEAP_TEST(Regress670675) { ...@@ -6497,7 +6501,8 @@ HEAP_TEST(Regress670675) {
if (marking->IsStopped()) break; if (marking->IsStopped()) break;
double deadline = heap->MonotonicallyIncreasingTimeInMs() + 1; double deadline = heap->MonotonicallyIncreasingTimeInMs() + 1;
marking->AdvanceWithDeadline( marking->AdvanceWithDeadline(
deadline, IncrementalMarking::GC_VIA_STACK_GUARD, StepOrigin::kV8); deadline, IncrementalMarking::CompletionAction::kGcViaStackGuard,
StepOrigin::kV8);
} }
DCHECK(marking->IsStopped()); DCHECK(marking->IsStopped());
} }
......
...@@ -31,7 +31,8 @@ void HeapInternalsBase::SimulateIncrementalMarking(Heap* heap, ...@@ -31,7 +31,8 @@ void HeapInternalsBase::SimulateIncrementalMarking(Heap* heap,
if (!force_completion) return; if (!force_completion) return;
while (!marking->IsComplete()) { while (!marking->IsComplete()) {
marking->Step(kStepSizeInMs, i::IncrementalMarking::NO_GC_VIA_STACK_GUARD, marking->Step(kStepSizeInMs,
i::IncrementalMarking::CompletionAction::kGCViaTask,
i::StepOrigin::kV8); i::StepOrigin::kV8);
if (marking->IsReadyToOverApproximateWeakClosure()) { if (marking->IsReadyToOverApproximateWeakClosure()) {
SafepointScope scope(heap); SafepointScope scope(heap);
......
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