hotspot/src/share/vm/runtime/synchronizer.cpp
// -----------------------------------------------------------------------------
// 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) {
{- -------------------------------------------
(1) neutral なら, CAS でロックを試みる. 成功すればここでロック処理は終了.
(この場合 BasicLock には mark を入れておく)
---------------------------------------- -}
markOop 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 == (markOop) Atomic::cmpxchg_ptr(lock, obj()->mark_addr(), mark)) {
TEVENT (slow_enter: release stacklock) ;
return ;
}
// Fall through to inflate() ...
{- -------------------------------------------
(1) 自分がロック済み (かつ stack-locked) かどうかを確認する.
そうだった場合にはここでロック処理は終了.
(この場合 BasicLock には NULL を入れておく)
---------------------------------------- -}
} 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(), "don't relock with same BasicLock");
lock->set_displaced_header(NULL);
return;
}
{- -------------------------------------------
(1) ?? (採用されなかった最適化が書かれているようだが..)
---------------------------------------- -}
#if 0
// The following optimization isn't particularly useful.
if (mark->has_monitor() && mark->monitor()->is_entered(THREAD)) {
lock->set_displaced_header (NULL) ;
return ;
}
#endif
{- -------------------------------------------
(1) 上記のどれでもなければ (あるいは CAS が失敗した場合は),
ObjectSynchronizer::inflate() で ObjectMonitor オブジェクトを取得した後,
ObjectMonitor::enter() でロックを行う.
(この場合, BasicLock には unused_mark を入れておく)
---------------------------------------- -}
// 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(markOopDesc::unused_mark());
ObjectSynchronizer::inflate(THREAD, obj())->enter(THREAD);
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.