mruby jitプレゼン

8
の JI 解説 三浦英樹

Upload: miura1729

Post on 19-Jan-2017

752 views

Category:

Software


1 download

TRANSCRIPT

mruby の JIT 解説

三浦英樹

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は

・ メソッドの再定義が出来る

・ 整数がオーバフローするとBignum

(mrubyはFloat)に勝手に変換される

どちらもせっかく生成したコードが使えなくなる

解決法

自己書き換え

無効になった命令列の先頭にVMに戻る

コードを上書きする

メソッドの再定義

Rubyはメソッドの再定義が可能で、mrubyのmake testは

再定義を多用する

メソッドが再定義されると当然古い定義は無効になるが、

古い定義だけではなく古い定義をcallしている場所も無効

化する必要がある。Inline化している場合もあるし

そこで、古いメソッドの定義の機械語列にはVMに戻るだ

けではなく、呼び出し元のメソッド先頭にVMに戻るコード

をパッチを当てるパッチも当てる (ややこしい)

詳しくは、 

http://qiita.com/miura1729/items/1ab49d34acf3e9e447f8

を見てください

オーバーフロー時の処理

mrubyのJITでは直前の演算結果の型を記録しておいて

型のガードを省略している

ところが、オーバーフローするとFixnumだと思っていたら、

Floatが来るかもしれないからガードが省略できない

そこで、オーバーフローは起きないものとしてコンパイル

し、オーバーフローしたらコードを無効化して、コンパイル

しなおす。irep(mrubyの命令列の構造体)にはオーバフ

ローするかのフラグを増やしている。

問題点

パッチを当てて無効化したコードはなにもせず放置するの

で非常にメモリがもったいない

コードを細分化して管理してGCみたいなものが求められる