ruby-trunk-changes r60381 - r60401

今日はブロック引数を受け取っても遅くならないようにする変更(呼んでも遅くならないとは言ってない)や、未使用の NODE のタイプの削除などがありました。

kazu: r60381 2017-10-23 21:59:05 +0900

NEWS ファイルの Zlib の typo を修正。

yui-knk: r60382 2017-10-23 22:25:59 +0900

拡張ライブラリ coverage の branch coverage 機能の後置 while, 後置 until のテストも追加しています。なるほどループも中を1度も実行しないことがあるので分岐の一種と考えるのか。

nobu: r60383 2017-10-23 23:05:07 +0900

拡張ライブラリ openssl の IO オブジェクトを模倣している OpenSSL::Buffering やテストで使っている IO を模倣するクラスで write の複数引数対応に追随させています。

normal: r60384 2017-10-24 06:50:08 +0900

FIBER_USE_NATIVE=0 にしてビルドした時に Linux でスタック破壊していたのを修正しているようです。 get_stack() で取得したスタックのアドレスじゃなくてその場で宣言した自動変数のアドレスを利用するようにしています。ちょっと範囲が足りなかったのかな。 [ruby-core:82737] [Bug #13887] (コミットログのチケット番号はまちがってるようですね)

svn: r60385 2017-10-24 06:50:10 +0900

version.h の日付更新。

normal: r60386 2017-10-24 10:20:04 +0900

File.chmod, File.lchmod, File.chown, File.lchown, File.unlink, File.utime などのファイルシステム操作するメソッド群でシステムコールを呼ぶ時に GVL を解放するようにしています。シングルスレッドでの性能は落ちますが、遅いファイルシステムで他の Thread をブロックしないようにしているのだと思います。 [ruby-core:83200] [Feature #13996]

svn: r60387 2017-10-24 10:20:05 +0900

r60386 の新規追加ファイルの svn property 設定。

normal: r60388 2017-10-24 10:22:08 +0900

lib/net/http.rb での require を require_relative に変更しています。LOAD_PATH の探索のぶんシステムコールの呼び出しを減らすのが目的らしいです。 [ruby-core:78285] [Feature #12973]

mame: r60389 2017-10-24 14:54:30 +0900

NODE の dump などで (NODE *)1 という値をチェックしていたのは NODE_ATTRASGN で使っていたためみたいなので、既に不要になっていたので削除しています。

mame: r60390 2017-10-24 15:16:31 +0900

compile.c の defined_expr() で defined? 文のために NODE オブジェクトをヒープに確保していたのをスタック上の自動変数を使うようにしています。 NODE オブジェクトを GC の対象にしないようにする計画があるらしくて、そのための準備みたいです。今の T_IMEMO オブジェクトもですけど NODE を GC が効く便利なメモリ管理用のコンテナとして使われてたところがいろいろあったので、それはもうやめよう、ということみたいです。

mame: r60391 2017-10-24 15:27:58 +0900

gc.c に rb_discard_node() という関数を導入して rb_gc_force_recycle() を呼び出してたところで利用しています。常にキャストして呼ばれているので、引数に NODE* を受け取る関数として切り出すことで型の間違いがないかチェックがきくように、という意図みたいです。

nobu: r60392 2017-10-24 16:17:36 +0900

rb_search_method_entry() から klass=0 の時の例外をオブジェクトの型に応じて発生させている処理を uncallable_object() という関数に切り出しています。

nobu: r60393 2017-10-24 16:41:48 +0900

struct parser_params に bit field で do_print, do_loop, do_chomp, do_split などのフラグを追加して、コマンドラインオプションの -a とか -b とかで特殊な parse をする時のフラグはこれを利用するようにしています。うーんこんな大変なことをしていたのか。

nobu: r60394 2017-10-24 17:00:36 +0900

NODE のタイプ NODE_OPT_N を使わないようにして削除しています。コマンドラインオプションの -n が指定されてた時に使ってたみたいです。

nobu: r60395 2017-10-24 17:13:13 +0900

rb_type_str() の switch 文で default 節で return していたのを switch の引数(っていうのかな)を enum 型にしたので、case T_MASK に変更してコンパイラの警告除去しています。

nobu: r60396 2017-10-24 20:09:41 +0900

r60393 のコマンドラインオプションのフラグを立てる位置を shebang の処理の後に移動しています。そういえば shebang のコマンドに書いたオプションも効くという仕様がありましたねぇ。

ko1: r60397 2017-10-24 20:13:49 +0900

ブロックを def meth(&b) のように Proc オブジェクトとしてブロック引数で受けとると、オブジェクトの生成や、環境を持ち出せるようにスタックの引き剥がし(…は1.8時代の話で今は嘘かも)が必要で遅くなってしまうので、ブロック引数がないほうが速いのですが、なんと実際に参照されるまで Proc オブジェクトの生成を遅延することで、そのままブロック引数を別のメソッドに渡すだけだったり、ブロック引数を受け取るけどブロックの呼び出しは yield を使うというようなケースでは高速に動くようにしています。 また VM 命令にも getblockparam と setblockparam という命令を追加していますが、これは名前からするとブロックを呼ぶ時のものかな…。いや、ブロック引数を参照した時に Proc 化したり、上書きした時にフラグを落としたりするためのものみたいですね。
確か &b はブロック引数(block argument)で、lambda{|x| } の x のようなのがブロックパラメーター(block parameter) という用法だと Matz に昔教わった記憶が。 [ruby-core:83536] [Feature #14045]
それはともかく、ブロックをブロック引数として受け取ると遅いというのはずいぶん前からどうにかできないかなーと思ってた問題ですが、このように解決できたんですねー。凄いです。ただ b.call のように呼ぶとそこで Proc 化のコストが変わる点は変わらないと思いますが、どうもブロック引数をブロックを受け取ることを明示するシグネチャとして書きたい(呼び出しは yield でいい)という要望があったみたいです。

svn: r60398 2017-10-24 20:13:50 +0900

r60397 の行末の空白除去。

naruse: r60399 2017-10-24 20:15:20 +0900

r60279 の Windows で拡張ライブラリ etc の Etc.sysconfdir をビルド時の変数から受け取るようにしてたのを revert しています。 Appveyor でのテストがこけてたようです。 https://ci.appveyor.com/project/ruby/ruby/build/1.0.5571

nobu: r60400 2017-10-24 20:24:19 +0900

r60396 で修正した shebang に書かれたコマンドラインオプションによって parser のモードが変わるもののテストを追加しています。 -b と -s のテストが追加されてます。

kazu: r60401 2017-10-24 21:10:32 +0900

ARGF.read_nonblock が IO#read_nonblock と同様にオプション引数で exception: true を受け付けるようになっているので、rdoc 用コメントにも反映させています。 [ruby-core:70000] [Feature #11358]