hotspot/src/share/vm/runtime/synchronizer.cpp
void ObjectSynchronizer::fast_exit(oop object, BasicLock* lock, TRAPS) {
{- -------------------------------------------
(1) (assert)
(ここに biased の状態でくることはないはず)
---------------------------------------- -}
assert(!object->mark()->has_bias_pattern(), "should not see bias pattern here");
{- -------------------------------------------
(1) もし BasicObjectLock の displaced_header が NULL なら (= 自分が複数回ロックを取得していたケースでは),
ここでリターン.
(なお, if の中で色々やっているようにも見えるが, 全部 assert チェック)
---------------------------------------- -}
// if displaced header is null, the previous enter is recursive enter, no-op
markOop dhw = lock->displaced_header();
markOop mark ;
if (dhw == NULL) {
// Recursive stack-lock.
// Diagnostics -- Could be: stack-locked, inflating, inflated.
mark = object->mark() ;
assert (!mark->is_neutral(), "invariant") ;
if (mark->has_locker() && mark != markOopDesc::INFLATING()) {
assert(THREAD->is_lock_owned((address)mark->locker()), "invariant") ;
}
if (mark->has_monitor()) {
ObjectMonitor * m = mark->monitor() ;
assert(((oop)(m->object()))->mark() == mark, "invariant") ;
assert(m->is_entered(THREAD), "invariant") ;
}
return ;
}
{- -------------------------------------------
(1) もし stack-locked であれば CAS で mark を書き戻す.
成功したらここでリターン.
---------------------------------------- -}
mark = object->mark() ;
// If the object is stack-locked by the current thread, try to
// swing the displaced header from the box back to the mark.
if (mark == (markOop) lock) {
assert (dhw->is_neutral(), "invariant") ;
if ((markOop) Atomic::cmpxchg_ptr (dhw, object->mark_addr(), mark) == mark) {
TEVENT (fast_exit: release stacklock) ;
return;
}
}
{- -------------------------------------------
(1) 上記のどれでもなければ (あるいは CAS が失敗した場合は),
ObjectSynchronizer::inflate() で ObjectMonitor オブジェクトを取得した後,
ObjectMonitor::exit() でアンロック処理を行う.
---------------------------------------- -}
ObjectSynchronizer::inflate(THREAD, object)->exit (THREAD) ;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.