ruby-trunk-changes r41396 - r41440

今日は RGenGC の不具合修正、デバッグ機能強化、テストで zombie プロセスがたくさん発生していた(wait(2) で終了を待っていないところがたくさんあった)のを修正、bignum.c の BDIGIT のサイズが大きい時のための修正などがありました。

ko1:r41396 2013-06-19 04:50:44 +0900

variable.c の rb_const_set() で klass の Write Barrier の挿入位置が st_insert() を呼び出す前だったため、st_insert() で GC が発生すると Write Barrier で remember set へ追加した klass がクリアされてしまい Write Barrier の意味がなくなってしまうという GC タイミングに依存した不具合があったので、OBJ_WRITE() の呼び出しを後ろに移動しています。
これ以降同様に Write Barrier の挿入場所の修正が続きます。

svn:r41397 2013-06-19 04:50:49 +0900

version.h の日付更新。

ko1:r41398 2013-06-19 06:29:30 +0900

hash.c の st_update() でも r41396 と同様に Write Barrier の挿入位置を GC が走る可能性のある更新操作の後に移動しています。

ko1:r41399 2013-06-19 06:30:42 +0900

vm.c の kwmerge_i() でも r41396 と同様に Write Barrier の挿入位置を GC が走る可能性のある更新操作の後に移動しています。

ko1:r41400 2013-06-19 06:35:40 +0900

GC.stress= がこれまでは真偽値で ON/OFF のみ制御していたのを、整数値(正確には Fixnum)を受け付けるようにしています。RGenGC と LazySweep への対応で、Minor Sweep のみ実施するとか即座に全て Sweep するか(現在の GC.stress = true は full GC ですぐに Sweep も完了)などを制御できるようにしています。

ko1:r41401 2013-06-19 07:04:30 +0900

RGENGC_CHECK_MODE というコンパイル時のマクロ定義の受け付けるレベルに 3 を追加して gc_marks_test() というデバッグ用関数で検出したオブジェクト間の参照情報を表示するようにしています。

ko1:r41402 2013-06-19 07:07:09 +0900

RGENGC_CHECK_MODE が1以上に設定してコンパイルされた時に rgengc_remember() に T_NONE か T_ZOMBIE のオブジェクトが渡されたら rb_bug() で落とすようにしています。

ko1:r41403 2013-06-19 07:12:39 +0900

rgengc_remember() と rgengc_rememberset_mark() のデバッグ用の出力のレベルや表示内容の変更。

akr:r41404 2013-06-19 07:20:22 +0900

bignum.c の rb_big_aref() で BDIGIT が 16bit の環境を考慮して BIGLO() というマクロの利用をしています。ここ結果が変わりそうな気がするのですが気のせいかなぁ。

ko1:r41405 2013-06-19 07:26:57 +0900

gc.c の make_deferred() で struct RBasic::flags のフラグに T_ZOMBIE をつける時に元の型のビットも保持していたのを T_ZOMBIE で上書きしてしまうようにしています。これ T_MASK のところ以外もクリアしてしまってもいいんでしょうか。特に具体的にどのフラグが消えてまずいというわけではないのですが。

ko1:r41406 2013-06-19 07:45:41 +0900

r41400 で GC.stress= で設定する内容を整数(Fixnum)も受け付けるようにしたので、内部的に保持する変数や構造体メンバの型も int から VALUE に変更しています。

ko1:r41407 2013-06-19 07:49:19 +0900

r41400, r41406 の変更に続き garbage_collect_body() で ruby_gc_stress の数値を FIX2INT() を使って取り出すように修正しています。

kazu:r41408 2013-06-19 10:44:10 +0900

r41389 の ChangeLog のインデントや改行、メソッド名の表示方法など体裁を修正しています。

kazu:r41409 2013-06-19 14:07:28 +0900

test/ruby/envutil.rb に中身が空になった unless 文があったので削っています。

nobu:r41410 2013-06-19 15:11:15 +0900

gc_mark_children() で T_NONE や T_ZOMBIE のオブジェクトが渡された時には rb_bug() で停止するようにしています。また GC_DEBUG が定義されていた時は rb_gcdebug_print_obj_condition() を呼び出して情報を表示するようにしています。

nobu:r41411 2013-06-19 15:14:15 +0900

test/ruby/test_signal.rb の TestSignal#test_signal_process_group で Process.spawn の子プロセスのコマンド引数(ruby の -e オプションの引数)に余分なクオートがあったため、sleep 10 させるところが実際には String リテラルの評価だけになっていたのを修正しています。

ko1:r41412 2013-06-19 15:26:01 +0900

T_DATA 型のオブジェクトも Write Barrier を挿入して normal (shady じゃない)オブジェクトであることを宣言することができるようにしています。struct rb_data_type_struct に flags メンバを追加して、ここに FL_WB_PROTECTED を格納することでそこから生成したオブジェクトにもフラグが継承されるようになります。
またこのしくみを使って、さっそく RubyVM::InstructionSequence を Write Barrier で保護するようにしています。

nobu:r41413 2013-06-19 16:47:07 +0900

test/runner.rb で Test::Unit::ZombieHunter というモジュールを定義して after_teardown で Process.waitall して子プロセスが全て終了済みであることをチェックするようにしています。
テストで zombie プロセスが残っていたのでそれを検出して修正するための方策みたいですね。

nobu:r41414 2013-06-19 16:47:10 +0900

test/ruby/envutil.rb の invoke_ruby で子プロセスにシグナルを送信しているものの停止まで確認していなかったため停止するまで待って、止まらなかったら SIGKILL で停止するようにしています。

nobu:r41415 2013-06-19 16:47:12 +0900

test/ruby/ 配下のテストで子プロセスを停止していないもしくは停止を待っていないテストを修正しています。

nobu:r41416 2013-06-19 16:47:15 +0900

test/ruby/test_signal.rb の test_kill_immediately_before_termination で fork を直接使っていたのを EnvUtil の assert_in_out_err を利用するように修正しています。また Process.kill が未定義の時にテストメソッド内で即 return するようにしていたのを、メソッド定義自体を省略するように変更しています。

nobu:r41417 2013-06-19 16:47:17 +0900

test/ruby/test_io.rb の test_cross_thread_close_stdio でも fork を使っていたのを assert_separately を利用するように書き変えています。

nobu:r41418 2013-06-19 16:47:19 +0900

test/test_curses.rb で子プロセスの終了を待っていなかったので待つようにしています。

nobu:r41419 2013-06-19 16:47:22 +0900

test/gdbm/test_gdbm.rb でも fork した子プロセスの終了を待つようにしています。

nobu:r41420 2013-06-19 16:47:24 +0900

test/rinda/test_rinda.rb でもテスト用に生成したサーバ用の子プロセスの終了を待つようにしています。

nobu:r41421 2013-06-19 16:47:26 +0900

test/testunit/ のしたのいくつかのテストで IO.pipe と spawn を使って書かれていたテストは IO.popen を使って書き変えることで zombie プロセスが残っていたのに対処しています。

nobu:r41422 2013-06-19 16:47:29 +0900

test/rinda/test_rinda.rb で fork が使えるかチェックするための have_fork? メソッドは既に使われなくなったのでメソッド定義を削除しています。

nobu:r41423 2013-06-19 16:47:31 +0900

test/dbm/test_dbm.rb でも同様に fork できるか試してみる have_fork? というメソッドが定義されていましたが、既に利用されなくなっていたので削除しています。

nobu:r41424 2013-06-19 16:47:33 +0900

test/gdbm/test_gdbm.rb では子プロセスで GDBM を open するテストが fork を使って書かれていたので IO.popen を使って書き直して、ついでに have_fork? メソッドも不要になったので削っています。

nobu:r41425 2013-06-19 16:47:36 +0900

test/sdbm/test_sdbm.rb でも同様に fork を使って書かれていた子プロセスでの SDBM の open のテストを IO.popen を使って書き直しています。

nobu:r41426 2013-06-19 16:47:38 +0900

test/drb 以下のテスト群で setup と teardown でのサーバの起動と停止の処理を DRbBase モジュールにメソッドとして切り出してこれを利用するようにリファクタリングしています。

nobu:r41427 2013-06-19 18:17:23 +0900

test/test_pty.rb でも子プロセスを待っていなかったテストで Process.wait を追加しています。
今気がついたんですけど、Process.wait って引数に pid を受け付けてるんですね。 Process.waitpid を使わないといけないものだと思ってました。今は(?)両者は同じものなんですね……。

akr:r41428 2013-06-19 19:36:22 +0900

bitnum.c で BDIGIT が long よりも大きいサイズの時のことを考慮するようにした修正。 DIGSPERLONG というマクロの定義は sizeof(BDIGIT) が sizeof(long) 以下のときだけ定義するように、また DIGSPERLL は sizeof(long long) 以下の時だけ定義するようにしています。

kazu:r41429 2013-06-19 20:53:07 +0900

r41400 で GC.stress= が Fixnum も受け付けるようになったので GC.stress も真偽値だけでなく Fixnum がセットされた時はその値を返せるようにしています。

akr:r41430 2013-06-19 21:19:10 +0900

bignum.c でさらに sizeof(BDIGIT) が sizeof(long) よりも大きい時のことを考慮するようにした修正です。

xibbar:r41431 2013-06-19 21:42:05 +0900

標準添付ライブラリ cgiCGI.unescapeHTML で文字列に '&' が含まれていなかったら unescape すべき文字列は存在しないので先に return するようにして不要な処理を避けています。どうせなら string.encoding の前に return すれば良いのにという気もしますね。 https://github.com/ruby/ruby/pull/333

ko1:r41432 2013-06-19 23:30:13 +0900

gc.c の rb_gc_force_recycle() で指定されたオブジェクトを即座に再利用できるよう free list に繋ぐ時に rememberset の bitmap から対象のオブジェクトのビットをクリアしていましたが旧世代の bitmap (r41127 で導入されたもの)の対象のビットのクリアも追加しています。

ko1:r41433 2013-06-19 23:34:11 +0900

RGenGC 用のマクロ RVALUE_PROMOTED() を inline 関数として定義しなおして、RGENGC_CHECK_MODE が 1以上に定義されてコンパイルされている時(デバッグ用)は struct RBasic::flag で管理されている旧世代のマークと oldgen bitmap (旧世代 bitmap) で管理されている旧世代のマークが一致しているかをチェックして食い違っていたら rb_bug() で止めるようにしています。

akr:r41435 2013-06-19 23:53:01 +0900

bignum.c の bigfixize() と check_shiftdown() で Bignum のサイズを判定する際に確保されているバッファサイズではなくてその数値を表現するのに必要なサイズを rb_absint_size() で取得するように修正しています。 また big2ulong() では同様に long に BDIGIT がいくつ入るかを bdigit_roomof() で取得するようにしています。

ko1:r41436 2013-06-19 23:59:35 +0900

RGenGC のデバッグ用の関数 gc_marks_test() の処理を変更しているようです。差分が込み入っているので ChangeLog から抜粋すると、RGENGC_CHECK_MODE が 2以上の時に minor marking 後に major marking を実行して major marking で生きていると判定されたオブジェクトが minor marking でマークされていないのを検出するように(これは前からしていたような気もしますが)しているそうです。またバグ検出時に RGENGC_CHECK_MODE の値に応じてそのオブジェクトへの参照や、全ての参照を出力するようにしているそうです(が、差分に RGENGC_CHECK_MODE をチェックしている部分が含まれていないので、これも既存のコードに含まれている模様)。

ko1:r41437 2013-06-20 00:06:27 +0900

inline 関数化した RVALUE_PROMOTED() 内で型の警告抑制のため(?) bitmap のチェック結果を直接 int 型の変数に代入せず条件演算子で TRUE/FALSE の定数を代入するようにしています。

svn:r41438 2013-06-20 00:06:31 +0900

version.h の日付更新。

nagachika:r41439 2013-06-20 00:20:25 +0900

r41436 の ChangeLogtypo 修正。

nagachika:r41440 2013-06-20 00:27:58 +0900

r41436 での gc_free_stored_bitmaps() の定義のインデント修正。