Up Top

Serviceability 機能 : JVMTI の処理 : JVMTI 関数の処理 : ブレークポイント (Breakpoint) : SetBreakpoint() 及び ClearBreakpoint() の処理


概要(Summary)

(See: JVMTI 仕様)

JvmtiEnv::SetBreakpoint() や JvmtiEnv::ClearBreakpoint() による breakpoint の追加/削除は, VM operation で (より具体的には VM_ChangeBreakpoints::doit() で) 行っている. 追加/削除で行う作業は以下の通り.

  1. JvmtiBreakpoints オブジェクトが内部で持つ JvmtiBreakpointCache に対して登録/削除する

    (JvmtiBreakpointCache 自体も, 内部で持つ GrowableCache に対して登録/削除しているだけ)

  2. methodOop の中のバイトコード列の該当個所を bytecode 命令に書き換える/元に戻す

    (bytecode 命令にした場合には, ついでに deopt もかけている)

備考(Notes)

JVMTI のブレークポイントは以下のクラス群によって管理されている.

実際のブレークポイント情報を記録しているのは BreakpointInfo クラスと JvmtiBreakpoint クラス. 使い分けとしては, JvmtiBreakpoint は高速化のためのキャッシュを作るために使われている模様 (See: JvmtiCurrentBreakpoints::is_breakpoint()). (<= とはいえこの関数自体が使われていないので, あまり有効に活用されている気がしないが...)

備考(Notes)

break point 機能を利用するためには, callback の設定と通知の有効化だけでなく, JvmtiEnv::SetBreakpoint() で監視対象を指定する必要が有る.

備考(Notes)

breakpoint が埋め込まれているメソッドに付いては, JIT Compile の対象にならない.

参考(for your information)

parse 段階での処理

C2 の場合 (@ Parse::do_one_bytecode())

    ((cite: hotspot/src/share/vm/opto/parse2.cpp))
      case Bytecodes::_breakpoint:
        // Breakpoint set concurrently to compile
        // %%% use an uncommon trap?
        C->record_failure("breakpoint in method");
        return;

C1 の場合 (@ GraphBuilder::iterate_bytecodes_for_block())

    ((cite: hotspot/src/share/vm/c1/c1_GraphBuilder.cpp))
          case Bytecodes::_breakpoint     : BAILOUT_("concurrent setting of breakpoint", NULL);

備考(Notes)

break point や singlestep を有効にした場合は, 重複してイベントを送信しないように, 現在の実行地点を記録する処理が行われる.

(See: JvmtiEnvThreadState::reset_current_location()) (<= ここのコメントで詳しく説明されているような... #TODO)

(See: JvmtiEnvThreadState::compare_and_set_current_location() )

参考(for your information)

http://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html

以下, 引用.

備考(Notes)

breakpoint capability を取得にした場合に true になる JvmtiExport::can_* フィールドは以下の通り. (<= それぞれどういう影響が有る? #TODO)

    ((cite: hotspot/src/share/vm/prims/jvmtiManageCapabilities.cpp))
      JvmtiExport::set_can_hotswap_or_post_breakpoint(
        avail.can_generate_breakpoint_events ||
        avail.can_redefine_classes ||
        avail.can_retransform_classes);
      JvmtiExport::set_can_modify_any_class(
        avail.can_generate_breakpoint_events ||
        avail.can_generate_all_class_hook_events);
    ...
      JvmtiExport::set_can_access_local_variables(
        avail.can_access_local_variables ||
        avail.can_generate_breakpoint_events ||
        avail.can_generate_frame_pop_events);
    ...
      JvmtiExport::set_can_post_breakpoint(avail.can_generate_breakpoint_events);
    ...
      JvmtiExport::set_should_clean_up_heap_objects(avail.can_generate_breakpoint_events);

処理の流れ (概要)(Execution Flows : Summary)

breakpoint 関係の capability の有効化処理 (AddCapabilities() の処理)

(See: here for details)

なお breakpoint 用の capability を取得すると, (JvmtiExport::can_*() が変更されることに加えて) 以下の最適化オプションが無効になる (See: JvmtiManageCapabilities::update()).

breakpoint 関係の callback の設定処理 (SetEventCallbacks() の処理)

(See: here for details)

(なお breakpoint の場合には, JvmtiEventControllerPrivate::recompute_enabled() の中で JvmtiEnvThreadState::reset_current_location() が行われる. #TODO)

breakpoint event の有効化処理 (SetEventNotificationMode() の処理)

(See: here for details)

(なお breakpoint の場合には, JvmtiEventControllerPrivate::recompute_enabled() の中で JvmtiEnvThreadState::reset_current_location() が行われる. #TODO)

breakpoint の設定処理 (SetBreakpoint() の処理)

JvmtiEnv::SetBreakpoint()
-> JvmtiBreakpoints::set()
   -> VMThread::execute()
      -> (略) (See: here for details)
         -> VM_ChangeBreakpoints::doit()  (<= コンストラクタ引数は VM_ChangeBreakpoints::SET_BREAKPOINT)
            -> JvmtiBreakpoints::set_at_safepoint()
               -> JvmtiBreakpointCache::append()
                  -> GrowableCache::append()
                  -> GrowableCache::recache()
               -> JvmtiBreakpoint::set()
                  -> JvmtiBreakpoint::each_method_version_do() (<= 引数は methodOopDesc::set_breakpoint)
                     -> methodOopDesc::set_breakpoint()
                        -> BreakpointInfo::BreakpointInfo()
                        -> BreakpointInfo::set()

breakpoint イベントの通知処理

(interpreter が breakpoint 命令を踏むとイベントが送信される)

* Template Interpreter の場合

  TemplateTable::_breakpoint() が生成したコード
  -> InterpreterRuntime::_breakpoint()
     -> JvmtiExport::post_raw_breakpoint()
        -> (登録されているコールバックを呼び出す)

* C++ Interpreter の場合

  BytecodeInterpreter::run() 又は BytecodeInterpreter::runWithChecks()
  -> InterpreterRuntime::_breakpoint()
     -> (同上)

breakpoint の解除処理 (ClearBreakpoint() の処理)

JvmtiEnv::ClearBreakpoint()
-> JvmtiBreakpoints::clear()
   -> VMThread::execute()
      -> (略) (See: here for details)
         -> VM_ChangeBreakpoints::doit()  (<= コンストラクタ引数は VM_ChangeBreakpoints::CLEAR_BREAKPOINT)
            -> JvmtiBreakpoints::clear_at_safepoint()
               -> JvmtiBreakpointCache::remove()
                  -> GrowableCache::remove()
                  -> GrowableCache::recache()
               -> JvmtiBreakpoint::clear()
                  -> JvmtiBreakpoint::each_method_version_do() (<= 引数は methodOopDesc::clear_breakpoint)
                     -> methodOopDesc::clear_breakpoint()
                        -> clear_matches()
                           -> BreakpointInfo::clear()

処理の流れ (詳細)(Execution Flows : Details)

JvmtiEnv::SetBreakpoint()

See: here for details

JvmtiCurrentBreakpoints::get_jvmti_breakpoints()

See: here for details

JvmtiBreakpoints::set()

See: here for details

VM_ChangeBreakpoints::doit()

See: here for details

JvmtiBreakpoints::set_at_safepoint()

See: here for details

JvmtiBreakpointCache::append()

See: here for details

GrowableCache::append()

See: here for details

GrowableCache::recache()

See: here for details

JvmtiCurrentBreakpoints::listener_fun()

See: here for details

JvmtiCurrentBreakpoints::set_breakpoint_list()

See: here for details

JvmtiBreakpoint::set()

See: here for details

JvmtiBreakpoint::each_method_version_do()

(#Under Construction) See: here for details

methodOopDesc::set_breakpoint()

See: here for details

BreakpointInfo::BreakpointInfo()

See: here for details

methodOopDesc::orig_bytecode_at()

See: here for details

BreakpointInfo::set()

See: here for details

TemplateTable::_breakpoint() (sparc の場合)

See: here for details

InterpreterMacroAssembler::dispatch_normal() (sparc の場合)

See: here for details

InterpreterRuntime::_breakpoint()

See: here for details

JvmtiExport::post_raw_breakpoint()

See: here for details

JvmtiEnvThreadState::compare_and_set_current_location()

(#Under Construction) See: here for details

TemplateTable::breakpoint() (x8664 の場合)

See: here for details

InterpreterMacroAssembler::dispatch_only_normal() (x86_64 の場合)

See: here for details

JvmtiEnv::ClearBreakpoint()

See: here for details

JvmtiBreakpoints::clear()

See: here for details

JvmtiBreakpoints::clear_at_safepoint()

See: here for details

JvmtiBreakpointCache::remove()

See: here for details

GrowableCache::remove()

See: here for details

JvmtiBreakpoint::clear()

See: here for details

methodOopDesc::clear_breakpoint()

See: here for details

clear_matches()

See: here for details

BreakpointInfo::clear()

See: here for details

JvmtiBreakpoints::clearall()

(使われていない??)

JvmtiBreakpoints::clearall_at_safepoint()

(使われていない??) See: here for details

JvmtiBreakpointCache::clear()

(使われていない??) See: here for details


This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.