ruby-trunk-changes r41441 - r41501

今日は RGenGC の修正や GC のためのベンチマークの追加、bignum.c のリファクタリングなどでたくさんコミットがありました。

nobu:r41441 2013-06-20 00:57:11 +0900

test/ruby/test_signal.rb の test_kill_immediately_before_termination でシグナルハンドラの動作テストのために SIGUSR1 を利用していたのですが、Signal.list で SIGUSR1 が利用可能かチェックするようにして、存在しなかったら SIGINT を使うようにしています。

nobu:r41442 2013-06-20 00:57:14 +0900

test/ruby/test_signal.rb の test_exit_action で IO.pipe と Process.spawn を使って書かれていたテストを IO.popen を使って、IO.new で file descriptor の番号を直接指定して開く方法をやめています。また使うシグナルも SIGUSR1 があるかどうかチェックするようにしています。 Windows で使えない機能を考慮したテストの修正です。

naruse:r41443 2013-06-20 00:59:41 +0900

test/test_open3.rb の test_noblock という Open3.popen3 のテストで子プロセスを待つ Thread の join を追加して終了を待つようにしています。

nobu:r41444 2013-06-20 01:01:16 +0900

GC.stress のフラグを保持する変数が VALUE 型に変更されたので、その変数へのポインタである ruby_initial_gc_stress_ptr の型も追随して変更しています。

nobu:r41445 2013-06-20 01:07:41 +0900

gc.c のビットマップ操作用の関数マクロ MARKED_IN_BITMAP() や FL_TEST2() を真偽値を返すように比較演算子を追加したり、引数の参照を常にかっこでくくるようにする修正など。

akr:r41446 2013-06-20 01:37:14 +0900

bignum.c で sizeof(BDIGIT) のかわりに SIZEOF_BDIGITS を参照するようにしたり、BDIGIT のサイズによる条件コンパイルの条件を修正したりと、BDIGIT のサイズ依存のコードの整理/修正をしているようです。

nobu:r41447 2013-06-20 02:44:47 +0900

Windows 版の Process.waitpid の実装で WNOHANG の指定の有無によらず子プロセスが停止していなくてもすぐに処理を返していたのを修正しています。

nobu:r41448 2013-06-20 02:46:39 +0900

test/ruby/test_process.rb のテストで標準出力や標準エラー出力を File::NULL にリダイレクトするようにしています。 Windows 環境では標準の handle は閉じることができないのでそれを考慮するようにしているそうです。

naruse:r41449 2013-06-20 03:04:16 +0900

test/ruby/test_notimp.rb のテストで子プロセスに SIGKILL を送るだけで Process.wait で待っていないテストがあったので修正しています。

nobu:r41450 2013-06-20 03:08:28 +0900

r41447 で修正した Windows 版の Process.waitpid の実装で子プロセスの状態取得にリトライした時にエラーをクリアするようにしています。リトライ後のエラーは無視していいというのがなぜなのかちょっとわからないのですが……。

nobu:r41451 2013-06-20 03:08:30 +0900

Windows 版の Process.waitpid のための poll_child_status() という関数でエラーを取得するための GetLastError() を1度呼び出してその結果をローカル変数に格納して使いまわすようにしています。

ko1:r41452 2013-06-20 05:09:59 +0900

RGenGC の不具合修正。 gc_marks() で minor GC を実行すべきところで gc_marks_body() の第3引数に FALSE を渡していて、full GC (major GC) を実行してしまっていたのを修正しています。

ko1:r41453 2013-06-20 05:43:33 +0900

gc.c の GC のプロファイル情報の収集の変更。 GC 時間として mark 時間と sweep 時間とその他(?)を合算したものを収集するようにしています。
改名された gc_prof_sweep_timer_stop() の中で sweep_time が 0 初期化されなくなっていますが、if 文の中でのみ代入されているのに GC_PROFILE_MORE_DETAIL が定義されているとその後で利用されているので、初期化しておいたほうがいいような気がします。

ko1:r41454 2013-06-20 05:49:28 +0900

gc.c の GC_PROFILE_MORE_DETAIL を 0 にセットするようにしています。デバッグ用に 1 にしたままコミットされてたとかでしょうか。また gc_prof_sweep_timer_start() のマージミスの修正。

xibbar:r41455 2013-06-20 06:11:52 +0900

r41431 での CGI.unescapeHTML の最適化で文字列に "&" が含まれていなかったらすぐ return するという変更ですが return をさらに encoding の取得の前に移動しています。

ko1:r41456 2013-06-20 06:21:16 +0900

gc.c の gc_profile_total_time() でローカル変数の宣言位置の移動などをしているのですが、if 文のなかのループをみると条件は objspace->profile.next_index > 1 でいいような気がします。

ko1:r41457 2013-06-20 06:26:13 +0900

tool/rdocbench.rb で ruby のバージョンや GC のプロファイル情報のサマリも出力するようにしています。

ko1:r41458 2013-06-20 07:33:02 +0900

make gcbench-rdoc と make gcbench-hash というルールを追加して GCベンチマークに特化したベンチマークの実施ができるようにしています。実体は tool/gcbench.rb と tool/hashbench1.rb tool/hashbench2.rb に実装されています。

nobu:r41459 2013-06-20 07:36:15 +0900

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

tarui:r41460 2013-06-20 07:48:03 +0900

rb_gc_writebarrier() で A -> B という参照の Write Barrier で A が T_ARRAY か T_HASH で要素数が 2**16 以上と大きい場合は A を remember set に追加するのではなく B のほうを remember set に追加することで remember set 経由のマーク処理を軽くしようとするチューニングを施しています。 2**16 というと結構大きいサイズでないかぎりは A をマークしたほうが早いんでしょうね。おもしろいですね。

akr:r41461 2013-06-20 08:09:05 +0900

bignum.c に Bignum のサイズを BDIGIT の配列の最後の要素(MSB 側)が非0なら単に配列のサイズで返し、そうでなかったら数値を表現できるサイズを計算する rb_absint_size() の呼び出しにするという最適化を施した BIGSIZE() というマクロを定義して、各所で利用するようにしています。

ko1:r41462 2013-06-20 08:15:56 +0900

GC 用 benchmark のスクリプトでサマリを1行にまとめて表示するように変更しています。また make gcbench-hash を gcbench-hash1 と gcbench-hash2 に分離しています。

nobu:r41463 2013-06-20 09:29:13 +0900

gc.c の gc_marks() のインデントの修正のみ。

naruse:r41464 2013-06-20 10:49:21 +0900

test/ruby/test_notimp.rb の test_call_fork でタイムアウトが頻発していたので fork 前に GC.start で強制的に GC しておくようにしています。このタイムアウトは手元でも発生してましたね。

kazu:r41465 2013-06-20 12:53:07 +0900

r41458 と r41462 の ChangeLog エントリの typo 修正。

nobu:r41466 2013-06-20 13:08:41 +0900

test/ruby/envutil.rb の invoke_ruby と assert_in_out_err でのオプション引数をキーワード引数を使って書きなおしています。省略時のデフォルト値がわかりやすいですね。

nobu:r41467 2013-06-20 13:08:47 +0900

test/ruby/envutil.rb の invoke_ruby で子プロセスの終了待ちがタイムアウトした時にメッセージとバックトレースを設定して例外を発生させるようにしています。

nobu:r41468 2013-06-20 13:08:49 +0900

test/ruby/test_fiber.rb の test_many_fibers というテストは大量のメモリを消費するのでタイムアウトがデフォルトの 10秒だと足りないことがよくあるので 60秒に伸ばしています。

nobu:r41469 2013-06-20 13:14:09 +0900

error.c に RB_TYPE_P() の引数に RARRAY_AREF() を渡していたところがあって、RB_TYPE_P() はマクロで複数回引数を評価する可能性があったので RARRAY_AREF() の結果を変数に受けとってから渡すように修正しています。なるほど、これは少し注意する必要がありますね。

ko1:r41470 2013-06-20 14:01:36 +0900

make の gcbench-rdoc gcbench-hash1 gcbench-hash2 のルールの依存関係から ruby を削除しています。

ko1:r41471 2013-06-20 14:01:56 +0900

tool/hashbench1.rb で繰り返し回数を半分に削って、そのかわり Hash に格納する内容を整数から文字列にしています。よりオブジェクトの確保が増えて GC の負荷は上がりそうですね。

ko1:r41472 2013-06-20 14:10:36 +0900

tool/hashbench1.rb で r41471 で繰り返し回数は削ったかわりに内部のループで一時的に確保するオブジェクト数は増やしています。

ko1:r41473 2013-06-20 15:18:09 +0900

GC 関係のベンチマークを tool/ の下から benchmark/gc/ の下に置くようにディレクトリ構成を変更しています。

nobu:r41474 2013-06-20 15:21:07 +0900

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

ko1:r41475 2013-06-20 16:01:58 +0900

GC 用のベンチマークに赤黒木によるベンチマークを追加しています。 jrubyベンチマークから持ってきたそうです。また ring.rb というベンチマークも追加しています。これは旧世代のオブジェクトをたくさん作るようなサンプルだそうです。なんか ring と言いつつ単方向 linked list を Ruby で実装したみたいに見えますけど……。

nobu:r41476 2013-06-20 16:03:15 +0900

r41476 で追加されたファイルの svn property 設定。また benchmark/gc/ring.rb の改行コードを変更しています。

nobu:r41477 2013-06-20 16:06:05 +0900

さらに benchmark/gc/ring.rb の行末の空白除去。

ko1:r41478 2013-06-20 16:07:46 +0900

benchmark/gc/pentomino.rb というペントミノGCベンチマークとして追加しています。単に benchmark/ にある bm_app_pentomino.rb を読み込んでいます。

nobu:r41479 2013-06-20 16:10:06 +0900

r41478 で新規追加されたファイルの svn property を設定しています。また改行コードも変更しています。

ko1:r41480 2013-06-20 16:30:41 +0900

benchmark/bm_so_binary_trees.rb で puts を再定義して出力を抑制して、最大の木の深さを増やしています。また benchmark/gc/binarytree.rb でこのベンチマークを読み込む GCベンチマークを追加しています。

nobu:r41481 2013-06-20 16:31:06 +0900

r41480 で新規追加されたファイルの svn property 設定。また改行コードも変更しています。

ko1:r41482 2013-06-20 16:47:10 +0900

benchmark/bm_app_aobench.rb に Ambient Occlusion というアルゴリズムで 3DCG をレンダリングするベンチマークを追加して、benchmark/gc/aobench.rb にもこれを読み込むベンチマークスクリプトを追加しています。

nobu:r41483 2013-06-20 16:49:15 +0900

r41482 で新規追加されたファイルの svn property 設定と改行コード変更。

kazu:r41484 2013-06-20 16:50:19 +0900

r41472 の ChangeLog エントリの typo 修正。

nobu:r41485 2013-06-20 16:51:05 +0900

r41482 で追加したファイルの行末の空白除去。

ko1:r41486 2013-06-20 16:58:13 +0900

r41482 で追加した AOBench のスクリプトで attr_accessor, attr_reader を利用してメソッド定義するように書き変えています。

ko1:r41487 2013-06-20 17:25:16 +0900

r41482 で追加した benchmark/gc/gcbench.rb で __dir__ が利用されていて 1.9.3 で動かなかったため修正しています。ベンチマークは各バージョンでの結果の比較に使うので古いバージョンでも実行できないといけないわけですね。

ko1:r41488 2013-06-20 18:00:41 +0900

benchmark/gc/gcbench.rb で GC::Profiler.report で GC のプロファイル情報出力する前に GC::Profiler.disable で無効化するようにしています。結果を生成しようとするとそこで大量のオブジェクトを生成するのでまた GC が発生して……となるのを防ぐためみたいですが、なんかそれを避けるために GC::Profiler に結果を生のオブジェクトで返すメソッドが追加されてませんでしたっけ。

nobu:r41489 2013-06-20 18:18:36 +0900

test/sdbm/test_sdbm.rb でテストクラスの定義を SDBM が存在する(拡張ライブラリがロード可能な時)だけ定義するようにしています。

ko1:r41490 2013-06-20 18:31:51 +0900

r41488 で GCベンチマーク実行時に GC::Profiler.report 前に disable を呼ぶようにしたのをやめています。1.9.3 では無限ループ(無限?)に陥っていたそうなのですが、disable を呼ぶと report でプロファイル情報を取得できなくなるので先に disableを呼ぶのがダメだったとのこと。なるほど。

knu:r41491 2013-06-20 19:19:02 +0900

defs/gmake.mk の先頭に emacs 用の mode line を追加しています。

knu:r41492 2013-06-20 19:19:05 +0900

逆に template/GNUmakefile.in からは不要な mode line を削除しています。

ko1:r41493 2013-06-20 21:20:27 +0900

rgengc_rememberset_mark() で RGENGC_PROFILE が 1以上に設定してコンパイルされていた時に remember set 内の normal (shady じゃない)オブジェクト数と shady なオブジェクト数をプロファイル情報として取得するように追加しています。

akr:r41494 2013-06-20 22:05:27 +0900

bignum.c の bary_unpack_internal() で負値のオーバフロー(アンダーフロー?)した時に -2 を返すようにしています。なんか以前もこういう変更があったような気がしますが……。

akr:r41495 2013-06-20 22:23:33 +0900

bignum.c の big2ulong() の返り値の型を VALUE から unsigned long に変更しています。関数名からして当然なのですがこれまでは VALUE 型でした。何故だー。

akr:r41496 2013-06-20 22:24:20 +0900

bignum.c に文末にセミコロンが2つ続いて書かれていたところがあったのを1つに削っています。

akr:r41497 2013-06-20 22:27:15 +0900

bignum.c の dump_bignum() でフォーマット文字列の BDIGIT 1つあたりの幅指定を8文字固定にしていたのを SIZEOF_BDIGITS を使って計算するようにして BDIGIT の型に応じて適切な表示になるようにしています。

akr:r41498 2013-06-20 22:40:09 +0900

bignum.c の rb_uint2big() で戻り値用の big の確保を bdigit_roomof(SIZEOF_VALUE) を使うことで #if の条件分岐の外に括り出すリファクタリング

akr:r41500 2013-06-20 22:52:19 +0900

bignum.c の bignorm() で bigfixize() した結果が Fixnum でない時だけ bigtrunc() を呼んで配列サイズを切り詰めるようにしています。
けど元はまず bigtrunc() で不要な配列サイズを切り詰めてから bigfixize() がその配列サイズをみて Fixnum 化できるか確認しているので、数値としては Fixnum の範囲に納まるけどなぜか配列サイズは大きいときに Fixnum にならなくなる(これまでと結果が変化する)のではないでしょうか。
[追記]と思いきや bigfixize() では BIGSIZE() を使ってチェックしていたので大丈夫みたいですね。[/追記]

akr:r41501 2013-06-20 23:09:32 +0900

bignunm.c の Toom3 アルゴリズムによる乗算関数 bigmul1_toom3() で最後に2度 bignorm() が呼び出されていたので1回にしています。