大域変数からの参照 - GC
大域変数から参照されているものは回収されてはならない。
まだ参照されているか?は、bss領域とかデータ領域の開始位置と終了位置の間を走査してやればよい。
開始や終了の位置はリンク時に解決されるので、ld のデフォルトリンカスクリプトを見ればわかりそう。
ld を --verbose で実行するとデフォルトのリンカスクリプトが表示されます。
ld --verbose /home/taro/scheme/gc $ ld --verbose GNU ld version 2.17 Debian GNU/Linux Supported emulations: elf_i386 i386linux elf_x86_64 using internal linker script: ================================================== /* Script for -z combreloc: combine and sort reloc sections */ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") 略
うんうん分かった。
extern "C" char __bss_start[]; extern "C" char _edata[]; extern "C" char _end[];
このあたりだね。
cygwin やら COFF のクロスコンパイラだとここが違うんだろうけど、今は手元の Linux 環境で動作すれば良い。
リンカスクリプトを見て実験した感じだと __bss_start == _edata < _end が成り立つ。
アドレス範囲さえ分かれば、mark & sweep のコードは使いまわせるので大域変数での回収もこれにて完了。