8334594: Generational ZGC: Deadlock after OopMap rewrites in 8331572

Reviewed-by: stefank, eosterlund, coleenp, zgu
This commit is contained in:
Aleksey Shipilev 2024-06-24 08:46:10 +00:00
parent 05a63d80b9
commit 05ff3185ed
6 changed files with 12 additions and 9 deletions

@ -132,7 +132,7 @@ bool VM_GC_Operation::doit_prologue() {
void VM_GC_Operation::doit_epilogue() {
// GC thread root traversal likely used OopMapCache a lot, which
// might have created lots of old entries. Trigger the cleanup now.
OopMapCache::trigger_cleanup();
OopMapCache::try_trigger_cleanup();
if (Universe::has_reference_pending_list()) {
Heap_lock->notify_all();
}

@ -44,7 +44,7 @@ void VM_ShenandoahOperation::doit_epilogue() {
assert(!ShenandoahHeap::heap()->has_gc_state_changed(), "GC State was not synchronized to java threads.");
// GC thread root traversal likely used OopMapCache a lot, which
// might have created lots of old entries. Trigger the cleanup now.
OopMapCache::trigger_cleanup();
OopMapCache::try_trigger_cleanup();
}
bool VM_ShenandoahReferenceOperation::doit_prologue() {

@ -134,7 +134,7 @@ public:
// GC thread root traversal likely used OopMapCache a lot, which
// might have created lots of old entries. Trigger the cleanup now.
OopMapCache::trigger_cleanup();
OopMapCache::try_trigger_cleanup();
}
bool gc_locked() const {

@ -456,7 +456,7 @@ public:
// GC thread root traversal likely used OopMapCache a lot, which
// might have created lots of old entries. Trigger the cleanup now.
OopMapCache::trigger_cleanup();
OopMapCache::try_trigger_cleanup();
}
bool success() const {

@ -592,10 +592,13 @@ bool OopMapCache::has_cleanup_work() {
return Atomic::load(&_old_entries) != nullptr;
}
void OopMapCache::trigger_cleanup() {
if (has_cleanup_work()) {
MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
void OopMapCache::try_trigger_cleanup() {
// See we can take the lock for the notification without blocking.
// This allows triggering the cleanup from GC paths, that can hold
// the service lock for e.g. oop iteration in service thread.
if (has_cleanup_work() && Service_lock->try_lock_without_rank_check()) {
Service_lock->notify_all();
Service_lock->unlock();
}
}

@ -183,8 +183,8 @@ class OopMapCache : public CHeapObj<mtClass> {
// Check if we need to clean up old entries
static bool has_cleanup_work();
// Request cleanup if work is needed
static void trigger_cleanup();
// Request cleanup if work is needed and notification is currently possible
static void try_trigger_cleanup();
// Clean up the old entries
static void cleanup();