今日はなんとオブジェクトの slot を compaction する GC.compact メソッドの追加、があったのですが CI のエラーで revert されたので最終的に NEWS ファイルの更新のみが残ったという感じです。
NEWS ファイルに行頭にチケット参照の開き bracket がくると rdoc のメタキャラクタになってしまうので改行の位置を調整しています。
同じく NEWS ファイルでコマンドラインオプションの "--" がメタキャラクタとして解釈されるのを防ぐため ++ で囲んでいます。
GC.compact というメソッドを追加して、compaction GC を実行できるようにしています。アルゴリズムの詳細はチケットのほうに ASCII Art による図解と疑似コード付きで説明されているのでそちらを参照。全ての struct RVALUE が動かせるわけではなくて、新しく追加した mark_entry_no_pin() で(のみ) mark したものだけ移動できるようにしているようです。これで heap 減らせるのかなぁ。 [ruby-core:91634] [Feature #15626]
r67479 の新規追加ファイルの svn property 設定。
r67479 で追加した GC.compact のテストで compaction がおきやすいように生成する一時的な Object インスタンスを2倍生成するようにしています。
r67479 の修正。 Compaction のために拡張ライブラリから参照するクラスは rb_gc_register_mark_object() で明示的に登録しておかないといけなくなったので、拡張ライブラリ json で 追加が漏れていた例外クラスを登録するようにしています。拡張ライブラリは普通の rb_gc_mark() が pin するようになるから大丈夫ってことだったけど、これ拡張ライブラリの互換性が問題になるということなのでは。
GC.compact の導入で weakref のテストがこけたそうなのでデバッグのために assert_nothing_raised をコメントアウトして例外を発生させるようにしています。
ObjectSpace::WeakMap からの参照を pin するようにしています。そして r67484 の weakref のテストのデバッグのための変更を revert しています。なるほど WeakMap からの参照は mark はしないけど pin する必要はあるわけか。
r67479 で追加した GC.compact のテストで1つもオブジェクトを移動できなくてもエラーにせず skip するようにしています。まあ、保守的GCなのでありえるから、ということかな。
構造体 struct RMoved の宣言を include/ruby/ruby.h から internal.h に移動して外部に見せないようにしています。
compile.c の iseq_add_mark_object_compile_time() と freeze_literal() で ISeq の mark_ary に要素を追加する時に RGenGC の write barrier を追加しています。
r67489 の変更で rb_gc_writebarrier() の引数の型の違いで警告が出てたので明示的なキャストを追加。
ヘッダファイル timev.h の struct tvm の宣言の前にコメントアウトした状態で struct tvm の空の宣言を追加しています。"for TAGS" とコミットログにあるので構造体宣言がマクロ PACKED_STRUCT_UNALIGNED() の中で行なわれてるので ctags でインデックスが作られないのでその対策ということかな?
parse.y で CompileError の例外メッセージで "p->xxx" みたいにソースコード上の変数名を使って書いてたところをメンバー名だけにしています。コミットログによるとリファクタリング時にうっかりメッセージ内も置換してしまってたようです。
r67479 の GC.compact 追加時の変更部分のスタイルの修正。
同じく r67479 の変更で rb_add_method_iseq で構造体 rb_method_iseq_t と同じレイアウトの構造体を関数内で定義して rb_add_method() に引数として渡してたのを普通に rb_method_iseq_t の変数を定義して使うように修正しています。なんでこんなことしてたんだろ。
id_table.c の rb_id_table_foreach_with_replace() で replace ポインタで渡された関数への第1引数に Qundef を渡してたところを NULL に修正しています。型は VALUE ではなくて ID* で Qundef != NULL なので。
rescue 節で例外を暗黙のうちに保持する特殊変数 $! の ID を defs/id.def に追加して組込みで定義しておくようにしています。
拡張ライブラリ openssl の OpenSSL::BN.new の第1引数に nil を渡すと SEGV してたので StringValuePtr() の呼び出しを if 文の条件部からその前に出すようにしています。 StringValuePtr() はマクロで内部で str 自身を上書きすることがあるから…でも Qnil の時には例外になりますよねぇ。関数の評価の順序のためかな(コンパイラによって違いそう)。 [ruby-core:92231] [Bug #15760]
r67479 の GC.compact で CI が失敗しているため r67479 から r67496 までのコミットを全部 revert しています。 けど実際には openssl の変更も revert されちゃってるので r67497 も revert されてそう。
svn さんによる version.h の日付更新も revert されたので再度更新されています。