実行時コンパイラ

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動: 案内検索

実行時コンパイラJust-In-Time CompilerJITコンパイラ、その都度のコンパイラ)とは、ソフトウェアの実行時にコードのコンパイルを行い実行速度の向上を図るコンパイラのこと。通常のコンパイラソースコード(あるいは中間コード)から対象CPUの機械語への変換を実行前に事前に行い、これをJITと対比して事前コンパイラ (Ahead-Of-Timeコンパイラ、AOTコンパイラ)と呼ぶ。

概要[編集]

JITコンパイルという用語は、ソフトウェアを構成するモジュールやクラス、関数などの、ある単位のコードがまさに実行されるその時に、コンパイルされることから「Just In Time」の名前が付けられた。一方、動的コンパイルという用語は、実行時に機械語を生成するというより広い意味で使われることがあり、その意味ではJITコンパイルは動的コンパイルの一種と考えることができる。

事前コンパイル方式と比べ、JIT方式ではコンパイル時間の分がプログラム実行時間に関するオーバーヘッドとなる。また、事前コンパイルで可能な、高度で時間のかかる最適化を行うことは許されない。これは、実行速度を向上させるためにコンパイルするのだから、あまり時間がかかっては意味がないためである。

事前のコンパイルと比べてこのような不利な点を持ちながらも、JIT方式が有用なのは、実行時にコンパイルを行うことでオペレーティングシステムやCPUに依存しないソースコードや中間コードの状態でソフトウェアを配布することができるからである。

JITを装備した処理系は、表面上はインタプリタとして動作するが、内部でコンパイルを行い、メモリ上に生成した機械語のコードが実行されるため、インタプリタと比べると実行速度を向上することができる。この意味で、JITはCPUOSに依存しない実行形式を配布できる、というインタプリタの利点を保ったまま、実行速度が遅い、という欠点を克服しようとするものといえる。

インタプリタ方式との比較[編集]

インタプリタ方式との違いは、インタプリタ方式がその都度コードを解釈しながら実行するのに対して、JIT方式は機械語に変換したものを実行することである。とはいえ、インタプリタ方式であっても究極的にはCPUが実行しているのは機械語である。そのためインタプリタ方式とJIT方式の本質的な違いは機械語に変換する単位の大きさであると言える。JIT方式ではモジュールやクラスといった比較的大きい単位で機械語に変換しているのに対し、インタプリタ方式では行ごと、ステートメントごとなどのごく小さい単位となる。 また、インタプリタ方式と同様に実行時にJava仮想マシン共通言語ランタイムのようなランタイム環境を必要とする。

インタプリタ方式と比較すると性能面では以下のような差が出てくる

  • 機械語に変換されるため、コンパイル後の実行速度はインタプリタ方式の数倍の性能となる
  • モジュールやクラス、関数のロード時にコンパイルが行われるため、プログラムの起動には時間がかかる
  • 一度コンパイルしたコードを保持するために、より多くのメモリ容量を必要とする

適応的コンパイル (Adaptive Compilation)[編集]

上のようなJITコンパイラの短所を補うためのJITコンパイルの一方式として適応的コンパイルという方式がある。これは、起動当初はインタプリタとして実行し、よく呼び出されるメソッドや繰り返し実行されるコードの検出(プロファイリング)を行い、そのようなコードのみをコンパイルする、というものである。このとき、コードが使われた時にすぐにコンパイルするのではなく、何回か呼ばれた後に遅らせてコンパイル を行うが、このことを遅延コンパイル (Lazy Compilation)と呼ぶ。一般にプログラムの実行においてその実行時間の大半はプログラム中のごく一部において費やされる、という経験則がある(実際の比率については状況に依存するが、典型的にはコードの実行時間の80%は20%のコードにおいて費やされるといわれ、80-20の法則と呼ばれる)が、適応的コンパイルにおいては実行時間の大半が費やされるような、ボトルネックとなるコードのみをコンパイルすることで、起動時のオーバーヘッドや利用メモリ増大を抑えたうえで、効率よく実行速度を向上することができる。 この適応的コンパイルによる適応的最適化 (Adaptive Optimization) は、静的コンパイルでは得られない情報を元に最適化が行えるため、静的コンパイルより、むしろパフォーマンスが上がる場合もある。

JITコンパイル方式の利点[編集]

JITコンパイル方式と事前コンパイルの生成コードの質を比べると、前述のようにコンパイル時間に対する制約のためJIT方式の方が不利であるが、有利な点もある。それは、実行環境を知った上でそれに応じた生成コードの選択や最適化を行うことができるということである。

インテルx86CPUを例にとって見ると、IA-32アーキテクチャの範囲内でもそれぞれの世代でさまざまに命令が拡張されてきているが、アプリケーションコードの後方互換性を保持する場合、実行バイナリ中では80386と互換の命令しか使うことができない。 つまり、MMX PentiumMMX命令を含んだコードは80386やPentiumでは実行できない。しかし、JIT方式では、CPUがMMXをサポートしているならMMX命令を使ったコードを生成し、そうでなければ多少効率の悪いPentiumの命令の範囲内での実行を行う、ということができる。

また、実行環境におけるキャッシュメモリのサイズ、速度特性なども実行時にならないと最終的にはわからない。JITコンパイル方式では実際に走行しているCPUやメモリの情報を知ることができるため、それに応じたコードを生成することができ、事前コンパイルよりも優れたコードを生成できる可能性がある。

さらに、オブジェクト指向言語の実行においては仮想メソッドの呼び出しは仮想関数表を経由した間接呼び出しになるが、動的コンパイルにおいては、そのメソッドをオーバーライド定義したサブクラスが存在しない限り、 間接呼び出しを静的束縛として呼び出したり、あるいはインライン展開することができる(そのメソッドをオーバーライドするサブクラスが動的にロードされる可能性があるが、その場合はこのコンパイルされたメソッドは最適化戻し (deoptimize) される必要がある)。

応用[編集]

JIT処理はJava技術の普及に伴い広範囲に使われるようになったが、JavaのHotspot技術はSunにおけるSelf言語での動的コンパイル技術研究に基づいており、それに先立つ商用Smalltalk処理系でもJITコンパイル技術は確立されていた。

JIT技術はトランスメタ社によるCrusoeでx86コードからCrusoeのVLIW命令への変換に用いられている。適応的コンパイル技術はDEC社によるFX!32技術でも用いられていた。

Microsoft社による.NETプラットフォームも当初からJITによる実行を前提に設計されている。

JavaのJITコンパイラ[編集]

Symantec社によるsymjitおよびBorland社によるJITコンパイラは初期の主要なJITコンパイラであった。

Sun Microsystems自身によるHotSpotコンパイラは本格的に適応的コンパイル方式を採用したJIT処理系である。Hotspot以降はJITコンパイラ部分のインタフェースが規定されており、JITコンパイルエンジン部分を差し替えることができるようになった。

IBMによるIBM JDK、BEAによるJRockitはいずれも適応的コンパイルを行う独自のJIT処理系を持っている。後者は特にx86に特化して実行効率を高めている。

学術的なものとしては、首藤によるShuJITや、富士通研究所東京工業大学によるリフレクション機能を扱うOpenJITなどがある。

JavaScriptのJITコンパイラ[編集]

近年の主要なウェブブラウザJavaScriptのエンジンにJITコンパイラを搭載し、高速に処理できるようになっている。Internet Explorer 9、Mozilla Firefox 3.5、Google Chrome 1、Safari 4、Opera 10.50、Opera Mobile 10.1以降のウェブブラウザに搭載されている。NetFront Browser 4.1 には搭載されていない。変数の型は統計的には安定しているという事実を使い、実行時の変数に代入された値の統計データから、変数に型を割り振ることにより、JITコンパイラが実現し、高速にJavaScriptを処理できるようになった[1]。Google ChromeのV8など、インタプリタを使わずに最初からJITコンパイルし、変数などの型は実行時に随時割り振っていくタイプと、Firefox 3.5のように、事前に一度インタプリタで実行して、その情報を元に型を割り振りながらJITコンパイルするタイプなどがある。どちらのタイプであっても、型が安定しているケースは、高速に実行できるようになっている。JavaScriptにおいて、型が安定しているというのは、オブジェクトについては、プロパティが追加されていないという意味も含む。プロパティアクセスの時に、まず、型が期待通りの型であるかチェックし、もし、そうならば、プロパティからそれが指し示す番地へはC言語構造体のように定数を足し算するだけで求まる。

関連項目[編集]

参照[編集]

  1. ^ an overview of TraceMonkey ✩ hacks.mozilla.org

外部リンク[編集]