2013-03-16

脱BoehmGCへの道 実装編(2)

昨晩BBCのコミックリリーフを見ながら(寝ながら)実装方針のようなものを考えていた。

とりあえず、SBCLがどのようにポインタ内のポインタを解決しているのかは考えないようにして(たぶんscavengeがその辺をうまいこと扱っているんだと思うけど)、まずは動くものを作ろうという感じである。

とりあえず現状での違いを列挙
【SBCL】
  • 保存するポインタは、スタック及びレジスタのみ
    • 静的領域は持ってない
    • 動的にコードを生成するのだからある意味当たり前ではある
  • 全てのポインタは中身にアクセスすることなくおよそLispオブジェクトかの判別が可能
    • これによって実際にscavenge及びtransportを行う手続きをテーブルで持つことが可能
  • 全てのポインタからおよその割付サイズを割り出すことが可能
【Sagittarius】
  • 保存するポインタは、スタック、レジスタ及び静的領域
    • 結構な勢いでstaticなオブジェクトを持っているので変更したくない
  • Schemeオブジェクトかどうかの判別にはポインタの中身を見る必要がある
    • 単なるコンテナのpairはどうしても一般的なメモリとしてしか判別できない
  •  動的領域から割り付けられたものならばメモリヘッダからサイズの割り出しが可能
    • あいまいなポインタがきた場合に多少困る
    • 一応チェックが走るけど、不安
 今更ながらにオブジェクトをタグにしておけばよかったと多少後悔しているが、まぁ泣くまい。

っで、実装戦略(というほどでもないが)だけど、現状で困っているのはポインタ内ポインタの保存である。とりあえず、スタック及びレジスタ上で参照されているポインタを動かすのは嬉しくないのでこいつは無視して(不可能ではないが)、静的領域である。
いったん保存されたアドレスはページ単位で移動を禁止される、なので保存先のアドレスから中身をたどっていき全てのオブジェクトを新たな世代(もしくは単にページ)に移動させる。この際に既に保存されているものであれば動かしてはいけないのでそのままにする必要がある。そうすると、たどれるポインタのうち、スタック、静的領域及びレジスタ上にないものは全て昇格することになり、世代別GC的に動く(ような気がする)。
ここで気になるのは、スタック上で保存されたポインタで、こいつからたどれるものはどうしようかなぁというところである。まぁ、静的領域と同様にやってしまってもいいような気はするのだが、そうするとまだ保存されていないポインタを動かすことになるような気がしている。あぁ、でも動いた先をいれてやれば問題ないのか?あんまりアグレッシブに動かすと1が10になる問題が起きるよなぁ。

とりあえずこの方針で行くことにする。

No comments:

Post a Comment