Coins Java - 例外処理の基本構造

例外処理の基本構造

[Coins Java - 例外処理]

gcjでの例外処理

gcjでの例外処理は、例外処理をあくまで例外と見て、正常処理をできるだけ高速に実行できるような構造になっている。

このような機構にするために、フレームの巻き戻しやレジスタの自動復帰に関する機構が備わっていた。

フレームの巻き戻し(unwinding)

フレームの巻き戻しとは、スタック上に詰まれた関数のフレームを巻き戻して、手前もしくはそれ以前のフレームに処理を戻すものである。フレームの巻き戻しは以下の図のように行われる。

上図では、以下のような作業を行っている。

  1. methodAからmethodBを呼び出す
  2. methodBからmethodCを呼び出す
  3. methodCでエラーを発生させる(_Jv_Throwを呼び出す)
  4. エラーをハンドリングして、例外処理を開始する
  5. フレームの巻き戻し(unwind)が行われ、methodAまで戻る
  6. methodA上のcatchでmethodCが発生させたエラーを拾う

このような機構はgccに元々組み込まれており、gcjではその機構を利用してJavaの例外処理をエミュレーションしていた。

gcjでは以下のような手順で例外をキャッチしている。

簡単に書いたが、巻き戻しを再開する条件や、キャッチする条件を各メソッド(及び関数)ごとに指定してやる必要がある。また、フレームに復帰した際に、フレームポインタやその他のレジスタも復帰する必要がある。これらを処理するために、gcc及びgcjでは専用のデータ構造をもたせてやる必要がある。

例外処理のデータ構造

例外処理を実装するデータ構造であるが、Javaのメソッドを先行してコンパイルした際に、その末尾にフレーム巻き戻しや例外をキャッチするための情報が付加される。

ただしこれらの情報は、いくつかのセクションに分かれて格納されているため、リンク時に別々の場所にまとめられる。

例外をキャッチするための情報は、大別して3種類ある

最初の2つ(CIE, FDE)はgcj特有の機能ではなく、gccのC++モードでも使用されている。最後の1つ(LSDA)が、Java特有の例外処理を実装しているもので、このように分割することによってC++とJavaの例外を混在させることも可能になる。

それぞれの詳しい情報に関しては、リンク先にある。

Copyright (C) 2002-2006 s.arakawa