コンピュータの処理により、実行対象のプログラムにおけるサブクラステスト関数の実行結果を再利用するプログラムの最適化方法であって、前記コンピュータが、実行対象のプログラムに含まれるサブクラステスト関数の関数呼び出しから呼び出されるコードの再利用可能性を、該コードにおけるグローバルメモリへのアクセスが、前記関数呼び出しにおいて指定された型情報及び該型情報から辿ることの可能な情報の読み出しのためのアクセスのみを含むか否かに基づいて判定するステップと、前記コンピュータが、再利用可能であると判定したコードの実行結果を該コードの関数呼び出しにおいて指定された指定情報と共に、該コードにおいて実際にアクセスされた型情報に関連付けて、前記コードのプロファイル情報として記憶装置に格納するステップと、前記コンピュータが、再利用可能であると判定したコードを呼び出すサブクラステスト関数の関数呼び出しの検出に応答して、前記記憶装置から前記コードのプロファイル情報を読み出し、該プロファイル情報の指定情報と検出した前記関数呼び出しにおいて指定される指定情報とが一致することを条件に前記プロファイル情報の実行結果を再利用するステップと、前記コンピュータが、前記記憶装置に格納されるプロファイル情報に含まれる実行結果に関連付けられた型情報を監視して、該型情報に対する変更に応答して前記型情報に関連付けられた実行結果の再利用を禁止するステップと、を含む最適化方法。前記格納するステップにおいて、前記コンピュータは、再利用可能であると判定した前記コードの実行結果と共に、実行時の名前空間を前記コードのプロファイル情報として更に格納し、及び、前記再利用するステップにおいて、前記コンピュータは、検出した前記関数呼び出しが再利用可能であると判定したコードを呼び出すことを、読み出した前記プロファイル情報の名前空間と現在の名前空間の一致により確認する、請求項1に記載の最適化方法。前記再利用するステップは、前記コンピュータが、検出した前記関数呼び出しにおいて指定される指定情報が一致することを条件に前記プロファイル情報の実行結果を再利用する再利用コードをコンパイル済みコードとして生成するステップを含む、請求項2に記載の最適化方法。前記コンピュータが、事前登録された型情報を操作する操作コードにアクセスし、該操作コードに、再利用する前記実行結果に関連付けられた前記型情報を変更することを条件として前記実行結果を再利用する前記再利用コードを無効化する命令列を挿入するステップを更に含み、前記禁止するステップは、前記命令の実行により行われる、請求項3に記載の最適化方法。再利用のために実行結果を格納すべきサブクラステスト関数のコードを、前記コンピュータに組み込まれたデフォルトのサブクラステスト関数のコードに限定する、請求項1に記載の最適化方法。前記コンピュータが、前記プロファイル情報として格納される前記実行結果に関連付けられた型情報の変更イベントに対応するリスナーであって、前記変更イベントの発生に応答して変更された前記型情報に対応する前記プロファイル情報を無効化する前記リスナーを生成するステップを更に含み、前記禁止するステップは、前記リスナーの実行により行われる、請求項5に記載の最適化方法。前前記コンピュータが、再利用する前記実行結果に関連付けられた型情報の変更イベントに対応するリスナーであって、前記変更イベントの発生に応答して前記実行結果を再利用する前記再利用コードを無効化する前記リスナーを生成するステップを更に含み、前記禁止するステップは、前記リスナーの実行により行われる、請求項6に記載の最適化方法。前記判定するステップにおいて、前記コンピュータは、再利用可能性を判定する前記コードからグローバルメモリへのアクセス命令を全て探し出し、探し出した全てのアクセス命令が、前記サブクラステスト関数の関数呼び出しにおいて指定される型情報及び該型情報から辿ることの可能な情報の読み出しのためのアクセスであることを条件に、前記コードを再利用可能であると静的に判定する、請求項2に記載の最適化方法。前記判定するステップにおいて、前記コンピュータは、サブクラステスト関数の関数呼び出しにおいて指定されたオブジェクト及び型情報の値を、再利用可能性を判定する前記コードに伝播させた判定用コードを生成し、生成した判定用コードの実行中になされたグローバルメモリへのアクセスが全て型情報の読み出しのためのアクセスであることを条件に、前記コードを再利用可能であると動的に判定する、請求項2に記載の最適化方法。前記コンピュータが、再利用可能であると判定した前記コードに対し、該コードの実行によりアクセスされる型情報のアドレスを収集するテンプレートを生成するステップを更に含み、前記プロファイル情報は前記テンプレートの実行結果を利用して作成される、請求項2に記載の最適化方法。前記実行対象のプログラムは、Pythonで記述されたソースプログラムからPythonインタプリタにより生成されたバイトコードである、請求項2に記載の最適化方法。コンピュータの処理により、実行対象のプログラムにおけるサブクラステスト関数の実行結果を再利用する最適化プログラムであって、前記最適化プログラムは前記コンピュータに、実行対象のプログラムに含まれるサブクラステスト関数の関数呼び出しから呼び出されるコードの再利用可能性を、該コードにおけるグローバルメモリへのアクセスが、前記関数呼び出しにおいて指定された型情報及び該型情報から辿ることの可能な情報の読み出しのためのアクセスのみを含む否かに基づいて判定するステップと、再利用可能であると判定したコードの実行結果を該コードの呼び出しにおいて指定された指定情報と共に、該コードにおいて実際にアクセスされた型情報に関連付けて、前記コードのプロファイル情報として記憶装置に格納するステップと、再利用可能であると判定したコードを呼び出すサブクラステスト関数の関数呼び出しの検出に応答して、前記記憶装置から前記コードのプロファイル情報を読み出し、該プロファイル情報の指定情報と検出した前記関数呼び出しにおいて指定される指定情報とが一致することを条件に前記プロファイル情報の実行結果を再利用するステップと、前記記憶装置に格納されるプロファイル情報に含まれる実行結果に関連付けられた型情報を監視して、該型情報に対する変更に応答して前記型情報に関連付けられた実行結果の再利用を禁止するステップと、を実行させる、最適化プログラム。実行対象のプログラムにおけるサブクラステスト関数の実行結果を再利用するプログラムの最適化装置であって、記憶装置と、実行対象のプログラムに含まれるサブクラステスト関数の関数呼び出しから呼び出されるコードの再利用可能性を、該コードにおけるグローバルメモリへのアクセスが、前記関数呼び出しにおいて指定された型情報及び該型情報から辿ることの可能な情報の読み出しのためのアクセスのみを含むか否かに基づいて判定する再利用可能性判定部と、再利用可能であると判定したコードの実行結果を該コードの呼び出しにおいて指定された指定情報と共に、該コードにおいて実際にアクセスされた型情報に関連付けて、前記コードのプロファイル情報として前記記憶装置に格納するプロファイリング部と、再利用可能であると判定したコードを呼び出すサブクラステスト関数の関数呼び出しの検出に応答して、前記記憶装置から前記コードのプロファイル情報を読み出し、該プロファイル情報の指定情報と検出した前記関数呼び出しにおいて指定される指定情報とが一致することを条件に前記プロファイル情報の実行結果を再利用する再利用処理部と、前記記憶装置に格納されたプロファイル情報に含まれる実行結果に関連付けられる型情報を監視して、該型情報に対する変更に応答して前記型情報に関連付けられた前記実行結果の再利用を禁止する監視部と、を含む最適化装置。しかしながら、特許文献1、2が開示するようなテスト結果を単純にキャッシュして再利用する再利用方式や、特許文献3が開示するクラス階層リストの値を埋め込んだcheck関数を生成する技術、また、特許文献4~6が開示するクラス階層を表現するデータ構造を使用する技術は、その動作が言語仕様で1つに決定されるようなサブクラステスト関数を有するプログラミング言語を対象としているので、Pythonのような、サブクラステスト関数に該当するバイトコードが存在せず呼び出される関数の実体やクラスごとのサブクラスの定義が動的に変わり得る動的プログラミング言語に対して適用することはできない。この発明は、上記の問題点を解決するためになされたものであって、Pythonのようなサブクラステスト関数に該当するバイトコードが存在せず呼び出される関数の実体やクラスごとのサブクラスの定義が動的に変わり得る動的プログラミング言語に対して、プロファイルしたサブクラステスト関数の実行結果を効率的に、また安全に利用することを可能にするための技術を提供することを目的とする。上記課題を解決するために、本願発明者は、型情報クラス情報は実行時に変化しにくいことに着目し、グローバル情報へのアクセスを、型情報を読み出すためだけに行うサブクラステスト関数のコードをプロファイルし、その実行結果を再利用するとともに、型情報の変更を検出した場合は実行結果の再利用を禁止するというアイデアに想到した。即ち、上記目的を達成する本発明は、次のような、コンピュータの処理により、実行対象のプログラムにおけるサブクラステスト関数の実行結果を再利用してプログラムを最適化する最適化方法によって実現される。そのような最適化方法は、前記コンピュータが、実行対象のプログラムに含まれるサブクラステスト関数の関数呼び出しから呼び出されるコードの再利用可能性を、該コードにおけるグローバルメモリへのアクセスが、前記サブクラステスト関数の関数呼び出しにおいて指定された型情報及び該型情報から辿ることの可能な情報の読み出しのためのアクセスのみを含むか否かに基づいて判定するステップと、前記コンピュータが、再利用可能であると判定したコードの実行結果を該コードの呼び出しにおいて指定された指定情報と共に、該コードにおいて実際にアクセスされた型情報に関連付けて、前記コードのプロファイル情報として記憶装置に格納するステップと、前記コンピュータが、再利用可能であると判定したコードを呼び出すサブクラステスト関数の関数呼び出しの検出に応答して、前記記憶装置から前記コードのプロファイル情報を読み出し、プロファイル情報の指定情報が検出した前記関数呼び出しにおいて指定される指定情報と一致することを条件に前記プロファイル情報の実行結果を再利用するステップと、前記コンピュータが、前記記憶装置に格納されるプロファイル情報に含まれる実行結果に関連付けられた型情報を監視して、該型情報に対する変更に応答して前記型情報に関連付けられた実行結果の再利用を禁止するステップと、を含む。好ましくは、前記格納するステップにおいて、前記コンピュータは、再利用可能であると判定した前記コードの実行結果と共に、実行時の名前空間を前記コードのプロファイル情報として更に格納する。そして、前記再利用するステップにおいて、前記コンピュータは、検出した前記関数呼び出しが再利用可能であると判定したコードを呼び出すことを、読み出した前記プロファイル情報の名前空間と現在のの名前空間の一致により確認する。より好ましくは、前記再利用するステップは、前記コンピュータが、検出した前記関数呼び出しにおいて指定される指定情報がプロファイル情報の指定情報と一致することを条件に前記プロファイル情報の実行結果を再利用する再利用コードをコンパイル済みコードとして生成する。更に好ましくは、上記最適化方法は、前記コンピュータが事前登録された型情報を操作する操作コードにアクセスし、該操作コードに、再利用する前記実行結果に関連付けられた前記型情報を変更することを条件として前記実行結果を再利用する前記再利用コードを無効化する命令列を挿入するステップを更に含み、前記禁止するステップは、前記命令の実行により行われる。また好ましくは、再利用のために実行結果を格納すべきサブクラステスト関数のコードを、前記コンピュータに組み込まれたデフォルトのサブクラステスト関数のコードに限定する。より好ましくは、上記最適化方法は、前記コンピュータが、前記プロファイル情報として格納される前記実行結果に関連付けられた型情報の変更イベントに対応するリスナーであって、前記変更イベントの発生に応答して、変更された前記型情報に対応する前記プロファイル情報を無効化する前記リスナーを生成するステップを更に含み、前記禁止するステップは、前記リスナーの実行により行われる。また、より好ましくは、上記最適化方法は、前前記コンピュータが、再利用する前記実行結果に関連付けられた型情報の変更イベントに対応するリスナーであって、前記変更イベントの発生に応答して、前記実行結果を再利用する前記再利用コードを無効化する前記リスナーを生成するステップを更に含み、前記禁止するステップは、前記リスナーの実行により行われる。また好ましくは、前記判定するステップにおいて、前記コンピュータは、再利用可能性を判定する前記コードからグローバルメモリへのアクセス命令を全て探し出し、探し出した全てのアクセス命令が、前記サブクラステスト関数の関数呼び出しにおいて指定される型情報及び該型情報から辿ることの可能な情報の読み出しのためのアクセスであることを条件に、前記コードを再利用可能であると静的に判定する。また好ましくは、前記判定するステップにおいて、前記コンピュータは、サブクラステスト関数の関数呼び出しにおいて指定されたオブジェクト及び型情報の値を、再利用可能性を判定する前記コードに伝播させた判定用コードを生成し、生成した判定用コードの実行中になされたグローバルメモリへのアクセスが全て型情報の読み出しのためのアクセスであることを条件に、前記コードを再利用可能であると動的に判定する。また好ましくは、前記コンピュータが、再利用可能であると判定した前記コードに対し、該コードの実行によりアクセスされる型情報のアドレスを収集するテンプレートを生成するステップを更に含み、前記プロファイル情報は前記テンプレートの実行結果を利用して作成される。また好ましくは、前記実行対象のプログラムは、Pythonで記述されたソースプログラムからPythonインタプリタにより生成されたバイトコードである。以上、実行対象のプログラムにおけるサブクラステスト関数の実行結果を再利用するプログラムの最適化方法として本発明を説明した。しかし、本発明は、上記最適化方法をコンピュータに実行させるための最適化プログラムとして把握することもできる。また本発明は、当該最適化プログラムをインストールして最適化方法を実行する最適化装置として把握することもできる。本願発明は、サブクラステスト関数の関数呼び出しから呼び出されるコードが、グローバル情報へのアクセスとして型情報の読み込みのみを行うことを確認し、確認できたコードについて実行結果をプロファイルし再利用する構成を採用する。上述したように、型情報は実行時に変化しにくいため、上記構成の採用によって将来無効とする可能性の高い実行結果の再利用を排除できる。また、本願発明は、実行時にアクセスした型情報を監視し、変更があった場合には対応する実行結果の再利用を禁止する構成を採用する。結果、本願発明によれば、単純に実行結果を再利用する場合に比べてより効率的にまた安全にサブクラステスト関数の実行結果を再利用することが可能となる。更に本願発明の上記構成によれば、グローバルメモリへの書き込みを行うサブクラステスト関数は再利用対象から除かれるので、副作用のあるサブクラステスト関数の実行結果の再利用によりプログラム全体が間違った動作を行うことを防止できる。本願発明のその他の効果については、各実施の形態の記載から理解される。以下、本発明の実施形態を図面に基づいて詳細に説明するが、以下の実施形態は特許請求の範囲にかかる発明を限定するものではなく、また実施形態の中で説明されている特徴の組み合わせの全てが発明の解決手段に必須であるとは限らない。なお、実施の形態の説明の全体を通じて同じ要素には同じ番号を付している。本願発明のサブクラステスト関数のテスト結果を再利用する技術は、Pythonのような、サブクラステスト関数に該当するバイトコードが存在せず呼び出される関数の実体やクラスごとのサブクラスの定義が動的に変わり得る動的プログラミング言語に対し適用される。そこで、本願発明の詳細な説明に入る前に、Pythonにおけるサブクラステスト関数であるisinstance関数を例として、動作が一意に決まらないサブクラステスト関数がどのように実行されるのかその仕組みを説明する。Pythonではサブクラステスト関数に該当するバイトコードがなく、サブクラステスト関数の動作はPython関数により定義されている。従ってPythonにおいてサブクラステスト関数は関数呼び出しによって実行される。以下に示すコードは、isinstanceを呼び出すための一連のバイトコードの例である。LOADGLOBALisinstanceLOADFASTobjLOADFASTclazzCALLFUNCTIONisinstance関数の振る舞いは次の2つにより決まる。1isinstanceの値で関数呼び出しにより呼び出される関数2clazzにおけるクラス階層の定義プログラムは、Pythonのソースコードに含まれる各isinstance関数に対して、上記1を、グローバルにもローカルにも、また、静的にも動的にも変更し得る。なお、isinstance関数のデフォルトの振る舞いはCPython等のインタプリタシステムによって提供されており、isinstance関数は組込みC関数に、クラス階層の定義はC関数により提供されている。もしユーザがPythonのソースコードにおいてisinstance関数を新たに定義すると、そのisinstance関数は実行される度に異なるアルゴリズムを実行することが可能である。即ち、isinstance関数の振る舞いは、アプリケーションのレベルで自由に定義されまたは変更され得る。isinstance関数がデフォルトではない関数を呼び出すケースは主に以下の通りである。ケース1:isinstance関数がシステムのbuiltin用辞書において置き換えられている場合ケース2:現在のスコープにおいて別のisinstance関数が定義されている場合ケース3:クラスが独自のisinstance関数を持つ場合ケース1に関し、組込み関数は実行時いつでも、また、コードのどの地点でも置き換え可能である。置き換えによる変更はプログラム内のあらゆるコードから透過的に見ることができる。以下はケース1の例である。なお、左端の数字は行番号を表す。5行目において置き換えが指示されており、結果、6行目のisinstance関数の結果が、7及び8行目に示されるように置換されたisinstance関数の実行結果になっている。1importbuiltin2deff3printIamf4returnFalse5builtinisinstancef6isinstance7Iamf8Falseケース2に関し、あるモジュールに固有のisinstance関数を定義できる。定義はapyファイル内において静的に行うことができ、実行時いつでも、また、コードのどの地点でも追加、置き換え、削除が可能である。このような変更はプログラム内のあらゆるコードから透過的に見ることができる。以下はケース2の例である。ここでも左端の数字は行番号を表す。また、1行目~6行目はapyファイル内の定義を示し、7行目~16行目は、apyファイルをインポートした際の実行結果を示す。10行目~11行目では、apyファイルで定義した自身のisinstance関数が呼び出されているが、14行目で再度デフォルトのisinstance関数に復元され、結果、15行目ではデフォルトのisinstance関数が呼び出されている。apy1defisinstance2printaisinstance3returnFalse4classmyclass5deftest6returnisinstacerun7importa8adictkeys9builtinsfilemyclassnameisinstancedoc10oamyclass11otest12aisinstance13False14aisinstanceisinstance15otest16Trueケース3に関し、ユーザは、クラスを定義する際に特別なメタクラスを設定することにより、isinstance関数に対してデフォルトのアルゴリズムを変更することができる。より具体的には、アルゴリズムはメタクラスのinstancecheckを定義することにより実行時いつでも、また、コードのどの地点でも置換できる。このような変更はそのクラスと当該クラスのサブクラスから透過的に見ることができる。以下はケース3の例である。ここでも左端の数字は行番号を表す。また、1行目~12行目はbpyファイル内の定義を示し、13行目~28行目は、bpyを実行させた結果を示す。この例では、デフォルトのisinstance関数を呼び出しているが、しかしisinstance関数の実際の動作は、ユーザが定義した動作であることに留意されたい。デフォルトのisinstance関数であれば、isinstanceはもしT1がT2のサブクラスでなければFALSEを返す。しかしbpyを実行させた結果をみると、デフォルトのisinstance関数は、ユーザが定義したinstancecheckによってTRUEを返している。bpy1fromabcimportABCMeta2classMyABC3metaclassABCMeta4classmethod5definstancecheck6printMyABCinstancecheck7returnTrue8classMyClass9pass10classHisClass11pass12printisinstanceMyClassRunpythonbpy13importb14MyABCinstancecheck15True16classMyXYZ17deff18printMyXYZf19returnTrue20oMyXYZ21bMyABCinstancecheck2223bMyABCinstancecheckof24bMyABCinstancecheck2526isinstancebMyClass27MyXYZf28True本願発明は、Pythonのように、サブクラステスト関数に該当するバイトコードが存在せず呼び出される関数の実体やクラスごとのサブクラスの定義が動的に変わり得る動的プログラミング言語に適用可能な、サブクラステスト関数の実行結果の再利用によるプログラムの最適化手法を提供する。当該手法は、サブクラステスト関数のコードの再利用可能性を判定する段階、再利用可能であると判定したサブクラステスト関数のコードの実行をプロファイルする段階、再利用可能であると判定したコードを呼び出す関数呼び出しを検出し、該関数呼び出しに対し一定の条件の下実行結果を再利用する段階、及び、実行結果の再利用が不適切となる状況の発生を監視し、再利用を禁止する段階を含む。上記4つの段階を含む最適化手法の具体的な実装方法は、インタプリタがプログラムの実行中にプロファイルを行い、JustInTimeコンパイラによりコンパイルされたJITコードがプロファイル結果を利用する第1の実装方法、プログラムの実行中にインタプリタ自身がプロファイル結果をキャッシュして利用する第2の実装方法、及び最適化レベルの低いJITコードがテスト結果をプロファイルし、最適化レベルの高いJITコードがプロファイル結果を利用する第3の実装方法等、複数考えられる。以下では、第1の実装方法に従って本願発明の実施形態を説明する。図1は、本願発明の実施形態に係る最適化装置100の機能ブロック図を示す。最適化装置100は、動的プログラミング言語で記述されたソースプログラムから生成され、仮想マシンによって実行されるバイトコードである実行対象のプログラムを実行する実行環境図示しないを備え、該実行環境において、記憶装置105と、イベント作成部110と、再利用可能性判定部120と、プロファイリング部130と、再利用処理部140と、監視部145とを含む。なお、以下では、実行対象のプログラムは、Pythonで記述されたソースプログラムからPythonインタプリタにより生成されたバイトコードであるとして説明する。記憶装置105は、再利用可能性判定部120によるサブクラステスト関数のコードの解析結果を格納する解析結果DB115と、プロファイリング部130によるサブクラステスト関数のプロファイリング結果を格納するプロファイリングDB125と、再利用処理部140により生成されたサブクラステスト関数の実行結果を再利用するコンパイル済みコードを格納する再利用コードDB135とを含む。それぞれのDBに格納される情報の詳細は、以下に説明する各要素に関連して後述する。イベント作成部110は、実行対象のプログラムにおいて次に実行されるバイトコードがサブクラステスト関数の関数呼び出しであることに応答して、関数呼び出しが呼び出すコードを指す関数ポインタと、関数呼び出しにおいて指定された指定情報とからなるイベント情報を作成する。ここで、サブクラステスト関数の関数呼び出しにおいて指定された指定情報とは、関数呼び出しにおける入力パラメータであり、テスト対象のオブジェクトと型クラスとを指定する情報である。なお、イベント作成部110により作成されるイベント情報は、更にカウンタ情報を含んでよく、イベント作成部110は、既にそのイベント情報を作成したサブクラステスト関数と同一のサブクラステスト関数が同一の入力パラメータを伴って呼び出された場合、対応するイベント情報のカウンタを1増分する。図2は、Pythonバイトコードにおける関数呼び出しと、関数呼び出しから呼び出されるコードとの関係の一例を示す。上述したように、Pythonソースコードにおけるサブクラステスト関数isinstanceは、Pythonインタプリタにより以下のような関数呼び出しCALLFUNCTIONを含む一連のバイトコードに変換される。LOADGLOBALisinstanceLOADFASTobjLOADFASTclazzCALLFUNCTION図2が示すように、関数呼び出しは、実際にはサブタイプテストラッパを介してサブクラステスト関数の実体であるコード図2ではサブルーチンと表示を呼び出す。再利用可能性判定部120は、実行対象のプログラムに含まれるサブクラステスト関数の関数呼び出しから呼び出されるコードの再利用可能性を、該コードにおけるグローバルメモリへのアクセスが、サブクラステスト関数の関数呼び出しにおいて指定された型情報及び該型情報から辿ることの可能な情報の読み出しのためのアクセスのみを含むか否かに基づいて判定する。ここで、サブクラステスト関数の関数呼び出しにおいて指定された型情報から辿ることの可能な情報とは、型情報であるクラスオブジェクトが有するポインタによって指される情報であり、一例として親クラスオブジェクトである。また、グローバルメモリとは、そのメモリへの変更がその変更を行った関数のような実行単位を抜けた後でも参照できるメモリ領域を意味し、例えばオブジェクトヒープやグローバル変数を含む。なお、再利用可能性判定部120は上記処理を、イベント作成部110による処理に応答して、イベント情報のカウンタが予め設定された所定の回数以上であることを条件に行ってよい。上述したように型情報は実行時に変化しにくいため、グローバル情報へのアクセスとして型情報の読み込みのみを行うことを条件としてサブクラステスト関数の実行結果を再利用可能と判定することで、将来無効とする可能性の高い実行結果の再利用を排除できる。また、上記条件によれば、グローバルメモリへ書き込みを行うサブクラステスト関数は再利用対象から除かれる。サブクラステスト関数内で書き込まれたグローバルメモリ内の値が他のスレッドにより参照される場合、実行結果の再利用によりサブクラステスト関数が実行されなくなると他のスレッドが間違った値を読み込んでしまう可能性がある。そのため、このような副作用を起こす可能性のあるサブクラステスト関数を再利用対象から除くことで、プログラムが全体として間違った動作をする事態を回避できる。なお、再利用可能性判定部120による上記判定は、一例として次のように静的に行ってよい。即ち、再利用可能性判定部120は、再利用可能性を判定するコードからグローバルメモリへのアクセス命令を全て探し出し、探し出した全てのアクセス命令が、サブクラステスト関数の関数呼び出しにおいて指定される型情報及び該型情報から辿ることの可能な情報の読み出しのためのアクセスであることを条件に、上記コードを再利用可能であると判定してよい。上記静的判定方法に代えて、再利用可能性判定部120は、サブクラステスト関数の関数呼び出しにおいて指定されたオブジェクト及び型情報の値を、再利用可能性を判定するコードに伝播させた判定用コードを生成し、生成した判定用コードの実行中になされたグローバルメモリへのアクセスが全て型情報の読み出しのためのアクセスであることを条件に、上記コードを再利用可能であると判定してよい。ここで判定用コードは、サブクラステスト関数の関数呼び出しにおいて指定されたオブジェクトと型情報のペアの統計をプロファイルし、ペアの集合が大きくなくキャッシュの効果があると判定することを条件に生成するのが好ましい。そして、ペアごとその値を固定した判定用コードを生成し、生成した全判定用コードについて、実行中になされたグローバルメモリへのアクセスが全て型情報の読み出しのためのアクセスであることを確認することを条件に、上記サブクラステスト関数のコードを再利用可能であると判定するのが好ましい。また、再利用可能性判定部120は、再利用可能であると判定したサブクラステスト関数のコードに対し、コードの実行によりアクセスされる型情報のアドレスを収集するテンプレートを作成するのが好ましい。テンプレートは、後述するプロファイリング部130により実行され利用される。なお、テンプレートは、一例として上記判定用コードに、次のようなinstrumentコードを挿入することにより作成してよい。そのようなinstrumentコードとは、判定用コードが実際に読み込む型情報が記憶されているメモリのアドレスを収集し、収集したアドレスを所定の領域一例として、オブジェクトであるテンプレートの所定のフィールド以下、TypeInfoReadSetというに格納するコードであってよい。なお、テンプレート作成時点において所定の領域一例として、TypeInfoReadSetは空とする。再利用可能性判定部120は、サブクラステスト関数の関数呼び出しから呼び出されるコードについて再利用可能であると判定した場合、生成したテンプレートと一緒に、イベント生成部110が生成した上記関数呼び出しのイベント情報を解析結果DB115に格納する。また、再利用可能性判定部120は、再利用可能であると判定したコードオブジェクトに、例えば1フィールド追加してテンプレートを指すポインタを設定する等マークを付けて、再利用可能であることを示してよい。プロファイリング部130は、再利用可能性判定部120により再利用可能であると判定されたサブクラステスト関数のコードの実行結果を、該コードの関数呼び出しにおいて指定された指定情報と共に、該コードにおいて実際にアクセスされた型情報に関連付けて、上記コードのプロファイル情報としてプロファイルDB125に格納する。ここでコードの実行結果とは、サブクラステスト関数の関数呼び出しにおいて指定されたテスト対象のオブジェクトが、同じく関数呼び出しにおいて指定されたクラスのインスタンス又は該クラスのサブクラスのインスタンスであるか否かを示すブーリアン型の情報である。なお、再利用可能であると判定されたコードであるか否かは、再利用可能性判定部120によりコードに付けられたマークによって識別される。また、上述したようにプロファイリング部130は、サブクラステスト関数のコードにおいて実際にアクセスされた型情報を、再利用可能性判定部120により作成されたテンプレートを実行することにより収集してよい。即ち、プロファイリング部130は、再利用可能であると判定されたサブクラステスト関数のコードの実行に応答して、該コードを指す関数ポインタをキーとして解析結果DB115から対応するイベント情報とテンプレートとを読み出す。そして、プロファイリング部130は、読み出したテンプレートを実行して、そのTypeInfoReadSetフィールドから実際にアクセスされた型情報のアドレスを取得してよい。読み出した対応するイベント情報と取得した型情報のアドレスは、それぞれ後述する監視部145と再利用処理部140による処理にためにプロファイルDB125に格納される。プロファイリング部130はまた、好ましくは、サブクラステスト関数のコードの実行結果と共に、コード実行時の名前空間をプロファイル情報としてプロファイルDB125に格納する。これは、本願発明が対象とする動的プログラミング言語では、サブクラステスト関数に該当するバイトコードが存在せず呼び出される関数の実体が動的に変わり得るため、プロファイル時と実行結果の再利用時とでサブクラステスト関数の関数呼び出しにより呼び出されるコードが異ならないことを、実行結果の再利用時に名前空間を利用して確認できるようにするためである。Pythonにおいて名前空間は、オブジェクトの名前をキーとして指定すると、対応するオブジェクトを返す辞書と考えることができる。名前空間は、関数呼び出しを含むオブジェクト全体に対して1つに決まる現在の辞書とする一方で、呼び出される関数のアルゴリズムが変更されたり、同名の新たなオブジェクトが定義されたりすると、現在の辞書が他の辞書に切り替わったり、辞書の内容が変わったりする。そこで、プロファイル時と実行結果の再利用時とで名前空間が一致することを確認することにより、サブクラステスト関数の関数呼び出しにより呼び出されるコードが同一であることを確認することができる。なお、サブクラステスト関数がシステムのbuiltin用辞書において置換されることは稀である。そこで、名前空間の利用に代えて、再利用のために実行結果を格納すべきサブクラステスト関数のコードを、システムに組み込まれたデフォルトのサブクラステスト関数のコードに限定することにより、プロファイル時と実行結果の再利用時とで呼び出されるコードが異ならないことを緩く保証してもよい。この場合、デフォルトのコードのポインタを予め取得し、再利用時には、再利用しない場合に呼び出されるはずだったコードのポインタが予め取得したポインタと一致することを確認する。なお、名前空間を利用したガード機構は、Pythonに限定されるものではなく、名前空間に関してPythonと同様のルールを採用する他の動的プログラミング言語に適用可能なことはいうまでもない。図3は、プロファイリング部130により記憶装置105に格納されるプロファイル情報の一例を示す。図3においてバイトコード300は関数呼び出し305を含み、該関数呼び出し305はサブクラステスト関数310のコードを呼び出す。プロファイルリポジトリ320は、プロファイル情報を格納する記憶装置105内の領域を示し、図1においけるプロファイルDB125に相当する。プロファイル325は、サブクラステスト関数310についてのプロファイル情報の集合であり、サブクラステスト関数310を指すポインタPC330と、互いに異なる入力パラメータを伴って呼び出された際のプロファイル情報335、340を含む。各プロファイル情報は、対応するイベント情報Eと、名前空間Nと、実行時にアクセスされた型情報のアドレスの集合Rと、実行結果Lとを含む。再利用処理部140は、再利用可能であると判定したコードを呼び出すサブクラステスト関数の関数呼び出しの検出に応答して、プロファイルDB125から対応するプロファイル情報を読み出し、検出した関数呼び出しにおいて指定される指定情報とプロファイル情報の指定情報とが一致することを条件にプロファイル情報の実行結果を再利用する。再利用可能と判定した関数呼び出しの検出は、関数ポインタをキーとして、対応するプロファイル情報がプロファイルDB125に存在することを確認することにより行ってよい。好ましくは、再利用処理部140は、検出した関数呼び出しが再利用可能であると判定されたコードを呼び出すことを、プロファイル情報作成時と再利用時とで名前空間が一致することを確認することにより保証する。JITコードがプロファイル結果を利用する第1実装方法に従う本実施形態では、実行結果はコンパイル済みコードにおいて利用される。即ち、再利用処理部140は、現在の関数呼び出しにおいて指定される指定情報がプロファイル情報に含まれる指定情報と一致することを条件にプロファイル情報に含まれる実行結果を再利用する再利用コードを生成する。生成された再利用コードは、最適化装置100による実行のため、再利用コードDB135に格納される。再利用処理部140によって生成される再利用コードの一例を以下に示す。当該例では、関数呼び出しにおいて指定される指定情報、即ち、オブジェクトと型情報が一致することに加えて、名前空間が一致することを、実行結果を利用する条件としている。なお、cacheForThisCodecountは、検出した関数呼び出しにより呼び出されるコードのプロファイル情報のエントリ数を示す。forifcacheForThisCodeentryiobjobjcacheForThisCodeentryiobjTypeobjTyperesultcacheForThisCodeentryiresultbreakなお、上記示した再利用コードに、一致するプロファイル情報のエントリが全くない場合は、サブクラステスト関数を呼び出す命令を追加してもよい。またコード中でループを展開して配列の要素引きをやめて効率化してもよい。またコード中で定数と判断される場合たとえばクラス引数が定数、コンパイラはコード中でそうした情報を適宜伝搬して再利用コードを効率化することも可能である。また名前空間の内容は不変なものと仮定する技術により、名前空間の識別子比較および不変性チェックにより一致確認を高速化することも可能である。監視部145は、プロファイルDB125に格納されているプロファイル情報に含まれる実行結果に関連付けられた型情報を監視して、該型情報に対する変更に応答して型情報に関連付けられた実行結果の再利用を禁止する。ここで実行結果の再利用の禁止は、変更のあった型情報に関連付けられたプロファイル情報又は該プロファイル情報を含むコードごとのプロファイル情報の集合の削除、及び変更のあった型情報に関連付けられる実行結果を再利用する再利用コードの削除の少なくとも一方を含む。監視部145の具体的な実装方法はいくつか考えられるが、ここでは、監視対象の型情報を操作するコードに監視部145の機能を果たすコードを挿入する第1の実装方法と、監視対象の型情報の変更イベントに対応するリスナーを利用する第2の実装方法の2つについて順に説明する。第1の実装方法では、再利用処理部140が、実行結果の再利用に応答して、型情報を操作する操作コードにアクセスし、該操作コードに、再利用する実行結果に関連付けられた型情報を変更することを条件として実行結果を再利用する再利用コードを無効化する命令列を挿入する。すると、監視部145は、操作コードの実行に伴って上記命令の実行により実現される。ここで、型情報を操作する操作コードはインタプリタの実装コードである場合と、JITコンパイラによりコンパイラされたJITコードである場合がある。なお、Pythonインタプリタでは型情報を操作する操作コードは限られており既知であるため、そのような操作コードは事前にリストしておき、無効化のための命令列を挿入する際はリストを参照するものとする。操作コードの型情報を操作する部分と、操作コードに挿入する命令列の一例を以下に示す。なお、再利用された実行結果のプロファイル情報には、実行中にアクセスされた型情報として以下に示すA.クラスオブジェクトのparentsフィールドを指すポインタと、実行結果を再利用した再利用コードを指すポインタが含まれているものとする。そして、これら2つのポインタ情報はgetNextTypeInfoReadSet関数によって取得されるものとする。挿入する命令列は、監視対象の型情報を操作する命令の前後いずれかに挿入される。A.クラスオブジェクトstructclassobjectheadertheaderlisttparents...B.型情報を操作する操作コードの操作部分tparentspC.挿入する命令列whileifInvalidate第2の実装方法では、監視部145は、プロファイル情報として格納される実行結果に関連付けられた型情報の変更イベントに対応するリスナーとして実現される。リスナーは、プロファイリング部130によってプロファイル情報が作成される際に生成され、対応するプロファイル情報へのポインタを有し、対応するプロファイル情報に含まれる実際にアクセスされた型情報が示す全てのクラスオブジェクトに登録される。そしてリスナーは、いずれかのクラスオブジェクトから型情報の変更イベントの通知を受け取ると、ポインタを使用して対応するプロファイル情報を無効化する。図4Aは、プロファイリング部130によりリスナーが生成され、該リスナーが対応するクラスオブジェクトに登録されるまでの処理の概要を示す。なお、図4Aでは、プロファイリング部130をプロファイラ415として、またプロファイルDB125を、プロファイルリポジトリ420として示している。1.バイトコード400に含まれる関数呼び出し405がサブクラステスト関数410を呼び出す。2.プロファイラ415は、サブクラステスト関数410の呼び出しを検出し、3.サブクラステスト関数410の実行結果をプロファイル情報440としてプロファイルリポジトリ420に格納する。4.プロファイラ415は、プロファイル情報440へのポインタを有する、プロファイル情報440に関するリスナーである第2リスナー450を作成し、5.第2リスナー450をプロファイル情報440に含まれる実際にアクセスされた型情報が示すクラスオブジェクト460に登録する。同様に、図4Aに示される第1リスナー445は、プロファイル情報435へのポインタを有し、クラスオブジェクト455の変更イベントに対応するリスナーである。図4Bは、生成されたリスナーが対応するクラスオブジェクトから変更イベントの通知を受け、対応するプロファイル情報を無効化するまでの処理の概要を示す。なお、図4Bでは、図4Aに示した要素と同一の要素には同じ番号を振っている。1.クラスオブジェクト455に対し変更が加えられる。2.第1リスナー445は、クラスオブジェクト455から変更イベントの発生の通知を受け取る。3.第1リスナー445は、自身が有する対応するプロファイル情報435へのポインタを使って、対応するプロファイル情報435をプロファイルリポジトリ420から削除して無効化し、また、自分自身第1リスナー445を消去する。この際第1リスナー445は、同じコードに対する他の全てのプロファイル情報440及び該プロファイル情報440に関連付けられる第2リスナー450を無効化してもよい。第2の実装方法ではまた、監視部145は、再利用された実行結果に関連付けられた型情報の変更イベントに対応するリスナーとしても実現される。リスナーは、再利用処理部140によって実行結果が再利用される際に生成され、対応する実行結果を再利用する再利用コードへのポインタを有し、対応するプロファイル情報に含まれる実際にアクセスされた型情報が示す全てのクラスオブジェクトに登録される。そしてリスナーは、いずれかのクラスオブジェクトから型情報の変更イベントの通知を受け取ると、ポインタを使用して対応する再利用コードを無効化する。図5Aは、再利用処理部140によりリスナーが生成され、該リスナーが対応するクラスオブジェクトに登録されるまでの処理の概要を示す。なお、図5Aに示されるコンパイル済みコード500は、図4Aに示した関数呼び出し405を、プロファイル425を用いて最適化したものである。プロファイル425には、関数呼び出し405の入力パラメータの2種類のペアについての実行結果であるプロファイル情報435、440が含まれることから、コンパイル済みコード500は、検出した現在の関数呼び出し405において指定される型情報をこれら2種類の入力パラメータのペアとそれぞれ比較し、一致した方のプロファイル情報に含まれる実行結果を利用するよう記述されている。1.再利用処理部140により、図4Aに示すプロファイル情報440を使用してコンパイル済みのコード500が生成される。2.再利用処理部140は、コンパイル済みのコード500へのポインタを有する、コンパイル済みコード500関するリスナーである第4リスナー540を作成し、3.第4リスナー540を、プロファイル情報440に含まれる実際にアクセスされた型情報が示すクラスオブジェクト545に登録する。同様に、図5Aに示される第3リスナー525は、コンパイル済みのコード500へのポインタを有し、プロファイル情報440に含まれる実際にアクセスされた他の型情報が示すクラスオブジェクト530に登録されるリスナーである。図5Bは、生成されたリスナーが対応するクラスオブジェクトから変更イベントの通知を受け取り、対応するコンパイル済みコードを無効化するまでの処理の概要を示す。示す。なお、図5Bでは、図5Aに示した要素と同一の要素には同じ番号を振っている。1.クラスオブジェクト530に対し変更が加えられる。2.第3リスナー525は、クラスオブジェクト530から変更イベントの発生の通知を受け取る。3.第3リスナー525は、自身が有するコンパイル済みのコード500に含へのポインタを使って、対応するコンパイル済みコード500の全体を無効化する。また、第3リスナー525は、自分自身第3リスナー525及び関連する他の第4リスナー540を消去してもよい。次に図6乃至図10を参照して、本願発明の実施形態に係る最適化装置100の動作を説明する。図6は、最適化装置100によるプログラム実行処理の流れの一例を示すフローチャートである。図7は、図6に示すフローチャートのステップ624に示す再利用可能性判定処理の流れの一例を示すフローチャートである。図8は、図6に示すフローチャートのステップ630に示すプロファイルリングの流れの一例を示すフローチャートである。なお、第1の実装方法に従う本願発明の実施形態では、図6に示すプログラム実行処理はインタプリタによって実行される。また、図7に示す再利用可能性判定処理は、インタプリタから呼び出された再利用可能性判定モジュール再利用可能性判定120に対応によって、図8に示すプロファイルリングは、インタプリタから呼び出されたプロファイリングモジュールプロファイリング部130に対応によってそれぞれ実行される。また、図9は、最適化装置100によるコンパイル処理の流れの一例を示すフローチャートである。図10は、最適化装置100による監視処理の流れの一例を示すフローチャートである。なお、第1の実装方法に従う本願発明の実施形態では、図9に示すコンパイル処理はJITコンパイラによって実行される。また、図10に示す監視処理は、型情報に対する操作がインタプリタによりなされる場合にはインタプリタにより、また、型情報に対する操作がJITコードによりなされる場合にはJITコードにより実行される。図6に示すプログラム実行処理はステップ600から開始し、最適化装置100は、実行対象のプログラムから次に実行すべきバイトコードBをフェッチする。続いて最適化装置100は、次に実行すべきバイトコードBがあるか否かを判定するステップ602。次に実行すべきバイトコードBがない場合ステップ602:NO、処理は終了する。一方、次に実行すべきバイトコードBがある場合ステップ602:YES、最適化装置100は、バイトコードBがCALLFUNCTION命令であるか否かを判定するステップ604。バイトコードBがCALLFUNCTION命令である場合ステップ604:YES、最適化装置100はCALLFUNCTION命令により呼び出されるターゲットの関数を取得しステップ606、関数Fがサブタイプテストラッパであるか否かを判定するステップ608。関数Fがサブタイプテストラッパである場合ステップ608:YES、最適化装置100はイベントEを作成するステップ612。なお、イベントEは、CALLFUNCTION命令によりサブタイプテストラッパを介して呼び出されるサブクラステスト関数のコードCの関数ポインタと、CALLFUNCTION命令に関して指定される引数のペアとからなる情報である。続いて最適化装置100は、イベントEの頻度をプロファイルしステップ614、イベントEの頻度に関するプロファイル情報が既に存在するか否かを判定するステップ616。イベントEの頻度に関するプロファイル情報は、最適化装置100の記憶装置105に格納されてよい。イベントEのプロファイル情報が記憶装置105に存在しない場合ステップ616:NO、最適化装置100はイベントEの頻度に関するプロファイル情報を作成し、記憶装置105に格納するステップ620。一方、イベントEのプロファイル情報が既に記憶装置105に存在する場合ステップ616:YES、最適化装置100は、記憶装置105に格納されるイベントEの頻度情報を更新する。なお、四角640で囲ったステップ614からステップ620までの一連の処理はオプションであってよく、頻繁に実行されるコードに関して最適化を行いたい場合等必要に応じて適宜行ってよい。続いて最適化装置100は、解析結果DB115にイベントEが存在するか否かを判定するステップ622。解析結果DB115にイベントEが存在しない場合ステップ622:NO、最適化装置100はバイトコードBが呼び出すサブクラステスト関数のコードCに関して再利用可能性を判定するステップ624。再利用可能性判定処理の詳細は、図7を参照して後述する。続いて最適化装置100は、再利用可能性判定処理の結果が、再利用可能であるか否かを判定するステップ626。サブクラステスト関数のコードCについて再利用可能でないとの判定結果が出された場合ステップ626:NO、ステップ604においてバイトコードBがCALLFUNCTION命令でない場合、またはステップ608において関数Fがサブタイプテストラッパでない場合、処理はステップ610へ進み、最適化装置100はバイトコードBを実行する。そして処理はステップ600へ戻り、最適化装置100は一連の処理を繰り返す。一方、ステップ626において、サブクラステスト関数のコードCについて再利用可能であるとの判定結果が出された場合、またステップ622において解析結果DB115にイベントEが存在した場合、処理はステップ628へ進み、最適化装置100はバイトコードBを実行する。これに平行して又は実行の後、最適化装置100は、バイトコードBにより呼び出されるサブクラステスト関数のコードCの実行結果のプロファイリングを行うステップ630。プロファイリングの詳細は、図8を参照して後述する。そして処理はステップ600へ戻り、最適化装置100は一連の処理を繰り返す。図7に示す再利用可能性判定処理部120による再利用可能性判定処理はステップ700から開始し、再利用可能性判定部120は、記憶装置105からイベントEの情報、即ち、関数ポインタと引数のペアの値を読み出し、サブクラステスト関数のコードCに引数のペアの値を伝播させて判定用コードSを作成する。なお、イベントEについて頻度情報が記憶装置105に格納されている場合、再利用可能性判定部120は、一定以上の頻度情報を有するイベントEに対してのみ、以下の処理を行ってもよい。続いて、再利用可能性判定部120は、判定用コードSを実行し、実行中にグローバルメモリへの書込みがあるか否か及びグローバル情報として型情報のみを読み込むか否かを判定するステップ702、704。グローバルメモリへのアクセスが型情報の読み込みのためのアクセスのみでない場合ステップ702:YES又はステップ704:NO、再利用可能性判定部120は、再利用不可の判定結果を生成するステップ712。その後処理は終了する。一方、グローバルメモリへのアクセスが型情報の読み込みのためのアクセスのみである場合ステップ702:NOかつステップ704:YES、再利用可能性判定部120は、サブクラステスト関数のコードCの実行中にアクセスされる型情報のアドレスを収集し、収集した情報を自身のTypeInfoReadSetフィールドに格納するテンプレートTを作成するステップ706。そして再利用可能性判定部120は、生成したテンプレートTと一緒にイベントEを解析結果DB115へ格納しステップ708、再利用可能の判定結果を生成するステップ710。そして処理は終了する。図8に示すプリファイリング部130によるプロファイリング処理はステップ800から開始し、プロファイリング部130は、イベントEに対応するプロファイル情報がプロファイルDB125に存在するか否かを判定する。イベントEに対応するプロファイル情報がプロファイルDB125に既に存在する場合ステップ800:YES、処理は終了する。一方、イベントEに対応するプロファイル情報がプロファイルDB125にまだ存在しない場合ステップ800:NO、プロファイリング部130は、バイトコードBの実行結果Lと、名前空間Nを取得するステップ802、ステップ804。また、プロファイリング部130は、バイトコードBが関数呼び出しのために使用する関数ポインタをキーとして、解析結果DB115からイベントEとテンプレートTを取得するステップ806。そしてプロファイリング部130は取得したテンプレートTを実行して、テンプレートTのTypeInfoReadSetフィールドから実行中にアクセスされた型情報Rのアドレスの集合を取得するステップ810。続いてプロファイリング130は、バイトコードBに再利用可能であることを示すマークを付けステップ810、プロファイルDB125にバイトコードBのプロファイル情報としてイベントE、名前空間N、型情報Rのアドレスの集合、実行結果Lを格納するステップ812。そして処理は終了する。図9に示すコンパイル処理はステップ900から開始し、最適化装置100は実行対象のプログラムから次に実行すべきバイトコードBをフェッチする。続いて最適化装置100は、未処理のバイトコードBがあるか否かを判定するステップ902。未処理のバイトコードBがない場合ステップ902:NO、処理は終了する。一方、未処理のバイトコードBがある場合ステップ902:YES、最適化装置100は、バイトコードBに対応するプロファイル情報がプロファイルDB125に存在するか否かを判定するステップ904。かかる判定は、バイトコードBがサブクラステスト関数のコードCを呼び出すCALLFUNCTION命令であること、そして関数呼び出しのために使用される関数ポインタをキーとして、サブクラステスト関数のコードCについてのプロファイル情報がプロファイルDB125から探し出せることを確認することによりなされる。ステップ904において、対応するプロファイル情報がプロファイルDB125に存在しない場合、最適化装置100は、バイトコードBを従来技術に基づきコンパイルして最適化するステップ906。そして処理はステップ900へ戻り、最適化装置100は一連の処理を繰り返す。一方、ステップ904において、対応するプロファイル情報がプロファイルDB125に存在する場合、最適化装置100は、プロファイルDB125からバイトコードBに対応する全てのプロファイル情報、即ち、バイトコードBから呼び出されるサブクラステスト関数のコードCについてのプロファイル情報E、N、R、Lの全ての組を読み出すステップ908。続いて最適化装置100は、読み出したプロファイル情報E、N、R、Lの各組について、再利用コードJの生成ステップ910と、監視コードDの生成及び挿入ステップ912とをそれぞれ行う。より具体的には、ステップ910において最適化装置100は、サブクラステスト関数を呼び出すバイトコードBのコンパイル済みコードとして、現在のサブクラステスト関数の関数呼び出しにおいて指定される引数のペアの値が、プロファイル情報のイベントEに含まれる引数のペアの値と一致し、かつ、現在の名前空間とプロファイル情報の名前空間Nとが一致することを条件にプロファイル情報に含まれる実行結果Lを再利用する再利用コードJを生成する。また、ステップ912はプロファイル情報の型情報の集合Rに含まれる各アドレスAについて実行され、最適化装置100は、アドレスAのメモリの値を変更し得る操作コードMにアクセスし、操作コードMの当該操作コード部分の前後に、変更されたメモリのアドレスがAであることを条件に再利用コードJを無効化する命令列を挿入する。ステップ910及びステップ912の処理がプロファイル情報E、N、R、Lの全組についてなされると、その後処理はステップ900へ戻り、最適化装置100は、一連の処理を繰り返す。なお、第1の実装方法に従う本願発明の実施形態では、図9において四角920で囲まれた部分の処理は、JITコンパイラにより呼び出された再利用処理モジュール再利用処理部140に対応により行われる。図10に示す監視部145による監視処理は、図9のステップ912において1以上の監視コードDを挿入された操作コードMの操作コード部分が実行され、アドレスYのメモリが変更されることにより開始される。監視部145は、操作コードMに挿入された各監視コードDについて、アドレスYとアドレスAが一致するか否かを判定するステップ1000。なお、監視コードDは対応するサブクラステスト関数のコードCの実行中にアクセスされた型情報の数だけ存在し、各監視コードDはそれぞれ異なる型情報に対する変更を監視するため、互いに異なる型情報のアドレスAに関連づけられることに留意されたい。いずれかの監視コードDについてステップ1000においてアドレスYとアドレスAが一致すると判定された場合、監視部145は対応する再利用コードJを削除により無効化するステップ1002。その後監視部145による処理は終了し、操作コードMの本来の処理に戻る。一方、ステップ1000においてアドレスYとアドレスAが一致しないとの判定がなされた場合、続いて監視部145は、未処理の監視コードDがあるか否かを判定しステップ1004、未処理の監視コードDがある場合ステップ1004:YES、ステップ1000に戻って一連の処理を繰り返す。一方、未処理の監視コードDがない場合ステップ1004:NO、監視部145による処理は終了し、操作コードMの本来の処理に戻る。図11は、本実施形態に係るコンピュータ50のハードウェア構成の一例を示した図である。コンピュータ50は、バス2に接続されたメインCPU中央処理装置1とメインメモリ4を含んでいる。ハードディスク装置13、30、及びCD-ROM装置26、29、フレキシブルディスク装置20、MO装置28、DVD装置31のようなリムーバブルストレージ記録メディアを交換可能な外部記憶システムがフレキシブルディスクコントローラ19、IDEコントローラ25、SCSIコントローラ27などを経由してバス2へ接続されている。フレキシブルディスク、MO、CD-ROM、DVD-ROMのような記憶メディアが、リムーバブルストレージに挿入される。これらの記憶メディアやハードディスク装置13、30、ROM14には、オペレーティングシステムと協働してCPU等に命令を与え、本発明を実施するためのコンピュータプログラムのコードを記録することができる。即ち、上記説明した数々の記憶装置には、上述した最適化装置100に、動的プログラミング言語で記述されたソースプログラムから生成され、仮想マシンによって実行されるバイトコードである実行対象のプログラムを実行する実行環境を与えるためのプログラムを記録することができる。即ち、上記説明した数々の記憶装置には、Cpython等のインタプリタ、SSLやzlib等のインタプリタにより利用される種々のライブラリ、JITコンパイラ、JITコンパイラにより生成されるJITコードを記録することができる。また、上記説明した数々の記憶装置には、コンピュータ50にインストールされ、コンピュータ50を最適化装置100として機能させる、最適化プログラムを記録することができる。上記最適化プログラムは、イベント作成モジュールと、再利用可能性判定モジュールと、プロファイリングモジュールと、再利用処理モジュールと、監視モジュールとを含む。これらモジュールは、CPU1等に働きかけて、コンピュータ50を、イベント作成部110、再利用可能性判定部120、プロファイリング部130、再利用処理部140、および監視部145としてそれぞれ機能させる。コンピュータプログラムは圧縮し、また複数に分割して複数の媒体に記録することもできる。コンピュータ50は、キーボード/マウスコントローラ5を経由して、キーボード6やマウス7のような入力デバイスからの入力を受ける。コンピュータ50は、オーディオコントローラ21を経由して、マイク24からの入力を受け、またスピーカー23から音声を出力する。コンピュータ50は、視覚データをユーザに提示するための表示装置11に、グラフィックスコントローラ10を経由して接続される。コンピュータ50は、ネットワークアダプタ18イーサネット登録商標カードやトークンリングカード等を介してネットワークに接続し、他のコンピュータ等と通信を行うことが可能である。以上の説明により、本実施形態に係るコンピュータ50は、通常のパーソナルコンピュータ、ワークステーション、メインフレームなどの情報処理装置、又は、これらの組み合わせによって実現されることが容易に理解されるであろう。なお、上記説明した構成要素は例示であり、そのすべての構成要素が本発明の必須構成要素となるわけではない。以上、実施形態を用いて本願発明の説明をしたが、本願発明の技術範囲は上記実施形態に記載の範囲には限定されない。上記の実施形態に、種々の変更又は改良を加えることが可能であることが当業者に明らかである。例えば、上述した本願発明の実施形態は、インタプリタがプログラムの実行中にプロファイルを行い、JITコンパイラによりコンパイルされたJITコードがプロファイル結果を利用する第1の実装方法に従うとして説明したが、本願発明は、プログラムの実行中にインタプリタ自身がプロファイル結果をキャッシュして利用する第2の実装方法、及び最適化レベルの低いJITコードがテスト結果をプロファイルし、最適化レベルの高いJITコードがプロファイル結果を利用する第3の実装方法により実装することも可能である。図12Aは、第1の実装方法における、再利用プログラムの構成モジュール1212~1218と、JITコンパイラ1206と、インタプリタ1208と、JITコード1210の関係を示した図である。第1の実装方法では、再利用可能性判定モジュール1214と、プロファイリングモジュール1216は、実行対象のプログラムを実行中のインタプリタ1208により呼び出される。また、再利用処理モジュール1212は、実行対象のプログラムのコンパイル時にJITコンパイラ1206により呼び出される。また、監視モジュール1218は、型情報に対する操作がインタプリタ1208によりなされる場合にはインタプリタ1208により、また、型情報に対する操作がJITコード1210によりなされる場合にはJITコード1210により呼び出される。図12Bは、第2の実装方法における、再利用プログラムの構成モジュール1214~1220と、JITコンパイラ1206と、インタプリタ1208と、JITコード1210の関係を示した図である。第2の実装方法は、再利用処理モジュール1220が、実行対象のプログラムを実行中のインタプリタ1208により呼び出される点で第1の実装方法と異なる。なお、第2の実装方法における再利用処理モジュール1220は、上記説明した再利用処理部140に対応する図12Aに示す再利用処理モジュール1212と異なり、再利用コードを生成するのではなく、名前空間と引数のペアの値の一致を条件として、実行結果を直接再利用する機能をインタプリタ1208に提供する。図12Cは、第3の実装方法における、再利用プログラムの構成モジュール1212~1218と、JITコンパイラ1206と、インタプリタ1208と、JITコード1210の関係を示した図である。第3の実装方法は、再利用可能性判定モジュール1214とプロファイリングモジュール1216が、JITコード1210により呼び出される点で第1の実装方法と異なる。なお、第3の実装方法では、JITコンパイラ1206は、再利用処理モジュール1212を呼び出して最適化レベルの高いJITコードを生成する前に、図12Cに図示しない新規のモジュールを呼び出して、最適化レベルの低いJITコードとして、再利用可能性判定モジュール1222とプロファイリングモジュール1224を呼び出すJITコード1210を生成する。以上のように、上記の実施形態に変更又は改良を加えた形態も当然に本発明の技術的範囲に含まれる。なお、特許請求の範囲、明細書、及び図面中において示した装置、システム、プログラム、及び方法における動作、手順、ステップ、及び段階等の各処理の実行順序は、特段より前に、先立って等と明示しておらず、また、前の処理の出力を後の処理で用いるのでない限り任意の順序で実現しうることに留意すべきである。また、前の処理の出力を後の処理で用いる場合でも、前の処理と後の処理の間に他の処理が入ることは可能である場合があること、又は間に他の処理が入るように記載されていても前の処理を後の処理の直前に行うよう変更することも可能である場合があることも留意されたい。特許請求の範囲、明細書、及び図面中の動作フローに関して、便宜上まず、、次に、、続いて、等を用いて説明したとしても、この順で実施することが必須であることを必ずしも意味するとは限らない。