(See: JVMTI 仕様)
HotSpot 内では, JvmtiEventEnabled オブジェクトという bit mask で現在有効になっているイベントを管理している. この管理は「env 毎および thread 毎(正確には スレッドと env の組み合わせごと)」に行われており, 合計 3種類の bit mask (JvmtiEventEnabled オブジェクト) が使われる.
(なお, 「現在有効になっているイベント」とは, 「コールバックが設定されておりイベント通知設定も有効になっているイベント」のこと (<= 正確には少し違う. 後述))
それぞれの JvmtiEventEnabled オブジェクトは以下のクラス内のフィールドに格納されている.
JvmtiEventController クラス
このクラスはイベント通知の設定変更を行う関数を納めた名前空間(AllStatic クラス). ついでに現在の設定値をキャッシュしてもいる.
JvmtiEnvEventEnable クラス
JvmtiEventEnabled を管理するためのクラス. env 毎に1つ.
JvmtiThreadEventEnable クラス
JvmtiEventEnabled を管理するためのクラス. thread 毎に1つ.
JvmtiEnvThreadEventEnable クラス
JvmtiEventEnabled を管理するためのクラス. env と thread の組み合わせ毎に1つ.
より正確には以下の通り.
JvmtiEventController クラス
JvmtiEventController::_universal_global_event_enabled フィールド
前回の JvmtiEventControllerPrivate::recompute_enabled() で計算した結果がキャッシュされている模様 (以下の JvmtiEnvEventEnable, JvmtiThreadEventEnable, JvmtiEnvThreadEventEnable の enalbed の和集合. 全体として enabled になるべきイベントは最終的にはこれで決まる).
JvmtiEnvEventEnable クラス
_event_user_enabled フィールド
ユーザーが SetEventNotificationMode() でイベント通知を有効化したイベント (の内で, SetEventNotificationMode で対象が全スレッドと指定されたもの)
_event_callback_enabled フィールド
ユーザーが SetEventCallbacks() や SetExtensionEventCallback() でコールバックを設定しているイベント一覧. (See: set_event_callbacks(), set_extension_event_callback())
_event_enabled フィールド
前回の JvmtiEventControllerPrivate::recompute_env_enabled() で計算した結果がキャッシュされている模様.
JvmtiThreadEventEnable クラス
_event_enabled フィールド
前回の JvmtiEventControllerPrivate::recompute_thread_enabled() で計算した結果がキャッシュされている模様 (その thread が関連する全部の JvmtiEnvThreadEventEnable の enabled の和集合).
JvmtiEnvThreadEventEnable クラス
_event_user_enabled フィールド
ユーザーが SetEventNotificationMode() でイベント通知を有効化したイベント (の内で, SetEventNotificationMode で対象スレッドが指定されていたもの)
_event_enabled フィールド
前回の JvmtiEventControllerPrivate::recompute_env_thread_enabled() で計算した結果がキャッシュされている模様.
有効化されているイベント種別については, HotSpot 内の対応する箇所からコールバックが呼び出される. 対応する箇所では, イベント種別が有効かどうかを確認し, 有効であればコールバックを呼び出す. この確認処理とコールバックの呼び出しは JvmtiExport クラスを介して行われる (JvmtiExport クラスが, イベント通知処理の実装をそれ以外の箇所から隠蔽する役割を果たしている).
上述の通り, ユーザーが SetEventNotificationMode()/SetEventCallbacks()/SetExtensionEventCallback() で指定した内容を直接的に格納している JvmtiEventEnabled オブジェクトと, それを元に計算した結果をキャッシュしているだけの JvmtiEventEnabled オブジェクトがある (キャッシュしているのは, 前回と今回で変化が有ったかどうかを調べるため (<= 結局, 高速化のため?? #TODO)).
ユーザーの指定内容を直接的に格納しているのは以下の3つ (その他は全てキャッシュ).
コールバックが設定されたりイベント通知設定が変わったり実行 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() {
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_*()
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() -> (同上)
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
(#Under Construction) See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.