JVMTI のイベントの中には, 実際にそのイベントが起こった瞬間ではなく, 少し遅れてから通知されるものがある.
(現状の HotSpot の実装では, CompiledMethodLoad, CompiledMethodUnload, DynamicCodeGenerated が遅延配送される模様)
これらのイベントを遅延させているのは, イベント通知は JavaThread から行わないといけないが, これらのイベントは CompilerThread や VMThread の中で発生するものであるため.
そのため, CompilerThread や VMThread 内ではイベントが発生したという情報だけを記録しておき, "ServiceThread" という JavaThread が実際の通知処理を行うことにしている.
((cite: hotspot/src/share/vm/prims/jvmtiImpl.hpp))
/**
* When a thread (such as the compiler thread or VM thread) cannot post a
* JVMTI event itself because the event needs to be posted from a Java
* thread, then it can defer the event to the Service thread for posting.
* The information needed to post the event is encapsulated into this class
* and then enqueued onto the JvmtiDeferredEventQueue, where the Service
* thread will pick it up and post it.
*
* This is currently only used for posting compiled-method-load and unload
* events, which we don't want posted from the compiler thread.
*/
以下のクラス群によって遅延通知が実現されている.
すぐに post できないイベントが発生すると, そのイベントの内容を格納した JvmtiDeferredEvent オブジェクトが作られ, JvmtiDeferredEventQueue に格納される.
この JvmtiDeferredEventQueue は ServiceThread によって監視されており, JvmtiDeferredEvent オブジェクトが追加されると ServiceThread がそれを取り出して JvmtiDeferredEvent::post() を呼び出すことでイベント通知処理を実行する.
(略) (See: here for details) -> ciEnv::register_method() -> nmethod::post_compiled_method_load_event() -> nmethod::get_and_cache_jmethod_id() -> JvmtiDeferredEvent::compiled_method_load_event() -> JvmtiDeferredEventQueue::enqueue() (略) (See: here for details) -> AdapterHandlerLibrary::create_native_wrapper() -> nmethod::post_compiled_method_load_event() -> (同上)
(略) (See: ...)
-> nmethod::make_unloaded()
-> nmethod::post_compiled_method_unload()
-> JvmtiDeferredEvent::compiled_method_unload_event()
-> * safepoint 中の場合
-> JvmtiDeferredEventQueue::add_pending_event()
* そうではない場合
-> JvmtiDeferredEventQueue::enqueue()
(略) (See: ...)
-> nmethod::make_not_entrant_or_zombie()
-> nmethod::post_compiled_method_unload()
-> (同上)
JvmtiExport::post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end)
-> * HotSpot の起動中の場合:
-> JvmtiExport::post_dynamic_code_generated_internal()
* それ以外の場合:
-> JvmtiDeferredEvent::dynamic_code_generated_event()
-> JvmtiDeferredEventQueue::enqueue()
ServiceThread::service_thread_entry()
-> JvmtiDeferredEventQueue::has_events()
-> JvmtiDeferredEventQueue::dequeue()
-> JvmtiDeferredEvent::post()
-> * CompiledMethodLoad の場合:
-> JvmtiExport::post_compiled_method_load()
* CompiledMethodUnload の場合:
-> JvmtiExport::post_compiled_method_unload()
* DynamicCodeGenerated の場合:
-> JvmtiExport::post_dynamic_code_generated_internal()
See: here for details
See: here for details
See: here for details
(#Under Construction) See: here for details
(#Under Construction) See: here for details
(#Under Construction) See: here for details
See: here for details
(#Under Construction) See: here for details
(#Under Construction)
See: here for details
See: here for details
See: here for details
(#Under Construction) See: here for details
See: here for details
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.