< prev index next >
src/hotspot/share/runtime/synchronizer.cpp
Print this page
@@ -255,35 +255,52 @@
return false; // revert to slow-path
}
// -----------------------------------------------------------------------------
-// Fast Monitor Enter/Exit
-// This the fast monitor enter. The interpreter and compiler use
-// some assembly copies of this code. Make sure update those code
-// if the following function is changed. The implementation is
-// extremely sensitive to race condition. Be careful.
+// Monitor Enter/Exit
+// The interpreter and compiler use some assembly copies of this code. Make sure
+// update those code if the following function is changed. The implementation
+// is extremely sensitive to race condition. Be careful.
-void ObjectSynchronizer::fast_enter(Handle obj, BasicLock* lock,
- bool attempt_rebias, TRAPS) {
+void ObjectSynchronizer::enter(Handle obj, BasicLock* lock, TRAPS) {
if (UseBiasedLocking) {
if (!SafepointSynchronize::is_at_safepoint()) {
- BiasedLocking::Condition cond = BiasedLocking::revoke_and_rebias(obj, attempt_rebias, THREAD);
- if (cond == BiasedLocking::BIAS_REVOKED_AND_REBIASED) {
- return;
- }
+ BiasedLocking::revoke(obj, THREAD);
} else {
- assert(!attempt_rebias, "can not rebias toward VM thread");
BiasedLocking::revoke_at_safepoint(obj);
}
- assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
}
- slow_enter(obj, lock, THREAD);
+ markWord mark = obj->mark();
+ assert(!mark.has_bias_pattern(), "should not see bias pattern here");
+
+ if (mark.is_neutral()) {
+ // Anticipate successful CAS -- the ST of the displaced mark must
+ // be visible <= the ST performed by the CAS.
+ lock->set_displaced_header(mark);
+ if (mark == obj()->cas_set_mark(markWord::from_pointer(lock), mark)) {
+ return;
+ }
+ // Fall through to inflate() ...
+ } else if (mark.has_locker() &&
+ THREAD->is_lock_owned((address)mark.locker())) {
+ assert(lock != mark.locker(), "must not re-lock the same lock");
+ assert(lock != (BasicLock*)obj->mark().value(), "don't relock with same BasicLock");
+ lock->set_displaced_header(markWord::from_pointer(NULL));
+ return;
+ }
+
+ // The object header will never be displaced to this lock,
+ // so it does not matter what the value is, except that it
+ // must be non-zero to avoid looking like a re-entrant lock,
+ // and must not look locked either.
+ lock->set_displaced_header(markWord::unused_mark());
+ inflate(THREAD, obj(), inflate_cause_monitor_enter)->enter(THREAD);
}
-void ObjectSynchronizer::fast_exit(oop object, BasicLock* lock, TRAPS) {
+void ObjectSynchronizer::exit(oop object, BasicLock* lock, TRAPS) {
markWord mark = object->mark();
// We cannot check for Biased Locking if we are racing an inflation.
assert(mark == markWord::INFLATING() ||
!mark.has_bias_pattern(), "should not see bias pattern here");
@@ -329,51 +346,10 @@
// We have to take the slow-path of possible inflation and then exit.
inflate(THREAD, object, inflate_cause_vm_internal)->exit(true, THREAD);
}
// -----------------------------------------------------------------------------
-// Interpreter/Compiler Slow Case
-// This routine is used to handle interpreter/compiler slow case
-// We don't need to use fast path here, because it must have been
-// failed in the interpreter/compiler code.
-void ObjectSynchronizer::slow_enter(Handle obj, BasicLock* lock, TRAPS) {
- markWord mark = obj->mark();
- assert(!mark.has_bias_pattern(), "should not see bias pattern here");
-
- if (mark.is_neutral()) {
- // Anticipate successful CAS -- the ST of the displaced mark must
- // be visible <= the ST performed by the CAS.
- lock->set_displaced_header(mark);
- if (mark == obj()->cas_set_mark(markWord::from_pointer(lock), mark)) {
- return;
- }
- // Fall through to inflate() ...
- } else if (mark.has_locker() &&
- THREAD->is_lock_owned((address)mark.locker())) {
- assert(lock != mark.locker(), "must not re-lock the same lock");
- assert(lock != (BasicLock*)obj->mark().value(), "don't relock with same BasicLock");
- lock->set_displaced_header(markWord::from_pointer(NULL));
- return;
- }
-
- // The object header will never be displaced to this lock,
- // so it does not matter what the value is, except that it
- // must be non-zero to avoid looking like a re-entrant lock,
- // and must not look locked either.
- lock->set_displaced_header(markWord::unused_mark());
- inflate(THREAD, obj(), inflate_cause_monitor_enter)->enter(THREAD);
-}
-
-// This routine is used to handle interpreter/compiler slow case
-// We don't need to use fast path here, because it must have
-// failed in the interpreter/compiler code. Simply use the heavy
-// weight monitor should be ok, unless someone find otherwise.
-void ObjectSynchronizer::slow_exit(oop object, BasicLock* lock, TRAPS) {
- fast_exit(object, lock, THREAD);
-}
-
-// -----------------------------------------------------------------------------
// Class Loader support to workaround deadlocks on the class loader lock objects
// Also used by GC
// complete_exit()/reenter() are used to wait on a nested lock
// i.e. to give up an outer lock completely and then re-enter
// Used when holding nested locks - lock acquisition order: lock1 then lock2
@@ -383,11 +359,11 @@
// 4) reenter lock1 with original recursion count
// 5) lock lock2
// NOTE: must use heavy weight monitor to handle complete_exit/reenter()
intptr_t ObjectSynchronizer::complete_exit(Handle obj, TRAPS) {
if (UseBiasedLocking) {
- BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+ BiasedLocking::revoke(obj, THREAD);
assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
}
ObjectMonitor* monitor = inflate(THREAD, obj(), inflate_cause_vm_internal);
@@ -395,11 +371,11 @@
}
// NOTE: must use heavy weight monitor to handle complete_exit/reenter()
void ObjectSynchronizer::reenter(Handle obj, intptr_t recursion, TRAPS) {
if (UseBiasedLocking) {
- BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+ BiasedLocking::revoke(obj, THREAD);
assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
}
ObjectMonitor* monitor = inflate(THREAD, obj(), inflate_cause_vm_internal);
@@ -409,11 +385,11 @@
// JNI locks on java objects
// NOTE: must use heavy weight monitor to handle jni monitor enter
void ObjectSynchronizer::jni_enter(Handle obj, TRAPS) {
// the current locking is from JNI instead of Java code
if (UseBiasedLocking) {
- BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+ BiasedLocking::revoke(obj, THREAD);
assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
}
THREAD->set_current_pending_monitor_is_from_java(false);
inflate(THREAD, obj(), inflate_cause_jni_enter)->enter(THREAD);
THREAD->set_current_pending_monitor_is_from_java(true);
@@ -421,11 +397,11 @@
// NOTE: must use heavy weight monitor to handle jni monitor exit
void ObjectSynchronizer::jni_exit(oop obj, Thread* THREAD) {
if (UseBiasedLocking) {
Handle h_obj(THREAD, obj);
- BiasedLocking::revoke_and_rebias(h_obj, false, THREAD);
+ BiasedLocking::revoke(h_obj, THREAD);
obj = h_obj();
}
assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
ObjectMonitor* monitor = inflate(THREAD, obj, inflate_cause_jni_exit);
@@ -445,27 +421,27 @@
_thread = thread;
_thread->check_for_valid_safepoint_state(false);
_obj = obj;
if (_dolock) {
- ObjectSynchronizer::fast_enter(_obj, &_lock, false, _thread);
+ ObjectSynchronizer::enter(_obj, &_lock, _thread);
}
}
ObjectLocker::~ObjectLocker() {
if (_dolock) {
- ObjectSynchronizer::fast_exit(_obj(), &_lock, _thread);
+ ObjectSynchronizer::exit(_obj(), &_lock, _thread);
}
}
// -----------------------------------------------------------------------------
// Wait/Notify/NotifyAll
// NOTE: must use heavy weight monitor to handle wait()
int ObjectSynchronizer::wait(Handle obj, jlong millis, TRAPS) {
if (UseBiasedLocking) {
- BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+ BiasedLocking::revoke(obj, THREAD);
assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
}
if (millis < 0) {
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative");
}
@@ -481,22 +457,22 @@
return dtrace_waited_probe(monitor, obj, THREAD);
}
void ObjectSynchronizer::waitUninterruptibly(Handle obj, jlong millis, TRAPS) {
if (UseBiasedLocking) {
- BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+ BiasedLocking::revoke(obj, THREAD);
assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
}
if (millis < 0) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative");
}
inflate(THREAD, obj(), inflate_cause_wait)->wait(millis, false, THREAD);
}
void ObjectSynchronizer::notify(Handle obj, TRAPS) {
if (UseBiasedLocking) {
- BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+ BiasedLocking::revoke(obj, THREAD);
assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
}
markWord mark = obj->mark();
if (mark.has_locker() && THREAD->is_lock_owned((address)mark.locker())) {
@@ -506,11 +482,11 @@
}
// NOTE: see comment of notify()
void ObjectSynchronizer::notifyall(Handle obj, TRAPS) {
if (UseBiasedLocking) {
- BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+ BiasedLocking::revoke(obj, THREAD);
assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
}
markWord mark = obj->mark();
if (mark.has_locker() && THREAD->is_lock_owned((address)mark.locker())) {
@@ -693,11 +669,11 @@
Handle hobj(Self, obj);
// Relaxing assertion for bug 6320749.
assert(Universe::verify_in_progress() ||
!SafepointSynchronize::is_at_safepoint(),
"biases should not be seen by VM thread here");
- BiasedLocking::revoke_and_rebias(hobj, false, JavaThread::current());
+ BiasedLocking::revoke(hobj, JavaThread::current());
obj = hobj();
assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
}
}
@@ -792,11 +768,11 @@
bool ObjectSynchronizer::current_thread_holds_lock(JavaThread* thread,
Handle h_obj) {
if (UseBiasedLocking) {
- BiasedLocking::revoke_and_rebias(h_obj, false, thread);
+ BiasedLocking::revoke(h_obj, thread);
assert(!h_obj->mark().has_bias_pattern(), "biases should be revoked by now");
}
assert(thread == JavaThread::current(), "Can only be called on current thread");
oop obj = h_obj();
@@ -831,11 +807,11 @@
// Possible mark states: neutral, biased, stack-locked, inflated
if (UseBiasedLocking && h_obj()->mark().has_bias_pattern()) {
// CASE: biased
- BiasedLocking::revoke_and_rebias(h_obj, false, self);
+ BiasedLocking::revoke(h_obj, self);
assert(!h_obj->mark().has_bias_pattern(),
"biases should be revoked by now");
}
assert(self == JavaThread::current(), "Can only be called on current thread");
@@ -867,11 +843,11 @@
JavaThread* ObjectSynchronizer::get_lock_owner(ThreadsList * t_list, Handle h_obj) {
if (UseBiasedLocking) {
if (SafepointSynchronize::is_at_safepoint()) {
BiasedLocking::revoke_at_safepoint(h_obj);
} else {
- BiasedLocking::revoke_and_rebias(h_obj, false, JavaThread::current());
+ BiasedLocking::revoke(h_obj, JavaThread::current());
}
assert(!h_obj->mark().has_bias_pattern(), "biases should be revoked by now");
}
oop obj = h_obj();
@@ -1461,12 +1437,11 @@
// If we know we're inflating for entry it's better to inflate by swinging a
// pre-locked objectMonitor pointer into the object header. A successful
// CAS inflates the object *and* confers ownership to the inflating thread.
// In the current implementation we use a 2-step mechanism where we CAS()
// to inflate and then CAS() again to try to swing _owner from NULL to Self.
- // An inflateTry() method that we could call from fast_enter() and slow_enter()
- // would be useful.
+ // An inflateTry() method that we could call from enter() would be useful.
// Catch if the object's header is not neutral (not locked and
// not marked is what we care about here).
assert(mark.is_neutral(), "invariant: header=" INTPTR_FORMAT, mark.value());
ObjectMonitor * m = omAlloc(Self);
< prev index next >