< prev index next >
src/share/vm/oops/instanceKlass.cpp
Print this page
@@ -1102,25 +1102,25 @@
}
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);
}
bool InstanceKlass::find_local_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const {
for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
< prev index next >