ruby-trunk-changes r51077 - r51091

今日は Struct の高速化などがありました。

normal: r51077 2015-07-01 05:45:44 +0900

Struct から生成したクラスでメンバーを管理するのに要素数が 10より多い時は配列をオープンアドレス法によるハッシュテーブルの実装として利用するようにしています。オープンアドレス法って複雑な割に弱点も多くてあんまり使ったことないですけど、あらかじめ要素数がわかっていたらただの線形探索よりは高速にできるっていう使いかたみたいですね。けどこれ最初のインデックスが ID と mask のビット演算なので割と衝突しやすいのでは。っていうかこれ mod じゃなくてビットANDでいいのかな。配列サイズになにか制限があるのかな。と思ったら要素数の5倍を超える最初の2の累乗-3としてあった(-3?)。あんまり空間効率は良くないということかな。 [ruby-core:66851] [ruby-core:69705] [ruby-core:69821] [Feature #10585]

svn: r51078 2015-07-01 05:46:02 +0900

version.h の日付更新。

normal: r51079 2015-07-01 06:07:18 +0900

rb_add_method_iseq() に RB_GC_GUARD() で渡された iseqval を保護するようにして、呼び元で RB_GC_GUARD() している部分を削除しています。また rb_iseq_clone() に RGenGC を無効化にしてコンパイルした時に必要と思われるということで RB_GC_GUARD() を追加しています。

naruse: r51080 2015-07-01 08:48:21 +0900

r51077 で Struct の実装を変更した時に配列サイズを long で受けている変数が暗黙の型変換の警告が出ていたので RARRAY_LENINT() で int で受けるように修正しています。

nobu: r51081 2015-07-01 09:28:49 +0900

r51080 の配列サイズを int で受けるようにしたのを revert して明示的なキャストを追加するようにしています。はて、まあどっちでもいいような気はしますが一応 RARRAY_LENINT() だとオーバフローチェックが入るぶん安全な気がしますが、なんででしょうね。
[追記]mask を int にしてもそこから先でまた暗黙の型変換があったからだそうです。[/追記]

nobu: r51082 2015-07-01 09:30:38 +0900

r51077 のオープンアドレス法を使った Struct の実装変更で内部的に使っている配列オブジェクトを rb_ary_tmp_new() を使って ObjectSpace.each_object から見えないようにしています。

hsbt: r51083 2015-07-01 10:55:03 +0900

Enumerable#none? の rdoc 用コメントにサンプルを追加して、同様のテストケースも追加しています。 https://github.com/ruby/ruby/pull/950

nobu: r51084 2015-07-01 17:16:48 +0900

r10487 の Struct の高速化で配列を線形探索するかオープンアドレス法を使うかの要素数しきい値 AREF_HASH_THRESHOLD を enum 型で定義するようにしています。

nobu: r51085 2015-07-01 17:17:02 +0900

r51077 の Struct 高速化についてオープンアドレス法で配列サイズや次のインデックスの計算につかう 5 というマジックナンバーを AREF_HASH_UNIT という enum 型の定数にしています。

nobu: r51086 2015-07-01 17:17:37 +0900

method_missing からの raise のテストで SEGV が発生しているそうで、情報の取得のため EnvUtil.invoke_ruby のかわりに assert_separately を利用するようにしています。

nobu: r51087 2015-07-01 17:17:58 +0900

vm_method.c の初期化関数 Init_eval_method() で Exception の method_missing/respond_to?/respond_to_missing? の method entry を複製する処理で visibility を固定していたのを、元の method entry のものを流用するようにしています。

nobu: r51088 2015-07-01 17:18:03 +0900

method.h の rb_method_entry_t を操作する各種 inline 関数で visibiliy の値の範囲をチェックしている VM_ASSERT() のチェックを強化しています。また $SAFE = 2,3 の廃止に伴なって safe のチェック範囲も変更しています。

nobu: r51089 2015-07-01 17:18:18 +0900

NOEX_NOREDEF というマクロを 0 に定義して vm_method.c にいくつか preprocessor の分岐があったのを METHOD_ENTRY_NOREDEF というマクロを参照するように変更しています。しかし METHOD_ENTRY_NOREDEF も定義されてなくて次の r51090 で分岐ごと削られてます。

nobu: r51090 2015-07-01 18:55:57 +0900

r51089 で分岐条件となるマクロ名を変更されたメソッドの再定義を禁止するコードを preprocessor の分岐毎削除しています。 r34983 で Exception の method_missing などの method entry をコピーするようにした時にフラグを付与して再定義を禁止するようにしたかったみたいですけど、実際に利用はされてなかったようです。 method_missing ということは r51086 からのテストでの SEGV の調査の一環(というかついで?)でしょうか。

kazu: r51091 2015-07-01 23:52:05 +0900

r51061 で追加した Net::HTTP で Content-Encoding ヘッダの大文字小文字を無視して扱うテストで、拡張ライブラリ zlib が利用できない時に自動で展開されずに Content-Encoding ヘッダがついたままレスポンスが返される時にヘッダの内容はそのまま(大文字のまま)なのでテストで小文字を期待していたのを修正しています。