[heap] Fix DCHECK failure in NotifyFullSweepingCompleted

In case of nested GCs, NotifyFullSweepingCompleted will first notify
that the nested young cycle is finished, which in turn will check
whether we need stop the full cycle as well.
After returning from NotifyYoungSweepingCompleted,
NotifyFullSweepingCompleted tries to stop the full cycle again, which
triggers the DCHECK that the current cycle is in a sweeping state.

Bug: v8:12612
Change-Id: I659038c04533b71bbc379cd51d22441e44e96021
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4069707
Commit-Queue: Omer Katz <omerkatz@chromium.org>
Commit-Queue: Anton Bikineev <bikineev@chromium.org>
Auto-Submit: Omer Katz <omerkatz@chromium.org>
Reviewed-by: Anton Bikineev <bikineev@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84600}
This commit is contained in:
Omer Katz 2022-12-01 16:11:09 +01:00 committed by V8 LUCI CQ
parent 8606191c98
commit 56b455ea57

View File

@ -517,11 +517,21 @@ void GCTracer::StopYoungCycleIfNeeded() {
}
void GCTracer::NotifyFullSweepingCompleted() {
// Notifying twice that V8 sweeping is finished for the same cycle is possible
// only if Oilpan sweeping is still in progress.
DCHECK_IMPLIES(notified_full_sweeping_completed_,
!notified_full_cppgc_completed_);
if (Event::IsYoungGenerationEvent(current_.type)) {
bool was_young_gc_while_full_gc_ = young_gc_while_full_gc_;
bool was_young_gc_while_full_gc = young_gc_while_full_gc_;
bool was_full_sweeping_notified = notified_full_sweeping_completed_;
NotifyYoungSweepingCompleted();
if (!was_young_gc_while_full_gc_) return;
// NotifyYoungSweepingCompleted checks if the full cycle needs to be stopped
// as well. If full sweeping was already notified, nothing more needs to be
// done here.
if (!was_young_gc_while_full_gc || was_full_sweeping_notified) return;
}
DCHECK(!Event::IsYoungGenerationEvent(current_.type));
if (v8_flags.verify_heap) {
// If heap verification is enabled, sweeping finalization can also be
@ -544,10 +554,6 @@ void GCTracer::NotifyFullSweepingCompleted() {
heap_->old_space()->PrintAllocationsOrigins();
heap_->code_space()->PrintAllocationsOrigins();
}
// Notifying twice that V8 sweeping is finished for the same cycle is possible
// only if Oilpan sweeping is still in progress.
DCHECK_IMPLIES(notified_full_sweeping_completed_,
!notified_full_cppgc_completed_);
notified_full_sweeping_completed_ = true;
StopFullCycleIfNeeded();
}