hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
//%note monitor_1
IRT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorexit(JavaThread* thread, BasicObjectLock* elem))
{- -------------------------------------------
(1) (デバッグ用の処理) (#ifdef ASSERT 時にのみ実行)
---------------------------------------- -}
#ifdef ASSERT
thread->last_frame().interpreter_frame_verify_monitor(elem);
#endif
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
Handle h_obj(thread, elem->obj());
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(Universe::heap()->is_in_reserved_or_null(h_obj()),
"must be NULL or an object");
{- -------------------------------------------
(1) 以下のどちらかの状態であれば, モニターの状態がおかしいので IllegalMonitorStateException.
* BasicObjectLock 中の obj フィールド(以下の elem)が null
* BasicObjectLock が指しているオブジェクトがロックされていない (mark フィールドが不正な状態になっている)
---------------------------------------- -}
if (elem == NULL || h_obj()->is_unlocked()) {
THROW(vmSymbols::java_lang_IllegalMonitorStateException());
}
{- -------------------------------------------
(1) ObjectSynchronizer::slow_exit() を呼んで, slow-path でのアンロック処理を行う.
---------------------------------------- -}
ObjectSynchronizer::slow_exit(h_obj(), elem->lock(), thread);
{- -------------------------------------------
(1) BasicObjectLock の obj フィールドを NULL にクリアする.
(クリアしておかないと, pending exception が立っていたときに
exception handler がもう一回開放しにいきかねないので必要らしい)
---------------------------------------- -}
// Free entry. This must be done here, since a pending exception might be installed on
// exit. If it is not cleared, the exception handling code will try to unlock the monitor again.
elem->set_obj(NULL);
{- -------------------------------------------
(1) (デバッグ用の処理) (#ifdef ASSERT 時にのみ実行)
---------------------------------------- -}
#ifdef ASSERT
thread->last_frame().interpreter_frame_verify_monitor(elem);
#endif
{- -------------------------------------------
(1) 終了
---------------------------------------- -}
IRT_END
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.