JP3813019B2 - プログラム処理方法、指定メソッドに関連するフレームを検出する方法、及び記憶媒体 - Google Patents
プログラム処理方法、指定メソッドに関連するフレームを検出する方法、及び記憶媒体 Download PDFInfo
- Publication number
- JP3813019B2 JP3813019B2 JP12702498A JP12702498A JP3813019B2 JP 3813019 B2 JP3813019 B2 JP 3813019B2 JP 12702498 A JP12702498 A JP 12702498A JP 12702498 A JP12702498 A JP 12702498A JP 3813019 B2 JP3813019 B2 JP 3813019B2
- Authority
- JP
- Japan
- Prior art keywords
- inlining
- code
- call
- program
- executed
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Expired - Fee Related
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/44—Arrangements for executing specific programs
- G06F9/448—Execution paradigms, e.g. implementations of programming paradigms
- G06F9/4488—Object-oriented
- G06F9/449—Object-oriented method invocation or resolution
- G06F9/4491—Optimising based on receiver type
Landscapes
- Engineering & Computer Science (AREA)
- Software Systems (AREA)
- Theoretical Computer Science (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Devices For Executing Special Programs (AREA)
Description
【発明の属する技術分野】
本発明は、コンパイラにおけるメソッド・インライニングに関し、特に、Java(Sun Microsystemsの商標)JIT(Just In Time)コンパイラ等におけるメソッド・インライニングに関する。
【0002】
【従来の技術】
Javaは言語にセキュリティ・チェック機能を有しており、SecurityManagerクラスに以下に示す5つのメソッドを含んでいる。
(1)getClassContext
スタック上の各フレームに対応するメソッドの属するクラスを配列として返すメソッドである。フレームは、メソッドを実行する際に生成される、当該メソッドに関する情報が記憶される記憶領域である。
(2)currentClassLoader
スタック上のフレームに対応するメソッドの属するクラスで、クラスローダーを有する最新のクラスのクラスローダーそれ自体を返す。クラスローダーとは、まだロードされていないクラスをロードするために使用するメソッド群を有するクラスである。最新とは、最も最近に実行された、ということである。
(3)currentLoadedClass
スタック上のフレームに対応するメソッドの属するクラスで、クラスローダーを有する最新のクラスを返す。
(4)currentDepth
指定したクラスと同じクラスに属する最新のメソッドに対応するフレームの、スタックにおける深さを返す。
(5)classLoaderDepth
クラスローダーを有する最新のクラスに属するメソッドに対応するフレームのスタックにおける深さを返す。
【0003】
これらのメソッドは、スタック上をトレースし必要な情報を獲得する。一方、メソッド・インライニングは、メソッド呼び出しの除去を目的として、実行時にメソッドを呼び出す代わりにコンパイル時に呼び出し側のメソッドのコードを呼び出し元に取り込んでしまうものである。このため、実行時にスタック上には、インライニングされてしまったメソッドの実行情報は生成されなくなる。もし、インライニングされたメソッドのコード中、又はそのメソッドから呼ばれるメソッド中にSecurityManagerクラスのメソッドが含まれていると、それらが正しい結果を返さずにプログラムの挙動が変わってしまうかもしれないという問題が発生する。従って、従来は末端までの呼び出し関係が完全に見切れており、且つそれらのメソッド呼び出しの中にSecurityManagerクラスのメソッドへの呼び出しが含まれていないことが保証されている場合しか、メソッド・インライニングを実行できなかった。
【0004】
Javaなどのオブジェクト指向言語では、メッセージを容易にオーバーロード可能である。そのためモジュールとしての再利用性や柔軟性は高いものの、前述のような保証ができるような解析をコンパイラが行うことはほとんど困難である。Javaでは特殊なメソッドにファイナル(final)という記述子を付けることを許している。このfinalは、末端にあってオーバーロードされないという意味である。一般的に用いられるバーチャル(virtual)メソッド呼び出しは、final属性を伴わないとオーバーライドされる可能性があるため、呼び出し先コードを特定できない。では、final属性を基にメソッド・インライニングを実施すればよいかというと、(a)一般のプログラマがfinal属性を用いることはまれであって、(b)たとえプログラムの作者自身がオーバーライドされないメソッド呼び出しであると認識していても、多くの場合final属性による明示的な指示がなされていない、という現状からして、それだけではメソッド・インライニングが適用できる範囲は限られてしまう。
【0005】
なお、"呼び出し関係が完全に見切れるメソッド呼び出し"とは、呼び出されるメソッドがネイティブ・メソッド(native method)ではなく、且つ、スタティック(static)呼び出し、非バーチャル(non-virtual)呼び出し、又はfinal属性のついたvirtualメソッド呼び出しのいずれかで呼び出されるメソッド呼び出しを意味する。nativeメソッドとは、C言語等Java以外の言語で書かれ且つコンパイル済のコードで構成されるメソッドである。また、static呼び出しとは、(static)という記述子を付けて定義されたメソッド(static メソッド)に対する呼び出しである。staticメソッドは、オブジェクトを使用せずに呼び出すメソッドであり、他のメソッドによりオーバーロードされることはない。従って、static呼び出しでは常に実行されるメソッドを一意に決定することができる。
【0006】
【発明が解決しようとする課題】
よって、本発明の目的は、Javaのようなセキュリティ機能を有する言語においてメソッド・インライニングによる実行最適化の適用範囲を増大させることである。
【0007】
さらに、メソッド・インライニングをJavaのJIT(Just In Time)コンパイラにおいて可能にすることも目的である。
【0008】
また、メソッド・インライニングを実施する際に、メソッド・インライニングを実施しない場合のスタック情報を再現できるようにすることも目的である。
【0009】
Javaのような言語において、呼び出された後の処理が不確定なメソッドの呼び出し及び自己再帰を含むメソッドに対し、テイル・リカージョン(Tail Recursion)によるループ化を可能にすることも目的である。
【0010】
さらに、当該ループ化において繰り返し数を把握できるようにすることも目的である。
【0011】
メソッド・インライニングを実施した場合に、メソッド・インライニング前のメソッド間の呼び出し関係を保存できるようにすることも目的である。
【0012】
メソッド・インライニングを実施した場合に、どのメソッドのコードを実行しているか判断できるようにすることも目的である。
【0013】
【課題を解決するための手段】
以上の目的を達成するために、本発明には以下のような態様がある。
第1の態様においては、呼び出された後の処理が不確定なメソッドの呼び出し及び自己再帰を含むメソッドに対し、テイル・リカージョン(テイル・リカージョンは末尾再帰状態をあらわす)のループ化に必要なコードを生成するステップと、ループの繰り返し数をカウントするためのコードを生成するステップとを含む。このようなコードを含むプログラムを実行すれば、ループの繰り返し数をカウントできるので、SecurityManagerの動作時にスタックの深さを補正できる。よって、Javaのような言語においてもテイル・リカージョンのループ化で最適化を図ることができる。
【0014】
上記ループの繰り返し数をカウントするためのコードを生成するステップは、プログラム実行時にスタック上に作業領域を生成するステップを含むようにすることができる。また、ループの繰り返し数のカウントを初期化するコードをループ化に必要なコードの前に生成することも考えられる。さらに、SecurityManagerの動作時に本処理が実施されていることを簡単に検出できるように、ループ化に必要なコードの生成を表すフラグをセットするステップを含むようにすることも考えられる。
【0015】
一方、呼び出された後の処理が不確定なメソッドの呼び出し及び自己再帰を含み、テイル・リカージョンのループ化に必要なコードと当該ループの繰り返し数をカウントするためのコードとを含む第1メソッドを含むプログラムの実行時に、実行した各メソッドに関する情報を対応フレームとして格納した記憶領域における、所定の条件を満たす指定メソッドに関連するフレームの深さを検出するために、SecurityManagerは、記憶領域内の現在検査中のフレームに関連する第2メソッドが指定メソッドであるか判断するステップと、第2メソッドが指定メソッドでない場合には、第2メソッドが第1メソッドであるか判断するステップと、第2メソッドが第1メソッドである場合、ループの繰り返し数をカウントするためのコードによるカウント値を用いて、第2メソッドに関連するフレームの記憶領域における深さを検出するステップとを実行する。これにより、テイル・リカージョンによるメソッド・インライニングが実施されても、何等の影響を受けなくなる。カウンタ値により補正を実施することにより、インライニングを実施しない場合のスタック情報を再現できる。
【0016】
また、第2メソッドが指定メソッドであって、当該指定メソッドに関連するフレームを検査するまでに第1メソッドに関連するフレームを検査していた場合には、第1メソッドのカウント値により補正された、記憶領域の最初のフレームから第2メソッドに関連するフレームまでの深さを返すステップをさらに実行する。前段落よりさらにスタックを深くトレースした場合の処理である。
【0017】
さらに、第2メソッドが第1メソッドでない場合、深さを1加算し、第2メソッドを次のフレームに関連するメソッドに変更するステップをさらに実行する場合がある。スタックのトレースは、指定メソッドが検出されるまで又は全てのスタックのフレームをトレースし終えるまで実行される。
【0018】
なお、第1メソッドがループ化に必要なコードを含んでいることを表すフラグを含んでいる場合には、第2メソッドが第1メソッドであるか判断する時に、当該フラグの有無を検査すればよい。
【0019】
本発明の第2の態様は、呼び出された後の処理が不確定な第1メソッドの呼び出しを含む第2メソッドに第1メソッドのコードをインライニングするステップと、第1メソッドのコードをインライニングする前の状態における、第1メソッドと第2メソッドの呼び出し関係を取得して、後に使用可能な記憶域に格納するステップと、インライニングされた第1メソッドのコードを実行する際に、第1メソッドを実行中であることを記憶するためのコードを生成するステップとを含む。よって、SecurityManagerの動作時には、メソッド・インライニング前のメソッド間の呼び出し関係及びどのメソッドのコードを実行しているか判断できるようになり、メソッド・インライニングによる実行最適化の適用範囲を増大させることができる。
【0020】
第1メソッドと区別するために、インライニング前から第2メソッドに含まれるコードを実行する際に、第2メソッドを実行中であることを記憶するためのコードを生成するステップをさらに含むようにすることもできる。さらに、第1メソッドと第2メソッドの呼び出し関係は、第1メソッドに関する項目に第2メソッドに関する項目を指すポインタを含むようにすることも考えられる。
【0021】
一方、複数のメソッドを含むプログラムであって、呼び出された後の処理が不確定な第1メソッドの呼び出しを含む第2メソッドに、メソッド・インライニングによる第1メソッドのコードと、インライニングされた第1メソッドのコードを実行する際に、第1メソッドを実行中であることを記憶するためのコードとを含み、第1メソッドのコードをインライニングする前の状態における、第1メソッドと第2メソッドの呼び出し関係を含む、上記プログラムの実行時に、実行した各メソッドに関する情報を対応フレームとして格納した記憶領域において、所定の条件を満たす指定メソッドに関連するフレームを検出するために、SecurityManagerは、記憶領域内の現在検査中のフレームに関連する第3メソッドが第2メソッドであるか判断するステップと、第3メソッドが第2メソッドである場合には、第2メソッドに関連する呼び出し関係を取得するステップと、呼び出し関係中の第3メソッドの対応項目を取得するステップと、呼び出し関係中の第3メソッドの対応項目を用いて、第3メソッドの呼び出し元メソッドを取得するステップと、呼び出し元メソッドが指定メソッドであるか判断するステップとを実行する。これにより、メソッド・インライニングが実施されても、メソッド・インライニングを実施しない場合のスタック情報を再現できるようなったので、メソッド・インライニングの影響を除去できた。
【0022】
また、呼び出し元メソッドが指定メソッドでなかった場合には、呼び出し関係中の呼び出し元メソッドの対応項目から、さらなる呼び出し元メソッドを取得するステップを実行する場合もある。スタックのトレースは、第1の態様と同じで、指定メソッドが検出されるまで又は全てのスタックのフレームをトレースし終えるまで実行される。
【0023】
なお、本発明の第1の態様及び第2の態様は、共に、JITコンパイラがJavaのバイトコードに対して実施することを念頭にしているが、JITコンパイラ内の中間コード等に対して実施することも可能である。また、他の言語であれば、通常のコンパイラで、プログラマの書いたプログラムに対して実施することも考えられる。
【0024】
以上本発明の処理のフローを説明したが、本発明はこれらの処理を実施する装置や、コンピュータにこれらの処理を実施させるプログラムの形態によっても実現可能である。このプログラムを、フロッピー・ディスクやCD−ROM等の記憶媒体又は他の形態の記憶装置に格納することは、当業者が普通に行う事項である。
【0025】
【発明の実施の形態】
本発明の装置構成を図1を用いて説明する。サーバ・コンピュータ1及びクライアント・コンピュータ5はネットワーク3を介して接続されている。クライアント・コンピュータ5は、JavaVM(Virtual Machine)52及びOS(Operating System)53及びハードウエア(CPU及びメモリを含む)55を含む。さらに、JavaVM52は、Javaインタープリタ54又はJava JITコンパイラ56、及びセキュリティ・マネージャ(SecurityManager)60を含む。インタープリタ54及びJITコンパイラ56の両者を有している場合もある。なお、クライアント・コンピュータ5は、通常のコンピュータの他、メモリの大きさが小さかったり、ハードディスク等の補助記憶装置を含まないような、いわゆるネットワーク・コンピュータや情報家電の場合もある。
【0026】
サーバ・コンピュータ1では、Javaソースコード10は、Javaコンパイラ12によりコンパイルされる。このコンパイルの結果が、バイトコード14である。このバイトコード14は、ネットワーク3を介してクライアント・コンピュータ5に送信される。バイトコード14は、クライアント・コンピュータ5内のWWWブラウザ(World Wide Web Browser)などに設けられたJava仮想マシン(Java VM)52にとってネイティブ・コードであり、実際ハードウエア55のCPUにて実行する場合には、Javaインタープリタ54や、JavaJITコンパイラ56を用いる。インタープリタ54は、実行時にバイトコード14をデコードし、命令ごとに用意される処理ルーチンを呼び出して実行する。一方、JITコンパイラ56は、バイトコードを事前にあるいは実行する直前にコンパイラを用いてマシン・コード58に変換してそれをCPUで実行する。
【0027】
本発明は、図1におけるJITコンパイラ56の処理に関する。以下、例を用いて処理のフローを説明する。
(1)実施例1(Tail Recursionによるループ化を実施する場合)
表1にサンプル・プログラムを示す。但し、実際にはバイトコードに関して処理は実行されるが、バイトコードでは分かりにくいので、以下のような擬似コードにて表す。
【表1】
10: class test {
20: public final int f( int x )
30: {
40: if ( x==0) {
50: return 0;
60: } else
70: h(x);
80: return f(x-1);
90: }
100: }
110: public void h( int x )
120: {
130: ......
140: }
150: }
なお、行番号は説明のためだけに付けてある。
【0028】
表1のサンプル・コードは、final属性を有するメソッドf(第20行乃至第100行)と、メソッドfから呼び出され(第70行)、final属性が付されていないメソッドh(第110行乃至第140行)が示されている。メソッドfにおいては、さらに自己再帰することが示されている(第80行)。
【0029】
これを従来手法に従って、テイル・リカージョンのループ化を実施すると、以下のようになる。
【表2】
第230行と第280行にテイル・リカージョンのループ化に必要なコードが生成された。
【0030】
表1を実行した場合には、図2のようなフレームがスタック上に生成される。すなわち、ステップ1ではメソッドfについてのフレームが1つ生成され、ステップ2ではメソッドhのフレームが1つ生成される。ポインタは前のメソッドfを指す。さらに、ステップ3では、メソッドhの実行が終了して再帰的にメソッドfを呼ぶので、メソッドhのフレームは消えて、メソッドfのフレームがもう一つできる。ポインタは前のメソッドfのフレームを指す。再帰的に呼ばれたメソッドfはその中でメソッドhを呼ぶので、ステップ4ではメソッドhのフレームが生成され、そのポインタはその前のメソッドfのフレームを指す。メソッドhの実行が終わると、メソッドhのフレームは消えて、メソッドfを再度再帰的に呼ぶ。これによりステップ5におけるメソッドfのフレームが生成される。ポインタは自身を呼び出したメソッドfのフレームを指す。さらに、再帰的に呼び出したメソッドfはその中でメソッドhを呼び出すので、このメソッドhのフレームが生成される。ポインタは呼び出したメソッドfを指す。このように、表1を実行した場合には、メソッドfのフレームが次々に生成されていく形となる。
【0031】
一方、表2を実行した場合には、図3のようなフレームがスタック上に生成される。すなわち、ステップ1ではメソッドfについてのフレームが1つ生成され、ステップ2ではメソッドhのフレームが1つ生成される。ポインタは前のメソッドfを指す。さらに、ステップ3では、メソッドhの実行が終了して、メソッドhのフレームが消去される。この時、もう新たにメソッドfは呼び出されないので、新たなフレームは生成されない。ステップ4では、新たな繰り返しでメソッドhが呼び出されるので、メソッドhのフレームが再度生成される。そして、メソッドhの実行が終了すれば、そのフレームは消去される(ステップ5)。また、新たな繰り返しでメソッドhが呼び出されれば、メソッドhのフレームが生成される(ステップ6)。
【0032】
このように、図2と図3とを比較するとステップ3以降スタック情報は異なるので、もし、メソッドhにおいてSecurityManagerクラスの例えばcurrentDepthメソッドが呼び出された場合には、ステップ3以降であれば、返されるスタックの深さの値は当然異なる。
【0033】
実施例1では、この差異を埋めるために、JITコンパイラにおいては以下の処理を実施する(図4)。まず、以下の説明のため、用語を定義しておく。
cb(class block):Javaのクラス情報を表す構造体へのポインタ。クラスに属する全てのメソッド情報(下記)を参照することができる。
mb(method block):Javaのメソッド情報を表す構造体へのポインタ(methodblock)。メソッドの属するクラスのcbへのポインタを有する。
mb-<CompiledCode:コンパイルされたコードの先頭アドレスを設定する領域
mb-<CompiledCodeInfo:メソッドに対するフラグを設定する領域
【0034】
まず、表2に示したように、テイル・リカージョンのループ化に必要なコードを生成する(ステップ1020)。そして、本処理が実施されていることを表すために、mb-<CompiledCodeInfoにフラグを立てる(ステップ1030)。そして、ループの繰り返し回数をカウントするために、ローカル変数(ここでは変数1とする)領域を1つ増やす(ステップ1040)。ローカル変数領域はスタック上に確保されるので、自動的にスタック上に作業領域を一つ確保したことになる。さらに、ループの戻り点より前に変数1を−1で初期化するためのコードと、戻り点より後に変数1を1インクメントするコードを生成する(ステップ1050)。ここでフレームとはプログラム実行時に各メソッドの実行毎にその実行コンテキストに対応して生成される作業領域である。スタックは通常計算機の実行環境で作業領域を提供する手法の一つである。コンパイルされたコードの実行では、通常フレームはスタック上に割り当てられる。バイトコードで表現すると、以下のようになる。
【表3】
プログラムの開始点:
iconst_m1
istore >変数1<
ループの戻り点:
iinc >変数1< 1
iconst_m1で−1をスタックに積んで、istoreで−1を変数1に格納したことを表す。iincは変数1を1インクメントすることを表す。
【0035】
発明を分かりやすくするために、表2からどのように変換されるかを表4に示す。
【表4】
第430行及び第450行にステップ1050(図4)で生成されたコードに対応するものが表されていることが分かる。
【0036】
図4の処理がなされ、必要なコンパイル処理が実施されると、マシン・コード58が生成されるので、このマシン・コード58をCPUにて実行する。マシン・コード58実行時には、オリジナル(表1)のプログラムでメソッドhが呼び出された時のメソッドfの再帰呼び出しされた回数(スタックの深さ)が変数1によりカウントされる。
【0037】
次に、SecurityManagerのスタック・トレース時の動作を説明する。最初に、表1のコードのままである場合の、SecurityManagerの処理フローを表5に示す。
【表5】
まず、フレームからメソッド情報を取り出し、メソッド・ブロックからクラスが取得する。もし、このクラスが目的のクラス(指定されたクラス)である場合には、SecurityManagerの処理を実施する。一方、目的のクラスでない場合には、深さ(depth)値をインクメントして次のフレームについて処理を繰り返す。
【0038】
では、本発明のSecurityManagerでは、以下のような処理を実施することにより、深さ値を補正する。
【表6】
表5と異なるのは、cbが目的のクラスでなければ、mb-<CompiledCodeInfoにフラグが設定されているか、すなわち本発明が実施されているかどうかを判断し、もしフラグが設定されている場合には、Tail Recursionにより増加しなくなったスタックの深さの値を補正する(depth += 変数1)部分である。このようにカウントしていた値(変数1)を用いて通常のトレースでカウントされた深さ値を補正することにより、図2と図3の差を埋めることができる。
【0039】
(2)実施例2(テイル・リカージョン以外のvirtualメソッド・インライニングの場合の処理)
表7にサンプル・プログラムを表す。擬似コードである点は変わらない。
【表7】
600: class test{
610: public void f ( int x )
620: {
630: for ( int i=0; i>x; i++ ){
640: g(i);
650: h(i);
660: }
670: }
680: public final void g ( int x )
690: {
700: h( x*x );
710: h( x+x );
720: }
730: public void h ( int x )
740: {
750: ........
760: }
770: }
行番号は以下の説明のためだけに付されている。
【0040】
表7のサンプル・プログラムでは、メソッドgはfinal属性が付されているのでこれ以上オーバーライドされないため、メソッドgに対する呼び出しの際には必ずメソッドgが実行される。一方、メソッドhはfinal属性が付されていないvirtualメソッドであるため、実際に実行されるメソッドをコンパイル時には特定できない。よって、従来ではこのようなプログラムに対してメソッド・インライニングを実施できなかった。
【0041】
表8に、メソッド・インライニングを実施した後のプログラムを示す。
【表8】
800: class test{
810: public void f ( int x )
820: {
830: for ( int i=0; i>x; i++ ){
840: h( i*i );
850: h( i+i );
860: h(i);
870: }
880: }
890: public void h ( int x )
900: {
910: ........
920: }
930: }
第840行及び第850行がメソッド・インライニングにより埋め込まれたコードである。
【0042】
では、この表7を実行した場合のスタックのフレーム状況を図5に示す。第610行が実行されると(ステップ1)、メソッドfのフレームが生成される。第640号が実行されると(ステップ2)、メソッドgのフレームが生成される。メソッドgは、メソッドhを呼ぶので、メソッドhのフレームが生成される(ステップ3)。第700行の分のメソッドhが実行されると、一度メソッドhのフレームは消滅するが、第710行の分のメソッドhが実行されるので、再度メソッドhのフレームが生成される(ステップ4)。第710行分のメソッドhが実行されると、メソッドgの実行が終了するので、メソッドgのフレームは消滅する。その後メソッドfにおいてメソッドhが呼び出されるので、メソッドhのフレームが生成される(ステップ5)。
【0043】
一方、表8を実行した場合のスタックのフレーム状況を図6に示す。最初のステップ1は同じであるが、表7ではメソッドgは存在しないので、いきなりメソッドhが呼ばれる(第840行)。そして、メソッドhのフレームが生成される(ステップ2)。以降、第850行のメソッドhの実行、第860行のメソッドhの実行に合わせて、ステップ3及びステップ4の状態になる。
【0044】
図5及び図6を参照すれば、メソッドgに関するフレームが生成されないことが分かる。メソッドgを実行している中で呼ばれたメソッドhでSecurityManagerが呼ばれるかもしれない。この場合、インライニングする前と同じ結果を返さない。
【0045】
そこで図7のような処理をJITコンパイラは実行する。最初に、本発明の処理を実行していることを示すために、mb-<CompiledCodeInfoにフラグを設定する(ステップ1120)。次に、インライニング処理を実行する(ステップ1130)。この際、末端まで呼び出し関係が見切れていないメソッド呼び出しを検出する。このメソッド呼び出しは、各メソッド呼び出しに対してインライニング処理を再帰的に行うことで検出可能である。すなわち、メソッド呼び出しを含まない末端のメソッドまで到達できたかどうかで判断できる。例えば、表8のプログラムでは、virtualメソッドとしてメソッドhが3つ存在していることが分かる。
【0046】
そして、このステップ1130により検出されたメソッド呼び出しに関する呼び出し関係情報を作成し、格納する(ステップ1140)。この呼び出し関係情報は、例えば図8のようなものである。識別番号は、メソッド・インライニングのベースとなるメソッド及びインラインされた各メソッドに対し一意に設定する。ここでは、インラインを行うベースとなるメソッドを根とし、インラインされたメソッドをノードとし、それらの間のメソッドの呼び出し関係をリンクとする木構造において、根から順に深さ優先探索(depth first search)を行って、後順(postorder)で0から1ずつインクリメントしながら値を設定する。そして、各行は、それぞれを呼び出したメソッドのメソッド・ブロックmbと、本呼び出し関係情報における、呼び出し元メソッドを表す要素へのポインタを保持している。そして、最終的には、インラインを行うベースとなるメソッド・ブロックmbと、nullが格納される。表8の例では、呼び出し関係を見切れないvirtualメソッドとして、メソッドhの呼び出しが3つ存在している(第840行乃至第860行)。第840行及び第850行の呼び出しは、メソッドgからの呼び出しがインライニングされたもので、第860行の呼び出しはメソッドf自身からの呼び出しである。よって、インライニングを行うベースとなるメソッドはメソッドfであり、インライニングされたメソッドはメソッドgである。これを後順にすると、メソッドgが識別番号0で、メソッドfが識別番号1となる。以上から、表8の呼び出し関係情報は、以下のようになる。
0:{メソッドgのmb,配列要素1のアドレス}
1:{メソッドfのmb,null}
【0047】
なお、この配列の先頭アドレスを、コンパイルされたコードの直前に格納する。メソッド・ブロックmbからこの配列へのアクセスは、例えば*(((long *)(mb-<CompiledCode))-1)というアドレスに設定する等により取得できる。以下 、このように設定されているものとして説明する。
【0048】
そして、メソッド呼び出しを行ったメソッドの識別番号を格納するため、ローカル変数(変数2)領域を1増やす(ステップ1150)。また、ステップ1120において検出されたメソッド呼び出しの直前に、当該メソッドの呼び出し元の識別番号を変数2に設定するコードを生成する(ステップ1160)。表8の例では、第840行及第850行のメソッドhの呼び出しは、メソッドgによる呼び出し(メソッドgのコード)であるから、このメソッドhの呼び出し前に変数2にメソッドgの識別番号0を格納するコードを生成する。また、第860行のメソッドhの呼び出しは、メソッドfが呼び出し元(メソッドfのコード)であるから、メソッドfの識別番号1を変数2に格納するコードを生成する。バイトコードで表現すると、以下のとおりになる。
【表9】
iconst >識別番号<
istore >変数2<
これを表8の例では2か所に生成する。すなわち、第830行の後及び第850行の後である。
【0049】
コンパイル後の状態を分かりやすいように表8の変形として表現すると、以下のとおりになる。
【表10】
1300: class test{
1310: public void f ( int x )
1320: {
1330: for ( int i=0; i>x; i++ ){
1340: >変数2< = 0;
1350: h( i*i );
1360: h( i+i );
1370: >変数2< = 1;
1380: h(i);
1390: }
1400: }
1410: public void h ( int x )
1420: {
1430: ........
1440: }
1450: }
第1340行及び第1370行に呼び出し関係をトレースするための情報を格納する変数2についてのコードが生成される。
【0050】
図7の処理がなされ、必要なコンパイル処理が実施されると、マシン・コード58が生成されるので、このマシン・コード58をCPUにて実行する。マシン・コード58実行時には、変数2にどのメソッドによる呼び出し(どのメソッドのコードを実行中)であるかの情報(識別番号)が格納される。すなわち、変数2が0を格納している場合には、メソッドgによる呼び出し(元々メソッドgのコードを実行中)であり、変数2に1が格納されている場合には、メソッドfによる呼び出し(元々メソッドfのコードを実行中)である。
【0051】
次にSecurityManagerの処理を説明する。従来のSecurityManagerは、表5に表したとおりに処理を実施する。一方、以下に本発明におけるSecurityManagerの処理を表す。
【表11】
1500: int depth = 0;
1510: for (スタック中のフレームを順にトレースする)
1520: {
1530: mb = フレームからメソッド情報を取り出す。
1540: cb = mb-<fb.class //メソッド・ブロックからクラスを取得する
1550: if (mb-<CompiledCodeInfoにフラグが設定されているか)
1560: {
1570: void * 呼び出し関係情報配列 = *(((long *)(mb-<CompiledCode))-1)
1580: void * 要素アドレス = 呼び出し関係情報配列[変数2]
1590: for ( ;要素アドレス!=NULL; 要素アドレス=要素アドレス[1] ) {
1600: mb = 要素アドレス[0];
1610: cb = mb-<fb.class;
1620: if ( cb が目的のクラスか )
1630: {
1640: >cbに対するSecurityManagerの処理<
1650: return depth;
1660: }
1670: depth ++;
1680: }
1690: }
1700: else
1710: {
1720: if ( cbが目的のクラスか )
1730: {
1740: >cbに対するSecurityManagerの処理<
1750: return depth;
1760: }
1770: }
【0052】
第1530行では、検査しているフレームからメソッド情報を取り出し、第1540行でそのメソッド情報からそのメソッドのクラス情報を取り出す。第1550行から第1690行までは、本発明において異なる処理をする部分である。第1550行では、先に述べたように本発明が実施されているかどうかをフラグにて判断する。そして、1570行では、当該メソッドの格納領域の直前に呼び出し関係情報の配列が格納されているので、そのアドレスにアクセスする。第1580行では、呼び出し関係情報の配列において変数2に格納された識別番号の所の要素アドレスを取得する。第1590行では、配列要素アドレスがNULLになるまで、第1680行までを繰り返すことを表しており、繰り返すごとに、配列の右側(図8の例)に格納された、呼び出し元メソッドを表す配列要素のアドレスを配列要素アドレスとする。第1600行では、取得した配列要素アドレスの、図8の例では左側の列に記憶されたメソッド・ブロックmbを取得し、第1610行でそのmbからそのメソッドのクラスを取得する。そして第1620行でそのクラスが目的のクラスかどうか検査する。もし目的のクラスであれば、第1640行で、SecurityManagerの処理を実施する。一方、そうでない場合には深さ値を1インクリメントして第1590行に戻る。図5及び図6において示したように、スタックの深さも異なるためである。
【0053】
以上述べた部分が従来と異なる部分であって、本発明が実施されていない場合には、従来と同じ処理を実施するようになっている(第1710行乃至第1770行)。
【0054】
以上本発明の実施例を2つ別々に述べたが、これらは2つ同時に実行することができる。例えば、表12のようなプログラムは、表13のようなプログラムになる。
【0055】
【表12】
【表13】
【0056】
また、本願発明は、JavaVM52内のJITコンパイラ56とSecutityManager60に関するものであるが、JavaVM52全体又はその一部、特に本願発明に関連する部分をハードウエア、特に半導体チップにて実装することも考えられる。
【0057】
【効果】
Javaのようなセキュリティ機能を有する言語においてメソッド・インライニングによる実行最適化の適用範囲を増大させることができた。
【0058】
メソッド・インライニングがJavaのJIT(Just In Time)コンパイラにおいても可能になった。
【0059】
また、メソッド・インライニングを実施する際に、メソッド・インライニングを実施しない場合のスタック情報を再現できるようにすることもできた。
【0060】
Javaのような言語において、呼び出された後の処理が不確定なメソッドの呼び出し及び自己再帰を含むメソッドに対し、テイル・リカージョン(Tail Recursion)によるループ化が可能になった。
【0061】
さらに、当該ループ化において繰り返し数を把握できるようになった。
【0062】
メソッド・インライニングを実施した場合に、メソッド・インライニング前のメソッド間の呼び出し関係を保存できるようにすることもできた。
【0063】
メソッド・インライニングを実施した場合に、どのメソッドのコードを実行しているか判断できるようになった。
【図面の簡単な説明】
【図1】本願発明の装置構成を表す図である。
【図2】従来(表1)におけるスタックの状態を表す図である。
【図3】実施例1におけるスタックの状態を表す図である。
【図4】実施例1におけるJITコンパイラの処理フローを表す図である。
【図5】従来(表7)におけるスタックの状態を表す図である。
【図6】実施例2におおけるスタックの状態を表す図である。
【図7】実施例2におけるJITコンパイラの処理フローを表す図である。
【図8】呼び出し関係情報の配列を表す図である。
【符号の説明】
1 サーバ・コンピュータ
3 ネットワーク
5 クライアント・コンピュータ
52 JavaVM
54 Javaインタプリタ
56 Java JITコンパイラ
58 マシンコード
60 セキュリティ・マネージャ
53 OS
55 ハードウエア(CPU及びメモリを含む)
Claims (7)
- 複数のメソッドを含むプログラムを処理する方法であって、前記方法は前記プログラムを処理するプロセッサを含むコンピュータにより実行され、前記プロセッサが、
呼び出し後の処理においてインライニングした場合とインライニングしない場合とで同じ結果を返さない第1メソッドの呼び出しを含む第2メソッドに前記第1メソッドのコードをインライニングするステップと、
前記第1メソッドのコードをインライニングする前の状態における、前記第1メソッドと前記第2メソッドの呼び出し関係情報を取得して、後に使用可能な記憶域に格納するステップと、
インライニングされた前記第1メソッドのコードを実行する際に、前記第1メソッドを実行中であることを記憶するためのコードを生成するステップと、
を含む、プログラム処理方法。 - インライニング前から前記第2メソッドに含まれるコードを実行する際に、前記プロセッサが、前記第2メソッドを実行中であることを記憶するためのコードを生成するステップ
をさらに含む、請求項1記載のプログラム処理方法。 - 前記第1メソッドと前記第2メソッドの呼び出し関係情報は、前記第1メソッドに関する項目に前記第2メソッドに関する項目を指すポインタを含む
ことを特徴とする、請求項1記載のプログラム処理方法。 - 複数のメソッドを含むプログラムであって、前記プログラムは、該プログラムを処理するプロセッサを含むコンピュータにより実行され、呼び出し後の処理においてインライニングした場合とインライニングしない場合とで同じ結果を返さない第1メソッドの呼び出しを含む第2メソッドに、メソッド・インライニングによる前記第1メソッドのコードと、インライニングされた前記第1メソッドのコードを実行する際に、前記第1メソッドを実行中であることを記憶するためのコードとを含み、さらに、前記第1メソッドのコードをインライニングする前の状態における、前記第1メソッドと前記第2メソッドの呼び出し関係情報を含んでいて、前記プログラムの実行時に、実行した各メソッドに関する情報を対応フレームとして格納した記憶領域において、前記呼び出し後の処理においてインライニングした場合とインライニングしない場合とで同じ結果を返さない指定メソッドに関連するフレームを検出する方法であって、前記プロセッサが、
前記記憶領域内の現在検査中のフレームに関連する第3メソッドが前記第2メソッドであるか判断するステップと、
前記第3メソッドが前記第2メソッドである場合には、前記第2メソッドに関連する前記呼び出し関係情報を取得するステップと、
前記呼び出し関係情報中の前記第3メソッドの対応項目を取得するステップと、
前記呼び出し関係情報中の前記第3メソッドの対応項目を用いて、前記第3メソッドの呼び出し元メソッドを取得するステップと、
前記呼び出し元メソッドが前記指定メソッドであるか判断するステップと、
前記呼び出し元メソッドが前記指定メソッドでなかった場合には、前記呼び出し関係情報中の前記呼び出し元メソッドの対応項目から、さらなる呼び出し元メソッドを取得するステップと、
を含み、
前記指定メソッドが検出されるまで、または、前記記憶領域のすべてのフレームを検査するまで、前記指定メソッドであるか判断するステップと、前記さらなる呼び出し元メソッドを取得するステップとを繰り返す検出方法。 - 複数のメソッドを含むプログラムをコンピュータに処理させる処理プログラムを格納する記憶媒体であって、
前記処理プログラムは、前記コンピュータに、
呼び出し後の処理においてインライニングした場合とインライニングしない場合とで同じ結果を返さない第1メソッドの呼び出しを含む第2メソッドに前記第1メソッドのコードをインライニングするステップと、
前記第1メソッドのコードをインライニングする前の状態における、前記第1メソッドと前記第2メソッドの呼び出し関係情報を取得して、後に使用可能な記憶域に格納するステップと、
インライニングされた前記第1メソッドのコードを実行する際に、前記第1メソッドを実行中であることを記憶するためのコードを生成するステップと、
を実行させる、記憶媒体。 - インライニング前から前記第2メソッドに含まれるコードを実行する際に、前記第2メソッドを実行中であることを記憶するためのコードを生成するステップ
をさらに実行させる、請求項5記載の記憶媒体。 - 複数のメソッドを含むプログラムであって、呼び出し後の処理においてインライニングした場合とインライニングしない場合とで同じ結果を返さない第1メソッドの呼び出しを含む第2メソッドに、メソッド・インライニングによる前記第1メソッドのコードと、インライニングされた前記第1メソッドのコードを実行する際に、前記第1メソッドを実行中であることを記憶するためのコードとを含み、さらに、前記第1メソッドのコードをインライニングする前の状態における、前記第1メソッドと前記第2メソッドの呼び出し関係情報を含んでいて、前記プログラムの実行時に、実行した各メソッドに関する情報を対応フレームとして格納した記憶領域において、前記呼び出し後の処理においてインライニングした場合とインライニングしない場合とで同じ結果を返さない指定メソッドに関連するフレームをコンピュータに検出させる処理プログラムを格納した記憶媒体であって、
前記処理プログラムは、前記コンピュータに、
前記記憶媒体内の現在検査中のフレームに関連する第3メソッドが前記第2メソッドであるか判断するステップと、
前記第3メソッドが前記第2メソッドである場合には、前記第2メソッドに関連する前記呼び出し関係情報を取得するステップと、
前記呼び出し関係情報中の前記第3メソッドの対応項目を取得するステップと、
前記呼び出し関係情報中の前記第3メソッドの対応項目を用いて、前記第3メソッドの呼び出し元メソッドを取得するステップと、
前記呼び出し元メソッドが前記指定メソッドであるか判断するステップと、
前記呼び出し元メソッドが前記指定メソッドでなかった場合には、前記呼び出し関係情報中の前記呼び出し元メソッドの対応項目から、さらなる呼び出し元メソッドを取得するステップと、
を実行させ、
前記指定メソッドが検出されるまで、または、前記記憶領域のすべてのフレームを検査するまで、前記指定メソッドであるか判断するステップと、前記さらなる呼び出し元メソッドを取得するステップとを繰り返し実行させる、記憶媒体。
Priority Applications (2)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
JP12702498A JP3813019B2 (ja) | 1998-05-11 | 1998-05-11 | プログラム処理方法、指定メソッドに関連するフレームを検出する方法、及び記憶媒体 |
US09/306,007 US6363521B1 (en) | 1998-05-11 | 1999-05-06 | Process for processing programs, process for detecting depth of frame associated with specified method, detection method, and computer |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
JP12702498A JP3813019B2 (ja) | 1998-05-11 | 1998-05-11 | プログラム処理方法、指定メソッドに関連するフレームを検出する方法、及び記憶媒体 |
Publications (2)
Publication Number | Publication Date |
---|---|
JPH11338699A JPH11338699A (ja) | 1999-12-10 |
JP3813019B2 true JP3813019B2 (ja) | 2006-08-23 |
Family
ID=14949804
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
JP12702498A Expired - Fee Related JP3813019B2 (ja) | 1998-05-11 | 1998-05-11 | プログラム処理方法、指定メソッドに関連するフレームを検出する方法、及び記憶媒体 |
Country Status (2)
Country | Link |
---|---|
US (1) | US6363521B1 (ja) |
JP (1) | JP3813019B2 (ja) |
Families Citing this family (14)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
JP3437932B2 (ja) * | 1999-01-05 | 2003-08-18 | インターナショナル・ビジネス・マシーンズ・コーポレーション | 配列レンジ・チェックのためのコード生成方法及び装置、並びにバージョニング方法及び装置 |
JP4088379B2 (ja) * | 1999-01-29 | 2008-05-21 | インターナショナル・ビジネス・マシーンズ・コーポレーション | コンパイル方法及び装置、並びにスタック・トレース方法及び装置 |
US7080368B2 (en) * | 2002-10-31 | 2006-07-18 | International Business Machines Corporation | Object oriented apparatus and method for preserving stack frame identity during inlined method calls |
US7386686B2 (en) * | 2003-03-28 | 2008-06-10 | Intel Corporation | Inlining with stack trace cache-based dynamic profiling |
JP2007226277A (ja) * | 2004-04-02 | 2007-09-06 | Matsushita Electric Ind Co Ltd | 仮想マシン改ざん検査方法、および仮想マシン改ざん検査装置 |
CA2557343C (en) | 2006-08-28 | 2015-09-22 | Ibm Canada Limited-Ibm Canada Limitee | Runtime code modification in a multi-threaded environment |
US8356286B2 (en) * | 2007-03-30 | 2013-01-15 | Sap Ag | Method and system for providing on-demand profiling infrastructure for profiling at virtual machines |
US8336033B2 (en) * | 2007-03-30 | 2012-12-18 | Sap Ag | Method and system for generating a hierarchical tree representing stack traces |
US8667471B2 (en) * | 2007-03-30 | 2014-03-04 | Sap Ag | Method and system for customizing profiling sessions |
US8522209B2 (en) * | 2007-03-30 | 2013-08-27 | Sap Ag | Method and system for integrating profiling and debugging |
US8601469B2 (en) * | 2007-03-30 | 2013-12-03 | Sap Ag | Method and system for customizing allocation statistics |
US8359496B1 (en) * | 2010-08-31 | 2013-01-22 | Google Inc. | Fault-resistant just-in-time compiler |
CA2719653A1 (en) | 2010-11-05 | 2011-01-18 | Ibm Canada Limited - Ibm Canada Limitee | Partial inlining with software based restart |
US8661426B2 (en) * | 2010-12-31 | 2014-02-25 | International Business Machines Corporation | Method frame aggregation for latest user-defined class loader identification |
Family Cites Families (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US5812850A (en) * | 1995-11-13 | 1998-09-22 | Object Technology Licensing Corp. | Object-oriented symbolic debugger using a compiler driven database and state modeling to control program execution |
US6199095B1 (en) * | 1996-01-29 | 2001-03-06 | Compaq Computer Corporation | System and method for achieving object method transparency in a multi-code execution environment |
US6226789B1 (en) * | 1996-01-29 | 2001-05-01 | Compaq Computer Corporation | Method and apparatus for data flow analysis |
US6101326A (en) * | 1997-05-29 | 2000-08-08 | Hewlett-Packard Company | Method and apparatus for frame elimination for simple procedures with tail calls |
US6047125A (en) * | 1997-10-01 | 2000-04-04 | Sun Microsystems, Inc. | Garbage collection system for improved use of memory by removal of reference conflicts |
-
1998
- 1998-05-11 JP JP12702498A patent/JP3813019B2/ja not_active Expired - Fee Related
-
1999
- 1999-05-06 US US09/306,007 patent/US6363521B1/en not_active Expired - Fee Related
Also Published As
Publication number | Publication date |
---|---|
JPH11338699A (ja) | 1999-12-10 |
US6363521B1 (en) | 2002-03-26 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
JP3813019B2 (ja) | プログラム処理方法、指定メソッドに関連するフレームを検出する方法、及び記憶媒体 | |
US7275239B2 (en) | Run-time wait tracing using byte code insertion | |
US7536680B2 (en) | Method for modifying a class file to monitor data flow | |
Maffeis et al. | An operational semantics for JavaScript | |
US6026237A (en) | System and method for dynamic modification of class files | |
US6662359B1 (en) | System and method for injecting hooks into Java classes to handle exception and finalization processing | |
US6131187A (en) | Method and system for translating exception handling semantics of a bytecode class file | |
US8578339B2 (en) | Automatically adding bytecode to a software application to determine database access information | |
US6704927B1 (en) | Static binding of dynamically-dispatched calls in the presence of dynamic linking and loading | |
US6675379B1 (en) | Automatic removal of array memory leaks | |
US20030135792A1 (en) | Language subset validation | |
US9183114B2 (en) | Error detection on the stack | |
US7103877B1 (en) | System and method for characterizing program behavior by sampling at selected program points | |
US20030212988A1 (en) | Preserving program context when adding probe routine calls for program instrumentation | |
US20020170033A1 (en) | Computer program language subset validation | |
US6385764B1 (en) | Method and apparatus for improving invocation speed of Java methods | |
US6330714B1 (en) | Method and computer program product for implementing redundant lock avoidance | |
Cook | Reverse execution of Java bytecode | |
US20060026584A1 (en) | Explicit linking of dynamic link libraries | |
US6553426B2 (en) | Method apparatus for implementing multiple return sites | |
US20050188379A1 (en) | Method and device to process multidimensional array objects | |
US20090150422A1 (en) | Representing pointers and boxing in environments using only reference types | |
US7428729B2 (en) | Methods, systems, and computer program products for integrating legacy applications into a platform-independent environment | |
CN112445706A (zh) | 程序异常代码获取方法、装置、电子设备以及存储介质 | |
JP4088379B2 (ja) | コンパイル方法及び装置、並びにスタック・トレース方法及び装置 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
RD12 | Notification of acceptance of power of sub attorney |
Free format text: JAPANESE INTERMEDIATE CODE: A7432 Effective date: 20050725 |
|
A521 | Request for written amendment filed |
Free format text: JAPANESE INTERMEDIATE CODE: A821 Effective date: 20050725 |
|
A521 | Request for written amendment filed |
Free format text: JAPANESE INTERMEDIATE CODE: A523 Effective date: 20060414 |
|
RD14 | Notification of resignation of power of sub attorney |
Free format text: JAPANESE INTERMEDIATE CODE: A7434 Effective date: 20060523 |
|
A61 | First payment of annual fees (during grant procedure) |
Free format text: JAPANESE INTERMEDIATE CODE: A61 Effective date: 20060530 |
|
R150 | Certificate of patent or registration of utility model |
Free format text: JAPANESE INTERMEDIATE CODE: R150 |
|
FPAY | Renewal fee payment (event date is renewal date of database) |
Free format text: PAYMENT UNTIL: 20100609 Year of fee payment: 4 |
|
LAPS | Cancellation because of no payment of annual fees |