ruby-trunk-changes r47444 - r47452

今日はインクリメンタルGC の導入がありました!!

ko1: r47444 2014-09-08 13:11:00 +0900

インクリメンタルGC が導入されました! [ruby-core:64383] [Feature #10137]
今回 CRuby に導入されたインクリメンタルGC は、既に導入されている世代別GC (RGenGC) の major GC の make & sweep の mark 処理を複数回に分割して実行することで、major GC の停止時間を分散させるようにする機能のことです。オーバヘッドがあるのでスループット(全体の処理時間)は少しのびる可能性がありますが、応答性は良くなる(グッ、と固まる時間が短くなる)ことが期待されます。
mark を断続的に実施するので、markの途中で Ruby のコードが動くことがあるため、既に mark 済みのオブジェクトにまだ mark されていないオブジェクトの参照が増えて、さらに他の参照はなくなると、mark 済みにオブジェクトから参照されているのに mark されなくて回収されてしまうオブジェクトが発生するおそれがあります。これを避けるために、RGenGC で導入されていた Write Barrier を利用して、既に mark 済みのオブジェクト(Incremental GCアルゴリズムでは伝統的に Black と呼ぶそうです)に mark されていないオブジェクト(同じく White と呼ぶ)の参照が作られる時に remember set に追加して、mark されるようにしています。また CRuby の Write Barrier は完全ではなくて、WB-unprotected (shady)なオブジェクトというのもあるので、このオブジェクトが mark された時も最後に 1step で mark 処理をまとめて実行することで mark 漏れを防ぐようにしています。 WB-unprotected なオブジェクトが減ったほうが効果的になるというのは RGenGC とも同じですね。
また、ついでに(?)、WB-protected かどうかのフラグは struct RBasic::flags ではなくて外に bitmap で持つようにしていた(これは元からだと思いますが本格的に bitmap のみ利用するようになります)ので、これを RGenGC の世代数(GC を生き延びた回数)のカウンタに利用することで、3世代だったのを4世代(3回 GC を生き延びると OLD になる)に変更しています。
この世代別GC の略称は RIncGC なんですかね。

svn: r47445 2014-09-08 13:11:13 +0900

version.h の日付更新。

svn: r47446 2014-09-08 13:11:16 +0900

r47444 の変更での行末の空白除去

ko1: r47447 2014-09-08 13:22:58 +0900

benchmark/ ディレクトリに lambda calculus を使った FizzBuzz の実装を追加しています。
"Understanding Computation" という書籍で説明されている実装だそうです。 http://computationbook.com/
もうすぐ日本語訳も出るそうです。 http://www.oreilly.co.jp/books/9784873116976/

svn: r47448 2014-09-08 13:23:01 +0900

r47447 で新規追加されたファイルの svn property 設定。

ko1: r47449 2014-09-08 16:08:00 +0900

r47447 で追加したベンチマークスクリプトで Array を代入する変数に answer_str という名前をつけていたので answer_ary に改名しています。

ko1: r47450 2014-09-08 16:08:56 +0900

さらに r47447 で追加したベンチマークスクリプトで標準出力に結果の配列を表示していたのをコメントアウトしています。ベンチマークなので出力は抑制しています。

nobu: r47451 2014-09-08 17:03:21 +0900

Time のテストで、必要なタイムゾーンが環境に存在するかをプラットフォームで設定していたのを、環境変数 TZ をセットして Time.now で取得してみて判定するようにしています。

nobu: r47452 2014-09-08 17:10:37 +0900

r47451 の続き。 タイムゾーンがあるかチェックするメソッドの名前に "?" をつけて TestTimeTZ::Util#have_tz_offset? に改名しています。