インラインキャッシュ

最近のRuby処理系の話

この話とは多分関係ないと思うが、以前1.9のコードを読んでいたときに解らなかったことがある。
メソッドのinline cache情報(class, method, vm state counter)を登録するためにNODEを生成して、NODEへの参照をバイトコード列に埋め込んでいるが、何故、情報をバイトコード列の中に直接埋め込まないのだろうか?
生成したNODEはすべてGC mark用の配列の中に登録しているので、GC markのためにそうしているように読める。しかしinline cacheに登録されたmethodをmarkする必要があるのだろうか。もしmethodがinline cacheからしか参照が無い状態に変化したのであれば、その時点でグローバルなvm state counterが更新されている筈なので、そのcache情報は既に無効になっている。


今日もう一度考えてみると、methodをmarkするためではなく、classをmarkするためではないか、ということに気付いた。
無名クラスに対する参照がinline cacheに登録された状態で、その無名クラスが消滅する。その後で別の無名クラスが作成されて、そのアドレスが偶然、消滅した無名クラスと同じになった場合、無効であるべきinline cacheが参照されてしまう可能性がある。それを避けるために、inline cacheに登録されているクラスが消滅しないようにしているのではないか?
これで解決したかと思ったが、まだおかしい。
もしこれが正しいのであれば、NODEのinline cache情報(class, method, vm state counter)の中のclassメンバだけをmarkしている筈。しかし、gc.cの中を見ると、classとmethodの両方をmarkしていた。
結局、まだ解決できていない。