ruby-trunk-changes 2022-02-24

今日は Class の継承関係チェックを高速化するための変更などがありました。

[651b2e5959] Peter Zhu 2022-02-22 16:16:25 UTC

Array#shift の実装に vm_args.c で使ってた rb_ary_behead() という配列オブジェクトの先頭にいくつか要素を追加する関数を流用するようにリファクタリング? しています。

[b8f0dc59d5] Jean Boussier 2022-02-23 15:51:28 UTC

$LOADED_FEATURES 変数への feature 追加のための rb_provide_feature() で追加前に rb_vm_t::loaded_features_snapshot の配列オブジェクトを空にリセットしておくようにしています。 loaded_features と loaded_features_snapshot はバッファを共有する配列なので loaded_features を破壊的変更すると共有解除のためにバッファのコピーが発生してしまうので非効率になっていたようです。どうせ loaded_features_snapshot も reset_loaded_features_snapshot() で追随させるのでクリアして共有を解除しておくことで不要なメモリコピーを抑制しようということのようです。 [ruby-core:107715] [Bug #18599]

[709a6a0786] git 2022-02-23 17:29:35 UTC

version.h の日付更新

[764e4fa850] John Hawthorn 2022-01-30 05:27:53 UTC

拡張ライブラリ objspace の ObjectSpace.memsize_of_all の実装で struct RBasic::klass が 0クリアされている内部的オブジェクトで rb_obj_is_kind_of() を呼ばないようにしています。そして rb_obj_is_kind_of() では RUBY_ASSERT() で CLASS_OF() が NULL だったら異常終了させるようにチェックを追加しています。

[b13a7c8e36] John Hawthorn 2022-01-26 03:16:57 UTC

ある Class の継承ツリーに別の Class が存在するか、つまり継承しているかというのをチェックする処理を高速化するため、 struct rb_classext_struct に superclass_depth および superclasses というメンバーを追加して全ての親 Class を配列にキャッシュしておいて、検索時には継承関係にあれば親の superclasses は子の superclasses の prefix になっているはずなので配列の要素の 1つだけ比較すれば判定できるという仕組みを使っています。この配列をメンテナンスするのがコストが高いですがクラスの継承関係が頻繁に変化することはないだろうということだと思います。地味に Object#kind_of? の実装の rb_obj_is_kind_of() でそのオブジェクトの struct RBasic::klass が比較対象の Class と同一の時のショートカットも追加されているのでこれが結構効きそうな気がします。