例外が非ランタイム(かつ非ネイティブ)フレーム内で伝搬され続け, ランタイムフレームまで戻ってきた場合, その境界で (非ランタイムフレーム用のものからランタイムフレーム用のものへと) 例外ハンドラ探索処理が切り替わる.
切り替えは, 呼び出したランタイム側がリターン時に CHECK マクロ等でチェックすることで行っている (ランタイムからの呼び出しに使われる JavaCalls::call_*() 等の中では CHECK マクロが使われているため, 普通に pending_exception をセットした状態でリターンすれば, 後はランタイム内で勝手に例外が持ち上げられていく. (See: here for details)).
以上のことから, この境界では普通にリターンするだけで例外が伝搬される. ただし, 呼び出し元に例外情報を伝えるためには JavaThread 内の例外関係のフィールドを設定しておく必要がある. このため, その処理を StubRoutines::catch_exception_entry() が指しているコードで行ってからリターンしている.
なお, どこまで遡ってもランタイムフレームがないということはあり得ない. どんなスレッドも最初にランタイムが JavaCalls で Java のメソッドを呼び出す所から始まるので.
各種のスタックの unwind 処理 (See: here for details) -> StubRoutines::catch_exception_entry() が指しているコード (= StubGenerator::generate_catch_exception() が生成したコード) -> JavaThread 内の例外関係のフィールドを設定 -> StubRoutines::_call_stub_return_address が指しているアドレスにジャンプ (リターンとほぼ同義. スタックフレームが既に無いので単にジャンプする)
See: here for details
See: here for details
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.