hotspot/src/share/vm/prims/jvmtiEnvBase.cpp
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
jvmtiError
JvmtiEnvBase::force_early_return(JavaThread* java_thread, jvalue value, TosState tos) {
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
JavaThread* current_thread = JavaThread::current();
HandleMark hm(current_thread);
uint32_t debug_bits = 0;
{- -------------------------------------------
(1) JvmtiThreadState::state_for() を呼んで,
処理対象のスレッド(java_thread)に対応する JvmtiThreadState を取得する.
(もし対象のスレッドが JvmtiThreadState を持っていなければ, この中で確保処理が行われる)
(なお, スレッドが既に死んでいる場合(もしくは確保処理が失敗した場合)は, ここでリターン(JVMTI_ERROR_THREAD_NOT_ALIVE エラー))
---------------------------------------- -}
// retrieve or create the state
JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread);
if (state == NULL) {
return JVMTI_ERROR_THREAD_NOT_ALIVE;
}
{- -------------------------------------------
(1) 対象のスレッドが suspend されているかどうかを確認する.
suspended されてなければ, ここでリターン(JVMTI_ERROR_THREAD_NOT_SUSPENDED).
(これは JVMTI 仕様で要求されている挙動)
---------------------------------------- -}
// Check if java_thread is fully suspended
if (!is_thread_fully_suspended(java_thread,
true /* wait for suspend completion */,
&debug_bits)) {
return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
}
{- -------------------------------------------
(1) もし対象のスレッドが既に ForceEarlyReturn*() をかけられた状態であれば, ここでリターン(JVMTI_ERROR_INTERNAL).
---------------------------------------- -}
// Check to see if a ForceEarlyReturn was already in progress
if (state->is_earlyret_pending()) {
// Probably possible for JVMTI clients to trigger this, but the
// JPDA backend shouldn't allow this to happen
return JVMTI_ERROR_INTERNAL;
}
{- -------------------------------------------
(1) もしスレッドが MONITOR_WAIT 状態であれば, ここでリターン(JVMTI_ERROR_OPAQUE_FRAME).
(この処理については bug 4812902 を参照とのこと #TODO)
---------------------------------------- -}
{
// The same as for PopFrame. Workaround bug:
// 4812902: popFrame hangs if the method is waiting at a synchronize
// Catch this condition and return an error to avoid hanging.
// Now JVMTI spec allows an implementation to bail out with an opaque
// frame error.
OSThread* osThread = java_thread->osthread();
if (osThread->get_state() == MONITOR_WAIT) {
return JVMTI_ERROR_OPAQUE_FRAME;
}
}
{- -------------------------------------------
(1) JvmtiEnvBase::check_top_frame() を呼び出し,
JVMTI 仕様上での様々な制限が満たされているかどうかチェックする .
チェックで問題が見つかればここでリターン.
(ついでに, もし先頭のフレームが compiled frame なら deopt も行う)
---------------------------------------- -}
Handle ret_ob_h = Handle();
jvmtiError err = check_top_frame(current_thread, java_thread, value, tos, &ret_ob_h);
if (err != JVMTI_ERROR_NONE) {
return err;
}
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(tos != atos || value.l == NULL || ret_ob_h() != NULL,
"return object oop must not be NULL if jobject is not NULL");
{- -------------------------------------------
(1) 以下のフィールドを変更し, ForceEarlyReturn*() の対象になっていることを
JvmtiThreadState オブジェクト内に記録しておく.
(これらは強制復帰処理を開始させるためのフラグ.
実際の強制復帰処理は, deopt 処理または call_VM_base() からのリターン処理時に行われる.)
* JvmtiThreadState::_earlyret_state フィールド
* JvmtiThreadState::_earlyret_oop フィールド
* JvmtiThreadState::_earlyret_tos フィールド
* JvmtiThreadState::_earlyret_value フィールド
* JvmtiThreadState::_pending_step_for_earlyret フィールド
---------------------------------------- -}
// Update the thread state to reflect that the top frame must be
// forced to return.
// The current frame will be returned later when the suspended
// thread is resumed and right before returning from VM to Java.
// (see call_VM_base() in assembler_<cpu>.cpp).
state->set_earlyret_pending();
state->set_earlyret_oop(ret_ob_h());
state->set_earlyret_value(value, tos);
// Set pending step flag for this early return.
// It is cleared when next step event is posted.
state->set_pending_step_for_earlyret();
{- -------------------------------------------
(1) リターン
---------------------------------------- -}
return JVMTI_ERROR_NONE;
} /* end force_early_return */
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.