msumimz's diary

RubyにJITコンパイラを実装する個人プロジェクトの情報発信ブログです。

rbjit

メソッド引数とselfを実装しました

久しぶりの更新になります。遅々として進みませんが、開発が行き詰まっているわけではなく、仕事が多忙であまり時間がとれないためです。*1さて、前回はベンチマークを取り、その結果、単純にJITコンパイルしただけで高速に実行されるわけではないことが判明…

先ほどのベンチマークのコードがどのようにコンパイルされたか

参考までに、先ほどのコードがどのようにコンパイルされたか見てみましょう。元のメソッドは下記のとおりです。 def m1 i = 1 sum = 0 while i <= 10000 sum += i i += 1 end sum end JITコンパイルされた結果は以下の通りです。*1 03450016 mov edi,3 ; i =…

最初のベンチマーク

これまでにif、while、メソッド呼び出し、ローカル変数のコンパイル処理を実装してきました。すでに簡単なプログラムが動くくらいになっていますので、この辺りでJITコンパイルされたコードの速度を確認してみたいと思います。コードは以下の通りで、1から10…

whileを実装しました

こんなコードが動きます。 def m1 i = 1 sum = 0 while i <= 10000 sum += i i += 1 end sum end precompile Object, :m1 puts m1 # => 50005000 たかがwhileにどれだけ時間かかってるんだという感じですが、機能追加に合わせて周辺コードを追加・変更してい…

メソッド呼び出しを実装しました

対応したのはMRIの内部でNODE_CALLと呼ばれる、レシーバを指定した形式です。そのうち、引数が単純でブロックを取らないもの限定です。足し算なども内部ではメソッド呼び出しですので、例えば以下のコードが動きます。 def m 1 + 2 end precompile Object, :…

ローカル変数参照を実装しました

ローカル変数参照を実装しました。以下のコードが実行できます。 def m if true a = 10 else a = 20 end a end precompile Object, :m puts m # => 10 LLVMは優秀なので、上のメソッドはこんなコードにコンパイルされます(x86の場合)。 mov eax, 15h ret 1…

if文を実装しました

ついでにtrue/false/nilリテラルも実装しています。 以下のコードが動くようになりました。 def m if 1 10 else 20 end end precompiled Object, :m puts m # => 10 実装した構文はifだけですが、内部でコントロールフローグラフをSSA形式というものに変換す…

最初のJITコンパイラを実装しました

JITコンパイラの最初のバージョンが動くようになりました。このバージョンのminirubyには、Object#precompileというメソッドが追加されています。これは precompile <クラス>, <メソッド名(シンボル)> という書式で呼び出すことで、で指定されたメソッドの…