Template Interpreter の場合, dispatchTable の中身を変更することで, 強制的な状態遷移を実現している.
より具体的に言うと, Safepoint が開始されると全ての codelet が Safepoint 処理を行うコードに置き換わる. このため任意のバイトコードの先頭が Safepoint になる (= インタープリタが次のバイトコードへ遷移する際に停止).
なお, 実際の停止処理は InterpreterRuntime の関数 (InterpreterRuntime::at_safepoint()) を呼ぶことで行い, その際の IRT_ENTRY/IRT_END のチェックで停止させている (See: here for details).
Template Interpreter は以下の 3つの dispatch table を持つ. 実際に使用するのは active_table. これに _normal_table の内容か _safepttable の内容がコピーされる.
通常時は Safepoint チェックを行わない dispatch table (= _normal_table) がコピーされている.
Safepoint 停止が必要になると safept_table の内容へと書き換えられる. Safepoint 処理が終了すると, また _normaltable の内容へと戻される.
(なお active_table の変更処理は, SafepointSynchronize::begin() と SafepointSynchronize::end() の中で行われている (See: TemplateInterpreter::noticesafepoints(), TemplateInterpreter::ignore_safepoints())).
((cite: hotspot/src/share/vm/interpreter/templateInterpreter.hpp))
static DispatchTable _active_table; // the active dispatch table (used by the interpreter for dispatch)
static DispatchTable _normal_table; // the normal dispatch table (used to set the active table in normal mode)
static DispatchTable _safept_table; // the safepoint dispatch table (used to set the active table for safepoints)
safept_table の中身は TemplateInterpreterGenerator::set_safepoints_for_all_bytes() で生成される. テーブル内のエントリは, (bytecode や tos 状態に関わらず) 全て TemplateInterpreter::safept_entry に格納されているコードを指している. (See: TemplateInterpreterGenerator::set_safepoints_for_all_bytes(), TemplateInterpreterGenerator::generate_safept_entry_for())
_safept_table の各エントリ -> TemplateInterpreter::_safept_entry に格納されているコード -> TemplateInterpreterGenerator::generate_safept_entry_for() が生成したコード -> InterpreterRuntime::at_safepoint() -> IRT_ENTRY マクロ -> (See: here for details) -> IRT_END マクロ -> (See: here for details) (Safepoint 処理が開始されていれば, この中で停止する)
See: here for details
See: here for details
See: here for details
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.