diff --git a/src/hotspot/share/gc/shared/gcVMOperations.cpp b/src/hotspot/share/gc/shared/gcVMOperations.cpp index 4cf1a4ccbaf..4cc75f47459 100644 --- a/src/hotspot/share/gc/shared/gcVMOperations.cpp +++ b/src/hotspot/share/gc/shared/gcVMOperations.cpp @@ -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(); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp index af221550c69..9d2782502fe 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp @@ -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() { diff --git a/src/hotspot/share/gc/x/xDriver.cpp b/src/hotspot/share/gc/x/xDriver.cpp index c477f4a135c..3e6fd03134e 100644 --- a/src/hotspot/share/gc/x/xDriver.cpp +++ b/src/hotspot/share/gc/x/xDriver.cpp @@ -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 { diff --git a/src/hotspot/share/gc/z/zGeneration.cpp b/src/hotspot/share/gc/z/zGeneration.cpp index 5c3afa9db8c..be86550d321 100644 --- a/src/hotspot/share/gc/z/zGeneration.cpp +++ b/src/hotspot/share/gc/z/zGeneration.cpp @@ -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 { diff --git a/src/hotspot/share/interpreter/oopMapCache.cpp b/src/hotspot/share/interpreter/oopMapCache.cpp index cae0efae9b2..7b60e4869e3 100644 --- a/src/hotspot/share/interpreter/oopMapCache.cpp +++ b/src/hotspot/share/interpreter/oopMapCache.cpp @@ -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(); } } diff --git a/src/hotspot/share/interpreter/oopMapCache.hpp b/src/hotspot/share/interpreter/oopMapCache.hpp index 3c124631377..46c85f6e879 100644 --- a/src/hotspot/share/interpreter/oopMapCache.hpp +++ b/src/hotspot/share/interpreter/oopMapCache.hpp @@ -183,8 +183,8 @@ class OopMapCache : public CHeapObj { // 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();