(57)【要約】【課題】効率的に排他制御を行うことができるようにする。【解決手段】マルチスレッドで動作するアプリケーションプログラムを実行する情報処理装置が、アプリケーションプログラムに含まれる、第１の排他制御用リソースに対してロックを取得してから解除するまでのプログラムである複数のクリティカルセクションを特定し、特定した各クリティカルセクションを実行した場合に読み書きしうる記憶領域である使用領域を特定し、使用領域の少なくとも一部が重なるクリティカルセクションをグループ化し、第１の排他制御用リソースに対するロックに代えて、グループごとに異なる第２の排他制御用リソースに対して前記クリティカルセクションがロックを取得するようにする。【選択図】図１
2008257594.tif 000002
【特許請求の範囲】
【請求項１】
マルチスレッドで動作するアプリケーションプログラムを実行する情報処理装置であって、
前記アプリケーションプログラムに含まれる、第１の排他制御用リソースに対してロックを取得してから前記ロックを解除するまでのプログラムである複数のクリティカルセクションを抽出するクリティカルセクション抽出部と、
抽出した各前記クリティカルセクションを実行した場合に読み書きしうる記憶領域である使用領域を決定する使用領域決定部と、
前記使用領域の少なくとも一部が重なる前記クリティカルセクションをグループ化するグループ処理部と、
前記第１の排他制御用リソースに対するロックに代えて、前記グループごとに異なる第２の排他制御用リソースに対して前記クリティカルセクションがロックを取得するようにする最適化処理部と、
を備えることを特徴とする情報処理装置。
【請求項２】
請求項１に記載の情報処理装置であって、
前記グループ処理部は、各前記グループに所属する前記クリティカルセクションの数を算出し、前記数が大きい順または小さい順に所定数の前記グループを第１のグループとし、前記第１のグループ以外のグループに所属する前記クリティカルセクションを、すべて同一の第２のグループとすること、
を特徴とする情報処理装置。
【請求項３】
請求項１に記載の情報処理装置であって、
前記記憶領域ごとに、過去に前記アプリケーションプログラムを実行した際に読み書きされた回数を記憶する実行プロファイル記憶部を備え、
前記グループ処理部は、各前記グループに対応する前記使用領域についての前記回数を前記実行プロファイル記憶部から読み出し、読みだした前記回数の順に所定数の前記グループを第１のグループとし、前記第１のグループ以外のグループに所属する前記クリティカルセクションを、すべて同一の第２のグループとすること、
を特徴とする情報処理装置。
【請求項４】
請求項１に記載の情報処理装置であって、
前記グループ処理部は、前記使用領域ごとに、前記使用領域を示す文字列が前記アプリケーションプログラム中に記述されている個数をカウントし、前記個数の順に所定数の前記グループを第１のグループとし、前記第１のグループ以外のグループに所属する前記クリティカルセクションを、すべて同一の第２のグループとすること、
を特徴とする情報処理装置。
【請求項５】
請求項１に記載の情報処理装置であって、
前記アプリケーションプログラムには、前記クリティカルセクションに対応する前記記憶領域の指定が記述可能であり、
前記使用領域決定部は、前記記憶領域の指定が前記クリティカルセクションに記述されているかどうかを判定し、前記記憶領域の指定が記述されている場合には、当該記憶領域の指定に基づいて前記クリティカルセクションに対応する前記記憶領域を決定すること、
を特徴とする情報処理装置。
【請求項６】
請求項２乃至５のいずれかに記載の情報処理装置であって、
前記最適化処理部は、前記第１のグループに所属する前記クリティカルセクションについては、前記第１のグループごとに異なる前記第２の排他制御用リソースに対してロックを取得するようにし、前記第２のグループに所属する前記クリティカルセクションについては、各前記第１のグループに対応するすべての前記第２の排他制御用リソースに対してロックを取得するようにすること、
を特徴とする情報処理装置。
【請求項７】
マルチスレッドで動作するアプリケーションプログラムのソースコードを読み込んで前記アプリケーションプログラムの実行ファイルを生成する情報処理装置であって、
第１の前記ソースコードに含まれる、第１の排他制御用リソースに対してロックを取得してから前記ロックを解除するまでの部分である複数のクリティカルセクションを抽出するクリティカルセクション抽出部と、
抽出した前記クリティカルセクションを実行した場合に読み書きしうる記憶領域である使用領域を決定する使用領域決定部と、
前記使用領域の少なくとも一部が重なる前記クリティカルセクションをグループ化するグループ処理部と、
前記第１のソースコードに基づいて、前記実行ファイルを生成するコンパイル処理用の第２のソースコードを出力する際に、前記第１の排他制御用リソースに対するロックを取得するコードに代えて、前記グループごとに異なる第２の排他制御用リソースに対するロックを取得するコードを出力する予備処理部と、
前記予備処理部が出力した前記第２のソースコードに基づいて前記実行ファイルを生成するコンパイル処理部と、
を備えることを特徴とする情報処理装置。
【請求項８】
マルチスレッドで動作するアプリケーションプログラムを実行するコンピュータによる情報処理方法であって、
前記コンピュータが、
前記アプリケーションプログラムに含まれる、第１の排他制御用リソースに対してロックを取得してから前記ロックを解除するまでのプログラムである複数のクリティカルセクションを抽出し、
抽出した各前記クリティカルセクションを実行した場合に読み書きしうる記憶領域である使用領域を決定し、
前記使用領域の少なくとも一部が重なる前記クリティカルセクションをグループ化し、
前記第１の排他制御用リソースに対するロックに代えて、前記グループごとに異なる第２の排他制御用リソースに対して前記クリティカルセクションがロックを取得するようにすること、
を特徴とする情報処理方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、情報処理装置および情報処理方法に関する。
【背景技術】
【０００２】
マルチスレッドで実行中のプログラムにおいて、複数のスレッド間で共有する共有データに対する読み書き（定義および参照）を排他的に行うことがある。これは、あるスレッドから共有データへの書き込み（定義）が行われている間に、他のスレッドからその共有データを参照すると、タイミングによっては想定外のデータの組み合わせが生じて、誤動作が発生する可能性があるためである。
【０００３】
オブジェクト内のデータへのアクセスを排他的に行うため、例えばＣ言語でのＰＯＳＩＸ（Portable Operating System Interface）規格に定義されるＰスレッド (非特許文献１)や、Ｊａｖａ（登録商標）言語でのsynchronized修飾子などが知られている。
【０００４】
synchronized修飾子はメソッド全体を排他制御するために用いられる。synchronized修飾子が記述されたメソッドはsynchronizedメソッドとも呼ばれる。典型的には、各インスタンスオブジェクトに排他制御を行うためのロック用のリソース（以下、ロックリソースという。）が１つ付帯されており、synchronizedメソッドでは、メソッドの所属するクラスオブジェクトまたはインスタンスオブジェクトに付帯されるロックリソースに対するロックを取得することによって排他制御を実現する。
【０００５】
例えば、クラスＡに２つのsynchronizedメソッドＭｓ１、Ｍｓ２があり、これらのメソッドからフィールドｄにアクセスする場合について考える。クラスＡのインスタンスオブジェクトｏｂｊＡが生成されており、スレッドＴ１がｏｂｊＡのメソッドＭｓ１を呼び出す場合、スレッドＴ１は、メソッドＭｓ１の呼び出し直前にｏｂｊＡに付帯されるロックリソースに対するロックを取得し、フィールドｄにアクセスし、その後ｏｂｊＡのロックリソースに対するロックを解除する。スレッドＴ２が、ｏｂｊＡのメソッドＭｓ２を実行する場合も同様であり、ｏｂｊＡのロックリソースに対するロックの取得および解除を行う。ここで、スレッドＴ１とＴ２とがｏｂｊＡを用いてほぼ同時にメソッドＭｓ１、Ｍｓ２を実行しようとした場合、ｏｂｊＡに付帯されるロックリソースへのロックを互いに取得しようとする。先にＴ１がロックを取得できた場合、Ｔ２はＴ１がロックを解除するまで待ち状態となる。逆に、Ｔ２が先にロックを取得できた場合は、Ｔ１が待ち状態となる。つまり、ｏｂｊＡのロック用リソースに対するロックを要求するsynchronizedメソッドＭｓ１、Ｍｓ２は絶対に同時に実行されることはなく、ｏｂｊＡのフィールドｄに対する排他的なアクセスが実現される。なお、synchronizedメソッドＭｓ１やＭｓ２のように、排他制御が適用されるプログラム区間は、クリティカルセクションと呼ばれる。
【０００６】
ロックリソースに対するロックの取得および解除に係る処理は、一般的にオーバヘッドが大きく、各種の最適化手法（非特許文献２〜５）が考案されてきた。例えば、上述のｏｂｊＡに対するロック取得および解除の例は、複数スレッドが１つのロックリソースに対するロックを取得しあう競合状態の例である。しかし、一般的なプログラムでは、ロック競合の発生は少なく、発生するとしても、ロック競合がなるべく少なくなるように、プログラムが作成されていることが多い。そこで、Ｍｅｔａ−Ｌｏｃｋ手法（非特許文献２）や、Ｔｈｉｎ−Ｌｏｃｋ手法（非特許文献３）のように、競合状態が少ないことを利用して、オーバヘッドを減らす手法が研究されている。
【０００７】
例えばＴｈｉｎ−Ｌｏｃｋ手法では、図２５に示すようなコードによって、オブジェクトに付帯されるロックリソースにスレッドＩＤ、ネストロック回数、識別ビットなどを書き込み、ロックを取得する。なお、図２５に示すコードは、実行ファイルの一部として生成されるコードを説明するための擬似コードであり、各行左側の数値は行番号である。
【０００８】
図２５に示すコードは、ロック用リソースが８バイト幅である場合の例であり、３行目において、８バイトのlocked_wordとして初期のロック状態を生成し、９行目でロックリソースに対してアトミック（atomic）命令「cmpxchg8」によるlocked_wordの書き込みを試行する。アトミック命令とは、読み込み、比較、書き込みの一連の動作を不可分に（アトミックに）行うよう指示するコマンドである。アトミック命令cmpxchg8（compare&exchange 8 byte）は第１引数のアドレス（ロック用リソースのアドレス &object->lock_part）が示すメモリから８バイトの部分の内容を第２引数（unlocked_word）の内容と比較し、等しければ第３引数（locked_word）の内容を第１引数のアドレスで示されるメモリに書き込む命令である。cmpxchg8のようなアトミック命令は、一般的なＣＰＵでサポートされており、８バイトの以外にも２バイト、４バイト、１６バイト幅でデータにアトミックにアクセスする命令をサポートしていることが多い。
【０００９】
１つのスレッドから複数回ロックが取得された場合、すなわちロックがネストした場合には、ロックリソースのネストロック回数を増やす。複数のスレッドが同一のロックリソースに対するロックを取得しあうロック競合が発生した場合は、１２行目に入りＴｈｉｎ−Ｌｏｃｋ手法によるロックの取得処理に代えて、重量ロックと呼ばれる異なるロック処理（非特許文献２、３参照。）を行う。Ｔｈｉｎ−Ｌｏｃｋ手法は非競合状態におけるロックの取得および解除を行うための手法であるため、ロックの競合が生じる場合には、効率が低下するからである。この場合、ロックリソースには重量ロックに必要な専用データ構造のＩＤを書き込み、識別ビットを立てる。クリティカルセクション終了時は、図２５の１８行目以降を実行して、ロックリソースに対するロックを解除する。まず、２３行目でオブジェクトのロックリソースの識別ビットをチェックし、競合時の専用データ構造のＩＤを持っている場合はその構造を用いたロックの解除処理（２４行目）を行い、そうでない場合は２８行目でロックリソースを０に書き換えることでロックの解除処理を行う。なお、ネストしたロックを解除する場合はロックリソースのネスト回数を１減らす。
【００１０】
また、Ｌｏｃｋ  Ｒｅｓｅｒｖａｔｉｏｎ手法（非特許文献４）のように、クリティカルセクションでのロック競合が発生する可能性が生じるまでは、ロックリソースに対するロックの取得および解除を行わないように回避する手法や、プログラムにおいてアクセスするデータについて、他スレッドへの露出の有無を調べるＥｓｃａｐｅ解析（非特許文献５）という手法を用い、クリティカルセクション内でアクセスする全データが露出しない場合は、クリティカルセクションの指定自体を削除するという手法も開発されている。
【非特許文献１】ビル・ルイス、ダニエル・バーグ、「Ｐスレッドプログラミング」、ピアソン・エデュケーション、1999年
【非特許文献２】Ole Agesen （他４名）, “An Efficient Meta-lock for Implementing Ubiquitous Synchronization”, In proceedings of the 14th Annual ACM Conference on Object-Oriented Programming, Systems, Languages, and Applications, 1999
【非特許文献３】David F. Bacon （他３名）, “Thin Locks: Featherweight Synchronization for Java”, In proceedings of the ACM Conference on Programming Language Design and Implementation, ACM SIGPLAN Notices Vol.33, No.6, 1998
【非特許文献４】Kiyokuni Kawachiya （他２名）, “Lock Reservation: Java Locks Can Mostly Do Without Atomic Operations”, In proceedings of the 17th ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications, 2002
【非特許文献５】B. Branchet, “Escape Analysis for Java: Theory and Practice”, In ACM Transactions on Programming Language and Systems, vol.25, No.6, 2003
【発明の開示】
【発明が解決しようとする課題】
【００１１】
排他制御を行うために、複数のクリティカルセクションから同一のロックリソースに対するロックを取得する処理が行われる場合であっても、各クリティカルセクションから読み書きされる記憶領域が異なる場合には、排他制御を行うことなく並行してそれらのクリティカルセクションを実行したとしても不具合は生じない。
【００１２】
しかしながら、排他制御を行うプログラムでは、例えば、同一のクラスの複数のメソッドに対してsynchronized修飾子を設定するなど、多数のクリティカルセクションから同一のロックリソースに対してロックを取得するような記述がなされていることが多い。
【００１３】
本発明は、このような背景を鑑みてなされたものであり、効率的に排他制御を行うことのできる情報処理装置および情報処理方法を提供することを目的とする。
【課題を解決するための手段】
【００１４】
上記課題を解決するための本発明の主たる発明は、ママルチスレッドで動作するアプリケーションプログラムを実行する情報処理装置であって、前記アプリケーションプログラムに含まれる、第１の排他制御用リソースに対してロックを取得してから前記ロックを解除するまでのプログラムである複数のクリティカルセクションを抽出するクリティカルセクション抽出部と、抽出した各前記クリティカルセクションを実行した場合に読み書きしうる記憶領域である使用領域を決定する使用領域決定部と、前記使用領域の少なくとも一部が重なる前記クリティカルセクションをグループ化するグループ処理部と、前記第１の排他制御用リソースに対するロックに代えて、前記グループごとに異なる第２の排他制御用リソースに対して前記クリティカルセクションがロックを取得するようにする最適化処理部とを備えることとする。
【発明の効果】
【００１５】
本発明によれば、効率的に排他制御を行うことができる。
【発明を実施するための最良の形態】
【００１６】
以下、本発明の一実施形態に係る情報処理装置１０について説明する。本実施形態の情報処理装置１０ではＪａｖａ（登録商標）プログラムを実行するための仮想マシンが実行される。仮想マシンでは、ユーザが作成したＪａｖａ（登録商標）言語により記述されるアプリケーションプログラム（以下、ユーザプログラムという。）が実行される。本実施形態の仮想マシンは、ユーザプログラムのインタプリタとして機能するが、実行頻度の高いメソッドについては、情報処理装置１０におけるネイティブ形式の実行ファイルを生成する、いわゆるＪＩＴ（Just In Time）コンパイル処理を行う。
【００１７】
ユーザプログラムは、マルチスレッドで動作し、複数のスレッドから同一の共有リソースを読み書きすることが可能である。共有リソースとは、例えば、構造化言語における変数や、オブジェクト指向言語におけるオブジェクトのメンバフィールドにより示される記憶領域である。共有リソースに対するアクセス時には、一般的に排他制御が行われる。Ｊａｖａ（登録商標）言語では、排他制御を行う命令としてメソッドに対するsynchronized修飾子が定義されている。メソッドにsynchronized修飾子が指定された場合、仮想マシンは、メソッドの開始時にそのメソッドが所属するオブジェクトに対するロックを取得し、メソッドの終了時にそのロックを解除することで排他制御を行う。すなわち、メソッド全体が排他制御の対象となる、いわゆるクリティカルセクションと呼ばれる部分となる。
【００１８】
本実施形態の情報処理装置１０では、ＪＩＴコンパイルを行う際に、synchronized修飾子が指定されたメソッドをグループ化し、グループごとに異なる排他制御を行うようにすることで、スレッドがロックの解除待ちとなる時間を短縮し、スレッドの動作の並行性を高めている。
【００１９】
図１は、本実施形態に係る情報処理装置１０のハードウェア構成を示す図である。同図に示すように、情報処理装置１０は、ＣＰＵ１０１、メモリ１０２、記憶装置１０３、入力装置１０４、出力装置１０５を備えている。記憶装置１０３は、各種のプログラムやデータを記憶する、例えばハードディスクドライブやＣＤ−ＲＯＭドライブ、フラッシュメモリなどである。ＣＰＵ１０１は、記憶装置１０３に記憶されているプログラムを実行することにより、各種の機能を実現する。入力装置１０４は、データの入力を受け付ける、例えばキーボードやマウス、トラックボール、タッチパネルなどである。出力装置１０５は、データを出力する、例えばディスプレイやプリンタなどである。
【００２０】
図２は情報処理装置１０のソフトウェア構成を示す図である。同図に示すように、情報処理装置１０は、仮想マシン１１、プログラム記憶部１５、実行プロファイル記憶部１６および実行ファイル記憶部１７を備えている。また、仮想マシン１１は、プログラムローダ１１１、インタプリタ１１２およびＪＩＴコンパイラ１２を含んでおり、ＪＩＴコンパイラ１２は、プログラム解析部１２１、コード生成部１２２およびコンパイル処理部１２３を含んでいる。なお、仮想マシン１１は、記憶装置１０３に記憶されている仮想マシン用のアプリケーションプログラムを、ＣＰＵ１０１がメモリ１０２に読み出して実行することにより実現される。
【００２１】
プログラム記憶部１５は、ユーザプログラムを記憶する。プログラム記憶部１５は、例えば、情報処理装置１０で実行されるオペレーティングシステム上のファイルシステムにおけるディレクトリなど、記憶装置１０３が提供する記憶領域として実現される。
【００２２】
プログラム記憶部１５に記憶されるユーザプログラムの一例を図３に示す。なお、プログラム記憶部１５に記憶されるユーザプログラムは、バイトコードと呼ばれる仮想マシン１１が実行しやすい形式に予めコンパイルするのが一般的であるが、本実施形態では、簡単のため、図３に示すような可読性の高いプログラムがプログラム記憶部１５に記憶されているものとする。
【００２３】
図３の例において、Exampleクラスは、９つのメソッド１５１〜１５６を有しており、各メソッドにはsynchronized修飾子が指定されている。また、Exampleクラスは３つのフィールド１５７を有しており、これらのフィールド１５７はすべてprivate属性となっている。synchronized修飾子が指定されたメソッドが実行される場合には、上述したように排他制御が行われる。すなわち、クラスExampleのインスタンスオブジェクトが生成されて、synchronized修飾子が指定されたメソッドが実行される場合、そのメソッドの処理が終了するまでインスタンスオブジェクトはロックされる。
【００２４】
各インスタンスオブジェクトのヘッダ部分には、排他制御用のリソース（以下、ロックリソースという。）として、６４ビットの領域が確保されており、このロックリソースに対してロックを取得したスレッドのみが、メソッドの処理が終了するまでの間、インスタンスオブジェクトのフィールドにアクセスできる。なお、本実施形態では、ロックリソースに対してＴｈｉｎ−Ｌｏｃｋ方式によりロックを取得するものとする。
【００２５】
本実施形態におけるインスタンスオブジェクトの構成例を図４に示す。同図に示すように、本実施形態の仮想マシン１１では、インスタンスオブジェクト４０は、ヘッダ部分にマーク（ｍａｒｋ）ヘッダ４１、クラス（ｋｌａｓｓ）ヘッダ４２、およびロック（ｌｏｃｋ）ヘッダ４３を備えており、データサイズはいずれも１ワードである。なお、本実施形態では、１ワードは６４ビットであるものとする。
【００２６】
マークヘッダ４１は、例えば、ガベージコレクション処理におけるコピー回数やインスタンスオブジェクトのハッシュ値などの各種の値を含む。クラスヘッダ４２は、インスタンスオブジェクトが所属するクラスを示す。ロックヘッダ４３は、排他制御を行うためのロックリソースであり、ロックを取得しているスレッドの識別子（スレッドＩＤ）などが含まれる。なお、一般的なＪａｖａ（登録商標）の仮想マシンでは、マークヘッダ４１がロックヘッダ４３の役割を兼ねることがある。
【００２７】
一般的なＪａｖａ（登録商標）の仮想マシンでは、ロックヘッダ４３の全体に対してロックが取得され、ロックヘッダ４３には、ロックを取得したスレッドのスレッドＩＤなどが１セット格納されることになる。すなわち、一般的なＪａｖａ（登録商標）の仮想マシンでは、第１スレッドにおいて、あるインスタンスオブジェクトのsetter_F1メソッドを実行し、第２スレッドにおいて、同時に同一のインスタンスオブジェクトのgetter_F3メソッドを実行する場合、同一のロックヘッダ４３に対してロックの取得処理が行われ、ロックを先に取得できた方のスレッドのみが上記メソッドを実行することが可能となり、他方のスレッドは、ロックリソースに対するロックが解除されるまで待ち状態となる。
【００２８】
これに対し、本実施形態の仮想マシン１１では、ロックヘッダ４３を１６ビットずつの４つの部分ロックヘッダに分割し、後述するように、１つのインスタンスオブジェクトに対して４つのスレッドが並行してロックを取得するようにしている。つまり、４つのメソッドがそれぞれ独立したロックリソースに対してロックを取得することができるようにしている。これにより、ロックの待ち時間を低減し、効率的にメソッドを実行することを可能としている。なお、ロックの取得処理の詳細については後述する。
【００２９】
部分ロックヘッダ４３１〜４３４はそれぞれ、スレッドＩＤ５０１、ネスト回数５０２、および識別ビット５０３が含まれており、これはＴｈｉｎ−Ｌｏｃｋとして知られる手法に用いられる構成である。Ｔｈｉｎ−Ｌｏｃｋ手法では、ロックを取得したるスレッドのスレッドＩＤをスレッドＩＤ５０１に設定する。同一のスレッドから複数のロックが取得された場合（ロックがネストした場合）には、ネスト回数５０２がインクリメントされ、ロックの解除命令に応じてネスト回数５０２がデクリメントされ、ネスト回数５０２が「０」である場合に、ロック解除処理を行うときは、スレッドＩＤ５０１を０とすることによってロックが解除されることになる。識別ビット５０３は、Ｔｈｉｎ−Ｌｏｃｋ手法においてロックの競合が発生する場合に用いられるフラグ値である。
【００３０】
プログラムローダ１１１（本発明のクリティカルセクション抽出部に該当する。）は、プログラム記憶部１５に記憶されているユーザプログラムをメモリ１０２に読み出す。また、本実施形態においてプログラムローダ１１１は、ユーザプログラムからクラスごとに、クリティカルセクションを抽出する処理も行うものとする。
【００３１】
インタプリタ１１２は、プログラムローダ１１１が読み出したユーザプログラムを実行する。また、インタプリタ１１２は、ユーザプログラムの実行時に、ユーザプログラムに含まれる各クラスについて、フィールドごとに読み書きされた回数をカウントし、メソッドごとに呼び出された回数をカウントする。インタプリタ１１２は、カウントしたフィールドごとのアクセス回数や、メソッドごとの呼出し回数を含む、ユーザプログラムの実行に係る統計情報（以下、実行プロファイル情報という。）を実行プロファイル記憶部１６に登録する。
【００３２】
実行プロファイル記憶部１６に記憶される実行プロファイル情報の構成例を図５に示す。同図に示すように、実行プロファイル情報には、メソッド統計１６１およびフィールド統計１６２が含まれる。メソッド統計１６１には、メソッド名に対応付けて、メソッドの呼出し回数が記憶される。メソッド名には、クラス名が含まれ、インタプリタ１１２が実行したユーザプログラムに含まれるすべてのクラスのすべてのメソッドについて、呼出し回数が記憶される。フィールド統計１６２には、フィールド名に対応づけて、フィールドに対して読み書きされた回数（アクセス回数）が記憶される。フィールド名には、クラス名が含まれ、インタプリタ１１２が実行したユーザプログラムに含まれるすべてのクラスのすべてのフィールドについて、アクセス回数が記憶される。なお、メソッド統計１６１およびフィールド統計１６２には、所定のクラスについてのみ、メソッドの呼出回数やフィールドのアクセス回数が登録されるようにしてもよい。
【００３３】
ＪＩＴコンパイラ１２は、インタプリタ１１２が実行しているユーザプログラムを、情報処理装置１０のネイティブ形式に変換する。本実施形態では、ＪＩＴコンパイラ１２は、メソッドの呼出回数が所定数を超えた場合に、そのメソッドを含むクラスのみをネイティブ形式に変換する処理を行う。メソッドの呼出回数は、実行プロファイル記憶部１６に記憶されるメソッド統計１６１に記憶されている。なお、本実施形態では、ＪＩＴコンパイラ１２は、Ｊａｖａ（登録商標）言語で記述されたクラスに基づいて、直接ネイティブ形式の実行ファイルを生成するものとする。
【００３４】
ＪＩＴコンパイラ１２に含まれるプログラム解析部１２１（本発明の使用領域決定部に該当する。）は、Ｊａｖａ（登録商標）言語で記述されたクラスを解析し、コンパイル対象となるクラスのメソッドから呼び出される他のメソッドを示す情報（以下、メソッド呼出情報という。）と、メソッドからアクセスされる１または複数のフィールド（以下、アクセスフィールドという。本実施形態の使用領域に対応する。）に関する情報（以下、データフロー情報という。）とを生成する。
【００３５】
プログラム解析部１２１が生成するメソッド呼出情報２０の構成例を図６に示す。なお、図６の例は、図３に示すExampleクラスを解析した結果例である。図６に示すように、メソッド呼出情報２０には、メソッド名２０１および呼出メソッド２０２が含まれている。メソッド名２０１は、メソッドの名称であり、呼出メソッド２０２は、そのメソッドから呼び出される他のメソッドの名称のリストである。図６の例では、Exampleクラスのcall_otherメソッドから、OtherClassクラスのother_methodメソッドが呼び出されていることが示されている。
【００３６】
プログラム解析部１２１が生成するデータフロー情報２１の構成例を図７に示す。なお、図７の例についても、図３に示すExampleクラスを解析した結果例である。図７に示すように、データフロー情報２１には、メソッド名２１１および処理内容２１２が含まれている。メソッド名２１１には、メソッドを名称が設定され、処理内容２１２には、そのメソッドにおいてフィールドに対する書き込み（定義）や、フィールドからの読み出し（参照）が行われるコードの記述位置が設定される。
【００３７】
コード生成部１２２（本実施形態のグループ処理部および最適化処理部に対応する。）は、メソッド呼出情報２０およびデータフロー情報２１、並びに実行プロファイル記憶部１６に記憶されている情報に基づいて実行ファイルを生成する。コード生成部１２２は、生成した実行ファイルを実行ファイル記憶部１７に記憶する。実行ファイル記憶部１７は、例えば、ファイルシステムにおけるディレクトリなどの、メモリ１０２や記憶装置１０３が提供する記憶領域として実現される。
【００３８】
以下、ＪＩＴコンパイラ１２の処理について説明する。図８は、ＪＩＴコンパイラ１２による処理の流れを示す図である。なお、上述したように、ＪＩＴコンパイラ１２は、実行プロファイル記憶部１６に記憶されているメソッド統計１６１において、呼出回数が所定数を超えた場合に起動される。
【００３９】
プログラム解析部１２１は、呼出回数が所定数を超えたメソッドが所属するクラス（以下、所属クラスという。）のコードをプログラム記憶部１５から読み出し（Ｓ３０１）、読み出したコードを解析してメソッド呼出情報２０およびデータフロー情報２１を生成する（Ｓ３０２）。
【００４０】
コード生成部１２２は、所属クラスに含まれるメソッドのグループ化処理を行う（Ｓ３０３）。メソッドのグループ化処理の流れを図９に示す。
【００４１】
コード生成部１２２は、所属クラスの各メソッドについて以下の処理を行う。  
コード生成部１２２は、メソッドの修飾子として「synchronized」が指定されている場合（Ｓ３２１：ＹＥＳ）、メソッドに対応するメソッド呼出情報２０の呼出メソッド２０２に他のメソッドが含まれていなければ（Ｓ３２２：ＹＥＳ）、メソッドに対応するデータフロー情報２１の処理内容２１２から、フィールド名を重複なく抽出してアクセスフィールドとする（Ｓ３２３）。一方、呼出メソッド２０２に他のメソッドが含まれている場合には（Ｓ３２２：ＮＯ）、コード生成部１２２は、所属クラスに含まれるすべてのフィールドのフィールド名をアクセスフィールドとする（Ｓ３２４）。
【００４２】
コード生成部１２２は、メソッド名とアクセスフィールドとを対応付けて、作業用のリストであるグループリスト２２に登録する（Ｓ３２５）。グループリスト２２の構成例を図１０に示す。同図に示すように、グループリスト２２には、メソッド名に対応付けて、アクセスフィールドおよびグループが登録される。グループは、メソッドが所属するグループを示す情報（以下、グループＩＤという。）であるが、上記（Ｓ３２４）の段階では、グループには値は設定されないものとする。
【００４３】
コード生成部１２２は、以上の処理を繰り返して、グループリスト２２を生成すると、次に図１１に示す作業リスト２３の生成処理を行う（Ｓ３２６）。コード生成部１２２は、グループリスト２２に登録されている各レコードについて、アクセスフィールドが所属クラスの全フィールドではなく（Ｓ３４１：ＮＯ）、アクセスフィールドが「private」フィールドであり、かつ作業リスト２３にアクセスフィールドが登録されていない場合には（Ｓ３４２：ＮＯ）、レコードのアクセスフィールドを作業リスト２３に登録する（Ｓ３４３）。
【００４４】
以上の処理により生成される作業リスト２３の一例を図１２に示す。図１２に示すように、作業リスト２３には、グループリスト２２から重複なくアクセスフィールドを読み出したリストから、さらに所属クラスの全フィールドを含むアクセスフィールドを除いたものになる。
【００４５】
コード生成部１２２は、以上の処理により作業リスト２３を生成した後、図１３に示す、グループ化のためのアクセスフィールドリスト２４の生成処理を行う（Ｓ３２７）。
【００４６】
コード生成部１２２は、作業リスト２３に登録されている各アクセスフィールドについて、当該アクセスフィールドの少なくとも一部と重なる他のアクセスフィールドをアクセスフィールドリスト２４から検索する（Ｓ３６１）。例えば、「ｆ１」のアクセスフィールドがアクセスフィールドリスト２４に既に登録されている場合、「ｆ１，ｆ２」のアクセスフィールドは、「ｆ１」と一部と重なると判断される。上記他のアクセスフィールドがなければ（Ｓ３６２：ＮＯ）、当該アクセスフィールドをアクセスフィールドリスト２４に登録する（Ｓ３６３）。
【００４７】
以上の処理により生成されるアクセスフィールドリスト２４の一例を図１４に示す。図１４に示すように、アクセスフィールドリスト２４に登録されている各アクセスフィールドは、他のアクセスフィールドと重なるフィールドを含んでいないことになる。
【００４８】
コード生成部１２２は、以上のようにしてアクセスフィールドリスト２４を生成した後、グループＩＤを「０」として（Ｓ３２８）、アクセスフィールドリスト２４に含まれる各アクセスフィールドについて、グループＩＤをインクリメントし（Ｓ３２９）、アクセスフィールドに一致するグループリスト２２のレコードにグループＩＤを設定する（Ｓ３３０）。
【００４９】
コード生成部１２２は、グループリスト２２に含まれるレコードのうちグループが設定されていないものには、「ＡＬＬ」を設定する（Ｓ３３１）。
【００５０】
以上のようにして、図１０に示すようなグループリスト２２が生成される。なお、グループＩＤが数値であるグループが本発明の第１のグループに該当し、グループＩＤが「ＡＬＬ」であるグループが本発明の第２のグループに該当する。
【００５１】
上記の処理を、図３に示したExampleクラスに適用した場合には、以下のようになる。図９の（Ｓ３２１）〜（Ｓ３２５）の処理により、setter_F1メソッドおよびgetter_F1メソッドのアクセスフィールドはｆ１であり、setter_F2メソッドおよびgetter_F2メソッドのアクセスフィールドはｆ２であり、setter_F3メソッドおよびgetter_F3メソッドのアクセスフィールドはｆ３である。また、setter_F1F2メソッドのアクセスフィールドはｆ１およびｆ２であり、setter_allメソッドのアクセスフィールドはｆ１、ｆ２およびｆ３である。call_otherメソッドは、他のメソッド（OtherClass.other_method）を呼び出しているため（Ｓ３２４：ＮＯ）、アクセスフィールドとしてExampleクラスのすべてのフィールドであるｆ１、ｆ２およびｆ３が設定される。
【００５２】
図１１に示す作業リスト２３の生成処理により、Exampleクラスの全フィールドを含む「ｆ１，ｆ２，ｆ３」を除く、「ｆ１」、「ｆ２」、「ｆ３」および「ｆ１，ｆ２」という４つのアクセスフィールドが登録された作業リスト２３が生成される。
【００５３】
図１３に示すアクセスフィールドリスト２４の生成処理では、「ｆ１」と一部が重なる「ｆ１，ｆ２」はアクセスフィールドリスト２４に登録されず（Ｓ３６２：ＹＥＳ）、図１４の例のように、「ｆ１」「ｆ２」および「ｆ３」がアクセスフィールドリスト２４に登録された状態となる。
【００５４】
次に、図９の（Ｓ３２９）〜（Ｓ３３０）では、「ｆ１」に対応するsetter_F1メソッドおよびgetter_F1メソッドのグループリスト２２のグループに「１」が設定され、「ｆ２」に対応するsetter_F2メソッドおよびgetter_F2メソッドのグループに「２」が設定され、「ｆ３」に対応するsetter_F3メソッドおよびgetter_F3メソッドのグループに「３」が設定される。
【００５５】
最後に、（Ｓ３３１）において、グループに値が設定されなかったsetter_F1F2メソッド、setter_allメソッド、およびcall_otherメソッドのそれぞれに対応するグループに「ＡＬＬ」が設定される。
【００５６】
コード生成部１２２は、上記のようにしてグループ化処理を行った後、所属クラスのコードに基づいてネイティブ形式の実行ファイルを生成する（Ｓ３０４）。なお、コード生成部１２２によるコードの生成処理には、排他処理を行うsynchronizedメソッド以外の部分については、一般的なＪＩＴコンパイラに用いられている手法を用いることができる。synchronizedメソッドに係るコードの生成処理の流れを図１５に示す。
【００５７】
コード生成部１２２は、メソッドに「synchronized」修飾子が付いている場合（Ｓ３８１：ＹＥＳ）、メソッド名に対応するグループをグループリスト２２から取得する（Ｓ３８２）。  
コード生成部１２２は、取得したグループが「ＡＬＬ」であった場合には（Ｓ３８３：ＹＥＳ）、すべての部分ロックヘッダ４３１〜４３４に対するロックを取得するためのコードを出力する（Ｓ３８４）。本実施形態では、コード生成部１２２は、部分ロックヘッダ４３１〜４３４のすべてに対して同時に読み込み、比較および書き込みを行うアトミック命令cmpxchg8を出力するものとする。
【００５８】
ステップＳ３８４においてコード生成部１２２が出力する、すべての部分ロックヘッダに対するロックを取得するコードを擬似コードで表現した例を図１６に示す。図１６に示すコードが、図２５に示す従来のＴｈｉｎ−Ｌｏｃｋ手法のコードと異なるのは、ロックヘッダ４３に書き込む値が１つのロック状態（スレッドＩＤ、ネスト回数および識別ビット）に代えて、４つのロック状態の論理和とした点である。図１６に示すように、スレッドＩＤ、ネスト回数および識別ビットを設定したper_lock_word変数を、インスタンスオブジェクトのヘッダ部分の６４ビットのロックヘッダ４３に含まれる４つの部分ロックヘッダ４３１〜４３４のすべてに対して設定するための６４ビットのデータlocked_wordを生成し（４１１）、アトミック命令（４１２）によりロックヘッダ４３に書き込むようにしている。
【００５９】
一方、グループが「ＡＬＬ」でない場合（Ｓ３８３：ＮＯ）、コード生成部１２２は、グループ（１〜４）番目の部分ロックヘッダ４３１〜４３４に対するロックを取得するためのコードを出力する（Ｓ３８５）。本実施形態では、コード生成部１２２は、部分ロックヘッダ４３１〜４３４のいずれかに対してアトミックに書き込みを行う、１６ビット（２バイト）幅のアトミック命令chpxchg2を出力するものとする。
【００６０】
ステップＳ３８５においてコード生成部１２２が出力する、部分ロックヘッダに対するロックを取得するコードを擬似コードで表現した例を図１７に示す。図１７に示すコードでは、図１６に示すコードと異なり、ロックを取得するコード４２１として、６４ビット幅のアトミック命令cmpxchg8に代えて、１６ビット幅のアトミック命令cmpxchg2を出力している（４２２）。また、部分ロックヘッダ４３１に設定するデータは、per_lock_wordに代えて、locked_wordになっている（４２３）。
【００６１】
図１７に示すコードを実行した場合、部分ロックヘッダ４３１に対するロックを取得しようとする同一グループのメソッド（図１０の例では、setter_F1およびgetter_F1の２つである。）は、排他的に実行される。しかし、グループが異なるメソッドは、異なる部分ロックヘッダに対してロックを取得しようとするため、同時に実行が可能である。例えば、グループ「２」に所属するsetter_F2は、部分ロックヘッダ４３２に対してロックを取得する。したがって、setter_F1が部分ロックヘッダ４３１に対するロックを取得していたとしても、setter_F2は、部分ロックヘッダ４３２のロックを取得することができる。よって、setter_F1とsetter_F2とは、同時に実行可能となる。
【００６２】
一方、グループ「ＡＬＬ」に所属するメソッド（例えば、setter_allなどである。）については、図１６に示すコード実行され、部分ロックヘッダ４３１〜４３４のすべてに対するロックを取得することになる。したがって、グループ「１」に所属するsetter_F1が部分ロックヘッダ４３１のロックを取得している間は、グループ「ＡＬＬ」に所属するsetter_allはロックを取得することができず、排他制御されることになる。
【００６３】
以上説明したように、本実施形態の情報処理装置１０によれば、同一のロックヘッダ４３に対してロックを取得する複数のメソッドを、フィールドが一部重なるアクセスフィールドごとにグループ化し、グループごとに異なる部分ロックヘッダ４３１〜４３４に対してロックを取得するようにすることができる。つまり、異なるグループに属するメソッドから同じフィールドにアクセスすることがないので、異なるグループに属するメソッド間での排他制御を行わないようにすることができる。これにより、ロックの競合の発生を低減し、効率的にユーザプログラムを実行することができる。
【００６４】
その一方で、アクセスフィールドが、他のグループに属するメソッドのアクセスフィールドと必ず重なるメソッド、すなわち、所属クラスのすべてのフィールドをアクセスフィールドとするメソッドについては、部分ロックヘッダ４３１〜４３４のすべてに対してロックを取得するようにしているので、実行排他性を保ち、実行結果の安全性を確保することができる。
【００６５】
また、あるメソッドが他のメソッドを呼び出している場合に、そのメソッドについてのアクセスフィールドを判定するためには、呼出し先のメソッドについても解析を行う必要があるが、本実施形態の情報処理装置１０では、他のメソッドを呼び出すメソッドについては、所属クラスのすべてのフィールドがアクセスフィールドであるものとして処理を行っている。したがって、解析処理に係る時間を軽減し、迅速にネイティブ形式の実行ファイルを生成することができる。
【００６６】
なお、本実施形態では、部分ロックヘッダ４３１〜４３４は、既存のロックヘッダ４３を分割するものとしたが、ロックヘッダ４３と同じ大きさのフィールドをヘッダ部分に追加するようにしてもよい。この場合のインスタンスオブジェクトの構成例を図１８に示す。同図の例では、部分ロックヘッダ４３１〜４３４が、６４ビット幅でヘッダ部分に確保されている。
【００６７】
ここで、ＣＰＵ１０１が複数ワードに対するアトミック命令をサポートしていない場合には、例えば、ヘッダ内にロック用のフラグを格納する管理領域を設け、ロックリソースにアクセスを行っている間は管理領域にフラグ値を格納したり、部分ロックヘッダ４３１〜４３４のそれぞれに対して、すべてのロック処理において常に一定の順序でロックを得るようにすることにより対応することができる。  
この場合、ロックリソースとして１ワードのデータ長を用いることができるので、ロックの取得に際してポインタ値を書き込むＭｅｔａ−Ｌｏｃｋ手法のような既存のロック手法を適用することが容易になる。
【００６８】
また、例えば、インスタンスオブジェクトのヘッダ部分に格納されるロックヘッダ４３のデータサイズが固定長であるような場合には、グループの数を制限する必要があり、このような場合には、上述したメソッドのグループ化処理において、生成するグループの数を制限するようにしてもよい。この場合、上述の図１３に示すアクセスフィールドリスト２４の生成処理において、アクセスフィールドリスト２４に登録されるアクセスフィールドの数を所定数以下に制限するようにする。図１９は、グループ数を所定数以下に制限する場合のアクセスフィールドリスト２４の生成処理の流れを示す図である。同図に示すように、コード生成部１２２は、図１３のステップＳ３６３の処理の後に、アクセスフィールドリスト２４の登録数が部分ロックヘッダの数（本実施形態では「４」である。）を超えていれば（Ｓ５０１：ＹＥＳ）処理を終了するようにしている。これにより、アクセスフィールドの数を部分ロックヘッダの数以下に制限することが可能となる。したがって、図９のステップＳ３２９〜ステップＳ３３０において各メソッドに対して付与するグループＩＤの数を制限することができる。
【００６９】
また、グループ数を制限することにより、例えばロックヘッダ４３の大きさが固定長として規定されている場合や、ヒープメモリの空き容量が少ない場合などにも、これらの制約を満たすようにすることができる。  
例えば、本実施形態の場合でも、インスタンスオブジェクトのヘッダ部分が固定長であり、ロックリソースは、部分ロックヘッダ４３１〜４３４の４つのみである場合には、「ＡＬＬ」を除くグループは４つまでに制限する必要があるが、上記の処理により４つ以下のグループを生成するようにすることができる。
【００７０】
グループの数を制限する場合、アクセスフィールドの優先順位を決定し、優先順位の順に所定数のグループを生成するようにしてもよい。優先度は、アクセスフィールド（フィールドの組み合わせ）へのアクセス頻度に応じて決定する。アクセスフィールドへのアクセス頻度は、（１）グループリスト２２からアクセスフィールドに対応するメソッドの数をカウントし、（２）実行プロファイル記憶部１６に記憶されているフィールド統計１６２のアクセス回数に基づいて算出し、（３）データフロー情報２１の処理内容にアクセスフィールドに含まれるすべてのフィールドが含まれている場合に、処理内容に含まれる各フィールドが定義または参照された回数に基づいて算出し、あるいは（４）プログラム記憶部１５に記憶されているユーザプログラム中の同一メソッド内において、アクセスフィールドに含まれている各フィールドが記述されている回数に基づいて算出することにより、求めることができる。
【００７１】
優先順位順にグループ数を制限する場合のアクセスフィールドリスト２４の生成処理を図２０に示す。同図に示すように、この場合は、図１９の処理の前に、コード生成部１２２は、作業リスト２３に含まれている各アクセスフィールドについて、（１）グループリスト２２からアクセスフィールドに対応するメソッドの数をカウントして優先度とし、（２）アクセスフィールドに含まれる各フィールドに対応する実行プロファイル記憶部１６のフィールド統計１６２のアクセス回数を集計して優先度とし、（３）アクセスフィールドに含まれるすべてのフィールドがデータフロー情報２１の処理内容に含まれている場合には処理内容において各フィールドが定義または参照された回数を集計して優先度とし、すべてのフィールドが含まれていない場合には優先度を「０」とし、あるいは（４）プログラム記憶部１５に記憶されているユーザプログラムを走査して、同一のメソッド内においてアクセスフィールドに含まれるすべてのフィールドが記述されている場合には、フィールドの記述数を集計して優先度とし、すべてのフィールドが記述されていない場合には優先度を「０」として、優先度を決定する（Ｓ５２１）。コード生成部１２２は、優先度順に作業用リストをソートする（Ｓ５２２）。
【００７２】
以上のようにして、優先度の高いアクセスフィールドから順に、他のアクセスフィールドと重ならないものをアクセスフィールドリスト２４に登録することができる。例えば、作業リスト２３に「ｆ１，ｆ２」「ｆ１」「ｆ２」の集合が登録されており、部分ロックヘッダが２つのみであったと仮定した場合に、（１）グループリスト２２からアクセスフィールドに対応するメソッドの数をカウントして優先度とするときには、図１０の例では、「ｆ１」に対応するメソッド数は「２」、「ｆ２」に対応するメソッド数は「２」、「ｆ１，ｆ２」に対応するメソッド数は「１」となり、優先度の順に「ｆ１」および「ｆ２」の２つのアクセスフィールドがアクセスフィールドリスト２４に登録されることになり、この場合には、「ｆ１」に対応する２つのメソッドがグループ「１」、「ｆ２」に対応する２つのメソッドがグループ「２」、その他の５つのメソッドがグループ「ＡＬＬ」に配属されることになる。
【００７３】
以上のように、優先度の高いアクセスフィールドについて、優先的にグループ化を行うことにより、グループごとに独立した部分ロックヘッダを用いて排他制御を行うことが可能となる。したがって、アクセス頻度の高いフィールドについての排他制御を、他のフィールドとは独立したロックリソースを用いて行うようにすることができる。よって、頻繁にアクセスされるフィールドについて、頻繁にロックが取得されても、他のフィールドについてのアクセスは、異なるロックリソースに対して同時にロックを取得することができるので、ロックの解除待ちとなる時間を短縮し、メソッド実行の並行性を高めることができる。したがって、メソッドの実行効率を向上することができる。
【００７４】
なお、本実施形態では、ＪＩＴコンパイラ１２がメソッドからアクセスされるフィールドを決定し、決定したフィールドに基づいてグループ化を行うものとしたが、ユーザがプログラム中に、メソッドが使用するフィールドを記述するようにしてもよい。この場合のメソッドのグループ化処理の流れを図２１に示す。同図に示すように、この場合、上述した図９の（Ｓ３２２）の処理の前に、コード生成部１２２は、プログラム記憶部１５に記憶されているプログラムを走査し、フィールドを指定する記述である「UseField.set」命令が記述されているかどうかを判定する（Ｓ５４１）。なお、本実施形態では、フィールドを指定する記述として、独自に規定した「UseField.set」命令を用いるものとしたが、例えば、コメントとして記述するようにしてもよいし、メソッドの修飾子として記述するようにしてもよい。UseField.set命令が記述されている場合には（Ｓ５４１：ＹＥＳ）、その引数をアクセスフィールドとし（Ｓ５４２）、記述されていなければ（Ｓ３２２）に進む。
【００７５】
フィールドを指定する記述を含むユーザプログラムの一例を図２２に示す。同図の例では、call_otherメソッドにおいて「UseField.set(f1)」が記述されている（５６１）。したがって、call_otherメソッドに対応するアクセスフィールドは「ｆ１」として図１０のグループリスト２２に登録されることになる。
【００７６】
通常、メソッドから他のメソッドが呼び出される場合には、呼出し元のメソッドの処理が終了するまでに、所属クラスのどのフィールドが使用されるのかは、呼出し先のメソッドおよびさらに呼出し先のメソッドからの呼出し先などについても連鎖的に解析する必要がある。しかし、上記のように、プログラムに記述されているアクセスフィールドの指定にしたがって、アクセスフィールドを決定することにより、解析処理を行うことなくアクセスフィールドを決定し、高精度なグループ化を行うことができる。したがって、グループごとに異なるロックリソースを用いてロックを行うことにより、クリティカルセクションの実行の並行性を向上し、ロックの解除待ちの状態をより少なくすることができる。
【００７７】
なお、本実施形態ではＪａｖａ（登録商標）言語によるプログラムを実行することを前提としたが、これに限らず同一のロックリソースに対してロックを取得する排他制御を行うクリティカルセクションを記述可能な各種のプログラム言語に適用することができる。例えば、Ｃ言語によるＰスレッドであっても、同一のロックリソース（ｍｕｔｅｘ）に対してロックを取得する複数のクリティカルセクションのそれぞれについて、アクセスされる変数群を特定して、変数群ごとにグループ化して、異なるｍｕｔｅｘに対するロックを取得するようにすることができる。
【００７８】
また、本実施形態では、仮想マシン１１におけるＪＩＴコンパイラ１２がＪａｖａ（登録商標）言語のユーザプログラムを読み込んでネイティブ形式の実行ファイルを出力するものとしたが、これに限らず、例えば、インタプリタ１１２がユーザプログラムの実行時に、メソッドをグループ化して、ロックヘッダ４３に対してロックを取得する代わりに、部分ロックヘッダ４３１〜４３４に対してロックを取得するようにしてもよい。
【００７９】
また、本実施形態では、ロックリソースに対するロックの取得は、Ｔｈｉｎ−Ｌｏｃｋ手法により行うものとしたが、これに限らず、各種の手法を用いるようにすることができる。この場合には、ロックリソースの構成を、ロックの手法に合わせたものにする。
【００８０】
また、プログラムローダ１１１が、プログラム記憶部１５からユーザプログラムを読み出すときに、メソッドのグループ化およびロックの取得先を変更するように、ユーザプログラムを書き換えるようにしてもよい。この場合、例えば、プログラムローダ１１１は、複数のロック用のインスタンスオブジェクトを生成するコードを追加し、各synchronizedメソッドについてグループ化を行い、グループごとに異なるロック用のインスタンスオブジェクトに対してロックを行うように記述を変更することができる。
【００８１】
また、本実施形態では、クリティカルセクションはsynchronizedメソッドであるものとしているが、同一のオブジェクトに対するロックを取得するsynchronizedブロックに対しても容易に適用可能である。
【００８２】
また、本実施形態では、他のメソッドを呼び出しているメソッドについては、所属クラスのすべてのフィールドをアクセスフィールドとするようにしたが、呼出し先のすべてのメソッドを解析して、アクセスフィールドを特定するようにしてもよい。この場合、コード生成部１２２が呼出し先のメソッドの解析を行うようにしてもよいし、プログラム解析部１２１が、呼出し先のメソッドを含めてフィールドにアクセスしているかどうかを解析した結果を出力するようにしてもよい。
【００８３】
また、本実施形態では、private属性のフィールドのみを有するExampleクラスを例として説明したが、所属クラスがpublicやprotected属性のフィールドを有する場合には、private属性のフィールドのみを対象として、アクセスフィールドを特定するようにしてもよいし、publicやprotected属性のフィールドであっても、他のクラスのコードに、当該所属クラスのフィールドを読み書きするコードが記述されているかどうかを判定するようにして、すべてのフィールドを対象として、アクセスフィールドを特定するようにしてもよい。
【００８４】
また、本実施形態では、１ワードは６４ビットであるものとして、６４ビットのロックリソースに対するアトミック命令がＣＰＵ１０１によってサポートされるものとしたが、例えば、１ワードが３２ビットや１６ビットであってもよい。
【００８５】
また、本実施形態では、ＣＰＵ１０１が記憶装置１０３に記憶されているプログラムを実行することにより仮想マシン１１を実現するものとしたが、これに限らず仮想マシン１１の一部または全部をハードウェアにより実現するようにしてもよい。
【００８６】
また、本実施形態では、コード生成部１２２は直接ネイティブ形式の実行ファイル、すなわち機械語で記述されたプログラムを生成するものとしたが、例えば、アセンブラ言語で記述されたソースコードを生成して、一般的なアセンブラにより機械語に翻訳するようにしてもよいし、Ｃ言語で記述されたソースコードを生成して、一般的なコンパイラによりコンパイルするようにしてもよい。
【００８７】
また、本実施形態では、ロックヘッダ４３を４つに分割した部分ロックヘッダ４３１〜４３４を用いるものとしたが、これに限らず任意の数に分割するようにしてもよい。
【００８８】
また、本実施形態では、すべてのオブジェクトは同じ大きさのロックヘッダ４３を有するものとしたが、クラスごとに可変数の部分ロックヘッダを確保するようにしてもよい。この場合のインスタンスオブジェクトおよび部分ロックヘッダの構成例を図２３に示す。同図に示すように、ロックヘッダ４３は、部分ロックヘッダが格納されるメモリ領域へのポインタであるものとし、ロックヘッダ４３が示すアドレスに可変数の部分ロックヘッダを設けるようにする。図２３の例では、「ＣｌａｓｓＡ」のオブジェクトについては、部分ロックヘッダ４３１および４３２の２つの部分ロックヘッダが確保されているが、「ＣｌａｓｓＢ」のオブジェクトについては、部分ロックヘッダ４３１〜４３５の５つの部分ロックヘッダが確保されている。
【００８９】
このように、クラスごとに可変長のロックリソースを設けることにより、例えば、クリティカルセクションが多いクラスについてはロックリソースを多く設け、クリティカルセクションが少ないクラスについてはロックリソースを少なく設けるようにすることで、管理者は排他制御に係るチューニングを行うことができる。
【００９０】
また、ロックリソースを可変数とする場合に、優先度が所定のしきい値以下のアクセスフィールドについては、ロックリソースを設けないようにしてもよい。この場合のアクセスフィールドリスト２４の生成処理の流れを図２４に示す。
【００９１】
図２４に示すアクセスフィールドの生成処理において、コード生成部１２２は、図２０のステップＳ５２２の次に、作業リスト２３から、優先度がしきい値以上であるアクセスフィールド数をカウントして組み合わせ数とする（Ｓ５６１）。コード生成部１２２は、組み合わせ数が所定の最大値よりも大きい場合には（Ｓ５６２：ＹＥＳ）、所定の最大値をグループ数とし（Ｓ５６３）、そうでなければ組み合わせ数をグループ数とする（Ｓ５６４）。所定の最大値とは、各クラスのインスタンスについて確保されるロックリソースの数の最大値であり、例えば８や１６などの値に予め設定されているものとする。所定の最大値は、管理者が設定を行うようにしてもよいし、情報処理装置１０のメモリの大きさなどに基づいて算出するようにしてもよい。
【００９２】
図２４の処理では、コード生成部１２２は、作業リスト２３の各アクセスフィールドについて、優先度がしきい値未満となった場合に（Ｓ５６５：ＮＯ）、処理を終了するようにする。また、コード生成部１２２は、（Ｓ５０１）において、登録数がグループ数を超える場合に（Ｓ５０１：ＹＥＳ）処理を終了するようにする。
【００９３】
なお、コード生成部１２２は、この処理で決定したグループ数のロックリソースを確保するようにコードを出力するようにする。
【００９４】
以上のようにして、優先度の高いアクセスフィールドの数に応じて、クラスごとにロックリソースの数を決定することができる。したがって、クラスの特定に応じて、適切な数のグループ化を行うことができるので、適切にメソッドを並行処理することができる。よって、全体として処理効率を向上することができる。
【００９５】
また、図２４の処理では、優先度の高いアクセスフィールドが数多くある場合でも、所定の最大値超えないようにグループ数を制限することができるので、ロックリソースを確保しすぎて情報処理装置１０のリソースを消費し過ぎないように抑制することができる。
【００９６】
以上、本実施形態について説明したが、上記実施形態は本発明の理解を容易にするためのものであり、本発明を限定して解釈するためのものではない。本発明は、その趣旨を逸脱することなく、変更、改良され得ると共に、本発明にはその等価物も含まれる。
【図面の簡単な説明】
【００９７】
【図１】情報処理装置１０のハードウェア構成を示す図である。
【図２】情報処理装置１０のソフトウェア構成を示す図である。
【図３】プログラム記憶部１５に記憶されるユーザプログラムの一例を示す図である。
【図４】インスタンスオブジェクトの構成例を示す図である。
【図５】実行プロファイル情報の構成例を示す図である。
【図６】メソッド呼出情報２０の構成例を示す図である。
【図７】データフロー情報２１の構成例を示す図である。
【図８】ＪＩＴコンパイラ１２による処理の流れを示す図である。
【図９】メソッドのグループ化処理の流れを示す図である。
【図１０】グループリスト２２の構成例を示す図である。
【図１１】作業リスト２３の生成処理の流れを示す図である。
【図１２】作業リスト２３の一例を示す図である。
【図１３】アクセスフィールドリスト２４の生成処理の流れを示す図である。
【図１４】アクセスフィールドリスト２４の一例を示す図である。
【図１５】排他処理を行うsynchronizedメソッドに係るコード生成処理の流れを示す図である。
【図１６】すべての部分ロックヘッダに対するロックを取得するコードの一例を示す図である。
【図１７】部分ロックヘッダに対するロックを取得するコードの一例を示す図である。
【図１８】ロックヘッダ４３と同じ大きさのフィールドをヘッダ部分に追加した場合のインスタンスオブジェクトの構成例を示す図である。
【図１９】グループ数を所定数以下に制限する場合のアクセスフィールドリスト２４の生成処理の流れを示す図である。
【図２０】優先順位順にグループ数を制限する場合のアクセスフィールドリスト２４の生成処理の流れを示す図である。
【図２１】メソッドが使用するフィールドがプログラム中に記述される場合の、メソッドのグループ化処理の流れを示す図である。
【図２２】フィールドを指定する記述を含むユーザプログラムの一例を示す図である。
【図２３】クラスごとに可変数の部分ロックヘッダを確保する場合のインスタンスオブジェクトおよび部分ロックヘッダの構成例を示す図である。
【図２４】優先度が所定のしきい値以下のアクセスフィールドについては、ロックリソースを設けないようにする場合のアクセスフィールドリスト２４の生成処理の流れを示す図である。
【図２５】Ｔｈｉｎ−Ｌｏｃｋ手法による排他制御を行う場合のコードを説明するための図である。
【符号の説明】
【００９８】
１０    情報処理装置
１０１  ＣＰＵ
１０２  メモリ
１０３  記憶装置
１０４  入力装置
１０５  出力装置
１１    仮想マシン
１２    ＪＩＴコンパイラ
１５    プログラム記憶部
１６    実行プロファイル記憶部
１７    実行ファイル記憶部
１１１  プログラムローダ
１１２  インタプリタ
１２１  プログラム解析部
１２２  コード生成部
１６１  メソッド統計
１６２  フィールド統計
２０    メソッド呼出情報
２０１  メソッド名
２０２  呼出メソッド
２１    データフロー情報
２１１  メソッド名
２１２  処理内容
２２    グループリスト
２３    作業リスト
２４    アクセスフィールドリスト
４０    インスタンスオブジェクト
４３    ロックヘッダ
４３１  部分ロックヘッダ
４３２  部分ロックヘッダ
４３３  部分ロックヘッダ
４３４  部分ロックヘッダ
５０１  スレッドＩＤ
５０２  ネスト回数
５０３  識別ビット
【図１】
2008257594.tif 000003
【図２】
2008257594.tif 000004
【図３】
2008257594.tif 000005
【図４】
2008257594.tif 000006
【図５】
2008257594.tif 000007
【図６】
2008257594.tif 000008
【図７】
2008257594.tif 000009
【図８】
2008257594.tif 000010
【図９】
2008257594.tif 000011
【図１０】
2008257594.tif 000012
【図１１】
2008257594.tif 000013
【図１２】
2008257594.tif 000014
【図１３】
2008257594.tif 000015
【図１４】
2008257594.tif 000016
【図１５】
2008257594.tif 000017
【図１６】
2008257594.tif 000018
【図１７】
2008257594.tif 000019
【図１８】
2008257594.tif 000020
【図１９】
2008257594.tif 000021
【図２０】
2008257594.tif 000022
【図２１】
2008257594.tif 000023
【図２２】
2008257594.tif 000024
【図２３】
2008257594.tif 000025
【図２４】
2008257594.tif 000026
【図２５】
2008257594.tif 000027