From febcfd69ffe88e8a9d3cdf267bc062816577f868 Mon Sep 17 00:00:00 2001 From: William Kemper Date: Tue, 21 Jan 2025 23:10:22 +0000 Subject: [PATCH] 8345750: Shenandoah: Test TestJcmdHeapDump.java#aggressive intermittent assert(gc_cause() == GCCause::_no_gc) failed: Over-writing cause Reviewed-by: ysr Backport-of: 6a29a8110ec38b4adc8163ba8651cbc935353f1d --- src/hotspot/share/gc/shared/gcVMOperations.cpp | 4 ++-- .../share/gc/shenandoah/shenandoahHeap.cpp | 16 +++++++++++++++- .../share/gc/shenandoah/shenandoahHeap.hpp | 1 + src/hotspot/share/services/heapDumper.cpp | 9 ++++----- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/hotspot/share/gc/shared/gcVMOperations.cpp b/src/hotspot/share/gc/shared/gcVMOperations.cpp index 4cc75f47459..4668c22009a 100644 --- a/src/hotspot/share/gc/shared/gcVMOperations.cpp +++ b/src/hotspot/share/gc/shared/gcVMOperations.cpp @@ -140,8 +140,8 @@ void VM_GC_Operation::doit_epilogue() { } bool VM_GC_HeapInspection::doit_prologue() { - if (_full_gc && UseZGC) { - // ZGC cannot perform a synchronous GC cycle from within the VM thread. + if (_full_gc && (UseZGC || UseShenandoahGC)) { + // ZGC and Shenandoah cannot perform a synchronous GC cycle from within the VM thread. // So VM_GC_HeapInspection::collect() is a noop. To respect the _full_gc // flag a synchronous GC cycle is performed from the caller thread in the // prologue. diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index b69ebdc7d14..dcebef5d772 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -1468,6 +1468,18 @@ size_t ShenandoahHeap::max_tlab_size() const { return ShenandoahHeapRegion::max_tlab_size_words(); } +void ShenandoahHeap::collect_as_vm_thread(GCCause::Cause cause) { + // These requests are ignored because we can't easily have Shenandoah jump into + // a synchronous (degenerated or full) cycle while it is in the middle of a concurrent + // cycle. We _could_ cancel the concurrent cycle and then try to run a cycle directly + // on the VM thread, but this would confuse the control thread mightily and doesn't + // seem worth the trouble. Instead, we will have the caller thread run (and wait for) a + // concurrent cycle in the prologue of the heap inspect/dump operation. This is how + // other concurrent collectors in the JVM handle this scenario as well. + assert(Thread::current()->is_VM_thread(), "Should be the VM thread"); + guarantee(cause == GCCause::_heap_dump || cause == GCCause::_heap_inspection, "Invalid cause"); +} + void ShenandoahHeap::collect(GCCause::Cause cause) { control_thread()->request_gc(cause); } @@ -1548,7 +1560,9 @@ void ShenandoahHeap::set_active_generation() { void ShenandoahHeap::on_cycle_start(GCCause::Cause cause, ShenandoahGeneration* generation) { shenandoah_policy()->record_collection_cause(cause); - assert(gc_cause() == GCCause::_no_gc, "Over-writing cause"); + const GCCause::Cause current = gc_cause(); + assert(current == GCCause::_no_gc, "Over-writing cause: %s, with: %s", + GCCause::to_string(current), GCCause::to_string(cause)); assert(_gc_generation == nullptr, "Over-writing _gc_generation"); set_gc_cause(cause); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp index a9a793f9e60..5a9ff374a65 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp @@ -608,6 +608,7 @@ public: MemRegion reserved_region() const { return _reserved; } bool is_in_reserved(const void* addr) const { return _reserved.contains(addr); } + void collect_as_vm_thread(GCCause::Cause cause) override; void collect(GCCause::Cause cause) override; void do_full_collection(bool clear_all_soft_refs) override; diff --git a/src/hotspot/share/services/heapDumper.cpp b/src/hotspot/share/services/heapDumper.cpp index 91bcce382f0..dfe612c7bf3 100644 --- a/src/hotspot/share/services/heapDumper.cpp +++ b/src/hotspot/share/services/heapDumper.cpp @@ -2349,11 +2349,10 @@ void VM_HeapDumper::dump_threads(AbstractDumpWriter* writer) { } bool VM_HeapDumper::doit_prologue() { - if (_gc_before_heap_dump && UseZGC) { - // ZGC cannot perform a synchronous GC cycle from within the VM thread. - // So ZCollectedHeap::collect_as_vm_thread() is a noop. To respect the - // _gc_before_heap_dump flag a synchronous GC cycle is performed from - // the caller thread in the prologue. + if (_gc_before_heap_dump && (UseZGC || UseShenandoahGC)) { + // ZGC and Shenandoah cannot perform a synchronous GC cycle from within the VM thread. + // So collect_as_vm_thread() is a noop. To respect the _gc_before_heap_dump flag a + // synchronous GC cycle is performed from the caller thread in the prologue. Universe::heap()->collect(GCCause::_heap_dump); } return VM_GC_Operation::doit_prologue();