今日はメソッド呼び出しに使う構造体のメモリ確保の方針変更によるパフォーマンス改善のほか date, fiddle, webrick などのライブラリの更新がありました。
lib/readline.rb で readline.so が require できない時の fallback で require "reline" する時に 既に定数 Reline が定義済みだったら require しないようにしています。require は重複しても false を返すだけなのでここまでしなくてもいい気がしますが、stub で Reline を定義して抑制したいってことかな。
標準添付ライブラリ reline の Windows 環境での Ctrl-Enter で改行を入力する処理を追加。
bundled gems の minitest のバージョンを 5.12.2 に更新しています。
make refresh-gems というターゲットを追加して bundled gems の更新と展開を行うようにしています。こういうのまだなかったのか。
標準添付ライブラリ reline で Windows 環境で左側の Alt キーのみを meta キーとして扱うようにしているそうです。German のキーボード配列では右の Alt を Shift として扱うという慣習? があるらしい。いろいろあるんですねー。
ENV#[] と ENV#fetch の rdoc 用コメントの説明を追加しています。 fetch のデフォルト値って nil か文字列じゃなくてもいいんだな……。
df91896f32fdf78c26fc38466927c0bd87444185 の Hash#fetch の rdoc 用コメントで非 ASCII 文字によるクオート記号がまぎれこんでたのを修正しています。
include/ruby/backward/cxxanyargs.hpp の rb_rescue2() が可変長引数を扱う va_end() の前に return してたのを修正しています。 Coverity Scan による検出とのこと。
tool/sync_default_gems.rb で e2mmap の gemspec ファイルをコピーする先を変更しています。
同じく default gem の e2mmap の gemspec ファイルで version.rb を require するパスを修正しています。
が ff953a003e03f5f070112ececefab4c07ff4cb0e は revert しています。 require_relative を使ってるので gemspec を移動したので require するパスはそのままでよかった。
fa8ac91e957a076f6df1adaecad7896817138009 の Fiber#transfer した時に呼び元の Fiber に transfered のフラグを立てて resume 禁止するよう変更してたのを revert しています。やはりこれはささださんの意図の通りの変更ではなかったか。
Fiber#to_s で文字列化した時に Fiber#transfer で起動されたことのある Fiberは "transfered" という文字列を状態のところに追加するようにしています。
メソッド呼び出しでだいたい一緒に使われる struct rb_call_info と struct rb_call_cache を struct rb_call_data という1つの構造体に埋め込んでまとめて確保することで、メモリ消費量の削減とアクセスのローカリティの改善によるパフォーマンス向上を狙っています。なのですがこの実現で VM 命令の attribute を sp_inc から comptime_sp_inc という attribute を分離する必要ができてその関連で VM のソースコード生成や MJIT 用のテンプレートにも変更が行なわれています。なぜこれ分けないといけなくなったのかはよくわかってないですが。 [ruby-core:95373] [Misc #16258]
89e7997622038f82115f34dbb4ea382e02bed163 で追加した compile.c の verify_call_cache() というデバッグ用関数は処理の前に関数の先頭で return するのでなにもしない状態でしたが CPDEBUG マクロが真の時のみチェックを行うように書きなおしています。
拡張ライブラリ date で Date を Range の終点に持ち、もう一方に -Float::INFINITY を持つようなものが作れなかった不具合を修正しています。 Range が <=> メソッドを呼んで始点終点のチェックをする時に -Float::INFINITY が infinite? メソッドを呼んでチェックするみたいで、Date#infinite? メソッドを追加するだけのシンプルな修正です。 [ruby-core:78220] [Bug #12961]
拡張ライブラリ date に rb_check_trusted() での taint チェックや OBJ_INFECT() での taint flag伝播の処理を削っています。 2.7 で taint は deprecated になるそうなのでそれに先んじて削除。date は default gem ですが古いバージョンでも $SAFE がサポートされなくなってきているので削っても大きな影響はないということで。
拡張ライブラリ date の Date#inspect および DateTime#inspect の表示をシンプルにしています。暦を意味するなにか? がくっついてたけど、まあ確かに読みかたはわからないんですよねー。とはいえこんなにサラっと変えて大丈夫だろうか…。
913807bd6ce98d3d362d27caef4f5e2aef0e5d79 の Date#inspect, DateTime#inspect の表示の変更に合わせて rdoc 用コメントも修正しています。
default gem date の gemspec ファイルから development dependency の rake-compiler を削除しています。
rubyspec の Date のテストで変更により失敗するようになってしまったものをとりあえず 2.7 以前でのみテストするように ruby_version_is による guard を追加しています。
拡張ライブラリ fiddle の Fiddle::Function.new で第1引数に渡された関数に対応するオブジェクトが GC で回収されてしまわないようにインスタンス変数 @closure にセットしておくようにしています。 [Bug #13286]
拡張ライブラリ fiddle のテストで環境変数 RUBYOPT や RUBYLIB の影響を受けないようにこれらをクリアしてからテスト実行するようにしています。
5ebb0d50f6560b35bc03deb79341a115c5f782ee の fiddle のテストの修正のリファクタリング。親プロセスで環境変数を一時的に書き換えるのでなく assert_in_out_err の引数で子プロセスに渡す環境変数の指定をするようにしています。
拡張ライブラリ fiddle のテスト用ヘルパーでポインタのサイズを得るのに RbConfig::SIZEOF['void*'] を参照するようにリファクタリングしています。
拡張ライブラリ fiddle で ffi_closure_free() のかわりに munmap(3) を直接呼ぶ実装があったのですが、どうやらこれは昔の libffi で不具合があったバージョンがあったようで、それを回避するためにやっていた extconf.rb でのチェックや preprocessor でのチェックなど不要になったので削って ffi_closure_free() を常に利用するようにしています。
拡張ライブラリ fiddle でも taint flag のチェックや伝播などの実装を削っています。
標準添付ライブラリ webrick のテストで Net::HTTP#write_timeout= は 2.6.0 以降でサポートされるようになったので RUBY_VERSION をチェックして代入するようにしています。 webrick も default gems なので古い ruby でもテストできるようにしないといけないため。
標準添付ライブラリ webrick の WEBrick::HTTPRequest で X-Forwarded-Host ヘッダを処理しているところでホスト部が IPv6 のアドレスだった場合を考慮してポート番号との分離を修正しています。
標準添付ライブラリ webrick でも tainted? をチェックしていたところを削っています。ただ RUBY_VERSION が 2.7 より古い場合は untaint の呼び出しは残しています。
ce6caade7c57a505f73086ccd7b33c14f7715f22 で fiddle で常に ffi_prep_closure() を使うようにしたのを revert しています。 CI には古い環境もあるからそれが壊れたかな?
fiddle のテストの変更 4d844cbaed518743776594fa5ae33b86fe176ad1 を revert。この変更自体というよりその元になった 5ebb0d50f6560b35bc03deb79341a115c5f782ee の revert のため。
ということで fiddle のテストで RUBYOPT と RUBYLIB をクリアする 5ebb0d50f6560b35bc03deb79341a115c5f782ee を revert。これも CI のエラー対応かなぁ。