hotspot/src/share/vm/prims/jvmtiExport.cpp
// Todo: inline this for optimization
void JvmtiExport::post_single_step(JavaThread *thread, methodOop method, address location) {
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
HandleMark hm(thread);
methodHandle mh(thread, method);
{- -------------------------------------------
(1) 処理対象のスレッドの JvmtiThreadState を取得する.
JvmtiThreadState がまだ作られていなければ
(明らかにこのタイミングでのイベント通知は不要なので) ここでリターン.
---------------------------------------- -}
JvmtiThreadState *state = thread->jvmti_thread_state();
if (state == NULL) {
return;
}
{- -------------------------------------------
(1) 処理対象の JvmtiThreadState オブジェクト内の全ての JvmtiEnvThreadState を辿り,
JVMTI_EVENT_SINGLE_STEP 通知が有効になっているもの全てに対してコールバックの呼び出しを行う.
(なお正確に言うと, 二重にイベントを送信しないように
JvmtiEnvThreadState::compare_and_set_current_location() でチェックしている.
二重送信の場合は single_stepping_posted() が true を返すようになる.
二重送信ではなく, かつ JVMTI_EVENT_SINGLE_STEP が有効になっており,
さらにコールバックが設定されている JvmtiEnvThreadState に対してだけ, コールバック呼び出しが行われる.)
(また, 一度コールバックを呼び出した JvmtiEnvThreadState についても,
JvmtiEnvThreadState::set_single_stepping_posted() を呼んで
single_stepping_posted() が true になるようにしている.)
(ついでに, コールバックの呼び出しを行う場合には(トレース出力)も出している)
---------------------------------------- -}
JvmtiEnvThreadStateIterator it(state);
for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
ets->compare_and_set_current_location(mh(), location, JVMTI_EVENT_SINGLE_STEP);
if (!ets->single_stepping_posted() && ets->is_enabled(JVMTI_EVENT_SINGLE_STEP)) {
EVT_TRACE(JVMTI_EVENT_SINGLE_STEP, ("JVMTI [%s] Evt Single Step sent %s.%s @ %d",
JvmtiTrace::safe_get_thread_name(thread),
(mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
(mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
location - mh()->code_base() ));
JvmtiEnv *env = ets->get_env();
JvmtiLocationEventMark jem(thread, mh, location);
JvmtiJavaThreadEventTransition jet(thread);
jvmtiEventSingleStep callback = env->callbacks()->SingleStep;
if (callback != NULL) {
(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
jem.jni_methodID(), jem.location());
}
ets->set_single_stepping_posted();
}
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.