RHGの逆襲 第8回

秋葉原ダイビルにて。ささださんの本拠地?会場提供および講義を行なってくださったささださんと東京大学 情報理工学系研究科に感謝致します。

名にし負うYARVの作者ささださんのVMの講義がただで受けられるという、冷静に考えたらすごいイベントですね。

とその前に、日本Rubyの会 高橋会長より RubyKaigi 2009 の開催決定のアナウンス。

RubyKaigi日記でもアナウンスされていますね。

http://rubykaigi.tdiary.net/20081005.html

また RegionalRubyKaigi も10月から毎月続々行われるそうです。なんてアツいんでしょう。

  1. 札幌 10/25(Sat)
  2. 関西 11/7-8(Fri-Sat)
  3. 九州 12/14(Sun)

それから Yugui さんからは Ruby 1.9.1 のリリース予定についての告知。

ABI(拡張ライブラリを書く時の C レベルの Ruby インタプリタへのインタフェース)の fix が 10/25 締め切り予定。ただし 1.9.1 への fix であって、将来的に 1.9.x では変更になるかもしれない。まあしかたない、というか 1.8 までも結構ころころ変わってたし。最近だと 1.8.6 から 1.8.7 でカレントスレッドへの参照が curr_thread から rb_curr_thread に変更になった(eval.c 内では #define rb_curr_thread cur_thread で吸収されてるけど、外から見えるシンボル名が変更になってるから、拡張ライブラリはバージョンを確認して自分で変更を吸収しないといけなかった)。もっとも多分 curr_thread は積極的に公開されていたシンボルではないのかもしれない。
これに絡んでライブラリの配置ディレクトリのバージョン番号を teeny まで含むかという議論があるという話。これは gtk 方式であれなんであれ teeny まで含めてディクトリを分ければそれでいいような気がするなぁ。ABI バージョンを埋め込んで云々というのはロードする前にチェックできる方法があるのならいいけど、上記のようなシンボルの解決に失敗した時のようにそもそもロードに失敗する場合もあるからグローバル変数とかで持たせるのはいまいちだと思う。

そしてささださんの講義。

なんかスライドをみて思ったのですが、わたし過去にも何度かささださんが YARV の説明するところを聴いていたことがあるんですよね。結構な回数。るびまYARV Maniacs 読んだし。なので意外と何度か聴いたことある話がポツポツと出てきました。なので今回はへぇーっと思ったところだけログ残しておきます。Ustream で流していたし、あかさたさんが録画していたようなのできっとニコニコにも上がると思うので詳しい内容はそちらを観ればいいと思います。あ、あと YARV Maniacs を今読み返すとまた何か得るものがあるような気がするので再読しようと思いました

るびま

  1. RubyVM では Instruction Sequence と言うことにしている
    1. けど面倒だから学会とかでは Byte Code と言っちゃう。
    2. Byte Code というと切り詰めてできるだけコンパクトに詰め込むような印象があるけど、RubyVM はそういう方針にしてない。
  2. コンパイルしたバイトコードを確認する手軽な方法
ruby のソースツリー上に test.rb 作る
make run で test.rb を実行する。
make parse とするとコンパイル結果がダンプされる。

ためしにやってみる。

$ cat test.rb 
puts "Hello World!"
$ make parse
./miniruby -I./lib -I.ext/common -I./- -r./ext/purelib.rb  ./tool/parse.rb ./test.rb
# ----------------------------------------------------------------------
# target program: 
# ----------------------------------------------------------------------
puts "Hello World!"
# ----------------------------------------------------------------------
# disasm result: 
# ----------------------------------------------------------------------
== disasm: <RubyVM::InstructionSequence:<main>@./test.rb>===============
0000 trace            1                                               (   1)
0002 putnil           
0003 putstring        "Hello World!"
0005 send             :puts, 1, nil, 8, <ic>
0011 leave            
# ----------------------------------------------------------------------

かっこいい。

  • CじゃなくてRubyで初期化コードを書く preleude.rb というしくみがあるらしい。
  • VM 一般的な話。意外と知ってたのでどんな話があったかだけ
    • 例外処理の実装方法
    • ダイレクトスレッディングコード
    • pinhole optimization
    • 命令融合
    • オペランド融合
    • 特化命令
  • iseq にはどこで(何を)定義したコードかでいくつか種別がある。Top(トップレベル)、Method、Class、Block など
  • iseq が決まると静的に最大のスタック消費量がわかる。無限ループするようなコードはスタック溢れるけど、コンパイラはそういうの出さない。
    • だけどメソッドの呼び出し等で積まれるフレームスタックのほうは静的に決まらないんじゃないかな……。呼ばれるメソッドも再定義されるかもしれないし。これちょっと疑問。
  • VM のグローバルロックの存在とブロックするシステムコール等への割り込みの話
    • BLOCKING_REGION マクロに処理関数と、割り込み専用の関数を渡すことでIOみたいにブロックする関数を呼ぶ。割り込みはUNIXではシグナルだけど、シグナルの喪失問題へ対処するために「かえってくるまで繰り返しシグナルを送信する」。あー繰り返すんだ……
    • ちなみに SIGVTALARM シグナルでシグナルハンドラを NULL にして割り込み用に使ってる。
  • コントロールフレームスタック(Control Frame Stack)とブロックが大変だったー。
    • 特に Proc オブジェクトになるブロックはスタックからヒープに剥すからいろいろ面倒
  • 定数の解決はレキシカルだから実は大変
    • そしてそのレキシカルなルールを破ってしまう module_eval は悪い子

でも module_eval のおかげでフレームワークみたいなのが書き易いんですよねぇ。会社のコードではめちゃ使ってます。Mixin や継承で頑張れないこともないかもしれないんですが。

それにしてもとても丁寧な講義でした。忙しいなか学生でもない(学生さんも少しはまじってたと思いますけど)人間に長時間割いて説明してくれるなんて、ささださんはいい人すぎる。

懇親会にもめっちゃ行きたかったのですけど、不幸にも客先トラブルの連絡が入ってしまったために断念。24時間保守契約してるわけでもないのに、日曜日に携帯に入電するとかどんだけ……。でもまあできるだけ対応しないとね……大人だから。