実行時コンパイラのソースを表示
←
実行時コンパイラ
移動先:
案内
、
検索
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
要求した操作を行うことは許可されていません。
このページのソースの閲覧やコピーができます。
'''実行時コンパイラ'''('''Just-In-Time Compiler'''、'''JITコンパイラ'''、その都度のコンパイラ)とは、[[ソフトウェア]]の実行時にコードのコンパイルを行い実行速度の向上を図る[[コンパイラ]]のこと。通常の[[コンパイル|コンパイラ]]は[[ソースコード]](あるいは[[中間言語|中間コード]])から対象CPUの[[機械語]]への変換を実行前に事前に行い、これをJITと対比して[[事前コンパイラ]] (Ahead-Of-Timeコンパイラ、AOTコンパイラ)と呼ぶ。 ==概要== JITコンパイルという用語は、ソフトウェアを構成するモジュールやクラス、関数などの、ある単位のコードがまさに実行されるその時に、コンパイルされることから「Just In Time」の名前が付けられた。一方、[[動的コンパイル]]という用語は、実行時に機械語を生成するというより広い意味で使われることがあり、その意味ではJITコンパイルは動的コンパイルの一種と考えることができる。 事前コンパイル方式と比べ、JIT方式ではコンパイル時間の分がプログラム実行時間に関するオーバーヘッドとなる。また、事前コンパイルで可能な、高度で時間のかかる最適化を行うことは許されない。これは、実行速度を向上させるためにコンパイルするのだから、あまり時間がかかっては意味がないためである。 事前のコンパイルと比べてこのような不利な点を持ちながらも、JIT方式が有用なのは、実行時にコンパイルを行うことで[[オペレーティングシステム]]やCPUに依存しないソースコードや中間コードの状態でソフトウェアを配布することができるからである。 JITを装備した処理系は、表面上は[[インタプリタ]]として動作するが、内部でコンパイルを行い、メモリ上に生成した[[機械語]]のコードが実行されるため、インタプリタと比べると実行速度を向上することができる。この意味で、JITは[[CPU]]や[[オペレーティングシステム|OS]]に依存しない[[実行ファイル|実行形式]]を配布できる、というインタプリタの利点を保ったまま、実行速度が遅い、という欠点を克服しようとするものといえる。 ==インタプリタ方式との比較== インタプリタ方式との違いは、インタプリタ方式がその都度コードを解釈しながら実行するのに対して、JIT方式は機械語に変換したものを実行することである。とはいえ、インタプリタ方式であっても究極的にはCPUが実行しているのは機械語である。そのためインタプリタ方式とJIT方式の本質的な違いは機械語に変換する単位の大きさであると言える。JIT方式ではモジュールやクラスといった比較的大きい単位で機械語に変換しているのに対し、インタプリタ方式では行ごと、ステートメントごとなどのごく小さい単位となる。 また、インタプリタ方式と同様に実行時に[[Java仮想マシン]]や[[共通言語ランタイム]]のようなランタイム環境を必要とする。 インタプリタ方式と比較すると性能面では以下のような差が出てくる * 機械語に変換されるため、コンパイル後の実行速度はインタプリタ方式の数倍の性能となる * モジュールやクラス、関数のロード時にコンパイルが行われるため、プログラムの起動には時間がかかる * 一度コンパイルしたコードを保持するために、より多くのメモリ容量を必要とする ==適応的コンパイル (Adaptive Compilation)== 上のようなJITコンパイラの短所を補うためのJITコンパイルの一方式として[[適応的コンパイル]]という方式がある。これは、起動当初はインタプリタとして実行し、よく呼び出されるメソッドや繰り返し実行されるコードの検出([[性能解析|プロファイリング]])を行い、そのようなコードのみをコンパイルする、というものである。このとき、コードが使われた時にすぐにコンパイルするのではなく、何回か呼ばれた後に遅らせてコンパイル を行うが、このことを[[遅延コンパイル]] (Lazy Compilation)と呼ぶ。一般にプログラムの実行においてその実行時間の大半はプログラム中のごく一部において費やされる、という経験則がある(実際の比率については状況に依存するが、典型的にはコードの実行時間の80%は20%のコードにおいて費やされるといわれ、[[パレートの法則|80-20の法則]]と呼ばれる)が、適応的コンパイルにおいては実行時間の大半が費やされるような、ボトルネックとなるコードのみをコンパイルすることで、起動時のオーバーヘッドや利用メモリ増大を抑えたうえで、効率よく実行速度を向上することができる。 この適応的コンパイルによる適応的最適化 (Adaptive Optimization) は、静的コンパイルでは得られない情報を元に最適化が行えるため、静的コンパイルより、むしろパフォーマンスが上がる場合もある。 ==JITコンパイル方式の利点== JITコンパイル方式と事前コンパイルの生成コードの質を比べると、前述のようにコンパイル時間に対する制約のためJIT方式の方が不利であるが、有利な点もある。それは、実行環境を知った上でそれに応じた生成コードの選択や最適化を行うことができるということである。 [[インテル]]の[[x86]]CPUを例にとって見ると、[[IA-32]]アーキテクチャの範囲内でもそれぞれの世代でさまざまに命令が拡張されてきているが、アプリケーションコードの後方互換性を保持する場合、実行バイナリ中では[[Intel 80386|80386]]と互換の命令しか使うことができない。 つまり、[[MMX Pentium]]の[[MMX]]命令を含んだコードは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 Framework|.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を処理できるようになった<ref>[http://hacks.mozilla.org/2009/07/tracemonkey-overview/ an overview of TraceMonkey ✩ hacks.mozilla.org]</ref>。Google Chromeの[[Google V8 JavaScript Engine|V8]]など、[[インタプリタ]]を使わずに最初からJITコンパイルし、変数などの型は実行時に随時割り振っていくタイプと、Firefox 3.5のように、事前に一度インタプリタで実行して、その情報を元に型を割り振りながらJITコンパイルするタイプなどがある。どちらのタイプであっても、型が安定しているケースは、高速に実行できるようになっている。JavaScriptにおいて、型が安定しているというのは、オブジェクトについては、プロパティが追加されていないという意味も含む。プロパティアクセスの時に、まず、型が期待通りの型であるかチェックし、もし、そうならば、プロパティからそれが指し示す番地へは[[C言語]]の[[構造体]]のように定数を[[足し算]]するだけで求まる。 ==関連項目== *[[動的コンパイル]] *[[トレーシング実行時コンパイル]] ==参照== <references /> == 外部リンク == * John Aycock, [http://pharos.cpsc.ucalgary.ca/Dienst/UI/2.0/Describe/ncstrl.ucalgary_cs/2001-689-12 A brief history of just-in-time] [[Category:コンパイラ|しやすといんたいむこんはいるほうしき]]
実行時コンパイラ
に戻る。
案内メニュー
個人用ツール
ログイン
名前空間
ページ
議論
変種
表示
閲覧
ソースを表示
履歴表示
その他
検索
案内
メインページ
コミュニティ・ポータル
最近の出来事
新しいページ
最近の更新
おまかせ表示
sandbox
commonsupload
ヘルプ
ヘルプ
井戸端
notice
bugreportspage
sitesupport
ウィキペディアに関するお問い合わせ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報