(57)【要約】【課題】  インタプリタを用いてバイトコードを実行するＪａｖａ（登録商標）等の仮想マシンでは、実行頻度の高いメソッド呼出しに対して、そのバイトコードをコンパイルすることにより実行効率を改善する最適化が行われている。しかし、コンパイルが実施された場合に、コンパイルされたバイトコード中のメソッド呼出しに対してインライン展開が実施されない場合がある。動的メソッド呼出しをサポートしているために、実際に呼び出されるメソッドをコンパイル時に決定することができないためである。【解決手段】  本発明は、インタプリタによる実行時に各メソッド呼出しの履歴を記録する。コンパイルが実施された場合には、その履歴を参照することで動的メソッド呼出しについてもインライン展開を実施し、コンパイルコードの実行効率を改善するものである。【選択図】  図１
2005346407.tif 000002
【特許請求の範囲】
【請求項１】
実行頻度の高いメソッド呼出しに対して、そのバイトコードをコンパイルして実行する機能を有するインタプリタにおいて、インタプリタ実行時にメソッド呼出しの履歴を記録し、コンパイル時にその履歴を参照することにより動的メソッド呼出しのインライン展開を実施する動的コンパイル方法。
【請求項２】
請求項１記載の動的コンパイル方法を利用したプログラミング言語処理系。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明はインタプリタを用いてバイトコードを実行することによりプログラムの実行を行うＪａｖａ（登録商標）等について動的にコンパイルを使用する方法に関し、より詳しくは動的コンパイル時のインライン展開の方法に関する。
【背景技術】
【０００２】
インタプリタを用いてバイトコードを実行するＪａｖａ（登録商標）等の仮想マシンでは、実行頻度の高いメソッド呼出しに対して、その呼び出されるメソッドのバイトコードをコンパイルしてマシンコードを生成することにより実行効率を改善する最適化が行われている。
【０００３】
【特許文献１】特開２０００−２２２２２０号公報
【発明の開示】
【発明が解決しようとする課題】
【０００４】
しかし、コンパイルが実施された場合に、コンパイルされたバイトコード中のメソッド呼出しに対してインライン展開が実施されない場合がある。Ｊａｖａ（登録商標）等では、実行時に与えられるレシーバクラスに基づいて呼び出されるメソッドを決定する動的メソッド呼出しをサポートしているため、実際に呼び出されるメソッドをコンパイル時に決定することができないためである。
【課題を解決するための手段】
【０００５】
本発明は、インタプリタによる実行時に、各メソッドについて、それが呼び出すメソッドの履歴を記録する。コンパイルが実施された場合には、コンパイルされるバイトコード中のメソッド呼出しについて、前記インタプリタ実行中のメソッド呼出しの履歴を参照することにより、動的メソッド呼出しについてもインライン展開を実施する。
【発明の効果】
【０００６】
本発明によれば、従来はインライン展開が実施されなかった動的メソッド呼出しについてもインライン展開を実施するため、コンパイルコードの実行効率を改善することができる。
【発明を実施するための最良の形態】
【０００７】
以下、本発明を実施するための最良の形態について図面に基づいて詳細に説明する。
【０００８】
図１は本発明の適用対象が動作する計算機システムの例である。計算機システムはプロセッサ１０７・主記憶１０８・ディスク１０９から構成され、これらがバス１１０によって結合されている。本発明を適用した言語処理系であるＪａｖａ（登録商標）仮想マシン１０２はディスク１０９から主記憶１０８へ読み出され、プロセッサ１０７で実行される。Ｊａｖａ（登録商標）仮想マシン１０２は、Ｊａｖａ（登録商標）インタプリタ部１０３とＪａｖａ（登録商標）ＪＩＴコンパイラ部１０４によりバイトコード列１０１を実行する。Ｊａｖａ（登録商標）インタプリタ部１０３は、バイトコード列１０１中のバイトコードをデコードし、バイトコードの各命令に対応した処理ルーチンを呼び出して実行する。このときＪａｖａ（登録商標）インタプリタ部１０３は、実行したバイトコードのメソッド呼出しに関する実行の履歴をメソッド呼出し履歴１０５として記録する。Ｊａｖａ（登録商標）ＪＩＴコンパイラ部１０４はバイトコード列１０１の一部をコンパイルしてマシンコード１０６を生成し、そのマシンコードを実行する。一度生成されたマシンコードはＪａｖａ（登録商標）仮想マシン１０２内に保存され、対応するバイトコード列が再度実行される場合には、その保存してあるマシンコードを実行する。
【０００９】
図２はＪａｖａ（登録商標）仮想マシン１０２におけるバイトコードの実行手順の詳細を表すフローチャートである。まずバイトコードを読み取り（ステップ２０１）、それがメソッド呼出しを意味するバイトコードかどうかを判定する（ステップ２０２）。メソッド呼出しを意味するバイトコードでない場合には、バイトコードの命令に対応した処理ルーチンを呼び出すバイトコード実行処理（ステップ２０３）を行う。その後、そのバイトコードが最後のバイトコードかどうかを判定し（ステップ２０９）、最後のバイトコードである場合には全体の処理が終了する。最後のバイトコードではなく、さらに実行すべきバイトコードが存在する場合には、ステップ２０１に戻り処理を継続する。ステップ２０２においてメソッド呼出しを意味するバイトコードである場合には、呼び出されるメソッドが既にＪａｖａ（登録商標）ＪＩＴコンパイラ部によりコンパイル済みであるかどうかを判定する（ステップ２０４）。コンパイル済みである場合には対応するマシンコードの実行を行う（ステップ２０５）。ステップ２０４においてコンパイル済みでない場合、当該メソッド呼出しについてのメソッド呼出し履歴を登録する（ステップ２０６）。このメソッド呼出し履歴の登録処理が本発明において追加したものであり、その詳細は後述する。その後、当該メソッド呼出しがコンパイル条件を満たすかどうかを判定する（ステップ２０７）。このとき、呼び出されるメソッドがこれまでに呼び出された総回数が定められた閾値を越えたかどうか、などが一般的なコンパイル条件として使用される。すべてのメソッドをＪａｖａ（登録商標）ＪＩＴコンパイルするのではなくステップ２０７の判定が設けられているのは、Ｊａｖａ（登録商標）ＪＩＴコンパイル時間もバイトコード列全体の実行時間に含まれることから、コンパイルしたことによるその後のそのメソッドの実行時間の短縮がコンパイル時間より大きくないとバイトコード列全体としての実行時間の短縮にならないためである。一般には、あるメソッドの呼出し回数を実行前に知ることができないため「そのメソッドがこれまでに呼び出された総回数」を判定値として用い、これまでに呼ばれた回数が多いものは今後も呼ばれる可能性が高いという予測により判定されている。コンパイル条件を満たす場合には呼び出されるメソッドに対応するバイトコード列に対してＪａｖａ（登録商標）ＪＩＴコンパイル処理を行いマシンコードが生成される（ステップ２０８）。それから、生成されたマシンコードを実行する（ステップ２０５）。ステップ２０７において当該メソッド呼出しがコンパイル条件を満たさなかった場合はステップ２０３のバイトコード実行処理により、そのバイトコードを実行する。
【００１０】
図３はメソッド呼出し履歴登録処理（ステップ２０６）の実行手順の詳細を表すフローチャートである。履歴登録処理では図４と図５の履歴テーブルにメソッド呼出しの情報を登録する。図４の履歴テーブルは各メソッド呼出しバイトコードに対して一個づつ割り付けるものであり、メソッド識別子４０１と整数値を格納するcaller_count４０２の２つのフィールドを持つ。図５の履歴テーブルは各メソッドに対して一個づつ割り付けるものであり、整数値を格納するcallee_count５０１のフィールドを持つテーブルが本発明において追加したものである。５０２は従来から使用されている各メソッドの情報を格納するテーブルであり、メソッド識別子・返却値の型・パラメタのサイズなどを格納している。callee_count５０１のフィールドを持つ履歴テーブルは、このテーブル５０２から辿れるようにするか、または、callee_count５０１のフィールドをテーブル５０２に追加してもよい。メソッド呼出し履歴登録処理（ステップ２０６）では、まず呼び出されるメソッドが持つ履歴テーブルにおけるcallee_countフィールドの内容を１増やす（ステップ３０１）。なお、callee_countフィールドの初期値は0である。次に、その呼び出されるメソッドの履歴テーブルにおけるcallee_countフィールドの内容を１次変数countに格納する（ステップ３０２）。その後、当該メソッド呼出しバイトコードが持つ履歴テーブルのcaller_countフィールドの値をcountの値と比較する（ステップ３０３）。countの値がcaller_countフィールドの値より小さい場合には履歴登録処理を終了する。他方、countの値がcaller_countフィールドの値と等しいかより大きい場合には、さらに次の処理を行う。まず、当該メソッド呼出しバイトコードが持つ履歴テーブルのcaller_countフィールドにcountの値を格納する（ステップ３０４）。次に、当該メソッド呼出しバイトコードが持つ履歴テーブルのメソッド識別子フィールドに、呼び出されるメソッドの識別子を格納する（ステップ３０５）。
【００１１】
図６はＪＩＴコンパイル処理（ステップ２０８）の実行手順の詳細を表すフローチャートである。まず、バイトコード列を中間コードに変換する（ステップ６０１）。その後、中間コード中のメソッド呼出しについて呼び出されるメソッドのインライン展開処理を実施する（ステップ６０２）。このとき、当該メソッド呼出しがもつ履歴テーブルを参照し、そのメソッド識別子フィールドに格納されているメソッドが既にＪＩＴコンパイル済みである場合は、そのメソッドをインライン展開する。このとき、Ｊａｖａ（登録商標）では、実行時に与えられるレシーバクラスに基づいて呼び出されるメソッドを決定する動的メソッド呼出しをサポートしているため、インライン展開においては、実際に呼び出されるメソッドがインライン展開されたものであるかどうかを検査するコードを追加することが必要である。詳細については、後述する実施例において説明する。最後に、中間コードからマシンコードを生成する（ステップ６０３）。
【００１２】
図７は本発明を適用したＪａｖａ（登録商標）仮想マシンによりＪａｖａ（登録商標）ＪＩＴコンパイルを実施した例である。Ｊａｖａ（登録商標）仮想マシンがメソッド７０１中のメソッド呼出し”obj.caller(some_obj);”に対応するバイトコードをＪＩＴコンパイル処理２０８にて処理する場合について述べる。メソッド７０１中で使用しているクラス定義は”Base.func”が持つ履歴テーブルは７０３であり、メソッド”Derived.func”が持つ履歴テーブルは７０４であるとする。７０３と７０４の履歴テーブルは、それぞれメソッド”Base.func”の情報テーブル７０７と”Derived.func”の情報テーブル７０８から辿れる。さらに、メソッド呼出し”obj.caller(some_obj);”に対応するバイトコードが持つ履歴テーブルは７０５とする。まず、中間コード生成処理６０１においてメソッド”Derived.caller”の中間コードを生成する。その後、インライン展開処理６０２においてメソッド呼出し”obj.caller(some_obj);”の中間コードに対してインライン展開を実施する。このとき、メソッド呼出し”obj.caller(some_obj);”のバイトコードに対応する履歴テーブル７０５のメソッド識別子は”Derived.func()”であるため、メソッド”Derived.func”のＪＩＴコンパイル済みのコードをインライン展開する。ここでは、メソッド”Derived.func”は既にＪＩＴコンパイル済みである場合を仮定している。履歴テーブル７０５においてメソッド識別子が”Derived.func()”となっているが、これは以前のメソッド呼出し”obj.caller(some_obj);”に対応するバイトコードの実行時にメソッド呼出し履歴登録処理２０６により記録されたものである。メソッド呼出し”obj.caller(some_obj);”からは”Base.func”と”Derived.func”が呼ばれたことがあるとした場合、履歴テーブル７０４のcallee_countの値が履歴テーブル７０３のcallee_countの値よりも大きいため”Derived.func”が記録されたものである。最後に、マシンコード生成処理６０３により生成されたマシンコードが７０６である。７０６においてＲ０・Ｒ１・Ｒ２はレジスタを表す。実際に呼び出されるメソッドがインライン展開されたものであるかどうかを検査するコードが７０６の４行目である。Ｒ２には実際に呼び出すメソッドのアドレスが入っており、インライン展開したメソッドである”Derived.func”のアドレスとそれが等しいかどうかを判定し、等しい場合のみにインライン展開したコードを実行するようにしている。
【図面の簡単な説明】
【００１３】
【図１】本発明を適用したＪａｖａ（登録商標）仮想マシンの構成図とそれが動作する計算機。
【図２】バイトコードの実行手順の詳細を表すフローチャート。
【図３】メソッド呼出し履歴登録処理の実行手順の詳細を表すフローチャート。
【図４】メソッド呼出しバイトコードに対して一個づつ割り付ける履歴テーブル。
【図５】メソッドに対して一個づつ割り付ける履歴テーブル。
【図６】ＪＩＴコンパイル処理の実行手順の詳細を表すフローチャート。
【図７】本発明を適用したＪａｖａ（登録商標）仮想マシンによるＪａｖａ（登録商標）ＪＩＴコンパイルの例。
【符号の説明】
【００１４】
１０１…バイトコード列、１０２…Ｊａｖａ（登録商標）仮想マシン、１０３…Ｊａｖａ（登録商標）インタプリタ部、１０４…Ｊａｖａ（登録商標）ＪＩＴコンパイラ部、１０５…メソッド呼出し履歴、１０６…マシンコード、１０７…プロセッサ、１０８…主記憶、１０９…ディスク、１１０…バス。
【図１】
2005346407.tif 000003
【図２】
2005346407.tif 000004
【図３】
2005346407.tif 000005
【図４】
2005346407.tif 000006
【図５】
2005346407.tif 000007
【図６】
2005346407.tif 000008
【図７】
2005346407.tif 000009