--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Fri Jun 03 01:31:01 2016 +0000
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Thu Jun 02 23:37:09 2016 -0400
@@ -1104,21 +1104,21 @@
void InstanceKlass::mask_for(const methodHandle& method, int bci,
InterpreterOopMap* entry_for) {
- // Dirty read, then double-check under a lock.
- if (_oop_map_cache == NULL) {
- // Otherwise, allocate a new one.
+ // Lazily create the _oop_map_cache at first request
+ // Lock-free access requires load_ptr_acquire.
+ OopMapCache* oop_map_cache =
+ static_cast<OopMapCache*>(OrderAccess::load_ptr_acquire(&_oop_map_cache));
+ if (oop_map_cache == NULL) {
MutexLocker x(OopMapCacheAlloc_lock);
- // First time use. Allocate a cache in C heap
- if (_oop_map_cache == NULL) {
- // Release stores from OopMapCache constructor before assignment
- // to _oop_map_cache. C++ compilers on ppc do not emit the
- // required memory barrier only because of the volatile
- // qualifier of _oop_map_cache.
- OrderAccess::release_store_ptr(&_oop_map_cache, new OopMapCache());
+ // Check if _oop_map_cache was allocated while we were waiting for this lock
+ if ((oop_map_cache = _oop_map_cache) == NULL) {
+ oop_map_cache = new OopMapCache();
+ // Ensure _oop_map_cache is stable, since it is examined without a lock
+ OrderAccess::release_store_ptr(&_oop_map_cache, oop_map_cache);
}
}
- // _oop_map_cache is constant after init; lookup below does is own locking.
- _oop_map_cache->lookup(method, bci, entry_for);
+ // _oop_map_cache is constant after init; lookup below does its own locking.
+ oop_map_cache->lookup(method, bci, entry_for);
}