< prev index next >

src/hotspot/share/runtime/synchronizer.cpp

Print this page




 203 
 204 bool ObjectSynchronizer::quick_enter(oop obj, Thread * Self,
 205                                      BasicLock * lock) {
 206   assert(!SafepointSynchronize::is_at_safepoint(), "invariant");
 207   assert(Self->is_Java_thread(), "invariant");
 208   assert(((JavaThread *) Self)->thread_state() == _thread_in_Java, "invariant");
 209   NoSafepointVerifier nsv;
 210   if (obj == NULL) return false;       // Need to throw NPE
 211   const markOop mark = obj->mark();
 212 
 213   if (mark->has_monitor()) {
 214     ObjectMonitor * const m = mark->monitor();
 215     assert(oopDesc::equals((oop) m->object(), obj), "invariant");
 216     Thread * const owner = (Thread *) m->_owner;
 217 
 218     // Lock contention and Transactional Lock Elision (TLE) diagnostics
 219     // and observability
 220     // Case: light contention possibly amenable to TLE
 221     // Case: TLE inimical operations such as nested/recursive synchronization
 222 
 223     if (owner == Self) {
 224       m->_recursions++;
 225       return true;
 226     }
 227 
 228     // This Java Monitor is inflated so obj's header will never be
 229     // displaced to this thread's BasicLock. Make the displaced header
 230     // non-NULL so this BasicLock is not seen as recursive nor as
 231     // being locked. We do this unconditionally so that this thread's
 232     // BasicLock cannot be mis-interpreted by any stack walkers. For
 233     // performance reasons, stack walkers generally first check for
 234     // Biased Locking in the object's header, the second check is for
 235     // stack-locking in the object's header, the third check is for
 236     // recursive stack-locking in the displaced header in the BasicLock,
 237     // and last are the inflated Java Monitor (ObjectMonitor) checks.
 238     lock->set_displaced_header(markOopDesc::unused_mark());
 239 





 240     if (owner == NULL && Atomic::replace_if_null(Self, &(m->_owner))) {
 241       assert(m->_recursions == 0, "invariant");
 242       assert(m->_owner == Self, "invariant");
 243       return true;
 244     }
 245   }
 246 
 247   // Note that we could inflate in quick_enter.
 248   // This is likely a useful optimization
 249   // Critically, in quick_enter() we must not:
 250   // -- perform bias revocation, or
 251   // -- block indefinitely, or
 252   // -- reach a safepoint
 253 
 254   return false;        // revert to slow-path
 255 }
 256 
 257 // -----------------------------------------------------------------------------
 258 //  Fast Monitor Enter/Exit
 259 // This the fast monitor enter. The interpreter and compiler use




 203 
 204 bool ObjectSynchronizer::quick_enter(oop obj, Thread * Self,
 205                                      BasicLock * lock) {
 206   assert(!SafepointSynchronize::is_at_safepoint(), "invariant");
 207   assert(Self->is_Java_thread(), "invariant");
 208   assert(((JavaThread *) Self)->thread_state() == _thread_in_Java, "invariant");
 209   NoSafepointVerifier nsv;
 210   if (obj == NULL) return false;       // Need to throw NPE
 211   const markOop mark = obj->mark();
 212 
 213   if (mark->has_monitor()) {
 214     ObjectMonitor * const m = mark->monitor();
 215     assert(oopDesc::equals((oop) m->object(), obj), "invariant");
 216     Thread * const owner = (Thread *) m->_owner;
 217 
 218     // Lock contention and Transactional Lock Elision (TLE) diagnostics
 219     // and observability
 220     // Case: light contention possibly amenable to TLE
 221     // Case: TLE inimical operations such as nested/recursive synchronization
 222 





 223     // This Java Monitor is inflated so obj's header will never be
 224     // displaced to this thread's BasicLock. Make the displaced header
 225     // non-NULL so this BasicLock is not seen as recursive nor as
 226     // being locked. We do this unconditionally so that this thread's
 227     // BasicLock cannot be mis-interpreted by any stack walkers. For
 228     // performance reasons, stack walkers generally first check for
 229     // Biased Locking in the object's header, the second check is for
 230     // stack-locking in the object's header, the third check is for
 231     // recursive stack-locking in the displaced header in the BasicLock,
 232     // and last are the inflated Java Monitor (ObjectMonitor) checks.
 233     lock->set_displaced_header(markOopDesc::unused_mark());
 234 
 235     if (owner == Self) {
 236       m->_recursions++;
 237       return true;
 238     }
 239 
 240     if (owner == NULL && Atomic::replace_if_null(Self, &(m->_owner))) {
 241       assert(m->_recursions == 0, "invariant");
 242       assert(m->_owner == Self, "invariant");
 243       return true;
 244     }
 245   }
 246 
 247   // Note that we could inflate in quick_enter.
 248   // This is likely a useful optimization
 249   // Critically, in quick_enter() we must not:
 250   // -- perform bias revocation, or
 251   // -- block indefinitely, or
 252   // -- reach a safepoint
 253 
 254   return false;        // revert to slow-path
 255 }
 256 
 257 // -----------------------------------------------------------------------------
 258 //  Fast Monitor Enter/Exit
 259 // This the fast monitor enter. The interpreter and compiler use


< prev index next >