Skip to content

Commit

Permalink
8331714: Make OopMapCache installation lock-free
Browse files Browse the repository at this point in the history
Reviewed-by: zgu, coleenp
  • Loading branch information
shipilev committed May 7, 2024
1 parent df1ff05 commit a2584a8
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 11 deletions.
17 changes: 9 additions & 8 deletions src/hotspot/share/oops/instanceKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1634,16 +1634,17 @@ void InstanceKlass::call_class_initializer(TRAPS) {

void InstanceKlass::mask_for(const methodHandle& method, int bci,
InterpreterOopMap* entry_for) {
// Lazily create the _oop_map_cache at first request
// Lock-free access requires load_acquire.
// Lazily create the _oop_map_cache at first request.
// Load_acquire is needed to safely get instance published with CAS by another thread.
OopMapCache* oop_map_cache = Atomic::load_acquire(&_oop_map_cache);
if (oop_map_cache == nullptr) {
MutexLocker x(OopMapCacheAlloc_lock);
// Check if _oop_map_cache was allocated while we were waiting for this lock
if ((oop_map_cache = _oop_map_cache) == nullptr) {
oop_map_cache = new OopMapCache();
// Ensure _oop_map_cache is stable, since it is examined without a lock
Atomic::release_store(&_oop_map_cache, oop_map_cache);
// Try to install new instance atomically.
oop_map_cache = new OopMapCache();
OopMapCache* other = Atomic::cmpxchg(&_oop_map_cache, (OopMapCache*)nullptr, oop_map_cache);
if (other != nullptr) {
// Someone else managed to install before us, ditch local copy and use the existing one.
delete oop_map_cache;
oop_map_cache = other;
}
}
// _oop_map_cache is constant after init; lookup below does its own locking.
Expand Down
2 changes: 0 additions & 2 deletions src/hotspot/share/runtime/mutexLocker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ Mutex* tty_lock = nullptr;
Mutex* RawMonitor_lock = nullptr;
Mutex* PerfDataMemAlloc_lock = nullptr;
Mutex* PerfDataManager_lock = nullptr;
Mutex* OopMapCacheAlloc_lock = nullptr;

Mutex* FreeList_lock = nullptr;
Mutex* OldSets_lock = nullptr;
Expand Down Expand Up @@ -349,7 +348,6 @@ void mutex_init() {
MUTEX_DEFL(PSOldGenExpand_lock , PaddedMutex , Heap_lock, true);
}
#endif
MUTEX_DEFL(OopMapCacheAlloc_lock , PaddedMutex , Threads_lock, true);
MUTEX_DEFL(Module_lock , PaddedMutex , ClassLoaderDataGraph_lock);
MUTEX_DEFL(SystemDictionary_lock , PaddedMonitor, Module_lock);
MUTEX_DEFL(JNICritical_lock , PaddedMonitor, AdapterHandlerLibrary_lock); // used for JNI critical regions
Expand Down
1 change: 0 additions & 1 deletion src/hotspot/share/runtime/mutexLocker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ extern Mutex* FullGCALot_lock; // a lock to make FullGCALot MT
extern Mutex* RawMonitor_lock;
extern Mutex* PerfDataMemAlloc_lock; // a lock on the allocator for PerfData memory for performance data
extern Mutex* PerfDataManager_lock; // a long on access to PerfDataManager resources
extern Mutex* OopMapCacheAlloc_lock; // protects allocation of oop_map caches

extern Mutex* FreeList_lock; // protects the free region list during safepoints
extern Mutex* OldSets_lock; // protects the old region sets
Expand Down

1 comment on commit a2584a8

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.