hotspot/src/share/vm/prims/jvmtiExport.cpp
void JvmtiExport::post_raw_breakpoint(JavaThread *thread, methodOop method, address location) {
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
HandleMark hm(thread);
methodHandle mh(thread, method);
{- -------------------------------------------
(1) 処理対象のスレッド(= breakpoint 命令を踏んづけたスレッド) の JvmtiThreadState を取得する.
なお, JvmtiThreadState がまだ作られていない場合は
(明らかにイベント通知は不要なので) ここでリターン.
---------------------------------------- -}
JvmtiThreadState *state = thread->jvmti_thread_state();
if (state == NULL) {
return;
}
{- -------------------------------------------
(1) (トレース出力)
---------------------------------------- -}
EVT_TRIG_TRACE(JVMTI_EVENT_BREAKPOINT, ("JVMTI [%s] Trg Breakpoint triggered",
JvmtiTrace::safe_get_thread_name(thread)));
{- -------------------------------------------
(1) 対象の JvmtiThreadState オブジェクト内の全ての JvmtiEnvThreadState を辿り,
JVMTI_EVENT_BREAKPOINT 通知が有効になっているもの全てに対してコールバックの呼び出しを行う.
(なお正確に言うと, 二重にイベントを送信しないように
JvmtiEnvThreadState::compare_and_set_current_location() でチェックしている.
二重送信の場合は breakpoint_posted() が true を返すようになる.
二重送信ではなく, かつ JVMTI_EVENT_BREAKPOINT が有効になっており,
さらにコールバックが設定されている JvmtiEnvThreadState に対してだけ, コールバック呼び出しが行われる.)
(また, 一度コールバックを呼び出した JvmtiEnvThreadState についても,
JvmtiEnvThreadState::set_breakpoint_posted() を呼んで
breakpoint_posted() が true になるようにしている.)
(なお, コールバックを呼び出している間だけ, 対象のスレッドの ThreadState は BREAKPOINTED に変更されている)
---------------------------------------- -}
JvmtiEnvThreadStateIterator it(state);
for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
ets->compare_and_set_current_location(mh(), location, JVMTI_EVENT_BREAKPOINT);
if (!ets->breakpoint_posted() && ets->is_enabled(JVMTI_EVENT_BREAKPOINT)) {
ThreadState old_os_state = thread->osthread()->get_state();
thread->osthread()->set_state(BREAKPOINTED);
EVT_TRACE(JVMTI_EVENT_BREAKPOINT, ("JVMTI [%s] Evt Breakpoint 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);
jvmtiEventBreakpoint callback = env->callbacks()->Breakpoint;
if (callback != NULL) {
(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
jem.jni_methodID(), jem.location());
}
ets->set_breakpoint_posted();
thread->osthread()->set_state(old_os_state);
}
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.