(57)【特許請求の範囲】
【請求項１】
コンピュータの処理により、実行コード中に埋め込まれた計装コードによって出力される情報をプロファイルするためのプロファイル計装方法であって、
コールサイトに、所定ビット数のコールサイトＩＤを振るステップと、
スレッド毎に、直近Ｎ段（Ｎは１より大きい整数）をコール・ヒストリ情報として保持するステップと、
仮想呼び出しの飛び先のプロファイル表に、実際の飛び先と回数及び前記コール・ヒストリ情報を記録するステップとを有する、
プロファイル計装方法。
【請求項２】
前記コール・ヒストリ情報の記録は、飛び先の分別に必要な分だけの呼び元情報だけ、前記所定ビット数単位で記録される、請求項１に記載の方法。
【請求項３】
前記コール・ヒストリ情報は、スタック・フレームに記録される、請求項１に記載の方法。
【請求項４】
前記所定ビット数は８であり、前記Ｎは４である、請求項２に記載の方法。
【請求項５】
前記コールサイトＩＤは、異なるコールサイトでの重複を許す、請求項１に記載の方法。
【請求項６】
前記プロファイル表への記録は、サイズが所定の値よりも大きいメソッドについてのみ行われる、請求項１に記載の方法。
【請求項７】
請求項１に記載の方法で作成された前記プロファイル表における前記コール・ヒストリ情報が、現在のコンパイル環境とマッチするエントリのみ抜き出してインライニングするステップを含む、ＪＩＴコンパイラ。
【請求項８】
コンピュータの処理により、実行コード中に埋め込まれた計装コードによって出力される情報をプロファイルするためのプロファイル計装プログラムであって、
前記コンピュータをして、
コールサイトに、所定ビット数のコールサイトＩＤを振るステップと、
スレッド毎に、直近Ｎ段（Ｎは１より大きい整数）をコール・ヒストリ情報として保持するステップと、
仮想呼び出しの飛び先のプロファイル表に、実際の飛び先と回数及び前記コール・ヒストリ情報を記録するステップとを実行させる、
プロファイル計装プログラム。
【請求項９】
前記コール・ヒストリ情報の記録は、飛び先の分別に必要な分だけの呼び元情報だけ、前記所定ビット数単位で記録される、請求項８に記載のプログラム。
【請求項１０】
前記コール・ヒストリ情報は、スタック・フレームに記録される、請求項８に記載のプログラム。
【請求項１１】
前記所定ビット数は８であり、前記Ｎは４である、請求項９に記載のプログラム。
【請求項１２】
前記コールサイトＩＤは、異なるコールサイトでの重複を許す、請求項８に記載のプログラム。
【請求項１３】
前記プロファイル表への記録は、サイズが所定の値よりも大きいメソッドについてのみ行われる、請求項８に記載のプログラム。
【請求項１４】
請求項８に記載のプログラムを含み、該プログラムで作成された前記プロファイル表における前記コール・ヒストリ情報が、現在のコンパイル環境とマッチするエントリのみ抜き出してインライニングするステップを含む、ＪＩＴコンパイラ。
【発明の詳細な説明】
【技術分野】
【０００１】
この発明は、コンピュータ上で、プログラムを呼び出して実行するための技術に関し、より詳しくは、プロファイル計装に関する。
【背景技術】
【０００２】
従来より、サーバ環境で使用されるプログラミング言語処理系、あるいは実行系として、PHPのような動的スクリプト言語と、Java(R)のようなより静的なプログラミング言語が使用されているが、近年になって、Java(R)のクラス資産をPHPなどから簡易に呼び出せるように、Java(R)仮想マシンあるいは、コンピュータ共通言語基盤(CLI)のような静的な言語プラットフォーム上でPHPのような動的スクリプト言語が、静的な言語プラットフォームのクラスを宣言し、静的にタイプ付けされていないアクセスを可能ならしめる仕組みが提供されるようになってきている。
【０００３】
特に、Java(R)仮想マシン上で動作するPHPとしてのP8及びQuercus、RubyとしてのJRuby、PythonとしてのJython、Groovyなどが知られている。
【０００４】
しかし、このようなJava(R)上の動的スクリプト言語処理系は、ネイティブな実装よりも遅い場合が多い。そのような速度低下の理由の１つとして、動的な型であるため、ＪＩＴコンパイラのメソッド・インライニングが使えないということがある。
【０００５】
図１は、Java(R)上の動的スクリプト言語処理系における典型的なハンドラ呼び出しパスの例を示す。図１において、FuncAから呼ばれる途中に仮想呼び出しx.addがあるが、これがどの実メソッド（処理ハンドラ）に飛ぶかは、呼び出されたコンテクストに大きく依存する。つまり、x.addは、真に多相的な(polymorphic)呼び出しになっている。
【０００６】
FuncAのＪＩＴコンパイル時に、適切な処理ハンドラ（この例では、DInt.add）をインラインするには、「FuncA→Handler.add→Operator.addと呼ばれた場合、仮想呼び出しx.addは、DInt.addへ飛ぶ」という、呼び出しコンテクストの情報を含んだプロファイリング情報が必要となる。
【０００７】
そこで、従来より、プロファイル計装を行い、その情報に基づき、妥当と判断されるコードをインライニングすることが行われている。
【０００８】
図２は、プロファイル計装によって得られたプロファイリング情報を用いて、FuncAに、DInt.addが適切にインラインされる例を示す。
【０００９】
プロファイリング情報を取得するための従来技術として次のようなものがある。
【００１０】
特開平９−６２５４４号公報は、オリジナルソースコードにより逐次形式で記載された並列計算機用プログラムの挙動を把握すべくプログラム実行時にプロファイルデータの計測を指示する計装コードを、コンパイル処理により最適化変換された前記プログラムの変換コード中に挿入するプロファイル計装方法であって、前記コンパイル処理による最適化変換前に、前記プログラムのオリジナルソースコード情報を収集するプロファイル初期化処理を行なうように構成することを開示する。
【００１１】
特開平１１−２１２８３７号公報は、プロファイル処理時のメモリ領域とオーバーヘッドとを削減するために、ソースプログラム中の関数呼出しを検出してコールペアの種別ごとに識別番号を付してデータベースに保存し、ソースプログラムに関数呼出しごとにプロファイル処理を挿入するとともに、識別番号ごとに関数呼出しの回数を格納するテーブルの領域を設定する静的解析・プロファイル処理挿入部と、プロファイル処理入りソースプログラムをコンパイルして実行し、プロファイル処理があったとき、コールペアの種別に該当する識別番号をインデックスとしてテーブルの関数呼出し回数をインクリメントするコンパイル・プログラム実行部と、識別番号ごとにテーブルの関数呼出し回数を読み出すことによって、コールペアの種別ごとの呼出し回数の情報を生成するプロファイル情報統合部とを備えた構成を開示する。
【００１２】
特開２００２−１３２５４２号公報は、プログラム内の動的関数呼出しにかかるコールペア情報を収集する際に必要なテーブルのサイズを縮小するために、動的呼出し側関数及び動的呼出され側関数を洗い出し、各関数に関数ＩＤを付与し、プロファイル処理挿入部は、動的呼出し側関数の関数ＩＤと動的呼出され側関数の関数ＩＤとの組み合わせである動的コールペア毎にその動的コールペアの呼出し回数を格納する動的コールペア情報格納テーブルの領域を確保する処理と動的呼出しプロファイル処理とを含むプロファイル処理入りソースプログラムを生成し、コンパイル・プログラム実行部は、ソースプログラムをコンパイルして実行し、テーブルを使って動的な呼出しにかかるコールペア毎の呼出し回数を収集することを開示する。
【００１３】
しかし、これら従来技術のプロファイリング処理では、プロファイルのためのコストと網羅性の点で、動的スクリプト言語処理系の処理ハンドラに適用するには適当ではなかった。
【００１４】
そこで、プロファイル時に、必要に応じてスタックトラバースするというナイーブな方法も考えられるが、この方法はコストが高い。
【００１５】
また、アップグレード・コンパイル時などにプロファイル用コードを一時的に埋め込む方式は、一部の非常によく実行されるメソッドにしか適用できない。
【００１６】
Kim Hazelwood and David Grove, "Adaptive Online Context-Sensitive Inlining", Code Generation and Optimization, 2003. International Symposium 23-26 March 2003は、サンプリングによるプロファイリング処理を開示するが、この方法では、情報が網羅的でない。また、特に動的スクリプト言語処理系の処理ハンドラは、末端（リーフ）メソッドでサイズも小さいので、うまくサンプルできない。また、スタックトラバースという重い処理が必要なため、サンプルレートは高くできない。
【００１７】
Matthew Arnold, Stephen Fink, Vivek Sarkar, Peter F. Sweeney, "A comparative study of static and profile-based heuristics for inlining", ACM SIGPLAN Notices, Volume 35 ,  Issue 7  (July 2000), Pages: 52 - 64は、コールグラフを使用するプロファイリング処理を開示するが、呼び出しが合流して分離する図１のようなケースで、インライン先を正しく判定できない。
【００１８】
Xiaotong Zhuang, Mauricio J. Serrano, Harold W. Cain, Jong-Deok Choi, "Accurate, efficient, and adaptive calling context profiling", Conference on Programming Language Design and Implementation Proceedings of the 2006 ACM SIGPLANは、呼び出しコンテクスト・ツリー(Calling Context Tree)を作ることにより正しい判定を可能とする技法を開示するが、この場合、ツリー作成のための追加処理やツリー保持のためのメモリが必要となる。
【００１９】
"HPROF: A Heap/CPU Profiling Tool in J2SE 5.0",http://java.sun.com/developer/technicalArticles/Programming/HPROF.htmlは、JVMTIを使ったプロファイラであるHPROFを記述する。このプロファイラは、網羅的な情報を取得可能であるが、遅い。また、ログ保持のためのメモリやコンテクスト情報集計のための後処理が必要である。
【００２０】
Michael D. Bond, Kathryn S. McKinley, "Probabilistic calling context", Conference on Object Oriented Programming Systems Languages and Applications, Proceedings of the 22nd annual ACM SIGPLAN,  Pages: 97 - 112, 2007に開示されている技術によれば、データ保持のためのメモリを極小化できるが、どのパスを通っているか、オンラインで知ることは難しく、インライニングのためには使用できない。
【先行技術文献】
【特許文献】
【００２１】
【特許文献１】特開平９−６２５４４号公報
【特許文献２】特開平１１−２１２８３７号公報
【特許文献３】特開２００２−１３２５４２号公報
【非特許文献】
【００２２】
【非特許文献１】Kim Hazelwood and David Grove, "Adaptive Online Context-Sensitive Inlining", Code Generation and Optimization, 2003. International Symposium 23-26 March 2003
【非特許文献２】Matthew Arnold, Stephen Fink, Vivek Sarkar, Peter F. Sweeney, "A comparative study of static and profile-based heuristics for inlining", ACM SIGPLAN Notices, Volume 35 ,  Issue 7  (July 2000), Pages: 52 - 64
【非特許文献３】Xiaotong Zhuang, Mauricio J. Serrano, Harold W. Cain, Jong-Deok Choi, "Accurate, efficient, and adaptive calling context profiling", Conference on Programming Language Design and Implementation Proceedings of the 2006 ACM SIGPLAN
【非特許文献４】"HPROF: A Heap/CPU Profiling Tool in J2SE 5.0",http://java.sun.com/developer/technicalArticles/Programming/HPROF.html
【非特許文献５】Michael D. Bond, Kathryn S. McKinley, "Probabilistic calling context", Conference on Object Oriented Programming Systems Languages and Applications, Proceedings of the 22nd annual ACM SIGPLAN,  Pages: 97 - 112, 2007
【発明の概要】
【発明が解決しようとする課題】
【００２３】
従って、本発明の目的は、動的スクリプト言語処理系のプロファイリングに適合する、呼び出しコンテキストの情報を低コスト且つ網羅的に取得する技法を提供することにある。
【課題を解決するための手段】
【００２４】
この発明によれば、各コールサイトに、所定ビット（好適には８ビット）のＩＤ（ゼロ以外、重複してもよい）を振り、スレッド毎に直近の所定段数（好適には、４段分）のコールサイトＩＤを、好適には３２ビット・データ（本発明では、コール・ヒストリと呼ばれる）として保持し、コンテクスト情報として使用する。
【００２５】
コール・ヒストリを保持する場所として、好適には、メソッド呼び出し時に作られるスタック・フレームに、３２ビットの領域が追加される。
【００２６】
メソッド呼び出し時には、現フレーム内にあるコール・ヒストリが８ビットだけ左シフトされ、下８ビットに、そのコールサイトのコールサイトＩＤを入れて新フレームに積まれる。
【００２７】
メソッドからのリターン時は、フレームが戻るので、コール・ヒストリの値も自動的に戻る。
【００２８】
さらなる改良として、コール・ヒストリをスタック・フレームでなくスレッドごとの固定場所に保持することで、スタック・フレームの消費を抑えることができる。保持する場所としては、例えば、JVMのスレッド構造体中の１フィールドが考えられる。あるいは、専用のレジスタを用意してもよい。
【００２９】
そして、メソッド呼び出し時には、コール・ヒストリ・フィールドを８ビット左シフトし、下８ビットに自分のコールサイトＩＤを入れる。
【００３０】
メソッドからのリターン時は、コール・ヒストリ・フィールドを８ビット右シフトする。すると、最上位部分のコールサイト情報は不明になるが、以下の方法で対応する。
【００３１】
すなわち、コール・ヒストリの値は一部不明のまま放置する。多くの場合はすぐ次のメソッド呼び出しを行うので、それでも問題とならない。
【００３２】
もし、コール・ヒストリの使用時に不明な部分の情報が必要であれば、スタック・トラバースして補充すればよい。
【００３３】
さらに、本発明によれば、仮想呼び出しの飛び先を記録するプロファイリングの表に、実際の飛び先と回数に加えてコール・ヒストリも記録するようにする。すると、ＪＩＴコンパイル時に、その情報をもとにコンテクストに依存した適切な飛び先をインラインすることができる。このとき、ＪＩＴ中のコンテクストと関係ない飛び先情報が排除できればよいので、コールサイトＩＤに重複があっても問題ない。
【００３４】
本発明の一側面によれば、飛び先の分別に必要な分だけの呼び元情報を記録することで表を小さくできる。そして、飛び先が実際に複数になっている場合だけ、飛び先の分離に必要な段数分だけ呼び元コンテクスト情報を記録する。
【発明の効果】
【００３５】
この発明によれば、網羅性を損なうことなく、プロファイリング処理のコストを下げることができる、という効果が得られる。そして、仮想呼び出しの飛び先を記録するプロファイリングの表に、実際の飛び先と回数に加えてコール・ヒストリも記録するようにすることにより、コンテクストに依存したインライニングが可能となる。
【図面の簡単な説明】
【００３６】
【図１】仮想メソッドの呼び出しを説明する図である。
【図２】インライン処理を説明する図である。
【図３】本発明を実施するためのハードウェアの一例のブロック図である。
【図４】機能ブロックのレイヤを示す図である。
【図５】メソッドを呼び出す処理のフローチャートを示す図である。
【図６】メソッドから戻る処理のフローチャートを示す図である。
【図７】コールサイトＩＤの付与、コール・ヒストリの記録、及び対応するプロファイル表を示す図である。
【図８】メソッドをＪＩＴコンパイルする際の追加処理のフローチャートを示す図である。
【発明を実施するための形態】
【００３７】
以下、図面に従って、本発明の実施例を説明する。これらの実施例は、本発明の好適な態様を説明するためのものであり、発明の範囲をここで示すものに限定する意図はないことを理解されたい。また、以下の図を通して、特に断わらない限り、同一符号は、同一の対象を指すものとする。
【００３８】
図３を参照すると、本発明の一実施例に係るシステム構成及び処理を実現するためのコンピュータ・ハードウェアのブロック図が示されている。図３において、システム・バス３０２には、ＣＰＵ３０４と、主記憶（ＲＡＭ）３０６と、ハードディスク・ドライブ（ＨＤＤ）３０８と、キーボード３１０と、マウス３１２と、ディスプレイ３１４が接続されている。ＣＰＵ３０４は、好適には、３２ビットまたは６４ビットのアーキテクチャに基づくものであり、例えば、インテル社のPentium(商標)4、インテル社のCore(商標) 2 DUO、Xeon(商標)、AMD社のAthlon(商標)などを使用することができる。主記憶３０６は、好適には、２ＧＢ以上の容量、より好ましくは、４ＧＢ以上の容量をもつものである。
【００３９】
ハードディスク・ドライブ３０８には、オペレーティング・システムが、格納されている。オペレーティング・システムは、Linux（商標）、マイクロソフト社のWindows(商標) 7、Windows XP(商標)、Windows(商標)2003サーバ、アップルコンピュータのMac OS(商標)などの、ＣＰＵ３０４に適合する任意のものでよい。
【００４０】
ハードディスク・ドライブ３０８にはまた、好適にはApacheなどの、Ｗｅｂサーバとしてシステムを動作させるためのプログラムが保存され、システムの起動時に、主記憶３０６にロードされる。
【００４１】
ハードディスク・ドライブ３０８にはさらに、Java(R)仮想マシン（VM）を実現するためのJava(R) Runtime Environmentプログラムが保存され、システムの起動時に、主記憶３０６にロードされる。
【００４２】
ハードディスク・ドライブ３０８にはさらに、動的スクリプト言語のJava(R)バイトコード生成器４０６、及び、その動的スクリプト言語の書かれたソースコード４１０が保存されている。この実施例における動的スクリプト言語は、Java(R)仮想マシン上で動作する動的スクリプト言語としてのP8及びQuercus、RubyとしてのJRuby、PythonとしてのJython、Groovyなどのうちの任意のものでよいが、特にこの実施例では、典型的にはP8である、PHPのJava(R)バイトコード生成器であるとする。
【００４３】
ハードディスク・ドライブ３０８にはさらに、本発明のインライニング機能を備えたＪＩＴコンパイラ４０８が保存されている。バイトコード生成器４０６及びＪＩＴコンパイラ４０８については、図４に関連して後述する。
【００４４】
キーボード３１０及びマウス３１２は、オペレーティング・システムが提供するグラフィック・ユーザ・インターフェースに従い、ディスプレイ３１４に表示されたアイコン、タスクバー、ウインドウなどのグラフィック・オブジェクトを操作するために使用される。
【００４５】
ディスプレイ３１４は、これには限定されないが、好適には、１０２４×７６８以上の解像度をもち、３２ビットtrue colorのＬＣＤモニタである。
【００４６】
通信インターフェース３１６は、好適には、イーサネット(R)プロトコルにより、ネットワークと接続されている。通信インターフェース３１６は、クライアント・コンピュータ（図示しない）からApacheが提供する機能により、ＴＣＰ／ＩＰなどの通信プロトコルに従い、処理リクエストを受け取り、あるいは処理結果を、クライアント・コンピュータ（図示しない）に返す。
【００４７】
図４において、最下層は、オペレーティング・システム４０２であり、これには限定されないが、この実施例では、Windows（商標）２００３サーバまたはLinux（商標）である。
【００４８】
オペレーティング・システム４０２の上では、オペレーティング・システム４０２に適合するバージョンのJava(R)  VM(JVMとも呼ぶ）４０４が動作する。
【００４９】
Java(R)  VM４０４のレイヤの上では、PHP用Java(R)バイトコード生成器４０６と、本発明に係るＪＩＴコンパイラ４０８が動作する。
【００５０】
PHPソースコード４１０は、ハードディスク・ドライブ３０８に保存され、周知のように、<?php 〜 ?>で記述されるステートメントを含み、拡張子phpをもつファイルである。ネットワークを介してクライアント・コンピュータ（図示さない）から受け取ったリクエストに応答して、PHP用Java(R)バイトコード生成器４０６が、指定されたPHPソースコード４１２を解釈実行して、バイトコードを生成する。
【００５１】
ＪＩＴコンパイラ４０８は、PHP用Java(R)バイトコード生成器４０６が生成したバイトコードに対して、後述する処理により適宜メソッド・インライン化することによって、より最適化された、ＣＰＵ３０４にネイティブな実行可能コードに変換する。
【００５２】
ＪＩＴコンパイラ４０８の機能は、本発明に従う機能により一旦メソッド・インライン的に最適化した後、ＣＰＵ３０４とオペレーティング・システム４０２にネイティブな実行コードに変換することである。
【００５３】
次に、図５のフローチャートを参照して、ＪＩＴコンパイラ４０８の機能によって、プロファイル表を作成する処理について説明する。
【００５４】
この処理を行うにあたって、ＪＩＴコンパイラ４０８は予め、例えば、下記のような計装コードを、バイトコード生成器４０６によって生成されたバイトコードの呼び出し(call)位置に挿入する。
void m(int call_history, int a, int b) {
int c = ...;
int d = ...;
n((call_history<<8)|CALLSITE_ID_1, c, d); // 新しいコール・ヒストリ(call_history)を計算し，第１引数として渡す
:
}
void n(int call_history, int c, int d) { ... }
このようなコードを埋め込まれたバイトコードを、所定期間Java(R) VMの下で実行することにより、プロファイル表が記録される。図５のフローチャートに示す処理は、主として、そのようなプロファイル表の記録処理に関する。
【００５５】
ステップ５０２では、ＪＩＴコンパイラ４０８は、呼び出しがあったとき、仮想呼び出し、すなわち仮想メソッドの呼び出しかどうか判断する。
【００５６】
もしそうなら、ＪＩＴコンパイラ４０８は、ステップ５０４で、上述の挿入したコードにより、確定した飛び先情報と、コール・ヒストリと呼び出し回数を、呼び出し地点（コールサイト）のプロファイル表に記録する。そうでないなら、ステップ５０４はスキップされる。
【００５７】
飛び先地点のプロファイル表に関して、好適には、飛び先の分別に必要な分だけの呼び元情報を記録することで表への記録量が節約される。すなわち、飛び先が実際に複数になっている場合だけ、飛び先の分離に必要な段数分だけ呼び元コンテクスト情報を記録する。
【００５８】
さらに好適には、サイズがある閾値より大きいメソッドだけをコンテクスト情報収集の対象にし、プロファイリングの表に記録するようにする。というのは、小さいメソッドは最終的には別のメソッドにインラインされてしまうので、情報収集しなくてもよいからである。さらに、サイズの小さいメソッドの情報は、前述のMichael D. Bond, Kathryn S. McKinley, "Probabilistic calling context", Conference on Object Oriented Programming Systems Languages and Applications, Proceedings of the 22nd annual ACM SIGPLAN,  Pages: 97 - 112, 2007に記載されているのと同様の方式で、局所的に縮退させてもよい。
【００５９】
ステップ５０６では、ＪＩＴコンパイラ４０８は、呼び出し地点のコールサイトＩＤを取得する。コールサイトＩＤは、0以外の乱数でもよいし、コールサイトのアドレスの適当な８ビットを使用してもよい。また、コールサイト間での多少の値の重複も許される。但し、コールサイトから一意的に決まること、すなわち、同じコールサイトは、何度計算しても同じＩＤの値になるこという条件は必要である。また、狭い範囲に値が集まらず、適度に値がばらけていることが望ましい。
【００６０】
ステップ５０８では、ＪＩＴコンパイラ４０８は、新しいコール・ヒストリを、現在のコール・ヒストリを８ビット左にシフトし、取得したコールサイトＩＤを下位８ビットに入れることで計算する。
【００６１】
ステップ５１０では、ＪＩＴコンパイラ４０８は、新しいコール・ヒストリを、スタック・フレームにプッシュする。
【００６２】
ステップ５１２では、通常の処理により、メソッドの呼び出しが行われる。
【００６３】
なお、ここでの説明は、ＪＩＴコンパイラ４０８および、それによって埋め込まれたコードがプロファイル計装を行うとしたが、実際は、Java(R) VM４０４内のバイトコード・インタープリタが処理を行うことも可能である。
【００６４】
図６は、メソッドから戻る(return)する時の処理を示す。すなわち、ステップ６０２に示すように、メソッドから戻ると、スタック・フレームが戻されて、元のコール・ヒストリが見えるようになる。
【００６５】
図７は、x.addの呼び出しに関連して、コールサイトにコールサイトＩＤが付与されている様子と、それに伴ってx.addに対する飛び先、コール・ヒストリ、及び回数がプロファイル表７０２に記録が行われる処理を模式的に示す。この実施例では、コール・ヒストリは３２ビットであるけれども、図７に示すように、飛び先の分別に必要な分だけ、すなわち、この場合、２バイトしか記録されていない。このような処理によって、プロファイル表の記録サイズを節約することができる。プロファイル表７０２は、主記憶３０６の適当な領域、例えば、ヒープ領域に、コールサイト毎に記録される。
【００６６】
図８は、ＪＩＴコンパイラ４０８がメソッドをコンパイルする時の追加処理のフローチャートを示す図である。
【００６７】
ステップ８０２では、ＪＩＴコンパイラ４０８が、インラインしたコード中の仮想メソッドを順に調査し、全て調査したなら処理を終了し、そうでないなら、ステップ８０４に進み、そこで、呼び出し地点のプロファイル表から、コール・ヒストリの情報が現在のコンパイル情報、すなわち、呼び出し順のコールサイトＩＤの並びとマッチするエントリのみを抜き出す。ここでのマッチは、プロファイル表に記録されているコール・ヒストリのバイト数分、マッチすればよい。
【００６８】
そのマッチの結果、ステップ８０６で、仮想メソッドの飛び先がほぼ一意的に決まる、すなわち、コール・ヒストリがマッチするエントリが単一である、あるいは、マッチするエントリが複数あっても、プロファイル表に記録された回数の偏りから、回数が大きいエントリを選ぶことができる。
【００６９】
もしステップ８０６で、仮想メソッドの飛び先が決まらないと判断されると、処理は、ステップ８０２に戻る。
【００７０】
ステップ８０６で、仮想メソッドの飛び先がほぼ一意的に決まるなら、ステップ８０８で、ＪＩＴコンパイラ４０８は、そうやって決められた飛び先を、ガード付きでインラインする。尚、「ガード付きインライン」とは、条件が成立しているか実行時にチェックするガードコードを付けてインラインすると言う意味である。例えばプロファイルにより、「ほぼ99%はDInt型である」ということが分かったとしても、確実ではないので、本当にそうかどうかを調べるガードをつける。これは、従来技術でも、インライニングでも行われている処理である。そのようなコードの例を以下に示す。
funcA() {
x = ...;
y = ...;
// Handler_add(x, y) 以下の処理をインラインしたコード
if (x instanceof DInt) // ガード
z = x.intValue + y.intValue;    // DIntの場合のインラインされたコード
else
z = x.add(y); // 仮想呼び出しを行う
:
}
【００７１】
以上、本発明を、Java(R) VM上で動作するＪＩＴコンパイラにおいてインライニングする処理を例にプロファイル計装処理を説明したが、これには限定されず、一般のプロファイル計装に適用可能である。
【００７２】
また、上記実施例では、コール・ヒストリを３２ビットとし、コール・ヒストリの段を構成するコールサイトＩＤを８ビットとしたが、これには限定されず、ＣＰＵのアーキテクチャなどに応じて、任意のビット数及び段数を採用することができる。
【００７３】
さらに、上記実施例では、コール・ヒストリをスタック・フレームに記録するようにしたが、スレッド構造体中の１フィールド、または専用レジスタに格納してもよい。
【符号の説明】
【００７４】
３０４  ＣＰＵ
３０６  主記憶
３０８  ハードディスク・ドライブ
４０２  オペレーティング・システム
４０６  バイトコード生成器
４０８  ＪＩＴコンパイラ
７０２  プロファイル表
【図１】
0005496849.tif 000002
【図２】
0005496849.tif 000003
【図３】
0005496849.tif 000004
【図４】
0005496849.tif 000005
【図５】
0005496849.tif 000006
【図６】
0005496849.tif 000007
【図７】
0005496849.tif 000008
【図８】
0005496849.tif 000009