2013-03-04

脱BoehmGCへの道 準備編(2)

Scheme48の世代別GCを読むと言ったな、あれは嘘だ・・・orz

引き続きSBCLの世代別GC。さすがにこの規模のコードを2,3時間でっていうのは無理があって、読んでるうちにいろいろ発見がある。

GC自体はcode/gc.lispで定義してあって、こいつが世界を止めてごみ集めしてまた世界を動かしてる。これは誰が読んでるんだ?メモリ割付はGCが必要かどうかのフラグをセットしてるだけだし。
以下はメモ:
  • Windows以外の環境ではsignal (SIG_STOP_FOR_GC: SIGUSR2)を使って世界を止めてる
    • Windowsではそんなシグナルないので、safepointと呼ばれるものでごにょごにょしてる
    • 多分CreateEventで何とかなるか?
  • 世界を止めるために作られたスレッドを全て管理している
    • そんで、pthread_killでSIG_STOP_FOR_GCを送りスレッドを止める
    • なんで現在のスレッド以外を再び起こしてるんだろう?
      • そして起こせたらエラーで死んでる・・・
      • 単なる再チェック?
  • シグナルを送らないとGCが発生しないように見えるけど、シグナル送るのはstop the worldという矛盾
    • interrupt_handle_pendingのコメントに書いてあった
      • allocが*gc-pending*にtを入れる
      • set_pseudo_atomic_interruptedが呼ばれる
      • do_pending_interruptが呼ばれる(アセンブラなんだぜこれ・・・)
        • int3もしくはud2命令でSIGTRAPを送る
        • 後ろにtrap_PendingInterruptをつけて識別する
      • handle_trapが起動される
      • ようやくinterrupt_handle_pendingにたどり着く・・・
なんでここまでしてシグナルを使いたいのかは不明。いろんな兼ね合いがあるのだろう。(シグナルを送るとスレッドのことを考えなくてもいいとか?GCの起動をぎりぎりまで遅らせたいとか?)

なんとなくばらばらなピースが合わさってきた感じがする。

No comments:

Post a Comment