JITコンパイラ

JITコンパイラの分類


(1) JITコンパイルの制御
(2) JITコンパイルの対象
(3) 多段コンパイルの仕方


(1) JITコンパイルの制御
(1-1) インタプリタ実行しており、条件に合致したらバックグラウンドでJITコンパイルする。
(1-2) 実行直前にJITコンパイルする。

起動時はインタプリタ実行しているが、メソッドをx回呼び出したらとか、ループをn回回ったらJITコンパイルを始める。
インタプリタ実行時に様々な情報を収集しておき、JITコンパイル時に活用できる。
インタプリタ実行と並行して、別スレッドでJITコンパイルするものがほとんどのはず。
代表例として
xxx monkeyやHotspotやchakra

実行直前型は、インタプリタ実行せず、実行をブロッキングしてJITコンパイルする。
この方式の場合、JITコンパイル時間そのものが実行時間に反映される。
実行直前のコンパイルを行うものの代表例として
LLVMやV8やDart VM

(2) JITコンパイルの対象
(2-1) メソッド単位
(2-2) Tracing単位
(2-3) インタプリタ

対象のプログラミング言語のメソッド単位でJITコンパイルする。
メソッド単位なのは、
Hotspot, IonMonkey, JaegerMonkey, LLVM, V8, DartVM


インタプリタ実行時にTracingを収集し、収集したTracing単位でJITコンパイルする。
TracingはBasicBlockの集合で、よく実行されるパスごとにまとめたもの。
Tracing単位なのは、
TraceMonkey, DalvikVM

インタプリタをJITコンパイルするのは、
pypy (これは俗にMetaTracingJITと呼ばれるが)
pypyはRPythonでインタプリタを記述し、そのインタプリタ自体をJITコンパイルする。
インタプリタを丸ごとJITコンパイルするのではなく、インタプリタのよく実行される単位をTracingするのが特徴。

(3) 多段コンパイルの仕方
(3-1) 軽量->重量
(3-2) 汎用->最適化

軽量->重量なのは、最初に軽量なJITコンパイルを行い、起動時のJITコンパイルの遅延を少なくする場合に使用する。
JVMなんかが代表的で、1回目はClientJIT + Profile情報収集を埋め込み、2回目はServerJITでProfile情報収集を埋め込み、3回目はServerJITでフルコンパイル。

汎用->最適化は、主にインタプリタ実行しない場合に使用する。主に動的型付けの場合が多いかも。
汎用的なJITコンパイルは、動的型付けでどんな型でも動作するコードをJITコンパイルしておき、型情報の収集を埋め込む。
最適化JITコンパイルでは、収集した型情報を使用して型を特化させた高速に動作するコードを生成する。
主にV8とDart VMが採用。
V8 Codegen -> Crankshaft
Dart VM FlowGraphCompiler -> FlowGraphCompiler + FlowGraphOptimizer

実装に関して


LLVM

LLVMのJITはおまけです。
bitcodeのstub呼び出しのあたりが見どころかも。

OpenJDK


IBM


IBMのJVMにtraceJITを実装した場合の効果に関して。
測定結果が速くなったり遅くなったり、コードサイズがバカでかくなったりでおもしろい。

Dynamic Scripting LanguageのJITコンパイルに関してまとめられた資料。
pythonの処理系を掘り下げて説明している。pypyのことも出てくる。

JavaScript処理系

JavaScriptの処理系や高速化の歴史に関して


goto conference 2012のスライド。IEのJavaScriptのエンジンの解説。

PyPy


SPUR


  • 最終更新:2013-10-21 23:20:38

このWIKIを編集するにはパスワード入力が必要です

認証パスワード