読者です 読者をやめる 読者になる 読者になる

minigcのgc_mark_stack(void):void はいつ動くの?

ガベージコレクションのアルゴリズムと実装を読む準備としてminigc(tree:ff305e...)を読んでいるのですが、どうにもよく分からないところがでてきました。それはgc_mark_stack()を通していつオブジェクトがマークされるのかということです。少なくともぼくの環境では、gc_mark_stack()が機能するコード例を作ることはできませんでした。いつも、gc_mark_register()の方だけが動いているようです。

ここでぼくが試したこと全て書いてもごちゃごちゃするので、オリジナルをあまりいじらない範囲で確かめてみます。環境としては、ubuntuを使っていますが、まずテストを実行するために、次のようにコマンドを打ちます。


git clone https://github.com/authorNari/minigc.git minigc
cd minigc
make test

すると、gcが動く(free_listからだけではメモリが足りずgcが動いてます)たびにmarkされたオブジェクトのポインタとヘッダーのアドレスが書きだされます(mark ptr : %p, header : %p\n)。それから、スイープ中に生きてるオブジェクトのマークはunsetされます(mark unset: %p)。"make test"すると、gcが200回ほど動いて、次のようなログを残してくれます(時間がかかるので途中でCtrl+cで止めたほうが良い)。

mark ptr : 0x8810090, header : 0x8810084
mark unset : 0x8810084
mark ptr : 0x89042e0, header : 0x89042d4
mark unset : 0x89042d4
mark ptr : 0x89042e0, header : 0x89042d4
mark ptr : 0x8810090, header : 0x8810084
mark unset : 0x8810084
mark unset : 0x89042d4
...

(これは、gc.cに書かれているテストのtest_garbage_collect_load_test()だけが関係しているのですが、)とりあえず今はこれはgc_mark_stack()とは関係ないことを確かめるために、garbage_collect()の中で呼び出されているgc_mark_register()をコメントアウトしたあと実行し直します。すると、何もマークされなくなります(何のログも表示されない。実際にmake testするとエラーが出ますが、それはmain関数にreturn 0;が欠けているから)。

スタックとかレジスタのことがよく分かってないのですが、gc_mark_register()だけでスタックも拾えているように思います(これも環境依存かと思いますが)。