Up Top

Exception の処理 : 処理の詳細 (4) : 例外ハンドラの探索処理 : 同種のフレーム内での処理 : 非ランタイム(かつ非ネイティブ)フレームでの処理 : Template Interpreter の場合


概要(Summary)

Template Interpreter フレーム用の例外処理コードは, HotSpot の初期化時に TemplateInterpreterGenerator::generate_throw_exception() によって生成される (See: here for details).

この関数は 4つのスタブを生成する. 生成されたスタブはそれぞれ下表のアクセサメソッドから格納される.

実際に行われる処理は以下のようになる.

  1. Interpreter::throw_exception_entry() が指しているコードで, 現在のメソッド内に対応する例外ハンドラがないかどうかを調べる

  2. なければ, Interpreter::remove_activation_entry() が指しているコードでスタックを一段さかのぼる.

  3. さかのぼった先がまだ Template Interpreter のフレームであれば, Interpreter::rethrow_exception_entry() が指しているコードで 1. とほぼ同様の処理を行う.

そうでなければ (= さかのぼった先がランタイムフレーム(callスタブ)であれば), ランタイムフレーム用の例外処理に移行する (See: here for details).

  1. 以下, 見つかるまで 2. と 3. を繰り返す.
Stub Accessor method
例外送出処理(throw)を行うスタブ Interpreter::throw_exception_entry()
例外の再送出処理(rethrow)を行うスタブ Interpreter::rethrow_exception_entry()
JVMTI の PopFrame 処理用のスタブ(※) Interpreter::remove_activation_preserving_args_entry()
スタックフレームの unwind 処理を行うスタブ Interpreter::remove_activation_entry()

(※) これだけは例外処理とは関係ないので別項参照 (See: here for details). そもそも何故ここで作られているのかよく分からないが... (というかまとめて4種類も作っているので全体的にコードの見通しが悪い気もするが...)

処理の流れ (概要)(Execution Flows : Summary)

対応する例外ハンドラの探索処理 (= 例外の送出処理(throw) または 再送出処理(rethrow))

Interpreter::throw_exception_entry() もしくは Interpreter::rethrow_exception_entry() が指しているコード (= TemplateInterpreterGenerator::generate_throw_exception() が生成したコード)
-> (1) 適切な例外ハンドラのエントリポイントを取得
       -> InterpreterRuntime::exception_handler_for_exception()
   (1) 取得したアドレスにジャンプ. なお, 以下の2つの可能性がある.
       * 現在のメソッドの例外テーブル内に対応するハンドラが見つかった場合:
         -> ハンドラのエントリポイントに対応するテンプレートにジャンプ
       * 〃 見つからなかった場合: (= unwind 処理が必要な場合)
         -> Interpreter::remove_activation_entry() が指しているコードにジャンプ (下記参照)

ハンドラが見つからない場合にスタックを一段さかのぼる処理

Interpreter::remove_activation_entry() が指しているコード (= TemplateInterpreterGenerator::generate_throw_exception() が生成したコード)
-> (1) 現在のスタックフレームを破棄 (synchronized method であればロックの解除も行う (See: here for details))
   (1) 適切な unwind 先のアドレスを取得
       -> SharedRuntime::exception_handler_for_return_address()
   (1) 取得したアドレスにジャンプ. なお, 以下の2つの可能性がある.
       * 呼び出し元がインタープリタフレームの場合:
         -> Interpreter::rethrow_exception_entry() が指しているコード (上記参照)
       * 呼び出し元がランタイムフレーム(callスタブ)の場合:
         -> StubRoutines::catch_exception_entry() が指しているコード
            -> (See: here for details)

処理の流れ (詳細)(Execution Flows : Details)

TemplateInterpreterGenerator::generate_throw_exception() (sparc の場合)

See: here for details

TemplateInterpreterGenerator::generate_throw_exception() (x86_64 の場合)

See: here for details

InterpreterRuntime::exception_handler_for_exception()

See: here for details

methodOopDesc::fast_exception_handler_bci_for()

(#Under Construction) See: here for details

SharedRuntime::exception_handler_for_return_address()

See: here for details

SharedRuntime::raw_exception_handler_for_return_address()

(#Under Construction) See: here for details


This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.