(57)【要約】【課題】プログラム内の非同期移行をモデル化するために使用されるあらゆる可能なエッジよりも少ない数のエッジを含むフローグラフを使用してプログラムの中間表現を形成するコンパイラを提供すること。【解決手段】フローグラフは複数のフェーズで形成される。あるフェーズでは、フローグラフは非同期移行をモデル化せずに形成される。後のフェーズでは、非同期移行の影響の表現が選択的に追加される。後のフェーズの一部として、保護領域の外部で生存する変数についての保護領域内での定義の後に、可能な非同期移行をモデル化したエッジがフローグラフに追加される。変数の生存性の修正された定義を使用して、非同期移行の後の保護領域を含むあらゆる領域での変数の使用を組み込む。定義された変数がハンドラ内でのみ使用される場合は、保護領域からのエッジもまたモデルに追加される。【選択図】図８Ａ
2006196002.tif 000002
【特許請求の範囲】
【請求項１】
複数の領域と少なくとも１つのハンドラを有するプログラムを処理する方法であって、前記方法は第１の領域の外部での変数の生存性（ｌｉｖｅ−ｎｅｓｓ）を判定するステップを備え、前記ステップは、前記ハンドラの実行の後で、ある変数が前記第１の領域を含むいずれかの領域で使用されるときに前記変数を前記第１の領域の外部で生存と分類するステップを含むことを特徴とする方法。
【請求項２】
前記第１の領域は保護領域を含むことを特徴とする請求項１に記載の方法。
【請求項３】
前記第１の領域で定義された変数が前記第１の領域の外部で生存と分類されているかどうかを表すデータ構造を形成するステップを備えることを特徴とする請求項１に記載の方法。
【請求項４】
データ構造を形成するステップは、コンパイラによって形成されたシンボルテーブルに値を書き込むステップを含むことを特徴とする請求項３に記載の方法。
【請求項５】
前記第１の領域の中間表現を形成するステップをさらに備え、前記中間表現は、変数を定義する命令部分と命令間の可能なフローパスを指示するエッジを定義する命令部分とを含み、前記中間表現を形成するステップは、前記データ構造が前記第１の領域の外部で生存と指示している変数を定義する各命令の後にエッジを定義する命令を含めるステップを含むことを特徴とする請求項３に記載の方法。
【請求項６】
データ構造を形成するステップはビットベクトルを形成するステップを含むことを特徴とする請求項３に記載の方法。
【請求項７】
前記第１の領域はいくつかのｔｒｙ領域が組み込まれたｔｒｙ領域であり、第１の領域の外部での生存性を決定するステップは、前記ｔｒｙ領域の外部での生存性を決定するステップと、前記組み込まれたいくつかのｔｒｙ領域の外部での生存性を判定するステップとを含むことを特徴とする請求項１に記載の方法。
【請求項８】
前記プログラムは、プログラム実行を前記ハンドラに非同期に移行することができる第１の領域と、前記ハンドラが実行された後で実行することができる第２の領域を含み、前記方法は、
ａ）少なくとも前記第１の領域の表現を形成するステップであって、前記表現は第１の種類の構成を複数含み、前記第１の種類の構成の各々は１つまたは複数の動作を表し、前記表現はさらに少なくとも１つの第２の種類の構成を含み、前記少なくとも１つの第２の種類の構成は前記第１の種類の構成間の実行フローを表すステップと、
ｂ）前記変数の定義を含む前記第１の領域の少なくとも１つの第１の種類の構成に対して、前記変数が前記第１の領域の外部で生存と判定されたときに、前記第１の種類の構成からのフローを指示する第２の種類の構成を前記表現に選択的に追加するステップと
をさらに備えることを特徴とする請求項１に記載のプログラムを処理する方法。
【請求項９】
第２の種類の構成を前記表現に選択的に追加するステップは、
前記変数が前記ハンドラ領域では使用されるが前記第２の領域では使用されないときに、前記表現とともに、第２の種類の構成を追加することなしに前記変数が前記ハンドラ領域で使用されることを記録するステップを備えることを特徴とする請求項８に記載の方法。
【請求項１０】
前記第１の種類の構成はブロックであり、前記第２の種類の構成はエッジであることを特徴とする請求項８に記載の方法。
【請求項１１】
第２の種類の構成を前記表現に追加するステップは、
ａ）少なくとも１つのエッジの始点であるシンクブロックを前記表現に追加するステップであって、前記シンクブロックを始点とする前記エッジは、前記ハンドラ領域の実行時にプログラム実行を移行することができる各位置を指示するステップと、
ｂ）前記追加されるエッジに前記シンクブロックを指示させるステップと
を含むことを特徴とする請求項１０に記載の方法。
【請求項１２】
シンクブロックを前記表現に追加するステップは、前記ハンドラ領域内部で使用されるかまたは定義される各変数の指示を含むシンクブロックを追加するステップを含むことを特徴とする請求項１１に記載の方法。
【請求項１３】
第１の領域、第２の領域、および第３の領域の命令を有する種類のプログラムを処理するためのコンピュータ可読媒体であって、前記プログラムの実行は前記第１の領域から前記第３の領域に非同期に移行することができ、前記第２の領域の命令は前記第３の領域の命令の後に実行され、
前記コンピュータ可読媒体はコンピュータ実行可能命令を含み、前記コンピュータ実行可能命令は、
ａ）前記第１の領域および前記第２の領域を含む表現を形成するステップであって、前記表現は複数の命令および前記複数の命令の実行の順序を表す情報を含むステップと、
ｂ）変数の定義を含む前記第１の領域の少なくとも１つの命令に対して、前記命令が前記第２の領域で使用される変数を定義するときは、前記表現に選択的に指示を追加するステップと
を含むステップを実施することを特徴とするコンピュータ可読媒体。
【請求項１４】
表現を形成するステップは、コンピュータメモリ中にデータ構造を形成するステップを含むことを特徴とする請求項１３に記載のコンピュータ可読媒体。
【請求項１５】
表現を形成するステップは、フローグラフを形成するステップと、フローグラフにエッジを追加することを含む指示を前記表現に追加するステップとを含むことを特徴とする請求項１３に記載のコンピュータ可読媒体。
【請求項１６】
第１の領域、第２の領域、および第３の領域を有するプログラムを処理するためのツールであって、前記プログラムの実行は前記第２の領域から前記第３の領域に非同期に移行することができ、前記第２の領域は前記第１の領域からの前記プログラムの前記非同期移行の後に実行することができ、前記ツールは、
ａ）前記第１の領域および前記第２の領域を含む表現を形成するようになされたモジュールであって、前記表現は複数のブロックおよび複数のエッジを含むモジュールと、
ｂ）エッジを前記表現に選択的に追加するようになされたモジュールであって、変数の定義を含む前記第１の領域のブロックを処理するようになされ、前記変数が前記第２の領域で使用されるかどうかに基づいて、ブロックからのエッジを前記表現に選択的に追加するようになされたモジュールと
を含むことを特徴とするツール。
【請求項１７】
前記ツールはコンパイラであることを特徴とする請求項１６に記載のツール。
【請求項１８】
前記コンパイラは、機械独立のグローバル最適化フェーズと、表現を形成するようになされた前記モジュールと、前記機械独立のグローバル最適化フェーズの一部を形成するエッジを選択的に追加するようになされた前記モジュールとを含むことを特徴とする請求項１６に記載のツール。
【請求項１９】
前記ツールはＪＩＴであることを特徴とする請求項１６に記載のツール。
【請求項２０】
前記ソフトウェアツールはある領域の外部での変数の生存性を判定するモジュールを含むソフトウェアシステム中で動作するようになされ、選択的にエッジを追加するようになされた前記モジュールは生存性を判定する前記モジュールにアクセスして前記第１の領域のブロックで定義された変数が前記第１の領域の外部で生存するかどうかを判定し、前記変数が前記領域の外部で生存するときはエッジを追加するように構成されることを特徴とする請求項１６に記載のツール。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は一般に、コンピュータソフトウェアシステムに関し、より詳細には実行の前にコンピュータプログラムを処理するコンピュータソフトウェアシステムに関する。
【背景技術】
【０００２】
コンピュータプログラムは一連の命令として記述されることが多い。命令の中には、プログラムの実行時に実施される動作を指定できるものがある。また、命令の中には、他の命令が実行される順序または条件を指定することによってプログラムのフローを制御できるものもある。また、命令の中には、プログラム中の変数を表す情報がそのプログラムを実行するプロセッサに接続されたメモリにどのように格納されるかなど、プログラム実行のパラメータを指定できるものもある。
【０００３】
高級プログラミング言語では、各命令は、ソフトウェアが実行されるプラットフォームによって実行することができる命令に、必ずしも１対１の関係で対応している必要はない。むしろ、命令は人間が理解できる形のこともある。この形のプログラムは、最初に特定のプラットフォームで実行するのに適した形に処理しなければならない。異なるプロセッサまたは異なるオペレーティングシステムを有するプラットフォームでは、適切な実行のためにプログラムを異なる形で表現しなければならないことがある。
【０００４】
ソフトウェアツールは通常、プログラムを特定のプラットフォームによって実行できる形に変換するために使用される。ツールの例にはコンパイラがある。これらのツールは、単に各高水準命令をプロセッサが実行できる一連の命令として表現することに加えて、プログラムを最適化あるいは処理することができる。実行の準備をするときにプログラム上で実施できる処理の例には、不要コード除去、スケジューリング、コード移動、共通副次式の除去などがある。
【０００５】
プログラムを処理する際に、ソフトウェアツールはコードを中間表現に変換することも多い。中間表現は、プログラムの実行時に実施しなければならない動作についての都合の良い表現を提供する。中間表現はまた、各変数が使用されるプログラムの部分についての情報など、プログラム実行の間に情報を格納するために使用される変数に関する情報も提供する。中間表現はまた、各動作の間のプログラムフローについての情報も提供する。
【０００６】
中間表現では、プログラムのフローを「フローグラフ」として記述することも多い。フローグラフはブロックとエッジを含む。各ブロックは所定の順序で実行される命令の集りを表し、したがって各ブロックには１つの始点と１つの終点が存在する。フローグラフでは、エッジは各ブロックを相互接続して各ブロックが実行される順序を表す。フローグラフは、プログラムの実行時にたどることができる、各ブロックを通るあらゆる可能なパスを表すエッジを含む。各ブロックには複数のパスを接続することができる。
【０００７】
プログラムフローとメモリ要件についての情報を使用して多くの方法でプログラムを処理することができる。その情報を使用して、特定のプラットフォーム上での実行用にプログラムを実装する命令を作成すること、またはプラットフォームとは独立した方法で最適化を実施することができる。
【０００８】
図１Ａは、Ｃ＃高級プログラミング言語で書かれたプログラム１００を示す。プログラム１００は、命令１１２や１１４など一連の命令を含む。図１Ａの例では、命令１１２および１１４は変数Ｙの「定義」である。本明細書の使用では、「定義」という用語は一般に、ある変数に関する情報を生成、修正または変更することができる任意の命令を意味する。
【０００９】
プログラム１００はまた、ｔｒｙボディの開始を定義する命令１２０を含む。ブラケット１２１は、命令１２０で開始されたｔｒｙボディの終了を定義する。ｔｒｙボディはまた、「コードの保護領域」と呼ばれることもある。
【００１０】
ｔｒｙボディは、「プロテクタ領域」または「ハンドラ」と呼ばれることもある１つまたは複数のコードの保護領域とともに動作することができる。この例では２つのハンドラ、すなわち例外ハンドラと「ｆｉｎａｌｌｙ」ハンドラが示されている。例外ハンドラは、「ｃａｔｃｈハンドラ」と呼ばれることもある。例外ハンドラは命令１２２で始まりブラケット１２３で終了する。プログラム１００は、ｔｒｙボディに関連したｆｉｎａｌｌｙハンドラも含む。ｆｉｎａｌｌｙハンドラは命令１２４で始まりブラケット１２５で終了する。
【００１１】
プログラム１００はまた、ｔｒｙボディの外部に存在する命令１３０などの命令を含む。
【００１２】
ハンドラの動作は、プログラム１００の実行を示す図１Ｂに示されている。この例では、ｔｒｙボディ１４０はプログラム１００内の最初の実行可能命令を含む。通常の動作では、ｔｒｙボディ１４０が最初に実行され、ｔｒｙボディ１４０の各命令が、それらの命令によって指定された順序で実行される。
【００１３】
ｆｉｎａｌｌｙハンドラ１４４内の各命令は、ｔｒｙボディ１４０、例外ハンドラ１４２、およびｆｉｎａｌｌｙハンドラ１４４で構成されたｔｒｙ領域中の最後の命令として実行される。通常の実行では、ｔｒｙボディ１４０内の命令が完了したときに、実行はｆｉｎａｌｌｙハンドラ１４４に移動する。
【００１４】
ｆｉｎａｌｌｙハンドラ１４４内の命令が実行された後で、プログラム１００内のｔｒｙ領域１４０に続く命令が実行される。この例では、それらの命令は領域１５０に存在する。
【００１５】
例外ハンドラ１４２内の命令は、ｔｒｙボディ１４０内の命令を実行している間に例外が発生した場合だけ実行される。例外状況は、プログラム１００の特別な例外命令の実行によって生成することができる。しかし、ほとんどの場合例外状況は、プログラム１００を実行するプラットフォームにそのプラットフォームにとって不適切な動作と見なされる動作を実施するように命令するプログラム１００内の命令を実行することによって引き起こされる。不適切な動作の例には、ゼロによる除算、システムに実装されていないアドレスまたはオペレーティングシステムに予約されたアドレスのメモリにアクセスするようプラットフォームに指令する命令などがある。
【００１６】
例外ハンドラ１４２は非同期に実行されるものと見なすことができる。本明細書の使用では、「非同期」という用語は、結果として制御の移行をもたらすことを意図したプログラムの命令以外の、他のプログラムの実行中の状況に応答して生ずる例外などのイベントを表す。最後に、ハンドラ１４４もまた非同期に実行されるものと見なされる。なぜならば、例外ハンドラ１４２の後に実行させることができるからである。
【００１７】
図１Ｃは、ｔｒｙボディ１４０から例外ハンドラ１４２への可能なパスをより詳細に示すフローグラフ１６０によって、非同期イベントから生じ得る問題を例示したものである。ｔｒｙ領域１４０の各命令はブロック１６２、１６４、１６６、１６８、１７０、または１７２で示される。エッジ１７８などのエッジは、ブロック間の通常のフローを示す。エッジ１８０Ａ、１８０Ｂ、１８２、１８４、１８６、１８８、１９０および１９２は非同期エッジを表す。非同期エッジは、ｔｒｙボディ１４０の任意の命令の実行によりプログラムフローが例外ハンドラ１４２に分岐する可能性を示す。エッジ１８０Ａは、ｔｒｙボディ１４０の任意の命令の実行の前にエラーが起こる可能性を示す。エッジ１８０Ｂは、例外ハンドラ１４２実行の終了時に起こる制御の移行を示す。
【００１８】
従来技術のソフトウェアツールのいくつかは、図１Ｃに示したように、ハンドラ領域１４２にフローを移行させることができる全ての可能な命令からエッジを追加することによって、ｔｒｙ領域など、非同期の制御の移行が可能なプログラムの中間表現を形成してきた。ｔｒｙ領域の各命令からエッジを追加することを使用して、不完全な表現のプログラムを処理することから生じ得るエラーを回避してきた。
【発明の開示】
【発明が解決しようとする課題】
【００１９】
しかし、図１Ｃに示された「あらゆる可能なエッジ」のアプローチを用いて非同期エッジを追加することの欠点は、結果としてフローグラフが複雑になることである。プログラム１００は比較的単純なプログラムを示す。商業的に意味のあるプログラムは例示のものよりはるかに多くの命令を含むことがある。さらに、プログラムは各領域に関連した複数のハンドラを有する複数のｔｒｙ領域を含むことができる。さらに、ｔｒｙ領域を他のｔｒｙ領域の内部に組み込むこともできる。さらに複雑なことには、フローはハンドラの実行の後にｔｒｙボディの終了部に戻る必要はない。ハンドラは実行時の状況によって決まる特定の位置を用いて、プログラムフローをプログラム内の任意の位置またはプログラム内の複数の位置のうちの任意の１つに分岐させることができる。結果として、フローグラフにあらゆる可能な非同期エッジを追加することでフローグラフは非常に複雑なものになる。したがって、このようなフローグラフに基づいてプログラムを処理することは、大量の時間またはコンピュータリソースを消費することになる。
【００２０】
従来技術のソフトウェアツールのいくつかでは、あらゆる可能な非同期エッジを追加することから生じる複雑さを、非同期エッジを含まないフローグラフを生成することによって回避している。しかし、その代償として、このようなフローグラフに基づいてプログラムを処理するツールは、全ての可能なフローパスについての正確な表現を利用するｔｒｙ領域中の各命令に関する動作を実施しない。このような方法でプログラムを処理することによって、より高速でより単純にはなり得るが、ソフトウェアツールの利点を実現することはできない。
【００２１】
非同期の制御移行を含むプログラムを、ソフトウェアツールによってプログラムの処理を容易にするような形で表現する方法があれば望ましいであろう。
【課題を解決するための手段】
【００２２】
本特許出願は、ｔｒｙボディ領域からハンドラへの移行で生ずるような非同期フローを含むプログラムをモデル化するために使用されるプログラムの中間表現について記載する。プログラム内の非同期移行の影響についての簡略化された表現を用いることで、結果の正確さを維持しながらプログラム処理の複雑さを低減することができる。この中間表現は、多くの方法で使用することができる。
【００２３】
一態様においては、本発明は、その領域からプログラムの実行を非同期に移行することができる第１の領域と、第１の領域からのプログラムの非同期移行の後で実行することができる第２の領域とを有するプログラムを処理する方法に関する。この方法は少なくとも第１の領域の表現を形成するステップを含む。また、この表現は第１の種類の構成を複数含む。第１の種類の構成の各々は、１つまたは複数の動作を表す。この表現は少なくとも１つの第２の種類の構成を含む。第２の種類の各構成は、第１の種類の各構成の間の実行フローを表す。変数の定義を含む第１の領域の少なくとも１つの第１の種類の構成に対して、第１の種類の構成からのフローを指示する第２の種類の構成が、その変数が第２の領域で使用されるかどうかに基づいて選択的にその表現に追加される。
【００２４】
他の態様においては、本発明はプログラムを処理するためのコンピュータ可読媒体に関する。プログラムは、第１の領域、第２の領域、および第３の領域の命令を含む。プログラム実行は第１の領域から第３の領域に非同期に移行することができ、第２の領域の命令は第３の領域の命令の後で実行される。コンピュータ可読媒体は、第１の領域と第２の領域を含む表現を形成するためのコンピュータ実行可能な命令を含む。この表現は複数の命令およびその複数の命令の実行の順序を表す情報を含む。このコンピュータ実行可能な命令はまた、変数の定義を含む第１の領域の少なくとも１つの命令に対して、その命令が第２の領域で使用される変数を定義するときには、その表現に選択的に指示を追加する。
【００２５】
他の態様においては、本発明は、第１の領域、第２の領域、および第３の領域を有するプログラムを処理するためのツールに関する。プログラム実行は第２の領域から第３の領域に非同期に移行することができ、第２の領域は第１の領域からのプログラムの非同期移行の後で実行することができる。このツールは、第１の領域と第２の領域を含む表現を形成するように構成されたモジュールを含む。この表現は複数のブロックと複数のエッジを含む。このツールはまた、表現にエッジを選択的に追加するようになされたモジュールも含む。このモジュールは、変数の定義を含む第１の領域のブロックを処理し、第２の領域でその変数が使用されるかどうかに基づいて、ブロックからのエッジを選択的に表現に追加するように構成される。
【００２６】
添付の図面は原寸に比例して描かれることを意図したものではない。図面中、様々な図面に示された同一またはほぼ同一の各コンポーネントは、同一の番号によって示されている。図面を見やすくするために、各図面において、必ずしも全てのコンポーネントに番号が付与されているとは限らない。
【発明を実施するための最良の形態】
【００２７】
本発明者らは、非同期移行の影響の指示を含むソフトウェアの中間表現を生成することによって従来技術の制限を克服した。この中間表現は、あらゆる可能な非同期エッジより少ない数のエッジを含むことができ、それによって、プログラムの中間表現およびそれに基づくあらゆる処理を単純化するとともに、中間表現を使用してプログラムを処理するツールの正確な動作を保証する。非同期移行の影響を１つまたは複数の方法で指示することができる。いくつかの実施形態では、非同期移行の影響の指示は、非同期移行を直接示すエッジの形をとる。他の実施形態では、非同期移行の影響はプログラム中で使用される変数に関連して格納された情報によって指示される。情報をシンボルテーブルまたは中間表現における擬似命令の形で格納することができる。同一の中間表現の中で、複数の形式を利用して非同期移行の影響を指示することもできる。
【００２８】
本発明を最初に、一例として、フローグラフを含む中間表現を使用して説明する。選択された非同期移行の影響はフローグラフ中のエッジとして表現される。他の非同期移行の影響は、中間表現に関係するシンボルテーブル中のアノテーションを用いて示される。このような表現は、既存のソフトウェアツールと互換であるという利点があるが、任意の適切な表現を使用することもできる。
【００２９】
中間表現は、従来の方法におけるプログラムの同期動作を表すこともできる。一実施形態では、プログラムの全ての部分は、現在知られているまたは今後開発される従来型の技術を使用するフローグラフとしてモデル化される。最初は、ハンドラへの非同期フローはフローグラフ中にモデル化されない。次いで、中間表現を追加または修正して非同期移行の影響を表すことができる。
【００３０】
図２は、図１Ｃに示されたと同一のプログラムのフローグラフ２６０をグラフィカルに示したものである。フローグラフ２６０は非同期エッジ１８０Ａ、１８０Ｂ、１８６、および１９０を含む。この表現には、全ての可能な非同期エッジが含まれている訳ではない。非同期エッジ１８６および１９０をフローグラフに含めたのは、それらを含めることで、従来のソフトウェアツールが不正なあるいは意図しない結果を生じることなく、このフローグラフを使用して動作できるようになるからである。図１Ｃの「全ての可能なエッジ」のフローグラフに示された、エッジ１８２、１８４、１８８、および１９２は含まれていない。なぜならば、それらが、フローグラフ２６０を用いて従来のソフトウェアツールを意図したとおりに動作させるために必要ないからである。
【００３１】
エッジ１８６と１９０をフローグラフ２６０に含めるように選択したのは、それらが、ｔｒｙ領域に含まれるブロックのうちのｔｒｙ領域の外側で使用される変数を定義するブロックの後にくるものだからである。この例では、変数Ｙが領域１５０で使用され、非同期エッジがＹを定義する各ブロックの後に追加されている。
【００３２】
逆に、ブロック１６２、１６４、１６８、および１７２の後には非同期エッジは含まれていない。これらのブロックはＡ、Ｂ、Ｘ、およびＺの変数の定義を含むが、これらの変数はどれもｔｒｙボディ１４０の外部では使用されていない。プログラム１００の実行の間に生じるある種の状況下では、それらの命令を領域１５０の命令の実行の前に実行することができる。他の状況下では、非同期移行のために、これらの命令は実行されないことがある。それにもかかわらず、非同期イベントによってプログラムフローがｔｒｙボディ１４０の外部に指示されたとしても、それらが定義する変数はどの命令によっても使用されることがないので、フローグラフがそれらの命令の後で非同期移行の可能性を示していない場合でもエラーが生じることはない。したがって、非同期エッジ１８２、１８４、１８８はフローグラフ２６０には含まれていない。
【００３３】
領域の外部でどの変数が使用されるかを識別することは、ソフトウェアツールで従来から実施されていた機能である。領域の外部で使用される変数は、その領域の「外部生存（ｌｉｖｅ−ｏｕｔ）」であると呼ばれることもある。変数が領域の外部で使用されるかどうかを判定するアルゴリズムは「生存性（ｌｉｖｅ−ｎｅｓｓ）」アルゴリズムと呼ばれている。変数がｔｒｙ領域の外部生存であるかどうかを判定するために、現在知られているまたは今後開発される任意のプロセスを使用することができる。
【００３４】
さらに、変数の生存性を任意の都合の良い方法で表すことができる。例えば、その領域の変数が有することもあり、有しないこともある特性を各々が記述する１つまたは複数のビットベクトルを使用して各ｔｒｙ領域のためのシンボルテーブルを構築することができる。その様なビットベクトルのあるものは、変数が外部生存かどうかの指示を格納することができる。ビットベクトルを使用することで処理時間を削減することができる。例えば、各変数にはビットベクトル中の特定のビット位置へハッシュできる整数値を割り当てることができる。変数ごとに生存性の計算が実施されるので、変数が外部生存かどうかに基づいて対応するビットをセットまたはクリアすることができる。変数を定義する命令ごとにシンボルテーブル中のビットベクトルへの単純なアクセスを実施することで、その定義の後に非同期エッジを追加すべきかどうかが指示される。
【００３５】
中間表現にエッジを追加する前述のアプローチは、シナリオによっては、全ての非同期移行の影響を十分には表現していない。図３は、非同期移行の追加の表現が所望され得るシナリオを示す。
【００３６】
図３はフローグラフ３６０を示す。フローグラフ３６０に示されたプログラムは、ｔｒｙボディ３４０、例外ハンドラ３４２、ｆｉｎａｌｌｙハンドラ３４４、および領域３５０によって示されるｔｒｙ領域外部の他のコードを含む。図３に示されたプログラムは、部分３４０Ａとブロック３４０Ｂを含み、例外ハンドラ３４２の実行の後で、実行がｔｒｙボディ３４０の内部のポイントに戻る点がプログラム１００（図１）と異なる。具体的には、実行はブロック３４０Ｂに戻る。
【００３７】
この例では、ブロック３４０Ｂは、例外ハンドラ３４２の実行の後のエントリポイント以外にはエントリポイントを持たないコードを含む。ブロック３４０Ｂ内部のコードはまた変数Ｘを使用する。この変数Ｘは、従来の生存性を用いたのでは、ｔｒｙ領域３４０の外部生存とは見なされないはずである。したがって、単にｔｒｙ領域の外部での変数の生存性に基づいてエッジを追加することによっては、フローグラフに含まれるＸの定義の後にエッジは生じないことになる。しかし、フローグラフにエッジが含まれないことにより、中間表現に基づくプログラムの不正な処理に通じる可能性がある。例えば、この表現は、命令１６８のＸの定義を「使用する（ｃｏｎｓｕｍｅ）」命令が存在しないことを示唆することができ、それによって命令１６８をコードから外して「最適化」することが可能になる。中間表現の使用による不正な動作を回避するために、非同期移行の後だけに実行されるｔｒｙ領域の部分を形成するブロックで変数が使用される場合には、ｔｒｙ領域の外部生存でない場合でもその変数の定義の後に非同期エッジを追加する。この例では、フローグラフ３６０は、この目的のためにエッジ３８０を含む。
【００３８】
プログラムを処理して中間表現を形成する際に、非同期移行の後にだけ実行されるｔｒｙボディ内のブロックで使用される変数の定義の後にエッジを追加することに関しては、いくつかの実施形態が可能である。一実施形態では、分離処理ステップを使用して、外部生存である変数の定義の後、およびハンドラ内で使用される変数の定義の後に非同期エッジを追加することができる。
【００３９】
別法として、外部生存の定義を、非同期移行の後だけに実行されるｔｒｙボディのブロック内で使用される変数を含むように修正することができる。修正された外部生存の定義を使用することにより、シンボルテーブルで使用されるビットベクトルが外部生存の変数を表し、非同期エッジを追加しなければならない変数の全リストを含むことが可能になる。上述のように、このビットベクトルが決定された後で、中間表現によって１つのパスを形成し、外部生存ビットベクトルに示された変数の各定義の後にエッジを追加することができる。
【００４０】
いくつかの実施形態では、外部生存ビットベクトルを２つ以上のパスで形成することができる。第１のパスでは、ｔｒｙボディに関して従来の外部生存の計算を実施することができる。第２のパスでは、非同期移行の後で実行されるｔｒｙボディのブロックで使用される変数を外部生存ビットベクトルに組み入れることができる。別法として、ｔｒｙ領域の外部で使用される変数、および非同期移行の後だけに実行されるｔｒｙ領域内のブロックで使用される変数を指示するビットベクトルが１つのパスで形成されるような、外部生存変数を識別するための修正されたアルゴリズムを使用することができる。修正された外部生存の定義を用いたビットベクトルを構成するために使用できるプログラムについては以下で説明する。
【００４１】
図３はまた、ｔｒｙ領域の外部生存である変数に対して単に非同期エッジを追加しただけでは、所望の結果が得られないことがある他の起こり得るシナリオも示す。この例では、Ｙの値は外部生存ではないが、例外ハンドラ３４２で使用されている。上述のように形成された中間表現では、ｔｒｙボディ３４０内のＹの定義の後に、Ｙを使用するハンドラ３４２内の命令を実行できることを指示するフローパスを生成するエッジが含まれないことになる。その結果、中間表現に基づいて動作するツールでは、実行時に例外ハンドラ３４２内のコードからアクセスすることができない変数Ｙのメモリ構造が構築される可能性がある。
【００４２】
例えば、変数Ｙを、レジスタまたは実行時に動的に決定されるスタック内のメモリ位置に格納することができる。レジスタに格納された値は、例外ハンドラの実行時に変更されることがあり、それによりＹの値の変化による好ましくない影響を受ける可能性がある。同様に、スタック上の情報にアクセスするために使用されるスタックポインタや他の構成は、プログラム実行がｔｒｙボディ領域から例外ハンドラに移行したときに変化する可能性がある。逆に、ｔｒｙボディ領域の外部で使用される変数は一般に、プログラムフローがｔｒｙボディ領域３４０を離れた後もそれらの変数にアクセスできるような方法で格納されている。
【００４３】
必ずしも全ての可能な非同期エッジを含まない中間表現では、変数Ｙの定義と例外ハンドラ３４２でのその変数の使用との間のフローパスが指示されないことがある。指示されていない場合には、中間表現に関して動作する従来のツールは、ｔｒｙボディで使用されるＹの値に例外ハンドラ３４２内のコードからアクセスできなくするような方法で変数Ｙに対する記憶領域を割り振る可能性がある。
【００４４】
意図しない結果を、変数Ｙの各定義の後にエッジを含めることのよって回避することができるが、このことにより、非同期移行によってフローがｔｒｙボディを離れた後でもその変数を使用できることが、中間表現を処理する任意のツールに明らかになる。より一般的には、非同期エッジを、フローグラフへ、関連するハンドラ内で使用される変数のｔｒｙボディ内での各定義の後に追加することができる。
【００４５】
フローグラフにエッジを追加することの別法として、変数がハンドラ内で使用されるときの非同期移行の影響を、変数Ｙを例外ハンドラ３４２内のコードからアクセス可能にするような形でメモリ中に格納する必要があるという中間表現内での指示によって表すこともできる。一実施形態では、この結果を、プログラムの従来の中間表現で使用できる構成を使用することによって実現することができる。
【００４６】
具体例として、ｔｒｙ領域３４０のために構成されたシンボルテーブル中にアノテーションを付与することができる。シンボルテーブルでは、変数Ｙがハンドラ内で使用されることを指示するようにアノテーションを付与することができる。変数の記憶領域を割り振るために中間表現を使用するツールは、その指示を認識し、例外ハンドラに通じる任意のパスに沿ってその変数がスタックに「格納される」よう要求するように構成することができる。スタックに格納される変数は、その変数が生成されたスタックに関して特定の位置を有することになる。変数をスタックに格納することにより、その変数にアクセスする例外ハンドラ３４２のためのコードを生成することができる。
【００４７】
ｔｒｙボディ内で定義され外部生存していないが、そのｔｒｙボディに付随したハンドラ内で使用される各変数に対して類似のアノテーションを作成することができる。この文脈での「使用する（ｕｓｅ）」という用語は、その変数が、変数が定義されるまたは使用されるのどちらをも意味することができることを表す。
【００４８】
シンボルテーブル中のアノテーションを任意の適切な形で作成することができる。シンボルテーブルがビットベクトルなどのデータ構造を含み、変数をスタックに格納しなければならないことを指示する他の目的のために使用される場合は、どの変数をスタックに格納すべきかを指示するためにデータ構造に値を書き込むこともできる。
【００４９】
この様なデータ構造が他の目的のために使用されない場合は、シンボルテーブルを、ハンドラ内でどの変数が使用されるかを指示するビットベクトルまたは他のデータ構造を用いて構成することができる。中間表現から機械実行可能なコードを生成するコンパイラまたは他のツールは、この様な変数ごとに、変数をスタックに格納するコードまたは変数に記憶領域を割り振るコードを生成して、その変数を使用するｔｒｙ領域に関係するハンドラ内でその変数にアクセスできるようにする。
【００５０】
図４は、プログラムの中間表現を形成する処理の一実施形態で使用されるフローグラフをさらに詳細に示したものである。図４は、ｔｒｙ領域、例外ハンドラ１４２、およびｆｉｎａｌｌｙハンドラ１４４を含むフローグラフ４６０を示す。フローグラフは上述の処理に従って構成される。
【００５１】
このフローグラフは、最初に同期フローだけを表すフローグラフを形成することによって生成される。エッジは非同期移行を表すために選択的に追加される。エッジ４８２はｔｒｙボディの内容を包含するように追加される。エッジ４８２はｔｒｙボディ中の稀で、到達不可能なブロックの阻止を簡素化するために含められている。エッジ４８４はｔｒｙボディの終了を包含している。エッジ４８４はｔｒｙボディに到達するもの全てのために完全なフローを保証する。記載の実施形態では、これらのエッジを、各変数がどこで定義または使用されるかにかかわらず、ハンドラを含むあらゆるｔｒｙボディの中間表現に含められる。
【００５２】
エッジ４８６1および４８６2は外部生存変数の定義の後に追加されたエッジを表す。エッジ４８８1、４８８2、および４８８3は、ハンドラ１４２の実行の後で起こり得るリターンパスを表す。エッジ４８８4はｆｉｎａｌｌｙハンドラ１４４からの戻りを表す。これらのフローパスの表現は、ほとんどのソフトウェアツールにとって中間表現を正確に処理するために望ましいものである。
【００５３】
しかし、簡略化は「シンクブロック（ｓｉｎｋ  ｂｌｏｃｋ）」を生成してハンドラとの間のフローをモデル化することによって、中間表現の中で実施することができる。シンクブロックは、ｔｒｙ領域からの非同期移行の影響を表すためにフローグラフに追加された全てのエッジの到達先にすることができる。ハンドラの実行の後で実行が移動する可能性がある各可能な場所へのエッジは、シンクブロックから発生させることができる。
【００５４】
図４の例では、領域４１０はｔｒｙ領域１４０のための全てのハンドラを含む。領域４１０をシンクブロックとして表すことができる。領域４１０内の任意の場所で終了するエッジを、シンクブロックで終了するように示すことができる。例えば、エッジ４８４、４８６1、および４８６2をシンクブロックで終了するものとして描くことができる。領域４１０の任意の点から発生するエッジはシンクブロックから発生するように描くことができる。例えば、エッジ４８８1、４８８2，４８８3、および４８８4をシンクブロックから発生するように描くことができる。
【００５５】
シンクブロックで終了しない、またはそこから発生する非同期エッジを、そのように示されたエッジによって表すことができる。例えば、エッジ４８２を除去し、シンクブロックに入ってくるエッジとシンクブロックで発生し領域１５０で終了するエッジとで置き換えることができる。しかし、エッジ４８４は、エッジ４８２と同じポイントで始まる。エッジ４８４はすでに、エッジ４８２を置き換えることになるシンクブロックへのエッジを表している。同様に、エッジ４８８4はすでに、シンクブロックとエッジ４８２の端点との間に存在する。同じ２点間に複数のエッジを含む必要はない。したがって図４の例では、シンクブロックを使用した場合は、エッジ４８２に沿ったフローを表すために追加のエッジを加える必要はない。
【００５６】
図２、３、および４において、フローグラフのブロックはシンボルによって表され、エッジはシンボル間を連結する矢印付きの線によって表される。このようなグラフィカル表現は、人間にとってのフローグラフの概念化を支援する。ソフトウェアツールでは、フローグラフのグラフィカル表現を生成する必要はない。フローグラフ中の各ブロックを、コンピュータプログラム中の命令と同様にファイル中の一連のテキストとして表すことができる。ブロックをラベルによって識別することができ、エッジをラベルへの分岐を指示する一連のテキストによって表すことができる。しかし、フローグラフを表すために選択される具体的な形態は本発明にとっては重要ではなく、任意の適切な表現を使用することができる。
【００５７】
図５は、フローグラフをコンピュータファイの形のテキストとして実装したものを示す。ファイルの各行は中間命令を含む。中間命令は、高水準プログラムで使用される命令、または中間表現から生成される機械語プログラム中の命令のどちらかに１対１に対応している必要はない。各命令は、中間表現が高水準プログラムから容易に生成でき、また機械レベルの命令がその中間表現から生成できる形であることが好ましい。このような中間命令セットについては既知であり、現在知られているまたは今後開発される任意の適切な中間命令セットを使用することができる。
【００５８】
図５の実施形態では、エッジはプログラムの制御を移行する命令によって表される。例えば、命令５１２は「ＧＯＴＯ」フレーズを含んでおり、この命令は命令中で識別されたラベルへの制御の移行を指示する。この例では、ラベルはＬ４２として示されている。ラベルＬ４２は、ｔｒｙボディ中の命令の実行が完了したときに実行されるｆｉｎａｌｌｙハンドラおよび続く領域１５０（図２）中の命令に先行するものである。
【００５９】
フローグラフ内の各ブロックは、図５では、制御を移行する命令または領域の終了を指示する命令によって中断されない連続した命令によって表されている。
【００６０】
全ての命令が機械レベルの命令に変換される訳ではない。擬似命令と呼ばれるいくつかの命令は、他の命令がどのように処理されるかを指示するために使用される。例えば、命令５１４はｔｒｙ領域の先頭を識別する。命令５１６は、ｔｒｙボディ領域の終了を識別する。命令５１８はｔｒｙ領域の終了を識別する。
【００６１】
擬似命令はまた、非同期移行の影響を表すためにも使用される。命令５２０、５２２、および５２４は、コードＯＰＯＮＥＲＲＯＲとラベルを含む擬似命令である。これらの擬似命令はＧＯＴＯ命令５１２と類似しているが、コードＯＰＯＮＥＲＲＯＲは、ラベルへの条件付きの非同期移行を示すものである。命令５２０および５２２は、図４に示されたエッジ４８２および４８４によって示された影響と同様の影響を示す。エッジ５２４は、図４のエッジ４８８3によって示された影響と同様の影響を示す。ラベルＬ１、Ｌ２、およびＬ３は、命令５２０、５２２、５２４の行先を示すために中間表現に追加されている。
【００６２】
命令５３０および５３２はまた、非同期移行の影響を表すためにも使用される。これらの命令は、ＯＰＯＮＥＲＲＯＲコードとそれに続くラベルを含む。命令５３０および５３２は、図４に示されたエッジ４８６1および４８６2によって示された影響と同様の影響を示す。
【００６３】
上述のように、中間表現は、どの変数が領域の外部生存であるかまたはどの変数をスタックに格納すべきかなど、プログラムに関する他の情報を提供するためにシンボルテーブルまたは他のデータ構造を含むことができる。しかし、この目的のために擬似命令を使用することもできる。
【００６４】
命令５４０は擬似命令である。図３に関して上述したように、中間表現は、変数がｔｒｙボディの外部で他の方法で使用されていないときは、変数がｔｒｙボディに関連するハンドラで使用されるかどうかを指示する。命令５４０はコードＯＰＳＩＤＥＥＦＦＥＣＴおよび変数名を含む。この命令は、命令に含まれた変数がハンドラ内部で使用されることを指示するために使用される。本明細書での使用では、ＯＰＳＩＤＥＥＦＦＥＣＴ Ｙの形の擬似命令は、その変数がハンドラ内で使用されることを指示する。Ｙ＝ＯＰＳＩＤＥＥＦＦＥＣＴの形の擬似命令は、変数がハンドラ内で定義されることを示す。例えば、このような命令を、この表現から形成される機械コードプログラムを実行しているプロセッサにおいて、変数に関連する情報の記憶に影響を与えるために使用することができる。さらに、この様な命令を、中間表現上でツールが動作する方法に影響を与えるために使用することもできる。例えば、ツールによっては「ガーベッジコレクション」を実施する。すなわち、プログラム処理の間中、ツールはもはや必要とされない変数の記憶用に割り振られたメモリ位置を識別する。次に、このメモリは、他の情報の記憶用に使用可能だと指示される。同様に、ツールによっては「不要コード」除去を実施する。これらのツールは、中間表現を処理して、今後使用されることがない変数を定義するコードを識別し、それを除去する。従来のガーベッジコレクションまたは不要コード除去が中間表現に基づいて実施される場合は、擬似命令を使用することによって、必要なコードが除去されること、あるいは変数用に必要な記憶位置が上書きされることを防止する。
【００６５】
変数の使用をこのような方法で表現することで、機械依存のグローバル最適化を中間表現上で実施することも可能になる。例えば、プラットフォームによっては、例外を様々に処理することができる。いくつかのプラットフォーム上では、ハンドラを個別の関数として実行することができる。例外が発生したとき、プロセッサはプロセッサ中のレジスタの内容を予測不能に上書きする可能性がある。したがって、この様なプラットフォームのためにコードを生成するツールは、このような擬似命令に応答して、例外ハンドラの一部であり、例外ハンドラにｔｒｙボディ中で定義された変数の値をレジスタに再ロードさせる命令を生成することができる。擬似命令は、例外ハンドラが適切に実行されるように、このコードを書く必要があることを指示する。
【００６６】
中間表現５１０によって示された実施形態においては、例外ハンドラは命令５５０によって示され、ｆｉｎａｌｌｙハンドラは命令５５２によって示される。例外ハンドラおよびｆｉｎａｌｌｙハンドラは、ハンドラがアクティブであるメソッドのＥＸＩＴ命令５６０の後に追加される。ハンドラは独立の関数として処理することができる。他の実施形態では、ハンドラ内の特定コードを、他の処理では単に無視することもできる。
【００６７】
図６Ａは、中間表現６１０の代替実施形態を示す。中間表現６１０は中間表現５１０（図５）と同一のプログラムを表す。中間表現６１０は、シンクブロック６４０を含むように形成されている。シンクブロック４１０（図４）と同様に、シンクブロック６４０は非同期移行を示すように追加されたエッジの終点になっている。シンクブロック６４０の開始は、ここではラベルＬ２によって示されている。
【００６８】
命令６２０は、ラベルＬ２でシンクブロックの開始を指示するＯＰＯＮＥＲＲＯＲ擬似命令である。命令６２０は、命令５２０と５２２（図５）の両方の影響をモデル化する。同様に、命令６３０および６３２は、ラベルＬ２を指示するＯＰＯＮＥＲＲＯＲ擬似命令である。命令６３０および６３２は、それぞれ命令５３０および５３２（図５）の影響をモデル化する。
【００６９】
シンクブロック６４０は、シンクブロックから各可能な非同期移行からの戻りへのエッジを表す命令を含む。例えば、図５では、命令５２０で始まった非同期移行は、ラベルＬ１に戻る。命令５２２、５３０、または５３２で始まった非同期移行はラベルＬ２に戻り、そこからフローがラベルＬ３を通過して通常処理を再開する。したがって、シンクブロック６４０は、ラベルＬ３に戻るエッジを表す命令６４４を含む。
【００７０】
シンクブロック６４０はまた、ハンドラ内の変数であって、そのハンドラに関連するｔｒｙボディの外部では使用されていない変数の使用を指示する擬似命令を含むこともできる。擬似命令６４６は、変数Ｙがハンドラ内で使用されることを指示する。この例では、変数ＹはラベルＬ３に戻るハンドラとともに使用される。したがって、命令６４６は、ラベルＬ３を指示する命令６４４に先行する。このようにして、ハンドラ内部の変数の使用は、ハンドラの実行の間にそのハンドラを通るパスに対応するフローグラフ中のパスに沿って指示される。
【００７１】
図６Ｂは、図６Ａに示した関数に対するフローグラフのグラフィカル表示である。関数は、ここではハンドラなしで示されている。記載の実施形態では、このプログラムの保護領域はプロテクタ領域とは別にモデル化される。プロテクタ領域は、類似のフローグラフでモデル化することができる。
【００７２】
フローグラフ６６０は、ｔｒｙボディ領域の諸ブロックを表す複数のブロック６６２、６６４、６６８、６７０、および６７２を含む。ブロック６７４はシンクブロック６４０（図６Ａ）を表す。ブロック６７６は、ｆｉｎａｌｌｙハンドラの一部として実行される命令を含む。ブロック６７８はｔｒｙボディ領域の外部にある命令を表す。
【００７３】
各ブロックはエッジによって結合される。エッジ６８２、６８４、６８６、および６８８はｔｒｙボディの各ブロックを結合する。エッジ６９０はｔｒｙボディからｔｒｙボディに続くコードへのフローを表す。エッジ６９２および６９４はハンドラからの戻りに関するフローを表す。エッジ６８１、６８３、および６８５はハンドラへの非同期フローを表す。
【００７４】
命令は図示のように、各ブロックが単一の入力ポイントおよび単一の出力ポイントを有するようにブロックに分割される。したがってコードは、各ブロックが分岐命令で終わるようなブロックに分割される。同様に、新しいブロックは、複数の位置から入力される可能性がある任意のラベルで始めることができる。
【００７５】
次に、図７を参照すると、プログラムの処理に関する流れ図７００が示されている。処理は処理ブロック７１０で始まる。処理ブロック７１０でプログラムの中間表現が形成される。ただし、ハンドラは別に処理される。この表現は、ｔｒｙ領域と対応するハンドラ間のフローパスをモデル化していない。中間表現の活用の仕方に応じて、ハンドラを完全に省略することもできる。ハンドラとの間のフローおよびハンドラ内部の変数の使用を表現することが適切なこともある。あるいは、ハンドラは分離した関数として表すこと、または他の任意の適切な方法で表すことができる。ブロック７１０で生成される中間表現は、ハンドラとの間の全ての可能なエッジの表現を含む必要はない。
【００７６】
ブロック７１０で形成される中間表現は、任意の適切な形をとることができる。例えば、図３および４に関連して示されているようなグラフィカル表現を含むこともできる。他の代替方法として、中間表現は、図５および６Ａに関連して示されているようなテキストベースの命令と擬似命令からなる命令を使用することもできる。
【００７７】
中間表現は、処理されるプログラムの全てまたは一部を含むことができる。本明細書で示される例では、例示のために１つのｔｒｙ領域を有する単純なプログラムが使用される。処理されるプログラムは複数のｔｒｙ領域を含むことができ、それら全てを、例示したｔｒｙ領域と同様の方法で処理することができる。
【００７８】
処理ブロック７１２でシンクブロックが追加される。例示の実施形態では、ｔｒｙ領域ごとに１つのシンクブロックが追加される。しかし、シンクブロックとｔｒｙ領域の間に、必ずしも１対１の対応が存在する必要はない。例えば、シンクブロックなしで示されるｔｒｙ領域もある。また、複数のシンクブロックとともに示されるｔｒｙ領域もある。
【００７９】
処理ブロック７１４で、ｔｒｙボディ領域の外部生存である変数の各定義の後にエッジを追加する。各エッジは命令の後で始まり、関連するハンドラのシンクブロックで終わる。例示の実施形態では、ｔｒｙ領域の「外部生存」である変数が、修正された生存性アルゴリズムを使用して識別される。修正された生存性アルゴリズムは、ｔｒｙボディからの非同期移行の後にだけ実行されるｔｒｙ領域の一部で使用される変数を外部生存変数に分類する。このようなアルゴリズムの例は、以下で図８Ａおよび８Ｂに関連して説明する。
【００８０】
処理ブロック７１６で、ハンドラは、非同期移行の後で実行が戻ることができる全てのポイントを識別するよう処理される。エッジは、シンクブロックからそれらの各位置に向けて追加される。
【００８１】
処理ブロック７１８で、各ｔｒｙボディを包含するエッジが中間表現に追加される。ｔｒｙボディを包含するエッジの例には命令６２０（図６Ａ）がある。
【００８２】
処理ブロック７２０で、ｔｒｙボディの外部では使用されないがハンドラで使用される変数を表すための中間表現が追加される。中間表現への追加は、図６Ａに示された命令、例えばＯＰＳＩＤＥＥＦＦＥＣＴコードを使用した擬似命令など、任意の適切な形をとることができる。別法としてまたは追加として、中間表現に関連するシンボルテーブル中にアノテーションを作成することができる。または、その情報を任意の適切な形で表すこともできる。
【００８３】
処理ブロック７２２で、結果として得られた中間表現を用いてプログラムが処理される。一実施形態では、中間表現はコンパイラで使用される。コンパイラは、グローバルな最適化およびコード生成のために中間表現を使用する。中間表現は不要コード除去、スケジューリング、コード移動、ガ−ベッジコレクション、および共通式の削除などの処理に使用することができる。コンパイラは、プロセッサベースのシステムにロードして実行できる機械語コードを生成することができる。しかし、実行可能ファイルを生成するために必ずしも中間表現を使用する必要はない。中間表現は、プログラムの実行時に機械語命令が生成されるインタプリタ型言語とともに使用することができる。しかし、機械語コードを生成するために中間表現を使用することも全く必要ない。例えば、中間表現は、プログラムの解析を支援するため、動作をシミュレートするため、または他の任意の所望の目的のために使用することができる。
【００８４】
図７に示された処理は、任意の適切な方法で実施することができる。一実施形態では、中間表現は、従来のコンピュータ上で動作するソフトウェアツールを使用して生成される。ソフトウェアツールを、現在知られているあるいは今後開発される任意の適切なプログラミング言語で実装することができる。
【００８５】
図７は、処理ブロック７１４を含み、そのブロックでは修正された生存性定義に基づいて中間表現にエッジが追加される。修正された定義に従えば、各変数は、それらがｔｒｙボディ領域からの非同期移行の後で使用される場合に生存する（ｌｉｖｅ）と見なされる。各変数が、非同期移行の後で実行される他の領域のプログラムで生存する場合に、それらは外部生存であると見なされる。各変数が、非同期移行の後でアクセスされるｔｒｙボディの領域の中で生存する場合にも、それらは外部生存であると見なされる。これらの変数がその領域の中だけで使用される場合は、そのｔｒｙボディの外部生存である変数のセットに既に含まれていることはないはずであり、したがってそのセットに追加することが必要になる。
【００８６】
図８Ａは、修正された定義に従ってｔｒｙボディ領域の外部生存である変数を識別するための処理の流れ図である。例示の実施形態では、処理はコンパイルされた関数上で実施される。しかし、この処理をより一般的に、任意の目的のために処理される任意のプログラムまたはコードユニットに適用することができる。
【００８７】
処理は処理ブロック８１０で始まる。図８Ａに示された処理は、中間表現が部分的に作成された後で開始される。記載の実施形態では、図８Ａの処理は、非同期移行の影響を反映するための最初の中間表現が追加された前に実施される。
【００８８】
この形では、関数はフローグラフと関連づけられており、ブロックを中間表現から識別することができる。中間表現はまた、関数における各領域間の相互接続を示す領域グラフを含むことができる。この例では、各領域はそれに関連する３つの種類、すなわちｔｒｙ、ハンドラ、またはルートのうちの１つである。ルートは、領域ツリーのトップにある非プロテクト領域である。各領域をネストすることができ、領域グラフを各領域がネストされる方法によって定義されたブランチを有するツリーと見なすことができる。
【００８９】
図８Ａの処理を任意の適切な方法で実装することができる。記載の実施形態では、処理は、中間表現を形成するツールによって使用されるソフトウェアドライバによって実施される。表Ｉは、図８Ａの処理を実装するために使用できる擬似コードの例を示す。擬似コードからプログラムを生成するために任意の適切なプログラミング言語を使用することができる。例えば、Ｃ++またはＣ#プログラミング言語を使用することができる。添付のコンピュータプログラムリストは（本出願の開示の一部を形成するものであるが）、表Ｉ、２、および３に示された擬似コードをどのように実装できるかの例を示す。
【００９０】
処理ブロック８１０で、プログラム中の各ブロックに対して内部生存である変数が計算される。図示の実施形態では、変数の生存性は、ハンドラ領域での変数の使用が生存性計算に影響を及ぼさないように、フローグラフから切り離されたハンドラ領域を用いて決定される。ただし、従来の生存性計算を使用することもできる。
【００９１】
処理ブロック８１２で、非同期のエントリポイントだけを有するブロックが識別される。非同期のエントリポイントは、ハンドラ領域中の制御命令の移行以外からは到達することができないコードのラベルによって識別される。
【００９２】
後続の処理ステップでは、各ｔｒｙ領域中の各ブロックに対してどの変数が内部生存であるかを表す値が領域ごとに集約されて各ｔｒｙボディ領域に対して外部生存である全ての変数のセットが生成される。
【００９３】
各ブロックは、ブロックが選択される処理ブロック８１４から始まり、一度に１ブロックずつ処理される。表Ｉの擬似コードは、コンパイルされた関数に関連するフローグラフが、その領域の全てのブロックをリストする、ｌｉｓｔ＿ｏｆ＿ｂａｓｉｃ＿ｂｌｏｃｋｓ（基本ブロックのリスト）として識別されたデータ構造上で動作することを指示する。したがって、処理ブロック８１４で、処理すべきブロックを、このリスト上の次のブロックとして、または任意の他の適切な方法によって選択することができる。
【００９４】
判定処理ブロック８１６で、選択されたブロックがｔｒｙボディ領域の内部にあるかどうかが調べられる。この例では、ｔｒｙボディ領域に追加する必要があるエッジが識別できるように、各ｔｒｙボディの外部生存である変数のセットが生成される。したがって、ｔｒｙ領域内にないブロックを処理する必要はない。
【００９５】
選択されたブロックがｔｒｙ領域内にない場合は、実行は判定処理ブロック８２４に続く。判定ブロック８２４でさらに処理すべきブロックが存在すると判定された場合は、実行は処理ブロック８１４に戻り次のブロックが選択される。逆に、処理すべきブロックが残っていないと判定された場合は、実行は処理ブロック８３０に移動し、後に記載の処理が行われる。表Ｉの擬似コードでは、これらのステップは、関数内の各ブロックが処理されることを示す「ｆｏｒｅａｃｈ」命令で示される。
【００９６】
選択されたブロックが処理されるｔｒｙボディ領域内部にある場合は、処理は判定ブロック８１６から判定ブロック８１８へと続く。判定ブロック８１８で、選択されたブロックに続くブロックもまた処理すべきｔｒｙボディ領域内にあるかどうかが調べられる。表Ｉの擬似コードの「ｆｏｒｅａｃｈ」命令によって指示されるように、複数の後続のブロックが存在する場合はその各々が考慮される。
【００９７】
後続のブロックが異なる領域にある場合は、処理はブロック８２２に続く。ブロック８２２で、後続のブロックに対して内部生存である変数が、ｔｒｙボディ領域の外部で生存する変数のセットに追加される。ｔｒｙボディ領域の外部で生存する変数のセットを任意の適切な方法で表すことができる。変数のセットを表すために使用できるデータ構造の例には、ビットベクトル、リスト、データテーブルなどがある。表Ｉに例として示されたプログラムでは、「ｌｉｖｅ＿ｏｕｔ＿ｏｆ＿ｒｅｇｉｏｎ」（「領域の外部生存」）は各領域に関連して形成することができるデータ構造を意味し、「ｌｉｖｅ−ｉｎ」（「内部生存」）は各ブロックに関連するデータ構造を意味する。これら２つのデータ構造の論理和が計算される。この操作は、後続のブロックが領域の外部にある場合は、その後続のブロックに対して内部生存である変数を、それに先行する領域の外部生存に追加することを指示する。
【００９８】
図８Ａは、処理が判定ブロック８２４に続くことを示す。さらにブロックが残っている場合は、処理は処理ブロック８１４に戻り、そこで次のブロックが処理される。各ブロックが処理されるとき、領域の外部にある後続のブロックが存在する場合は、その後続の領域の内部生存である変数は、処理中のブロックのその領域の外部生存である変数を表すセットに追加される。ここでは、各変数は論理和演算を用いて「追加」される。変数が既に領域の外部生存としてリストされている場合は、リストにその変数を「追加」してもリストに影響を与えない。
【００９９】
関数または他のプログラム中の全てのブロックが処理されたとき、処理は判定ブロック８２４から処理ブロック８３０に続く。この処理ブロックでは、ハンドラからだけ到達可能な部分を有する領域に対する調整がなされる。処理ブロック８３０によって実施される処理は、以下の表Ｉの例ではメソッドＡｓｙｎｃＬｉｖｅＯｕｔＯｆＲｅｇｉｏｎによって実施されるが、これについては以下の図８Ｂに関連してより詳細に説明する。
【０１００】
【表１】
2006196002.tif 000003
【０１０１】
メソッドＡｓｙｎｃＬｉｖｅＯｕｔＯｆＲｅｇｉｏｎによって実施される処理は、図８Ｂに示されている。表ＩＩは、メソッドＡｓｙｎｃＬｉｖｅＯｕｔＯｆＲｅｇｉｏｎを実装するために使用することができる擬似コードの例である。
【０１０２】
図８Ｂの処理は処理ブロック８５０で始まる。図８Ｂの処理は、中間表現を構成する少なくとも１つのフェーズが完了した後に実施される。この状態で、処理されるプログラムの領域は、領域間の関係とともに識別されている。領域を他の領域に組み込むことで、ツリー構造と見なされる構造を生成することができる。このツリー構造では、各領域がツリーのノードを形成し、領域間の関係がノード間の接続を定義する。
【０１０３】
図８Ｂによって示される処理は、領域を処理する順序を決定するための領域ツリー構造を使用して、各領域の処理を順序づける。記載の実施形態では、後順走査（ｐｏｓｔ−ｏｒｄｅｒ  ｔｒａｖｅｒｓａｌ）を使用して領域ツリーが処理されるので、組み込まれた領域が最初に処理される。
【０１０４】
表ＩＩの擬似コードの例では、同一のメソッドを再帰的に呼び出す「ｆｏｒｅａｃｈ」ループを使用して後順走査を実現している。このメソッドが呼び出されるたびに、処理される領域は、その全ての子領域または組み込まれた領域に対してこのメソッドを呼び出す。この再帰呼出しは、処理される全ての領域がスタックに含まれるまで、このメソッドへの多数の呼出しを実施する。次に、各呼出しはそれがスタックに積まれた逆順にスタックから処理され、後順走査が生成される。表ＩＩの例では、処理される領域がｔｒｙ領域である場合にだけ呼出しが行われる。
【０１０５】
図８Ｂで、処理は処理ブロック８５２に続く。処理ブロック８５２で、処理すべき次の領域が選択される。ブロック８５４において、その領域が非同期エントリを有していない場合は、処理は判定ブロック８７０に続く。非同期エントリを有していない領域に対しては、それ以上の処理は必要ない。どの領域が非同期移行によってのみ到達される部分を含むかを指示する情報を、処理ブロック８１２（図８Ａ）で収集することができる。
【０１０６】
逆に、ブロック８５４において、領域が非同期のエントリポイントを有する場合は、処理は処理ブロック８５６に進む。表ＩＩの例では、メソッドＡｓｙｎｃＬｉｖｅＯｕｔＯｆＲｅｇｉｏｎの呼び出しにより他の処理が実施される。この処理については表ＩＩＩにより詳細に示す。
【０１０７】
【表２】
2006196002.tif 000004
【０１０８】
領域が少なくとも１つの非同期エントリポイントを有するときは、処理は処理ブロック８５６に続き、そこで非同期エントリから始まるその領域中のブロックが選択される。処理ブロック８５６は判定ブロック８６４で終わるループの始点であり、そのループにより非同期エントリを含む各ブロックが処理される。表ＩＩＩの擬似コード例では、このループは「ｆｏｒｅａｃｈ」命令によって実装されている。
【０１０９】
非同期エントリポイントを含む各ブロックに対して、処理ブロック８５８、８６０、および８６２の処理が実施される。これらの処理ブロックは表ＩＩＩに示されたメソッドＡｓｙｎｃＵｐｄａｔｅＬｉｖｅＯｕｔＯｆＴｒｙ、ＡｓｙｎｃＵｐｄａｔｅＣｏｎｔａｉｎｉｎｇＴｒｙＬｉｖｅｎｅｓｓ、およびＡｓｙｎｃＵｐｄａｔｅＣｏｎｔａｉｎｅｄＴｒｙＬｉｖｅｎｅｓｓに対応する。
【０１１０】
処理ブロック８５８で、あるブロックに対して内部生存であると識別された各変数は、処理中のブロックを含む領域の外部生存である変数のセットに追加される。
【０１１１】
処理ブロック８６０で、ステップ８５８でその領域の外部生存として識別された変数が、その領域がネストされている領域（すなわち、その領域の「親」）に対して外部生存と識別される変数のセットに追加される。
【０１１２】
処理ブロック８６２で、選択されたブロックの外部生存として識別された変数が、そのブロックを含む領域に組み込まれたあらゆる領域に対して外部生存である外部生存変数のセットに追加される。処理ブロック８６２の機能を、例えば表ＩＩＩに示されたＡｓｙｎｃＵｐｄａｔｅＣｏｎｔａｉｎｅｄＴｒｙＬｉｖｅｎｅｓｓなどのメソッドによって実装することができる。示されているように、このメソッドは、このメソッドを再帰的に呼び出す「ｆｏｒｅａｃｈ」ループを含み、それによって各子領域に対して処理を実施するように指示する。
【０１１３】
処理ブロック８６２に続いて、判定ブロック８６４が実行される。その領域中に非同期エントリを有するブロックがまだ存在する場合は、処理は処理ブロック８５６に戻り、非同期エントリを有する次のブロックが選択され、処理される。
【０１１４】
非同期エントリを有するブロックが残っていなかった場合は、処理は判定ブロック８７０に続く。処理すべきｔｒｙ領域がまだ残っている場合は、処理は処理ブロック８５２に戻り、次の領域が選択され処理される。
【０１１５】
【表３】
2006196002.tif 000005
【０１１６】
上述のように、本発明の少なくとも１つの実施形態についてのいくつかの態様を説明してきたが、様々な代替形態、修正形態、および改良を当業者には容易に実施できることを理解されたい。
【０１１７】
例えば、本発明はコンパイラとともに使用するように例示されている。本発明は、コンピュータまたは他の機械にロードされて実行される実行可能な機械コードを生成する従来のコンパイラにおいて有用なはずである。しかし本発明を、プログラムを処理する任意のソフトウェアツールとともに使用することができる。例えば本発明を、プログラムを実行するプロセッサ上に常駐し、必要に応じてプログラムの一部を機械コードに変換するＪＩＴ（Ｊｕｓｔ  Ｉｎ  Ｔｉｍｅ）コンパイラとともに使用することができる。
【０１１８】
このような代替形態、修正形態、および改良は本開示の一部であることが意図され、本発明の趣旨および範囲に含まれることが意図される。したがって、上述の記載および図面は例示のためだけに示されたものである。
【０１１９】
本発明の上述の実施形態を、多くの方法のうちのいずれかで実装することができる。例えば、各実施形態をハードウェア、ソフトウェア、またはそれらの組合せを使用して実装することができる。ソフトウェアの形で実装されたとき、単一のコンピュータに提供されるか複数のコンピュータに分散されるかに関わらず、ソフトウェアコードを任意の適切なプロセッサまたはプロセッサの集りの上で実行することができる。上述の機能を実施する任意のコンポーネントまたはコンポーネントの集りを一般に、上述の機能を制御する１つまたは複数のコントローラと見なすことができることを理解されたい。この１つまたは複数のコントローラは、上述の機能を実施するためにマイクロコードまたはソフトウェアを用いてプログラムされた専用のハードウェアまたは汎用のハードウェア（例えば、１つまたは複数のプロセッサ）を使用して、多くの方法で実装することができる。
【０１２０】
また、本明細書で概説した様々な方法または処理を、様々なオペレーティングシステムまたはプラットフォームのいずれか１つを使用する１つまたは複数のプロセッサ上で実行可能なソフトウェアとしてコード化することができる。さらに、このようなソフトウェアを、いくつかの適切なプログラミング言語、および／または従来のプログラミングもしくはスクリプト記述ツールのいずれかを使用して書き込むことができ、また実行可能な機械語コードにコンパイルすることもできる。
【０１２１】
なお、本発明の一実施形態は、１つまたは複数のコンピュータまたは他のプロセッサ上で実行されるときに、上述の本発明の様々な実施形態を実行する方法を実現する１つまたは複数のプログラムで符号化された１つ（または複数）のコンピュータ可読媒体（例えば、コンピュータメモリ、１つまたは複数のフロッピディスク、コンパクトディスク、光ディスク、磁気テープなど）を対象とする。この１つまたは複数のコンピュータ可読媒体は、格納された１つまたは複数のプログラムを１つまたは複数の異なるコンピュータまたは他のプロセッサ上にロードして上で論じた本発明の様々な態様を実行することができるように可搬型であってもよい。
【０１２２】
本明細書で使用される「プログラム」という用語は一般に、コンピュータまたは他のプロセッサをプログラムして上で論じた本発明の様々な態様を実行するために使用することができる任意の種類のコンピュータコードまたは命令のセットを意味する。さらに、本実施形態の一態様によれば、実行時に本発明の方法を実施する１つまたは複数のコンピュータプログラムは、単一のコンピュータまたはプロセッサ上に常駐している必要はなく、いくつかの異なるコンピュータまたはプロセッサの間にモジュールごとに分散させて本発明の様々な態様を実行させることができることを理解されたい。
【０１２３】
本発明の様々な態様を、単体で、組合せで、または上述の実施形態では詳細に論じていない様々な構成で使用することができる。したがって、本発明の用途は、上記説明に記載された、または図面に例示された各コンポーネントの詳細および構成に制限されるものではない。例えば、一実施形態に記載された諸態様を、他の実施形態に記載された諸態様と任意の方法で組み合わせることができる。
【０１２４】
特許請求の範囲における、請求項要素を修飾する「第１」、「第２」、「第３」など順序を表す用語の使用は、それ自体では、ある請求項要素の他の請求項要素に対する、あるいはある方法の動作が実施される時間的な順序に対する優先度、先行、または順序を暗示するものではなく、各請求項要素を区別するために、ある名前を有するある請求項要素を（順序を表す用語の使用を除いて）同じ名前を有する他の要素と区別するための単なるラベルとして使用されるものである。
【０１２５】
さらに、「追加」や「集約」などの用語を、オブジェクトのセットの生成について記述するために使用する。その様なセットを生成する際に、各セットに対してそのセットのメンバーが生成または追加される順序は本発明にとっては重要ではない。セットのメンバーを任意の順序で、または同時に生成することができる。セットの各メンバーを、生成された順序、あるいは他の任意の順序でセットのメンバーであると識別することができる。
【０１２６】
また、本明細書で使用される表現および用語は説明のためのものであり、制限のためのものと見なすべきではない。本明細書で使用される「含む（ｉｎｃｌｕｄｉｎｇ）」、「備える（ｃｏｍｐｒｉｓｉｎｇ）」、または「有する（ｈａｖｉｎｇ）」、「内包する（ｃｏｎｔａｉｎｉｎｇ）」、「包含する（ｉｎｖｏｌｖｉｎｇ）」という用語およびその変形は、その後にリストされたアイテムおよびその均等物、ならびに追加のアイテムを包含することを意味している。
【０１２７】
［コンピュータプログラムリスト］
このアルゴリズムが全ての例外ハンドラを完全に無視したフローグラフ上で実施されることに留意されたい。本発明者らは、ＪＩＴ６４において、例外ハンドラを親メソッドから抜き出すことを選択し、それらを最後のＥＸＩＴステートメントに独立の関数として付加した。他の方法として、ＳＥＳＥ領域を形成するなどのハンドラを無視することもできるであろう。
【０１２８】
（親メソッドの中だけの）ブロックレベルで内部生存および外部生存を計算した後で、その計算をＥＨ領域グラフにマップする必要がある。具体的には、各ｔｒｙ領域に対して領域の外部生存を計算する。次に、非同期でのみ到達するブロックを使用して領域の外部生存の定義を拡張する。この拡張は、ＭＳＩＬ＿ＡｓｙｎｃＬｉｖｅＯｕｔＯｆＲｅｇｉｏｎ（）で行われる。この表では、呼出し部分が太字で示されている。この被呼側の詳細は次ページに展開されている。以下は最上位レベルのドライバである。
【０１２９】
【表４】
2006196002.tif 000006
【０１３０】
最上位レベルドライバは領域ツリーの後順走査を実施する。最上位レベルドライバがツリー内のノードに関する再帰呼出しから「ポップバック（ｐｏｐｓ  ｂａｃｋ）」したとき、実行はループから抜ける。次に、最上位ドライバはｔｒｙ領域である（すなわち、ＥＨ領域グラフのハンドラノードでない）あらゆる領域を処理する。
【０１３１】
最上位ドライバは、「ワーカ（ｗｏｒｋｅｒ）」ルーチンＭＳＩＬ＿ＡｓｙｎｃＬｉｖｅＯｕｔＯｆＡＴｒｙＲｅｇｉｏｎを使用する。このルーチンの詳細を次ページに示す。
【０１３２】
直感的には、単純な再帰であるＥＨ領域ツリーの後順走査のために「逆方向（ｉｎｓｉｄｅ−ｏｕｔ）」順序付けが必要になる。したがって、最も深くネストされたｔｒｙ領域が、それを含む任意のｔｒｙ領域の前に処理されることになる。
【０１３３】
【表５】
2006196002.tif 000007
【０１３４】
【表６】
2006196002.tif 000008
【０１３５】
最後に、領域の外部生存の定義を拡張できるキーブロックを見つけるアルゴリズムの詳細を示す。
【０１３６】
【表７】
2006196002.tif 000009
【図面の簡単な説明】
【０１３７】
【図１Ａ】従来技術の高水準プログラミング言語で書かれたプログラムを示す図である。
【図１Ｂ】図１Ａの従来技術のプログラムの動作についてのグラフィカル表現を示す図である。
【図１Ｃ】図１Ａの従来技術のプログラムの動作を表すフローグラフのグラフィカル表現を示す図である。
【図２】本発明の一実施形態によるフローグラフのグラフィカル表現を示す図である。
【図３】本発明の実施形態の理解に役立つフローグラフのグラフィカル表現を示す図である。
【図４】本発明の実施形態の理解に役立つフローグラフのグラフィカル表現を示す図である。
【図５】本発明の実施形態の理解に役立つフローグラフのテキスト表現を示す図である。
【図６Ａ】本発明の実施形態の理解に役立つフローグラフのテキスト表現を示す図である。
【図６Ｂ】図６Ａのテキスト表現の理解に役立つフローグラフのグラフィカル表現を示す図である。
【図７】本発明の一実施形態によるプログラムの処理を示す流れ図である。
【図８Ａ】本発明の一実施形態によるプログラムの処理を示す流れ図である。
【図８Ｂ】本発明の一実施形態によるプログラムの処理を示す流れ図である。
【符号の説明】
【０１３８】
１００  プログラム
１１２  命令
１１４  命令
１２０  命令
１２１  ブラケット
１２２  命令
１２３  ブラケット
１２４  命令
１２５  ブラケット
１３０  命令
１４０  ｔｒｙボディ
１４２  例外ハンドラ
１４４  ｆｉｎａｌｌｙハンドラ
１５０  領域
１６０  フローグラフ
１６２  命令
１６４  命令
１６６  命令
１６８  命令
１７０  命令
１７２  命令
１８０Ａ  エッジ
１８０Ｂ  エッジ
１８２  エッジ
１８４  エッジ
１８６  エッジ
１８８  エッジ
１９０  エッジ
１９２  エッジ
２６０  フローグラフ
３４０  ｔｒｙボディ
３４０Ａ  部分
３４０Ｂ  ブロック
３４２  例外ハンドラ
３４４  ｆｉｎａｌｌｙハンドラ
３５０  領域
３６０  フローグラフ
３８０  エッジ
４１０  領域
４６０  フローグラフ
４８２  エッジ
４８４  エッジ
４８６1  エッジ
４８６2  エッジ
４８８1  エッジ
４８８2  エッジ
４８８3  エッジ
４８８4  エッジ
５１０  中間表現
５１２  命令
５１４  命令
５１６  命令
５１８  命令
５２０  命令
５２２  命令
５２４  命令
５３０  命令
５３２  命令
５４０  命令
５５０  命令
５５２  命令
５６０  命令
６１０  中間表現
６２０  命令
６３０  命令
６３２  命令
６４０  シンクブロック
６４４  命令
６４６  命令
６６０  フローグラフ
６６２  ブロック
６６４  ブロック
６６８  ブロック
６７０  ブロック
６７２  ブロック
６７４  ブロック
６７６  ブロック
６７８  ブロック
６８１  エッジ
６８２  エッジ
６８３  エッジ
６８４  エッジ
６８５  エッジ
６８６  エッジ
６８８  エッジ
６９０  エッジ
６９２  エッジ
６９４  エッジ
７００  流れ図
７１０  ハンドラを分離したプログラムの中間表現を生成する
７１２  シンクブロックを追加する
７１４  修正された外部生存定義を用いて識別された外部生存変数定義の後にエッジを追加する
７１６  ハンドラからの戻り用のエッジを追加する
７１８  ｔｒｙボディを包含するようなエッジを追加する
７２０  ハンドラで使用される変数の中間表現を追加する
７２２  中間表現を使用して処理を行う
８１０  各ブロックの内部生存を計算する
８１２  非同期のエントリだけを有するブロックを識別する
８１４  ブロックを選択する
８１６  ｔｒｙボディ内か？
８１８  後続は領域内にあるか？
８２２  後続に内部生存を追加する
８２４  まだブロックは残っているか？
８３０  非同期エントリを有する領域を調整する（図８Ｂ）
８５０  各領域を順序づける
８５２  次の領域を選択する
８５４  領域は非同期エントリを含むか？
８５６  非同期によってのみ到達可能な次のブロックを選択する
８５８  ブロックに対する内部生存を領域の外部生存に追加する
８６０  その領域を含む各ｔｒｙ領域の生存性を記録する
８６２  その領域に組み込まれた各ｔｒｙ領域の生存性を記録する
８６４  非同期ブロックはまだ有るか？
８７０  領域はまだ有るか？
【図１Ａ】
2006196002.tif 000010
【図１Ｂ】
2006196002.tif 000011
【図１Ｃ】
2006196002.tif 000012
【図２】
2006196002.tif 000013
【図３】
2006196002.tif 000014
【図４】
2006196002.tif 000015
【図５】
2006196002.tif 000016
【図６Ａ】
2006196002.tif 000017
【図６Ｂ】
2006196002.tif 000018
【図７】
2006196002.tif 000019
【図８Ａ】
2006196002.tif 000020
【図８Ｂ】
2006196002.tif 000021