RHGの逆襲 第9回

ラクリナックス社にて。いつも会場の提供ありがとうございます。そして発表者のさわださんにも感謝。

主なテーマは YARV(という名称はもう使わないほうがいいのだろうか)の構造についてと、オレオレ命令語を追加する方法について。今回あまりメモが残ってないので軽く読み直しながら復習のとっかかり用の忘備録用として書いておく。

  • vm_core.h をざっくりと
    • rb_vm_t
    • rb_thread_t
    • rb_control_frame_t
    • rb_block_t
    • rb_iseq_t
    • さわださんの発表資料にはこれらの構造体の静的構造図があった。まあ心がキレイならだいたいわかるような気がする。
    • 多分キモはスタックにはスタックマシンであるVMのスタック(machine_stack)と、control frame のスタックとがあって、rb_thread_t が両者を持っているってあたり。rb_control_frame_t からは sp で VM のスタック(machine_stack)のポインタも持ってる。それから iseq(命令列、いわゆるバイトコード)とそこへの pc (program counter)も rb_control_frame_t が持ってる。ブロックのコードは rb_block_t が持ってる。けど rb_control_frame_t にも block_iseq というメンバがあるな……。
      • そういえばスタックサイズってどこで決めてるんだろう。実行時のことは今回はあまり追ってなかった。
      • block のほうもまだきちんと読んでいない。第8回のささださんの解説で control frame の構造の話はちょっと聞いたけども。
  • 命令列(命令語)の構造
    • 命令語の例をみる(newrange)
    • 専用のマクロをいっぱい利用して書かれてる。
    • (gcc だと)関数ではなくてラベルつきのコード片に展開される。
      • スレッデッドコード の最適化も多分されてる(YARV Maniacs を参照)。vm_exec.c で #ifdef 分岐ごちゃごちゃとやっている。
  • 命令列の変換(*.def から *.inc へ)
    • instruction.rb
    • insn2vm.rb
  • ここからオレオレ命令語を作るサンプルとして SUPPORT_JOKE の bitblt, answer 命令語を動かしてみようとしていっせいにはまる事態に。
    • 結局 id.h に vm_opts.h が #include されてないせいでシンボルが有効になってなかったせいだったみたい。
    • 命令語を追加しても、当然その code を吐くように compiler にも手を加えないと試せない。
    • iseq_load を使えるようにすればバイトコード直接実行させることはできるかも。
  • 雑談
    • GC 話。hogelog さん曰く、Bignum と Fixnum の加算など、C の関数で一時的に作成してその関数を抜けると捨てられる VALUE 型の変数などは、明示的に解放してやるほうがいいんじゃないかという話。Bignum に限らずあちこちにあるようならちまちま対処すれば性能が良くなるかも? GC が走る前に終了するようなスクリプトならかえって遅くなるけど。保守的 GC だから、確実にゴミになるって判っている場合はこまめに解放するようにするというのは個人的には気分はいいな。まあやってみてベンチマークを取ってどうなるかを見て、それからだという結論になったと思う。
    • RNode の nd_file が使われてないから何かに流用するという件はどうなったんでしたっけ -> 4分木にする? というあたりで ruby-dev では話が止まってますね。
      • 意味ありげに残しておくよりは reserved に変更してしまって、ここ空いてますぜってことを明示しておいたほうが忘れなくて良いんじゃないかと個人的には思う。
  • 次回は compile 回りの予定。

VM の構造については本当に構造体群とその関係の確認だけで、コードのほうはあまり読まなかったので、そのあたりは復習というか独習しておいたほうがよさそう。読み返してて理解があいまいなところが結構あった(心がキレイじゃないらしい)。

(2008-11-14 追記)
凄く大事なことを書き忘れていた。id:walf443 さんも参加されていたので、懇親会で classx 使わせてもらってますーと報告とお礼をしたのでした。それで Validator を dRuby 越しに使うと、StandardError じゃない例外が発生して、connection closed になっちゃうから、せめて ClassX 内の例外の根っこになる例外を(dRuby における DRbErrorみたいに)定義できないですかねーという話になって、github で fork してどんなことをしたいのかやってみよう、ということになったのですが、まだできていません。是非やってみよう。