Up Top

Serviceability 機能 : JVMTI の処理 : JVMTI 関数の処理 : イベント管理 (Event Management) : SetEventCallbacks() 及び SetEventNotificationMode() の処理


概要(Summary)

(See: JVMTI 仕様)

HotSpot 内では, JvmtiEventEnabled オブジェクトという bit mask で現在有効になっているイベントを管理している. この管理は「env 毎および thread 毎(正確には スレッドと env の組み合わせごと)」に行われており, 合計 3種類の bit mask (JvmtiEventEnabled オブジェクト) が使われる.

(なお, 「現在有効になっているイベント」とは, 「コールバックが設定されておりイベント通知設定も有効になっているイベント」のこと (<= 正確には少し違う. 後述))

それぞれの JvmtiEventEnabled オブジェクトは以下のクラス内のフィールドに格納されている.

より正確には以下の通り.

有効化されているイベント種別については, HotSpot 内の対応する箇所からコールバックが呼び出される. 対応する箇所では, イベント種別が有効かどうかを確認し, 有効であればコールバックを呼び出す. この確認処理とコールバックの呼び出しは JvmtiExport クラスを介して行われる (JvmtiExport クラスが, イベント通知処理の実装をそれ以外の箇所から隠蔽する役割を果たしている).

備考(Notes)

上述の通り, ユーザーが SetEventNotificationMode()/SetEventCallbacks()/SetExtensionEventCallback() で指定した内容を直接的に格納している JvmtiEventEnabled オブジェクトと, それを元に計算した結果をキャッシュしているだけの JvmtiEventEnabled オブジェクトがある (キャッシュしているのは, 前回と今回で変化が有ったかどうかを調べるため (<= 結局, 高速化のため?? #TODO)).

ユーザーの指定内容を直接的に格納しているのは以下の3つ (その他は全てキャッシュ).

備考(Notes)

コールバックが設定されたりイベント通知設定が変わったり実行 phase が変わったりする度に, JvmtiEventControllerPrivate::recompute_enabled() が呼び出される. この関数で, 実際に有効になっているイベント("truly enabled event") がどれかを判定し, JvmtiExport::should_post_* の値を変更している.

(ここでの "truly enabled event" とは, 「ユーザーが各スレッド単位かグローバル化でイベント通知を有効にし, かつ callback もちゃんと設定されているイベント」のこと. field watch や frame pop の場合には, さらに「監視対象まで設定されている」という条件も付く)

("truly enabled event" は, スレッドごと, environment ごと, スレッドと environment の組み合わせ(thread x environment)ごと, グローバル(??#TODO), についてそれぞれ計算される)

    ((cite: hotspot/src/share/vm/prims/jvmtiEventController.cpp))
    // Compute truly enabled events - meaning if the event can and could be
    // sent.  An event is truly enabled if it is user enabled on the thread
    // or globally user enabled, but only if there is a callback or event hook
    // for it and, for field watch and frame pop, one has been set.
    // Compute if truly enabled, per thread, per environment, per combination
    // (thread x environment), and overall.  These merges are true if any is true.
    // True per thread if some environment has callback set and the event is globally
    // enabled or enabled for this thread.
    // True per environment if the callback is set and the event is globally
    // enabled in this environment or enabled for any thread in this environment.
    // True per combination if the environment has the callback set and the
    // event is globally enabled in this environment or the event is enabled
    // for this thread and environment.
    //
    // All states transitions dependent on these transitions are also handled here.
    void
    JvmtiEventControllerPrivate::recompute_enabled() {

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

コールバックの設定処理 (SetEventCallbacks() の処理)

JvmtiEnv::SetEventCallbacks()
-> JvmtiEventController::set_event_callbacks()
   -> JvmtiEnvBase::set_event_callbacks()
   -> JvmtiEventControllerPrivate::set_event_callbacks()
      -> JvmtiEventControllerPrivate::recompute_enabled()
         -> JvmtiEventControllerPrivate::recompute_env_enabled()
         -> JvmtiEventControllerPrivate::recompute_thread_enabled()
            -> JvmtiEventControllerPrivate::recompute_env_thread_enabled()
               -> JvmtiEnvThreadState::reset_current_location()      #TODO
            -> JvmtiEventControllerPrivate::enter_interp_only_mode()
               -> VMThread::execute()
                  -> (略) (See: here for details)
                     -> VM_EnterInterpOnlyMode::doit()
                        -> JavaThread::increment_interp_only_mode()
                           -> JvmtiThreadState::leave_interp_only_mode()
            -> JvmtiEventControllerPrivate::leave_interp_only_mode()
               -> JavaThread::decrement_interp_only_mode()
         -> JvmtiExport::set_should_post_*()

イベント通知の有効化処理 (NotificationMode() の処理)

JvmtiEnv::SetEventNotificationMode()
-> JvmtiEnvBase::record_class_file_load_hook_enabled()
-> JvmtiEventController::set_user_enabled()
   -> JvmtiEventControllerPrivate::set_user_enabled()
      -> JvmtiEnvEventEnable::set_user_enabled()
      -> JvmtiEnvThreadEventEnable::set_user_enabled()
      -> JvmtiEventControllerPrivate::recompute_enabled()
         -> (同上)

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

JvmtiEnv::SetEventCallbacks()

See: here for details

JvmtiEventController::set_event_callbacks()

See: here for details

JvmtiEventControllerPrivate::set_event_callbacks()

See: here for details

JvmtiEnvBase::set_event_callbacks()

See: here for details

JvmtiEventControllerPrivate::recompute_enabled()

See: here for details

JvmtiEventControllerPrivate::recompute_env_enabled()

See: here for details

JvmtiEventControllerPrivate::recompute_thread_enabled()

See: here for details

JvmtiEventControllerPrivate::recompute_env_thread_enabled()

See: here for details

JvmtiEnvThreadState::reset_current_location()

(#Under Construction) See: here for details

JvmtiEventControllerPrivate::enter_interp_only_mode()

See: here for details

VM_EnterInterpOnlyMode::doit()

See: here for details

JvmtiThreadState::invalidate_cur_stack_depth()

See: here for details

JvmtiThreadState::enter_interp_only_mode()

See: here for details

JavaThread::increment_interp_only_mode()

See: here for details

JvmtiThreadState::leave_interp_only_mode()

See: here for details

JavaThread::decrement_interp_only_mode()

See: here for details

JvmtiEventControllerPrivate::leave_interp_only_mode()

See: here for details

JvmtiEnv::SetEventNotificationMode()

See: here for details

JvmtiEnvBase::record_class_file_load_hook_enabled()

See: here for details

JvmtiEnvBase::record_first_time_class_file_load_hook_enabled()

See: here for details

JvmtiEventController::set_user_enabled()

See: here for details

JvmtiEventControllerPrivate::set_user_enabled()

See: here for details

JvmtiEnvEventEnable::set_user_enabled()

See: here for details

JvmtiEnvEventEnable::set_user_enabled()

See: here for details


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