Top


定義場所(file name)

hotspot/src/share/vm/prims/jvmtiExport.cpp

名前(function name)

void JvmtiExport::post_raw_breakpoint(JavaThread *thread, methodOop method, address location) {

本体部(body)

  {- -------------------------------------------
  (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.