DのGC

class Foo
{
    public string name = "foo";
}

void main()
{
    auto foo  = new Foo;

    GC.free(cast(void*)foo);
    writefln(foo.name);      // -> foo
    writefln(foo);           // -> object.Error: Access Violation
}

D言語のバージョン2.020からD runtime projectのおかげでコア部分が大きく変わって,GCはcore.memoryのGC構造体からアクセスできるようになったので試してみたのだけど,上のってバグ?


そもそもGCに関してはよく理解してなくて,GCの各クラスメソッドに渡すvoid*ってオブジェクトのポインタでいいよね(ブロックの範囲ってPoolのテーブルでいいのかな?).
GCでのfreeって流し読みした感じだと,サイズによってPoolの値を埋め尽くすのと,フリーリストに繋ぐ二つに分かれてる気がするんだけど,これだと領域のfreeはしてないような(freeの印があるのがGCされた状態ってこと?).やっぱ一からGCのソースを読んで理解するしかないのかなぁ.
というかcast(void*)objで得られるのがオブジェクトのアドレスだとしたら,現状オブジェクトのtoHashで得られる値ってポインタの数値ってことでいいのか?

return cast(hash_t)cast(void*)this;

中身これだし.でも'BUG: this prevents a compacting GC from working, needs to be fixed'って書かれてるから,いずれコンパクションを実装する予定があるんだろうか?あー,分からんことだらけ.

追記

GC.minimizeを行うとfreeされるのかな.恐らくPoolが実際の割り当て領域で,これをfreeしてるのがminimizeしか見当たらない.fullCollectもmark処理をした後,sweep処理の所はフリーの印をつけてリストやページを再構築し直してるだけっぽいし.
というかminimizeが既にPoolのコンパクションをしてると思うのだけど.この辺の処理はもう少し詳しく見てみないと駄目っぽいな.