mruby jitプレゼン
TRANSCRIPT
mrubyのJITはtracing JITを採用しています。ざっくり言う
と、命令実行のたびに対応するVMと同等の機械語命令を
命令領域に書きこんでいいき、次にその命令を実行する場
合はその機械語命令を実行するというものです。
OP_LOADSELF R1
OP_LOADI R2, 1
OP_SEND R1, 1
PC
move EAX, 1
move 8(ECX), EAX
命令を実行しつつ、同等の機械語命令を生成する
/* A sBx R(A) := sBx */
SET_INT_VALUE(regs[GETARG_A(i)], GETARG_sBx(i));
NEXT;
生成コードバッファ
mrubyのJITの概要
mrubyのJITはmrubyにJITコンパイラをいれたものです。
機械語生成にXbyakを使用させてもらっています
>>> Test test <<<
mrbtest - Embeddable Ruby Test
........................................................................................................................................................................
........................................................................................................................................................................
........................................................................................................................................................................
........................................................................................................................................................................
...................................................?...................................................................................................................
.........................................F...................
Skip: Module#prepend super in alias super does not currently work in aliased methods
Fail: multiple assignment (nosplat array rhs) (mrbgems: mruby-test)
- Assertion[1] Failed: Expected "Expected to be equal" to be nil
Expected: nil
Actual: 0
Total: 899
OK: 898
KO: 1
Crash: 0
mrubyのJITはmrubyの5~10倍速い(こと
がある)とかあるけど、一番の売りはこれ
RubyのJITコンパイラなのに脅威の互換性
メソッドの再定義
Rubyはメソッドの再定義が可能で、mrubyのmake testは
再定義を多用する
メソッドが再定義されると当然古い定義は無効になるが、
古い定義だけではなく古い定義をcallしている場所も無効
化する必要がある。Inline化している場合もあるし
そこで、古いメソッドの定義の機械語列にはVMに戻るだ
けではなく、呼び出し元のメソッド先頭にVMに戻るコード
をパッチを当てるパッチも当てる (ややこしい)
詳しくは、
http://qiita.com/miura1729/items/1ab49d34acf3e9e447f8
を見てください
オーバーフロー時の処理
mrubyのJITでは直前の演算結果の型を記録しておいて
型のガードを省略している
ところが、オーバーフローするとFixnumだと思っていたら、
Floatが来るかもしれないからガードが省略できない
そこで、オーバーフローは起きないものとしてコンパイル
し、オーバーフローしたらコードを無効化して、コンパイル
しなおす。irep(mrubyの命令列の構造体)にはオーバフ
ローするかのフラグを増やしている。