Template Interpreter の場合, TemplateInterpreterGenerator::generate_return_entry_for() が生成したコードによって後片付けが行われる.
これは, 各invoke*命令が実行された際に, 呼び出し先からのリターンアドレスとして (現在の PC の代わりに) 上記のreturn_entry()が生成したコードの先頭アドレスを設定することで実現している (See: here for details). このため, 呼び出し先から return してくると, 本当の呼び出し元である invoke*処理用の codelet の中ではなく, return entry の先頭に飛ぶことになる.
TemplateInterpreterGenerator::generate_return_entry_for() が生成したコード内では 「次の命令 (bcp の次の1byte) を調べて適切な codelet にジャンプする」という処理が行われる. このため, 呼び出された側は普通にリターンするだけでいい. リターンによって return_entry() が生成したスタブに飛び, そこで次の命令を調べて適切な codelet への遷移が起こる.
invoke* の種類によって次の命令の位置が変わるため (3byte 先 or 5 byte 先), TemplateInterpreter::return_entry() では両方のパターンを作っておき, prepare_invoke() 等の中で引数に応じて適切なアドレスを選んでいる (See: here for details).
(See: here for details) -> TemplateInterpreterGenerator::generate_all() -> TemplateInterpreterGenerator::generate_return_entry_for()
TemplateInterpreterGenerator::generate_return_entry_for() が生成したコード -> (1) レジスタの値を復帰させる (1) 次のバイトコードに対応するテンプレートへとジャンプする -> InterpreterMacroAssembler::dispatch_next() が生成するコード
See: here for details
See: here for details
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.