例外がランタイムフレーム内で伝搬され続け, 非ランタイム(かつ非ネイティブ)フレームまで戻ってきた場合, その境界で (ランタイムフレーム用のものから別の種類のフレーム用のものへと) 例外ハンドラ探索処理が切り替わる. 切り替えは, ランタイムを呼び出した側がリターン後に pending_exception をチェックすることで行っている.
切り替え後の例外ハンドラ探索処理は, StubRoutines::forward_exception_entry (アクセサは StubRoutines::forward_exception_entry()) が指しているスタブコードが行う このスタブは, 例外ハンドラの取得とその呼び出し処理を行う. このスタブは, HotSpot の初期化時に StubGenerator::generateforward_exception() という関数で生成されている.
ランタイムを呼び出す各種のコードでは, ランタイムからのリターン後に pending_exception がセットされていれば, このスタブにジャンプして例外処理を行う.
なお, どこまで遡ってもランタイムのフレームしかない場合もありうるが, その場合はどこにも例外のキャッチ場所がないので異常終了になる.
それぞれの場合におけるランタイムとの境界は以下の通り.
Code | Boundary |
---|---|
Template Interpreter の場合 | MacroAssembler::call_VM_base() が生成したコード (See: here for details) |
C++ Interpreter の場合 | |
C1 JIT Compiler が生成したコードの場合 | |
C2 JIT Compiler が生成したコードの場合 | GraphKit::gen_stub() が生成したコード, SharedRuntime::generate_handler_blob() が生成したコード, SharedRuntime::generate_resolve_blob() が生成したコード (See: here for details) |
Shark JIT Compiler が生成したコードの場合 |
(See: here for details) -> StubGenerator::generate_initial() -> StubGenerator::generate_forward_exception()
ランタイムを呼び出す各種のコード (See: here and here for details) -> StubRoutines::forward_exception_entry() が指しているコード (= StubGenerator::generate_forward_exception() が生成したコード) -> SharedRuntime::exception_handler_for_return_address() で, 適切な例外ハンドラのエントリポイントを取得. -> SharedRuntime::raw_exception_handler_for_return_address() -> 取得したアドレスにジャンプ
See: here for details
See: here for details
See: here for details
(#Under Construction) See: here for details
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.