shuJITのUSTを見てメモ書き

首藤さん本人によるshuJITの解説のUSTの録画を見つけたので、それを見ながらつぶやきました。 shuJIT http://www.shudo.net/jit/index-j.html
2
koba @tetsu_koba

昔のUST見つけた。 x86opti-1-9 shuJITコンパイラネタ - cybozulabs http://t.co/ZaGWTqqK

2012-03-31 13:02:10
koba @tetsu_koba

shuJIT: Javaのオペランドスタックの状態を5つ定義して、スタックのトップのひとつかふたつをレジスタにキャッシュする。全てのバイトコードについて5つの状態のネイティブコードの断片を用意しておいて、コンパイル時にそれらをつなぎ合わせる。アセンブラ不要。

2012-03-31 13:07:16
koba @tetsu_koba

shuJIT: 「rubyのスクリプトでx86の逆アセンブラを解析して、定数が埋め込まれるオフセットを調べた。」

2012-03-31 13:09:57
koba @tetsu_koba

shuJIT: 「JITコンパイラのデバッグはけっこう地獄。」

2012-03-31 13:10:52
koba @tetsu_koba

shuJIT: 「JITコンパイラの生成するコードの中にprintf相当の機能を埋め込んだ。」

2012-03-31 13:12:19
koba @tetsu_koba

shuJIT: 「デバッグログが大量に出るので、あるパターンのメソッドの時だけログが出るような機能を追加した。」

2012-03-31 13:14:40
koba @tetsu_koba

shuJIT: 「他の処理系が末尾再帰の除去の最適化を行ってるか調べる方法。無限に再帰するメソッドを動かして、スタックオーバーフローになったら最適化していない。」

2012-03-31 13:22:16
橙よつ葉🍊🍀 @orange_clover

RT @tetsu_koba: shuJIT: 「JITコンパイラの生成するコードの中にprintf相当の機能を埋め込んだ。」

2012-03-31 13:23:09
koba @tetsu_koba

shuJIT: 「OSのシグナルの活用。正常時の判断を省略できる。SEGVでNull PointerExceptionを検出。SIGFPEでArithmaticExp を検出。SEGVでStackOverFlowErrorを検出。」

2012-03-31 13:26:29
koba @tetsu_koba

shuJIT: 「OSのシグナルハンドラの中で状況判断して、復帰するときのpcを書き換えることでJavaの例外ハンドラに飛ばすことができる。」

2012-03-31 13:30:40
koba @tetsu_koba

shuJIT: 「自己書き換え。初期化メソッドなど一度だけ実行するメソッドは、その中で自身のコードを書き換えて2度目は実行しないようにした。」

2012-03-31 13:33:12
koba @tetsu_koba

shuJIT: 「Javaの言語仕様では全てのstaticのメソッド呼び出し、変数アクセスで一番最初の使用かどうかをチェックして、一番最初ならそのときにstatic initializerを呼び出すようにしなければならない。初期化がすんだ後はその判断のコードが無駄になる。」

2012-03-31 13:55:28
koba @tetsu_koba

shuJIT: 「最初にやった自己書き換え。2つのnopを入れておいて、後でそれをジャンプ命令に書き換えた。」

2012-03-31 13:58:34
三宅陽一郎MiyakeYouichiro @miyayou

RT @tetsu_koba: shuJIT: 「最初にやった自己書き換え。2つのnopを入れておいて、後でそれをジャンプ命令に書き換えた。」

2012-03-31 13:58:54
koba @tetsu_koba

shuJIT: 「2バイトがもったいないので、それを 1バイトのint 3のソフトウェア割り込みのコードに置き換えた。この命令は普通はデバッガが使うものなので、ますますデバッガとの相性が悪くなる。。」

2012-03-31 14:01:39
koba @tetsu_koba

shuJIT: 「int 3を埋め込んだアドレスと、そこで何をすべきかの対応表を作っておき、int 3のハンドラではその表に従って処理を行うようにした。」

2012-03-31 14:03:30
koba @tetsu_koba

shuJIT: 「書き換える命令が1バイトなら、atomicに書き換えるのが簡単。ロック不要。」

2012-03-31 14:05:29
koba @tetsu_koba

shuJIT: 「5バイトの命令を書き換える時のテクニック。書き換えの途中で別のスレッドがそこを実行するとまずいので、まず最初の2バイトを自分自身にループするジャンプ命令に書き換える。残りの3バイトを書き換えてから、最初の2バイトを目的のコードに書き換える。」

2012-03-31 14:10:17
koba @tetsu_koba

shuJIT: 「shuJITではコンパイルしてできたネイティブコードのサイズは元のバイトコードの10倍に膨らんでしまう。無駄なコンパイルをしないことも重要。」

2012-03-31 14:15:39
koba @tetsu_koba

shuJIT: 「どこか組み込み用のVMで元のコードの3倍にしかならないというのがあったらしいが ...」これは多分ARMのThumb2EEのプレゼンの誇大広告。

2012-03-31 14:18:04
koba @tetsu_koba

shuJIT: 「JITコンパイルしたコードをファイルに保存して、次回起動したときにそれを使えばコンパイルの時間が得するのでは?しかし、実際にはリンク(アドレスのリロケーションなど) の処理は省略できず、それはけっこうかかるのであまり得にならない。」

2012-03-31 14:22:04
koba @tetsu_koba

shuJIT: 「配列の範囲チェックの改良。IBMの方に教えてもらった。0 <= x < MAX のチェックは (unsigned)x < MAX の一回の条件分岐に置き換え可能。」

2012-03-31 14:26:10
はろ @hidenorly

マルチコアでのキャッシュの整合性大丈夫なの? RT @tetsu_koba: shuJIT: 「5バイトの命令を書き換える時のテクニック。略。まず最初の2バイトを自分自身にループするジャンプ命令に書き換える。残りの3バイトを書き換えてから、最初の2バイトを目的のコードに書き換え」

2012-03-31 14:30:11
@baitonau

(@hidenorly)マルチコアでのキャッシュの整合性大丈夫なの? RT @tetsu_koba: shuJIT: 「5バイトの命令を書き換える時のテクニック。略。まず最初の2バイトを自分自身にループするジャンプ命令に書き換える。残りの3バイトを書き換えてから、最...

2012-03-31 14:30:42
ひしだま @hishidama

RT @tetsu_koba: shuJIT: 「JITコンパイルしたコードをファイルに保存して、次回起動したときにそれを使えばコンパイルの時間が得するのでは?しかし、実際にはリンク(アドレスのリロケーションなど) の処理は省略できず、それはけっこうかかるのであまり得にならない。」

2012-03-31 17:56:31