(57)【要約】  【課題】変数名を通じて変数を上書きする機能を提供するプログラミング言語では，上書機能を通じた上書きを考慮すると最適化できる機会が減るという課題がある。  【解決手段】実行時に上書機能を通じて更新されうる変数の集合を求め，求めた集合に属さない変数については，リフレクション（６１５）による更新が発生しないものと仮定してコンパイル，最適化を適用する（６１４）。実行の過程で新たに変数が上書機能経由で更新可能になった場合には，その変数が上書機能経由で更新されえないと仮定して最適化したコードを無効化する（６１３）。【選択図】図６
2008102748.tif 000002
【特許請求の範囲】
【請求項１】
記憶部と処理部とを有する計算機システムにおいて、前記記憶部に記憶した言語処理系のプログラムを使って、前記記憶部に記憶した実行対象のプログラムを実行するプログラム実行方法であって、
前記実行対象のプログラムを、前記言語処理系の動的コンパイラを使って、前記記憶部の所定領域に記憶している変数の保持する値が不変であると仮定して最適化を適用し，
前記言語処理系の実行時ルーチンを使って，前記実行対象のプログラムが、前記所定領域を，前記所定領域に対応する変数名を通じて上書きしうるか監視し，
前記上書きの可能性が生じた場合に，前記動的コンパイラが前記所定領域に対応する前記変数の保持する値が不変と仮定して最適化を適用しつつ生成したコードを無効化する
プログラム実行方法。
【請求項２】
請求項１記載のプログラム実行方法であって、
前記動的コンパイラは、前記最適化を適用した場合、不変であると仮定した前記変数を最適化記録に記録し、
前記実行時ルーチンは、前記最適化記録を参照して、前記コードの無効化を実行する
プログラム実行方法。
【請求項３】
プログラムを記憶する記憶部と前記プログラムを処理する処理部とを有する計算機システムにおける言語処理系であって、
前記プログラムの実行時に，前記記憶部の所定領域に記憶されている変数を確認し，確認した前記変数が不変であると仮定して最適化を適用する動的コンパイラと，
前記プログラムが実行時ルーチンを使って，前記所定領域を，前記所定領域に対応する変数名を通じて上書きしうるか監視し，前記上書きの可能性が生じた場合に，前記動的コンパイラが前記所定領域の前記変数が不変と仮定して最適化を適用しつつ生成したコードを無効化する実行時ルーチンとを含む
言語処理系。
【請求項４】
請求項３記載の言語処理系であって、
前記動的コンパイラは、前記最適化を適用した場合、不変であると仮定した前記変数を最適化記録に記録し、
前記実行時ルーチンは、前記最適化記録を参照しながら、前記コードの無効化を実行する
言語処理系。
【請求項５】
動的コンパイラを含むプログラムを処理する処理部で実行される実行時ルーチンであって、
前記プログラムが前記実行時ルーチンを使って，
メモリへの上書きの可能性が生じた場合に，前記動的コンパイラが前記メモリの値が不変と仮定して最適化を適用しつつ生成した動的コンパイル済みコードを無効化する
実行時ルーチン。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は，変数名を通じた上書きの機能を提供するプログラミング言語向け言語処理系における最適化処理技術に関する。
【背景技術】
【０００２】
これまでのコンパイラは，メモリの内容が特定の値になると判っているとき，その情報をもとに，プログラムを最適化できる（非特許文献１）。最適化の具体例を図１の関数getVar()を使って説明する。まず，最適化を適用しない場合について述べる。関数getVar()を最適化せずにコンパイルすると図２のコードになる。図２のコードはアセンブリ言語で記述したものである。
【０００３】
図２のコードでは，まず，最初に命令movによって，変数varの値を格納するメモリを参照し，メモリの内容，つまり変数varの値をレジスタeaxにコピーする。ここでレジスタeaxは関数の返戻値を格納する役割を果たすものとする。命令movの実行が終了したら，続いて手続きから戻るための命令retを実行する。
【０００４】
つぎに，最適化を適用する場合について述べる。もし，図１のプログラムについて，変数varの値が必ず1であると判れば，コンパイルの際に最適化を適用し，図１のプログラムを図３のコードに変換できる。図３のコードでは，最初に命令movでレジスタeaxに値1を格納し，次に命令retで手続きから戻る。図３のコードは，図２のコードよりも高速に動作する。なぜなら，図３のコードは，変数varの値を格納するメモリにアクセスしないので，その分，実行に手間がかからないからである。
【０００５】
コンパイラが最適化を適用するには，コンパイル対象のプログラムに関する情報が必要になる。たとえば図１のプログラムを，図３のコードに最適化するには，「変数varの値は必ず１」という情報が必要である。コンパイラはコンパイル対象のプログラムを解析して，最適化に必要な情報を収集する。収集の結果，必要な情報が得られなければ最適化を適用することはできず，たとえば「変数varの値は必ず１」という情報なしに，図１のプログラムを，図３のコードに最適化することはできない。
【０００６】
コンパイラによる最適化を目的とした情報収集を困難にする従来技術の１つに，リフレクションなど，変数名を通じて変数の値を上書きする技術がある。リフレクションはJava（登録商標、以下同じ）などのプログラミング言語が提供する機能であり（非特許文献2），プログラムが自身の構成要素を参照する際に用いる。ここでプログラムの構成要素とは，クラスやインタフェース，メソッド，クラス変数やメンバ変数を意味する。リフレクションの実装によっては，リフレクションの機能を通じてクラス変数やメンバ変数の値を書き換えることもできる。
【０００７】
リフレクションなど，変数名を通じた変数の上書きが最適化に悪影響を及ぼす例を，図４を使って説明する。図４のプログラムはJavaで記述したものである。図４のプログラムは，クラスKlassを定義するもので，クラスKlass内では，クラス変数varを定義し，その初期値は1と指定している。ここでクラス変数varの定義には，クラス変数を参照可能な範囲を指定するための予約語privateがついており，この結果，クラス変数varは原則としてクラスKlass内のみから参照可能になっている。もしここで，クラス変数varが完全にクラスKlass内のみから参照可能なのであれば，クラス変数varの値は必ず1ということができる。なぜなら，クラス変数varの初期値は1であり，なおかつ，クラスKlassの定義の中に，クラス変数varの値を書き換える処理がないからである。
【０００８】
しかしながら図４のプログラムについて，クラス変数varの値が必ず1ということはできない。なぜなら図４のプログラムについては，Javaが提供するリフレクションを使うと，クラスKlassの外から，クラス変数varの値を書き換えられるからである。リフレクションを使って，クラス変数varの値を，クラスKlassの外から書き換えるプログラムを図５に示す。図５のプログラムは，まず最初にリフレクション用のメソッドforName()を呼び出して，クラス名を表す文字列”Klass”に対応するクラスへの参照を取得して変数cに格納し，次にメソッドgetDeclaredField()を呼び出して，変数cの指示先にあるクラスが宣言するメンバ変数群から，メンバ変数名を表す文字列”var”に対応するメンバ変数を表すインスタンスへの参照を変数fに格納し，次にメソッドsetAccessible()を呼び出して，変数fが参照するインスタンスを通じたメンバ変数の更新を可能にし，最後にメソッドsetInt()を呼び出して，変数fが参照するインスタンスに対応するクラス変数varの値を2に更新する。
【０００９】
図５に示したプログラムが，クラスKlassの外に存在しうることを考慮すると，図４のクラスKlassのみを解析しても，「クラス変数varの値は必ず1」という情報は得られないことが判る。この例が示すように，リフレクションなど，変数名を通じて変数の値を上書きする技術は最適化を阻害することがある。
【００１０】
このようなリフレクションを提供するプログラミング言語向けにも最適化を適用可能にするための従来技術として，コンパイラでプログラムの全体を解析し，リフレクションを通じて更新されうる変数を求める方法がある（非特許文献3）。この方法を使って，たとえば図４のプログラムについて「クラス変数varの値はリフレクション経由で更新されえない」という情報が得られれば，得られた情報に基づいてクラスKlassを解析することで，「クラス変数varの値は必ず1」という情報が得られる。
【００１１】
【非特許文献１】Alfred V. Aho, Ravi Sethi, and Jeffrey D. Ullman: Compilers Principles, Techniques, and Tools, pp.592, Addison-Wesley, 1986.
【非特許文献２】Ken Arnold, James Gosling, and David Holmes: The Java Programming Language, 4th edition, Addison-Wesley, 2005.
【非特許文献３】Bruno Blanchet: Escape Analysis for Java: Theory and Practice, ACM Transactions on Programming Languages and Systems, Vol. 25, Issue 6, pp.713775 (2003).
【非特許文献４】Kazuaki Ishizaki, Motohiro Kawahito, Toshiaki Yasue, Hideaki Komatsu, Toshio Nakatani: A Study of Devirtualization Techniques for a Java Just-In-Time Compiler, In proceedings of the ACM SIGPLAN conference on Object Oriented Programming, Systems, Language and  Applications, pp. 294-310 (2000).
【非特許文献５】Urs Holzle, Craig Chambers, and David Ungar: Debugging optimized code with dynamic Deoptimization, In proceedings of the ACM SIGPLAN '92 Conference on Programming Language Design and Implementation, pp.32-43 (1992).
【発明の開示】
【発明が解決しようとする課題】
【００１２】
しかしながら従来技術には問題点が２つある。１つ目の問題はプログラム全体の解析が容易でない場合があることで，２つ目の問題はリフレクションによる更新の対象を特定できない場合があることである。
【００１３】
１つ目の問題点は，コンパイル時にプログラムの全体を把握しきれない場合に発生する。たとえばJavaではプログラムの実行を進めながら，随時，必要になったプログラム片を読み込む。したがってJavaでは，実行時にコンパイルをおこなう場合でも，コンパイルの時点で全てのプログラム片が読込済の状態になっているとは限らず，このとき全プログラムを対象とした解析は不可能になる。この問題は別の従来技法で解決されている（非特許文献４，５参照）。非特許文献４の技法では，読み込み済みのプログラム片のみがプログラムの全体だと仮定して解析をおこない，あとから追加読み込みをおこなったら，再度解析をやりなおす。
【００１４】
２つ目の問題点は，リフレクションのメソッドが受け取る引数が変数である場合に発生する。たとえば図５のプログラムについて考えると，リフレクションのメソッドforName()やgetDeclaredField()が受け取る引数は”Klass”や”var”といった定数であり，このプログラムを従来技術によって解析すると，図５のプログラムが更新しうる変数は，クラスKlassが定義するクラス変数varだと判る。しかしながらメソッドforName()やgetDeclaredField()が受け取る引数は変数の場合もあり，このとき，コンパイラの解析によって引数がとりうる値を特定しきれないケースも生じうる。特定しきれない場合には，たとえば全クラス変数が更新されうると想定する必要が生じ，結果として最適化を適用可能な範囲が狭まる。
【００１５】
本発明の目的は，変数名を通じて変数の値を上書きする機能を原因とする最適化の抑止を回避し，プログラムの実行を高速化することが可能なプログラム実行方法、言語処理系、及び実行時ルーチンを提供することにある。
【課題を解決するための手段】
【００１６】
上記目的を達成するため、本発明においては、記憶部と処理部とを有する計算機システムにおいて、記憶部に記憶した言語処理系のプログラムを使って、記憶部に記憶した実行対象のプログラムを実行するプログラム実行方法であって、実行対象のプログラムを、言語処理系の動的コンパイラを使って、記憶部の所定領域に記憶している変数の保持する値が不変であると仮定して最適化を適用し，言語処理系の実行時ルーチンを使って，実行対象のプログラムが、所定領域を，所定領域に対応する変数名を通じて上書きしうるか監視し，上書きの可能性が生じた場合に，動的コンパイラが前記所定領域に対応する変数の保持する値が不変と仮定して最適化を適用しつつ生成したコードを無効化するプログラム実行方法、及び言語処理系を提供する。
【００１７】
また、本発明は、動的コンパイラが、所定領域に記憶された変数が不変と仮定して最適化を適用してコードを生成する場合、どの変数が上書機能によって更新されえないと仮定したかを最適化記録として記録するプログラム実行方法、及び言語処理系を提供する。
【００１８】
更に、本発明は、プログラムを処理する処理部で実行される実行時ルーチンであって、プログラムが実行時ルーチンを使って，メモリに記憶された変数への上書きの可能性が生じた場合に，動的コンパイラがこのメモリの値が不変と仮定して最適化を適用しつつ生成した動的コンパイル済みコードを無効化する実行時ルーチンを提供する。
【００１９】
即ち、本発明の言語処理系においては、コンパイラと、変数名を通じて変数の値を上書機能を実現する実行時ルーチンを含み、このコンパイラは，上書機能によって変数が更新されえないと仮定して最適化に必要な情報を収集し，最適化を適用する。この最適化の適用にあたって，どの変数が上書機能によって更新されえないと仮定したかを最適化記録として記録する。一方、上書機能を実現する実行時ルーチンは，実行時に上書機能を通じて新たな変数が更新可能になるたびに，この変数が上書機能によって更新されえないと仮定して最適化されたコードの集合を，最適化記録を参照して求め，求めた集合に属するコードに無効化の処理を行う。ここで無効化の処理とは，コードをプログラムの実行に使えなくするための処理を意味する。コードを無効化したメソッドを実行する必要が生じた場合には，更新された変数を用い、再度動的コンパイル処理を行う、或いはインタプリタなど代替の実行手段を使う。
【００２０】
更に，本発明においては、上書機能を実現する実行時ルーチンは，上書機能を通じて，どの変数が更新されうるか更新可能変数記録として記録をとり、この更新可能変数記録がある場合，コンパイラは，該記録に記載されている変数について，上書機能を通じて更新されうるとみなして最適化処理を抑止可能になる。
【００２１】
なお、本明細書において、「言語処理系」とは、プログラミング言語で記述されたプログラムを計算機上で実行するためのソフトウエアのことを言う。また、本明細書において、プロセッサを処理部、主記憶とハードディスクを記憶部と呼ぶことがある。更に、変数などが記憶されている記憶部の所定領域をメモリと呼ぶことがある。
【発明の効果】
【００２２】
変数名を通じて変数の値を上書きする機能によって実行時に更新されない変数について，最適化を抑止する必要がなくなり，プログラムの実行を高速化できる。
【発明を実施するための最良の形態】
【００２３】
本発明を実施する最良の言語処理系は，動的コンパイラと，変数名を通じて変数の値を上書きする機能を実現する実行時ルーチンからなる。この実行時ルーチンは更新可能変数記録を作成して動的コンパイラに引き渡し，動的コンパイラは更新可能変数記録に載っていない変数のみが実行時ルーチンによって更新されえないと仮定して最適化を適用し，動的コンパイル済みコードと，最適化記録を生成する。動的コンパイル済みコードが，実行時ルーチンによって無効化された場合には，再度、動的コンパイル処理をおこなうことで，無効化された動的コンパイル済みコードに代わる実行手段を用意する。
【実施例１】
【００２４】
以下、本発明の第一の実施例である、言語処理系を実行する計算機システムを図６に示す。図６の計算機システムはプロセッサ６０１，主記憶６０２，ハードディスク６０３，ＤＶＤ−ＲＯＭ（Digital Versatile Disc  Read Only Memory）読み取り装置６０４と，これらを結ぶバス６０５からなる。図６の計算機システムは，ＤＶＤ−ＲＯＭ６０６から，本実施例の言語処理系を読み取り，バス６０５を介してハードディスク６０３にインストールする。なお、言語処理系のインストールは、ＤＶＤ−ＲＯＭ６０６のような可搬記録媒体を使う場合のみならず、計算機システムの図示されていないネットワークインターフェースを用い、ネットワークからインストールすることも可能である。本実施例の言語処理系を実行する際には，ハードディスク６０３にインストールした言語処理系のプログラム６０７を，バス６０５を介して主記憶６０２に読み込み，プロセッサ６０１で実行する。本明細書において、プロセッサ６０１を処理部、主記憶６０２とハードディスク６０３を記憶部と呼ぶことがある。
【００２５】
本実施例の言語処理系６０７は，静的コンパイラ６０８と実行環境６０９から構成され，実行環境６０９は，インタプリタ６１０と動的コンパイラ６１１，実行時ライブラリ６１２，動的コンパイル済みコード無効化処理６１３を含む。動的コンパイラ６１１は最適化処理６１４を含み，実行時ライブラリ６１２はリフレクションルーチン６１５を含む。
【００２６】
次に、言語処理系６０７を使って，ソースコード６１６に記述したプログラムを実行するまでの過程を図７に示す。図７の過程では，まず，処理７０１でソースコード６１６を静的コンパイラ６０８によってコンパイルし，中間コード６１７に変換する。次に，処理７０２で中間コード６１７をインタプリタ６１０に入力してプログラムの実行を開始する。処理７０１でソースコード６１６を中間コード６１７に変換する理由は，ソースコード６１６のままインタプリタ６１０に解釈実行させると解釈に大きなコストがかかるからである。処理７０１におけるコンパイル作業では，出力するコードを中間コード６１７ではなく，機械コードとすることもでき，機械コードにはインタプリタ６１０を使わずにプロセッサ６０１で直接実行できるという利点があるが，一方で中間コードには機種非依存性を確保しうるという利点があり，本実施例では，処理７０１で出力するコードを中間コード６１７にする。
【００２７】
図７に戻り，処理７０２において，インタプリタ６１０は実行の過程で，個々のメソッドの実行頻度を求め，頻度が高いものについては，コンパイルするよう，動的コンパイラ６１１に指示する。指示を受け取った動的コンパイラ６１１は，中間コード６１７に対応する，機械コード形式の動的コンパイル済みコード７０３を生成する。動的コンパイルの過程では最適化処理６１４を適用する。最適化処理６１４は，更新可能変数記録７０４，すなわち，リフレクションを通じて更新されうる変数一式の記録を参照して，ここに記録されていない変数についてはリフレクションを通じて更新されえないと仮定して処理をおこなう。最適化処理６１４では，最適化を適用した場合，最適化記録７０５を生成する。最適化記録７０５は，個々のメソッドの動的コンパイル済みコードごとに作成するデータ構造であり，対応するメソッドを動的コンパイル，最適化する過程で，どの変数がリフレクションによって変更されえないと仮定したかを記録する。最適化記録７０５の実施例については後述する。
【００２８】
インタプリタ６１０は，メソッド呼出しを実行する際に，呼出先のメソッドに対応する動的コンパイル済みコード７０３があるか調べ，あるならば自身でそのメソッドを解釈実行する代わりに，動的コンパイル済みコード７０３を呼び出す。インタプリタ６１０や動的コンパイル済みコード７０３は，実行の過程で，実行時ライブラリ６１２を呼び出すことがあり，このとき呼出先がリフレクションルーチン６１５である場合もある。
【００２９】
本実施例のリフレクションルーチン６１５は，どの変数がリフレクションを通じて更新されうるか，更新可能変数記録７０４に記録し，また，更新可能変数記録７０４に記録された変数が，いずれかの動的コンパイル済みコード７０３の最適化記録７０５に含まれているか監視し，もし含まれているならば，動的コンパイル済みコード無効化処理６１３を呼び出して，対応する動的コンパイル済みコードを無効化する。無効化の処理は，具体的には，次の２つの処理からなる。（１）インタプリタ６１０でメソッド呼出しを実施する際に，無効化対象の動的コンパイル済みコードを呼び出さないようにするための処理。（２）無効化の時点で，無効化対象の動的コンパイル済みコードを実行途中ならば，実行をインタプリタ６１０に引き継ぐ処理。動的コンパイル済みコード無効化処理６１３は本発明に固有な処理ではなく，非特許参考文献５で言及されており，また，いくつかのJava向け実行環境で実現されている。本実施例における動的コンパイル済みコード無効化処理６１３の実現は，これら従来の実現に倣うものとする。
【００３０】
動的コンパイラ６１１の一実施例を図８に示す。図８の動的コンパイラ６１１は，まず，処理８０１において中間コード６１７を入力として受け取り，コンパイラの内部表現８０２に変換する。次に，内部表現８０２に対して，本発明の最適化処理６１４を適用する。最後に処理８０３で，最適化後の内部表現８０２を，動的コンパイル済みコード７０３に変換する。
【００３１】
最適化処理６１４の一実施例を図９に示す。図９の処理では，まず処理９０１において，空の最適化記録７０５を生成し，続く処理９０２で内部表現８０２から参照する変数の集合を求め，判断９０３で集合が空か確認し，空ならば最適化を終了し，空でないならば処理９０４に進む。処理９０４では集合から変数を１つ取り出し，続く判断９０５で変数が更新可能変数記録７０４に記録されているか調べ，記録されているならば最適化を諦めて判断９０３に戻り，記録されていないならば判断９０６に進む。
【００３２】
判断９０６では中間コード６１７を走査してリフレクション以外の手段による変数の更新が発生しうるか調べる。たとえば図４のプログラムに対応する中間コード６１７を走査すると，変数varの値を更新する処理は唯一，初期化処理の中あり，他に更新するコードがないと判ることから，初期化処理の実行より後で動的コンパイルをおこなった場合には，リフレクション以外の手段による変数varの更新は発生しないと判断する。判断９０６における調査の結果，発生しうると判ったならば最適化を諦めて判断９０３に戻り，発生しないと判ったならば処理９０７に進んで最適化をおこなう。具体的には，内部表現８０２中にある変数への参照を，変数が保持している値で差し替える。たとえば最適化対象の変数がvarで，なおかつ動的コンパイル時点における変数varの値が1であるとき，内部表現８０２中に「return (var);」に相当する処理があるならば，この処理中のvarを1で差し替える。差替の結果，「return (var);」は「return (1);」になる。処理９０７が終了したら処理９０８に進み，最適化対象の変数を最適化記録７０５に記録する。
【００３３】
記録後の最適化記録７０５の一実施例を図１０に示す。図１０の最適化記録７０５には，記録された変数の個数を記述する欄１００１と，変数のアドレスを記述する欄１００２がある。図１０の最適化記録７０５は，変数varのアドレスが0x12345678であると仮定して，変数varのみを記録したものである。具体的には，変数の個数を記述する欄に１００１に１を，変数のアドレスを記述する欄１００２に0x12345678のみを記述した状態になっている。なお，図１０に示した最適化記録は，大域変数のように，アドレスを唯一に定めることができる変数向けの最適化記録である。変数の中には，メンバ変数のように，アドレスが唯一に定まらず，データ構造の先頭からのオフセットのみが唯一に定まるものもある。メンバ変数を本発明の最適化の対象とする場合には，メンバ変数向け最適化記録として，図１０のように変数のアドレスを記録する最適化記録ではなく，メンバ変数を宣言する型と，データ構造の先頭からのオフセットを記録する最適化記録を用いればよい。本実施例では，大域変数のように，アドレスを唯一に定めうる変数のみを最適化対象とする。
【００３４】
図９に戻り，処理９０８における最適化記録７０５への記入が終わったら，判断９０３に戻る。なお，図９では変数を対象として最適化をおこなっているが，最適化対象は必ずしも変数である必要はなく，変数が指示する配列中の要素などを最適化対象とすることもできる。また，図９の実施例で実施する最適化はコピー伝播（変数参照を変数の保持している値で差し替える最適化）だが，本発明はコピー伝播以外の最適化にも応用できる。たとえば図１１のJavaで記述したプログラムでは，クラスDaysが文字列の配列daysとメソッドlength()を定義しており，メソッドlength()は引数dを受け取って，配列daysのd番目の要素が参照する文字列の長さを返すが，このプログラムに本発明の最適化を適用すると，メソッドlength()における処理内容を，dが0〜6の範囲にある場合には，単に3を返す処理 に最適化できる。なぜなら配列daysの個々の要素が参照する文字列の長さは全て3で，なおかつ，リフレクション以外に配列daysを上書きする手段がないからである。この最適化はコピー伝播とは異なる。
【００３５】
次に、リフレクションルーチン６１５の一実施例を図１２に示す。リフレクションルーチン６１５は，インタプリタ６１０や動的コンパイル済みコード７０３によるプログラムの実行の過程で呼び出されるもので，たとえば図５のプログラムを実行すると呼び出される。図５のプログラムでは，文字列に対応するクラスへの参照を返戻するメソッドforName()や，文字列に対応する変数を表わすインスタンスを作成し，該インスタンスへの参照を返戻するメソッドgetDeclaredField()，変数の値を更新するメソッドsetInt()を呼び出すが，これらはいずれもリフレクションルーチンである。図１２は，文字列に対応する変数を表わすインスタンスを作成し，該インスタンスへの参照を返戻するリフレクションルーチンの実施例であり，まず処理１２０１で文字列に対応する変数を表わすインスタンスを作成する。続く判断１２０２では前記変数が更新可能変数記録７０４に登録済みか調べ，登録済みでなければ処理１２０３に，さもなくば処理１２０９に進む。処理１２０３では前記変数を更新可能変数記録７０４に登録する。登録後の更新可能変数記録７０４の実施例を図１３に示す。
【００３６】
図１３の更新可能変数記録７０４には，登録された変数の数を記録する欄１３０１と，登録された変数のアドレスを記録する欄１３０２がある。図１３はアドレス0x12345678の変数varのみ登録した状態を表している。具体的には，登録された変数の数を記録する欄１３０１の値が１になっており，登録された変数のアドレスを記録する欄１３０２には，変数varのアドレスが登録されている。
【００３７】
図１１に戻り，処理１２０３に続いて処理１２０４で全ての最適化記録７０５を納めた集合を求める。続く判断１２０５で集合が空か調べ，空でなければ処理１２０６に進む。処理１２０６では集合から最適化記録７０５を１つ取り出して，続く判断１２０７で最適化記録７０５に前記変数が登録されているか調べ，登録されているならば，最適化記録７０５に対応する動的コンパイル済みコード７０３を無効化するために，処理１２０８で，動的コンパイル済みコード無効化処理６１３を呼び出す．無効化が終了した，あるいは登録されていなかったならば，判断１２０５に戻る。判断１２０５で集合が空にならば，処理１２０９に進み，処理１２０１で作成したインスタンスへの参照を返戻する。図１１の処理のうち，本発明に固有な部分は判断１２０２〜処理１２０８であり，処理１２０１と処理１２０９は従来のリフレクションルーチンと変わりない。
【００３８】
図４のメソッドgetVar()を，本実施例の実行環境６０９で実行すると，次のように最適化される。まず，図７にあるように，インタプリタ６１０が動的コンパイラ６１１にメソッドgetVar()をコンパイルするよう指示すると，動的コンパイラ６１１は図８にあるように，本発明の最適化処理６１４の適用を試みる。図９に示した本発明の最適化処理６１４を適用すると，最適化の時点で変数varを1に初期化する処理が終わっており，なおかつ，更新可能変数記録７０４に変数varが登録されていなければ（リフレクションルーチンによって変数varを表わすインスタンスを作成したことがなければ），メソッドgetVar()のコードは最適化されて「return (1);」になり，また，この動的コンパイル済みコード７０３に対応する最適化記録７０５として，図１０の最適化記録７０５が生成される。動的コンパイル後に図５のリフレクションを含む処理を実行すると，図１１に示したリフレクションルーチン（文字列に対応する変数を表わすインスタンスを作成し，該インスタンスへの参照を返戻するリフレクションルーチン）を起動した時点で，処理１２０３で更新可能変数記録７０４に変数varが登録され，また，getVar()の最適化記録７０５に変数varが登録されていることから，処理１２０８においてgetVar()の動的コンパイル済みコードが無効化される。動的コンパイル済みコードが無効化されたgetVar()は，無効化後しばらくの間，インタプリタ６１０で実行され，再度動的コンパイラ１１１によってコンパイルされることもありうるが，再コンパイルの際には，更新可能変数記録７０４に変数varが登録されていることから，再度getVar()に処理９０７の最適化処理が適用されることはなくなる。
【００３９】
なお，本実施例の言語処理系６０７は，マルチスレッドを考慮した作りにはなっていない。マルチスレッドの機能を提供する場合には，排他制御などの処理を追加する必要が生じる。具体的には，マルチスレッド環境で動的コンパイラ６１１とリフレクションルーチン６１５が並列に動作すると，それぞれが参照するデータ構造（更新可能変数表７０４と最適化記録７０５）を，それぞれが書き換えたうるので，それに対処する処理が必要になる。たとえば，動的コンパイラ６１１が最適化処理６１４の時点で参照した更新可能変数表７０４の内容は，動的コンパイルの終了までに変化している可能性があり，変化が生じた場合には動的コンパイル中のコードを無効にするといった処理が必要になる。マルチスレッド対応するには，簡単には，動的コンパイラ６１１とリフレクションルーチン６１５に排他制御を適用し，これらの処理を同時に実行しうるスレッドの数を唯一に制限すればよい。
【００４０】
以上のように、本発明によれば，プログラム全体を解析せずとも，また，どの変数がリフレクションなどの対象になりうるか解析できない場合であっても，リフレクションなどを原因とする最適化の抑止を解除可能になる。例えば、Javaのリフレクション機能など，変数名を通じて変数を上書きする機能を提供するプログラミング言語向けの言語処理系において，プログラムの実行を高速化できる。
【図面の簡単な説明】
【００４１】
【図１】ソースコードの例を示す図。
【図２】コンパイル済みコードの例を示す図。
【図３】コンパイル済みコードの例を示す図。
【図４】ソースコードの例を示す図。
【図５】リフレクションを使うソースコードの例を示す図。
【図６】本発明の言語処理系を駆動する計算機システムの一実施例を示す図。
【図７】第一の実施例の言語処理系６０７の一実施例を示す図。
【図８】第一の実施例の動的コンパイラ６１１の一実施例を示す図。
【図９】第一の実施例の最適化処理６１４の一実施例を示す図。
【図１０】第一の実施例の最適化記録７０５の一実施例を示す図。
【図１１】第一の実施例におけるソースコードの一例を示す図。
【図１２】第一の実施例のリフレクションルーチン６１５の一実施例を示す図。
【図１３】第一の実施例の更新可能変数記録７０４の一実施例を示す図。
【符号の説明】
【００４２】
６１７…中間コード、７０４…適化対象外の変数の集合、７０５…最適化を適用した変数の集合、８０２…コンパイル対象のメソッドの内部表現、９０１…最適化を適用した変数の集合を確保，空に初期化する処理、９０２…内部表現中から参照する変数の集合を求める処理、９０３…集合が空か否かの判断、９０４…集合から変数を１つ取り出す処理、９０５…変数が最適化対象か否かの判断、９０６…変数が最適化対象か否かの判断、９０７…最適化を適用する処理、９０８…変数を集合に加える処理。
【図１】
2008102748.tif 000003
【図２】
2008102748.tif 000004
【図３】
2008102748.tif 000005
【図４】
2008102748.tif 000006
【図５】
2008102748.tif 000007
【図６】
2008102748.tif 000008
【図７】
2008102748.tif 000009
【図８】
2008102748.tif 000010
【図９】
2008102748.tif 000011
【図１０】
2008102748.tif 000012
【図１１】
2008102748.tif 000013
【図１２】
2008102748.tif 000014
【図１３】
2008102748.tif 000015