ruby-trunk-changes r64683 - r64698

今日は昨日の VM 命令に leaf フラグを追加したのを利用した MJIT の最適化や、Numeric#step や Range#step が内部で使う Enumerator::ArithmeticSequence が step に Complex が渡された時の不具合修正などがありました。

k0kubun: r64683 2018-09-11 21:53:52 +0900

r64677 で VM 命令に追加した leaf フラグをみて MJIT で命令の pc の更新を行なう処理を skip するようにしています。これまでも例外処理がない時など条件を定めて pc 操作を省く最適化が試されてましたが、問題が起きて revert されてたので、これをするために leaf フラグを入れたんですね。また今のところ常に無条件で leaf が true になる命令のみスキップしています。

k0kubun: r64684 2018-09-11 22:48:00 +0900

MJIT で trace 命令の処理を一部の命令のみ行うように書いてたのを、leaf でない可能性がある命令で行なうというように条件を変更しています。独自に明示的な命令リストをメンテするのは漏れもおきやすいので leaf フラグを利用したほうが良いということみたいです。現状でこれで trace 処理が増える命令もあるので若干パフォーマンスにも悪い影響があるようです。

k0kubun: r64685 2018-09-11 23:10:00 +0900

tool/ruby_vm/models/bare_instructions.rb で VM 命令の leaf などの attribute を取り出すのに Hash#[] ではなく Hash#fetch を使うようにして、うっかり attribute を消した時に例外が発生して気がつけるようにしています。

k0kubun: r64686 2018-09-11 23:38:05 +0900

MJIT 用の worker の verbose() でメッセージの後の改行を別の fprintf() で出力してたのを format 文字列を改行つきのものを組み立てて渡すようにして1度の vfprintf() で出力するようにしています。

k0kubun: r64687 2018-09-12 00:14:56 +0900

MJIT で VM 命令の実装時に pc を動かしたかどうかのフラグを明示的に管理して、JIT の cancel 時に catch_except_p をみて戻すかどうか判定していのをこのフラグをチェックするようにしています。 cancel するのが pc 操作前だと不具合になるので、将来の不具合を避けるためとのことです。

svn: r64688 2018-09-12 00:14:57 +0900

version.h の日付更新。

shyouhei: r64689 2018-09-12 10:55:00 +0900

r64677 で opt_case_dispatch() は一部メソッド呼び出しを行なう可能性があったので leaf フラグが立てられなかったのを、cdhash_cmp() と cdhash_hash() を再実装してオブジェクトの型で分岐して rb_funcall() を呼ばないですむようにして leaf=true にしています。

shyouhei: r64690 2018-09-12 12:39:36 +0900

同じく r64677 で leaf=true にできなかった opt_str_freeze および opt_str_uminus も rb_funcall() を含まない実装にしています。なんですがこれはメソッド呼び出しが必要になったら命令の実装内で rb_funcall() するんじゃなくて、VM スタックに push してから opt_send_without_block 命令に dispatch しなおすことで結果的にメソッド呼び出しが行なわれるようにしていて、はーなるほどなー。よくみると opt_xxx 系の命令は既にだいたいこのテクニックを使ってますね。

shyouhei: r64691 2018-09-12 13:04:31 +0900

r64690 でメソッド呼び出しの命令に委譲するために VM 値スタックに push する文字列に rb_str_resurrect() を呼んでおくように修正しています。String#freeze が破壊的な処理を行うように再定義されていた時のために duplicate しておくそうです。

mrkn: r64692 2018-09-12 14:35:46 +0900

Numeric#step や Range#step を Enumerator 化した時に使われる Enumerator::ArithmeticSequence の each メソッドで step が Complex だった時に対応するため Float として扱う前に T_FLOAT 型であることを確認するようにしています。なんですがこれは次で revert されています。

mrkn: r64693 2018-09-12 14:52:27 +0900

r64692 を revert しています。

nobu: r64694 2018-09-12 16:01:59 +0900

.travis.yml の build matrix で gcc 8 を利用する時に環境変数で CC や AR などのツールを指定する環境変数をセットしていたのを、configure.ac で CC にセットされている名前をみて自動的に他の名前もセットするようにしています。

mrkn: r64695 2018-09-12 16:35:42 +0900

64692 のリベンジ。 begin と step が T_FLOAT の時だけ ruby_float_step() を呼ぶとしてたのを逆に step が Complex の時は ruby_float_step() を使わない、という条件に変更しています。ふーむ ruby_float_step() は from, to, step のいずれかが Float ならいいみたいなので、そこで NUM2DBL() を呼ばれるのがまずいのかな。それだと from や to が Complex の時もまずそうだけど、そもそもそういう Range は作れないし Complex#step も未定義なのでいいのか。

mrkn: r64696 2018-09-12 17:36:48 +0900

Enumerator::ArithmeticSequence の rdoc 用コメントを追加しています。

mrkn: r64697 2018-09-12 17:51:34 +0900

r64696 の Enumerator::ArithmeticSequence の rdoc 用コメントにサンプルや説明を追加しています。

nobu: r64698 2018-09-12 21:14:45 +0900

r64668 で .travis.yml の build matrix に古い ruby (Travis-CI でシステムにインストールできる 2.3)を使って rubyspec を実行するやつの説明(?)を stage じゃなくて name という属性にしています。コメントによると並列で動かすためみたいです。