ruby-trunk-changes r37629 - r37647

今日はまずは DTrace のプローブが追加されています。 Mac OS X で(とりあえず Mac OS X のみ?) dtrace でトレースできるようにしています。 また最近のメソッド呼び出しの情報キャッシュのしくみの不具合修正や String#index などで使っている検索処理 rb_memsearch() の高速化などがありました。

kazu:r37629 2012-11-13 00:37:30 +0900

r37603 と r37625 の ChangeLogtypo 修正。 garbage は非可算名詞なので garbages にはならないそうです。なんか garbages と書いてしまったことがあるような気がする……。

svn:r37630 2012-11-13 00:37:34 +0900

version.h の日付更新。

tenderlove:r37631 2012-11-13 06:52:12 +0900

ruby に DTrace によるプローブを追加しています。 DTrace は(多分元は Solaris で産まれて) Mac OS XFreeBSD でサポートされているアプリケーションのトレースを取る機構です。これにより ruby を変更せずに動的にプローブの追加されたイベントを検出してプロファイル情報を取得できるようになります。 [ruby-core:27448] [Feature #2565]
今回 Ruby に追加されているプローブは

  • 例外生成
  • GC (開始/終了)
  • GC の mark フェーズ(開始/終了)
  • GC の sweep フェーズ(開始/終了)
  • Hash の生成
  • メソッドの開始、return
  • load (開始/終了)
  • require (開始/終了)
  • require のパスサーチ部分 (開始/終了)
  • オブジェクト生成
  • ruby スクリプトのパース (開始/終了)
  • String の生成
  • Array の生成

などで、その他 INSN の利用頻度の測定を実施している時にだけ呼ばれるプローブ? もあったりしますがよくわかりません。
一応構想としては https://bugs.ruby-lang.org/projects/ruby/wiki/DTraceProbes というページがありますが、ここに書かれているものよりは多いみたいです。
またプローブを使わない場合のパフォーマンスについては、C の見た目上分岐があるようにみえますが、DTrace が有効でない環境ではこれは単に消えます。DTrace が有効な環境でもプローブを有効にしなければその部分にいくつか nop が入るだけなのであまり速度への影響はないのではないかということでした。(参考URL: http://www.atdot.net/~ko1/diary/201205.html#d13 )
あとコミットログに無関係な ChangeLog のエントリが紛れこんでいるようですね。

nobu:r37632 2012-11-13 06:52:33 +0900

新規追加されたファイルの svn property 設定。

kazu:r37633 2012-11-13 09:44:12 +0900

probes.h を svn:ignore property へ追加。また .gitignore にはもともと存在していたのですが場所をファイル名でソート済みになるように移動しています。

glass:r37634 2012-11-13 11:12:40 +0900

String#index や String#index で利用されている rb_memsearch_ss() の実装を memmem(3) が利用できたら利用して実装するようにしてパフォーマンス向上を試みています。 [ruby-dev:45530] [Feature #6311]

usa:r37635 2012-11-13 12:32:06 +0900

win32/README.win32 にビルドディレクトリはソースディレクトリ(ソースツリーのルート)でなくてもいいけど win32 の下ではビルドできないという制限事項があることが追記されています。

naruse:r37636 2012-11-13 15:13:39 +0900

r37631 の DTrace のサポートで Mac OS X 以外の環境でのビルドについて修正しています。 configure で FreeBSD では DTrace を無効にしています。 また tool/gen_dummy_probes.sed というツールを tool/gen_dummy_probes.rb として ruby で書き直しています。 WindowsVC++コンパイルする環境では sed が使えないため。その他 make の依存関係の追加など。 [ruby-core:27448] [Feature #2565]

nobu:r37637 2012-11-13 15:14:44 +0900

新規追加されたファイルの svn property を追加しています。

usa:r37638 2012-11-13 15:35:30 +0900

r37636 で common.mk に追加した .d.h (*.d から *.h の生成)の依存関係は Makefile.in に移動して、win32/Makefile.sub に tool/gen_dummy_probes.rb を使って生成するルールを別途書いています。 ルールにシェルスクリプトが書かれていたところが nmake (か Windows のコマンド?)で動作しなかったとかでしょうきっと。

naruse:r37639 2012-11-13 15:38:08 +0900

さらに .d.h という依存関係の定義が有効になるために .SUFFIXES を Makefile.in に追加しています。

naruse:r37640 2012-11-13 16:49:09 +0900

dtrace 絡みのビルドの変更、特に r37638、r37639 あたりをやめにして、dmyprobes.h という dtrace 無効時のプローブの定義を記述したヘッダファイルは常に生成するようにして、 probes.h は dmyprobes.h に依存するように書き換えています。 dmyprobes.h が probes.d に依存しているので結果的に probes.h は probes.d に依存しています、というところは変わりありません。

ko1:r37641 2012-11-13 17:34:43 +0900

最近の rb_call_info_t にメソッド呼び出しの情報を集めている修正の不具合を修正しています。メソッドの呼び出しで rest 引数(もう引数リストの最後以外の場所にも * つきの引数は書けるので splat 引数というべきかも)があると to_a とがメソッド呼び出しの処理中にインタプリタから呼ばれたり、ブロック引数の to_proc メソッドが呼ばれたりするので、そこから呼び出されつつあるメソッドがさらに呼ばれたりすると同じ rb_call_info_t の内容を書き換えてしまって内容が破壊されるという問題があったので、これら変換メソッドを呼ぶ可能性がある処理の前後で rb_call_info_t の内容を一時的に保存して復旧する処理を追加しています。

ko1:r37642 2012-11-13 17:35:22 +0900

r37641 の ChangeLog エントリの修正です。

ko1:r37643 2012-11-13 17:36:42 +0900

r37180 で入っていたデバッグ用のコードを除去しています。うーむ読んでいてこれを見過していたとは我ながら残念。見返すと insns の disassemble のあたりなので油断してました。

naruse:r37644 2012-11-13 17:41:11 +0900

common.mk に r37631 の dtrace 対応で入った無意味な依存関係を削除しています。常に再ビルドするようになっていたとのこと。

naruse:r37645 2012-11-13 17:52:34 +0900

dtrace のテストは dtrace コマンドが利用可能な時だけ定義するようにしています。

shugo:r37646 2012-11-13 18:05:18 +0900

refinement で using する Module とされる Module のあいだで循環構造ができるとメソッドサーチが無限ループ(再帰)に陥ってマシンスタックを食い潰してしまうので Module#using でループが発生しないかチェックするようにしています。 [ruby-core:49092] [Bug #7308]

ko1:r37647 2012-11-13 18:48:08 +0900

メソッド呼び出しの rb_call_info_t の情報の破壊の可能性としてメソッド呼び出しのイベントフック(set_trace_func) で同じメソッドが呼ばれるという可能性があったので、EXEC_EVENT_HOOK を呼び出す前に rb_call_info_t の内容をローカル変数に保存しておいて、それを使うようにしています。またそのために rb_method_cfunc_t::invoker の引数の型を rb_call_info_t を直接受け取らないように変更しています。 r37641 のように save して restore する方法にしなかったのは速度的なことを気にしてでしょうか。