例外処理では「ユーザーが書いた Java コード内から対応する例外ハンドラを見つけてキャッチさせる」ことが主な仕事になる. このため処理の流れは以下の通り (なお, 対応する例外ハンドラがなかった場合は異常終了になる).
「例外オブジェクト(java.lang.Exceptionやjava.lang.Errorのサブクラスのオブジェクト)」を作成する.
なお, 例外オブジェクトは, HotSpot の内部的な処理中においても, Java レベルでのオブジェクト(Exception オブジェクト) の形でハンドリングされる
現在のメソッド内で対応するハンドラを見つけてジャンプする. 現在のメソッド内で見つからなければ, スタックフレームを一つ上がって同じ処理を繰り返す.
このうち, "2." の例外ハンドラの探索処理では以下のように処理が行われる. どちらの場合も, 対応するハンドラが見つかるまでスタックフレームの unwind が繰り返される.
Java コード内の場合:
例外ハンドラテーブル情報がクラスファイルに埋め込まれているため, それを用いる.
現在のスタックフレームに対応するメソッドのテーブルを調べ, 該当する例外ハンドラが見つかればそこにジャンプする. 見つからなければスタックフレームの unwind を行い, 見つかるまで同じことを繰り返す.
それ以外の場合 (= ネイティブコード内(JVM 内部や JNI コード内)の場合):
ネイティブコードには例外ハンドラテーブル情報といったものはない. 代わりに, もしネイティブコード内でその例外に対する捕捉処理 (ExceptionClear()) が行われれば, そこで例外は消滅する (See: here for details).
例外が捕捉されなければフレームを unwind することになるが, ネイティブコードのスタックを (C++の例外機能等を用いて) unwind すると処理がコンパイラ依存になったり性能が予見できなくなる恐れがある. このため, 明示的な return で unwind 処理を行うことになっている.
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.