動的にコンパイルされる関数は、プログラムの実行中にコンパイルされてリンクされる関数です。コレクタ API 関数 collector_func_load() を使用して必要な情報をユーザーが提供しないかぎり、コレクタは C や C++ で記述された動的にコンパイルされる関数に関する情報を持っていません。「関数」タブ、「ソース」タブ、「逆アセンブリ」タブに表示される情報は、次のように、collector_func_load() に渡される情報によって異なります。
情報が提供されていない場合、つまり collector_func_load() が呼び出され ていない場合は、動的にコンパイルされて読み込まれた関数が、関数リストに <Unknown> として表示されます。関数ソースも逆アセンブリコードも、アナライザには表示されません。
ソースファイル名と行番号のテーブルが提供されていない場合に、関数の名前、サイズ、およびアドレスが指定されている場合は、動的にコンパイルされて読み込まれる関数の名前とそのメトリックが関数リストに表示されます。注釈付きソースは利用可能で、逆アセンブリ命令は表示できます。ただし、行番号は、未知であることを示すために [?] で示されます。
ソースファイル名を指定して、行番号テーブルを提供しないと、アナライザによって表示される情報は、ソースファイル名を指定しない場合と似ています。ただし、注釈付きソースの先頭には、関数が行番号のない命令で構成されていることを示す特別なインデックス行が表示されます。次に例を示します。
1.121 1.121 <関数 func0, 行番号なしの命令> 1. #include <stdio.h> |
ソースファイル名と行番号のテーブルが提供されている場合、関数とそのメトリックは、従来の方法でコンパイルされた関数と同じように、「関数」タブ、「ソース」タブ、および「逆アセンブリ」タブに表示されます。
コレクタ API 関数の詳細については、「動的な関数とモジュール」を参照してください。
Java プログラムでは、ほとんどのメソッドが JVM ソフトウェアによってインタプリタされます。別個のスレッドで動作する Java HotSpot 仮想マシンは、インタプリタの実行中にパフォーマンスを監視します。監視プロセス中仮想マシンは、1 つ以上のインタプリタを行なっているメソッドを取り出し、それらのメソッド用のマシンコードを生成し、元のマシンコードをインタプリタするのではなくさらに効率の良いマシンコードバージョンを実行することを決定する場合があります。
次の例に示すように、Java プログラムの場合は、コレクタ API 関数を使用する必要はありません。アナライザは、メソッドのインデックス行の下の特別な行を使って、注釈付き逆アセンブリリストでの Java HotSpot がコンパイルしたコードの存在を示します。
11. public int add_int () { 12. int x = 0; <関数: Routine.add_int()> 2.832 2.832 Routine.add_int() <HotSpot コンパイル済みリーフ命令> 0. 0. [ 12] 00000000: iconst_0 0. 0. [ 12] 00000001: istore_1 |
逆アセンブリリストには、コンパイルされた命令ではなく、インタプリタされたバイトコードのみが示されます。デフォルトでは、コンパイルされたコードのメトリックは、特別な行の隣りに表示されます。排他的および包括的 CPU 時間は、インタプリタされたバイトコードの各行に示されているすべての包括的および排他的 CPU 時間の合計とは異なります。通常は、何回かメソッドが呼び出されると、コンパイルされた命令の CPU 時間は、インタプリタされたバイトコードの CPU 時間の合計より多くなります。なぜなら、インタプリタされたコードは、メソッドが最初に呼び出されたときに一度だけ実行されるのに対し、コンパイルされたコードはその後も実行されるからです。
注釈付きソースには、Java HotSpot でコンパイルされた関数は表示されません。その代わりに、行番号なしで命令を示す特別なインデックス行が表示されます。たとえば、前述の逆アセンブリの抜粋に対応する注釈付きソースは、次のようになります。
11. public int add_int () { 2.832 2.832 <関数: Routine.add_int(), 行番号なしの命令> 0. 0. 12. int x = 0; <関数: Routine.add_int()> |