ruby-trunk-changes r42028 - r42043

今日は Array#count の SEGV する不具合修正や gc.c, bignum.c のリファクタリング、Hash のいくつかのメソッドの最適化などがありました。

akr:r42028 2013-07-17 22:53:24 +0900

bignum.c の SIZEOF_LONG と SIZEOF_BDIGITS の関係(いずれかが他方の倍数)をチェックする STATIC_ASSERT() を追加しています。また bary_mul() の小さい数の時の最適化と bigfixize() で long と BDIGIT のサイズの大小を考慮した最適化(?) と bignorm() で bigtrunc() を呼ばないようにしています。r41500 とも関連しそうですね。

glass:r42029 2013-07-17 22:59:53 +0900

Hash#delete の rb_hash_foreach() のコールバック delete_if_i() で要素を削除するために rb_hash_delete_key() を読んでいましたが、コールバック内では常に対象の Hash はイテレータ内なので直接は消せないので ST_DELETE を返すようにしています。余分な関数呼び出しやチェックを省く最適化が目的だと思われます。

ko1:r42030 2013-07-18 08:19:38 +0900

gc.c の GC に関する関数(gc.c の関数はどれも GC に関係してるという気もしますが……)に gc_ という prefix を付けたり gc_ から始まるように単語の順番をいれかえたり、heap_ から始まるようにする改名の追加と、関数定義位置の移動などのリファクタリングです。

svn:r42031 2013-07-18 08:19:43 +0900

version.h の日付更新。

akr:r42032 2013-07-18 13:00:49 +0900

bignum.c に BDIGIT の配列を 0 クリアする BDIGITS_ZERO() という関数マクロを追加して MEMZERO() のかわりにこちらを利用するようにしています。

ko1:r42033 2013-07-18 14:39:30 +0900

string.c の str_alloc() で確保した struct RString のポインタなどを 0 で初期化しているところは、既に初期化済みで不要なので削除しています。

ko1:r42034 2013-07-18 14:54:32 +0900

array.c の ary_alloc() でも embed フラグ(配列のサイズが小さい時に struct RVALUE 内に配列要素を埋め込んだ表現を利用するので、そのフラグ)のセットを NEWOBJ_OF() の時点で一緒にセットするようにして、またサイズのセットも既に 0 初期化済みで不要なので消しています。

nobu:r42035 2013-07-18 15:11:16 +0900

r41273 のあたりで $SAFE = 4 が廃止されたのに伴なって rb_ensure(4) のように rb_ensure() に定数で 4 が渡されていた時に gcc 4.4 以降の拡張機能を使ってチェックしてエラーにするようにする仕組みのために定義している関数名に "$" が含まれていたために AIX でのビルドが失敗していたそうなので、 $ を関数名に使わないようにしています。 [ruby-dev:47512] [Bug #8646]

ko1:r42036 2013-07-18 15:42:28 +0900

RGenGC の Write Barrier 用の inline 関数 rb_obj_write() でデバッグ用のログ出力のマクロ名を typo していて常に出力されていなかったのを修正しています。

nobu:r42037 2013-07-18 15:45:50 +0900

r41273 のあたりでの rb_set_safe_level(4) と rb_ensure(4) をコンパイル時にチェックしてエラーにするようにした変更のうち rb_ensure(4) は不要なチェックが残るだけなので互換性を考慮して拡張ライブラリのビルド時には警告するだけにするように変更しています。 ruby 本体のビルド時はエラーのままです。 [ruby-dev:47517] [Bug #8652]

ko1:r42038 2013-07-18 16:18:22 +0900

RGenGC のデバッグ用に array.c で Write Barrier による保護がなくなる(Shady になる)時にログを残しておいてプロセス終了時にまとめて統計情報を出力するようにする機能を追加しています。通常時はビルド時に off になっています。

glass:r42039 2013-07-18 17:48:12 +0900

Hash#flatten で引数が省略されたか 1 が指定された時は Array#flatten は呼び出さずに rb_hash_foreach() を使って直接配列に key と value を詰めていく処理を書くことで不要な中間データを抑える最適化です。

glass:r42040 2013-07-18 18:18:50 +0900

Array#count のブロック内でその Array のサイズを切り詰めるようなことをすると SEGV する不具合を修正しています。ループの最初に配列のバッファ先頭を取り出してアクセスしていたのでループ内で毎回 RARRAY_AREF() でアクセスするようにしています。 [ruby-core:56072] [Bug #8654]
コミットログが r42039 のと同じですね。 ChangeLog は正しいようなので修正は不要ですけど。

eregon:r42041 2013-07-18 20:38:01 +0900

r42040 の Array#count の SEGV の修正の続きで、引数が渡された時のループが未修正だったのでそちらも同じように修正しています。またテストも追加しています。 [ruby-core:56072] [Bug #8654]

glass:r42042 2013-07-18 20:51:54 +0900

Array#fill の実装を memfill() を利用するようにリファクタリングしています。 memfill() なんで標準ライブラリ関数あったっけ……と思ったら array.c で定義されている VALUE の配列用の関数でした。

glass:r42043 2013-07-18 21:21:51 +0900

Array#equal の実装で RARRAY_PTR() でバッファのアドレスが一致したら同一の配列としてその後の比較をスキップする最適化です。Array は replace や部分配列の切り出し時にバッファを共有することがあるので異なるオブジェクトが同一のバッファを参照している可能性があります。