鳩舎

レースしない

RubyKaigi 1 日目

ルビー会議楽しいですね。

ということで RubyKaigi はおいておいて、メソッドキャッシュの話をしましょう。笹田さんの発表の最後で出てきたやつです。僕は一人で感動に打ち震えていましたが、 IRC に書いたのは『Charlis++』とか書いててですね、ちげーよ Charlie だよみたいなことを家に帰ってから気づいて、アーオって気持ちになりました。

そんなこんなで問題のチケットはこちら。もうチケット名みただけでヨダレ垂らしながら転げまわりたくなりますね。やったぜクラスヒエラルキーメソッドキャッシュサイコー。

ちょっと関係ないコミットとかも混ざって出てるんですけど Github でどういう変更がなされたかが見れます。さらっと流し読みしながらどう変わったかを見てみましょう。

bye bye ruby_vm_global_state_version

メソッドキャッシュに使われていた ruby_vm_global_state_version が削除されています(vm_insnhelper.h#261)。

いままでは ruby_vm_global_state_version で一括管理されていたものが分割された模様。ruby_vm_sequence, ruby_global_method_state_version, ruby_global_const_state_version とあとはクラス / モジュールオブジェクトに生えてる seq で管理されてるのかな?あと、 ruby_vm_global_state_versionVALUE だったんですけど、 ruby_vm_sequence とかは vm_state_version_t という型になっています。中身は unsigned long longuint64_t っぽい(internal.h#58)。

hello method_cache_entry

前は cache_entry っていう構造体があって(vm_method.c#25)、それがメソッドキャッシュのデータだったんだけど、廃止されて method_cache_entry に置き換わってます(internal.h#74)。合わせて iseq_inline_cache_entry のメンバも変わってますね(vm_core.h#135)。

肝心のメソッドキャッシュそのものはどうなってんのかと思ったらクラスが自分のシーケンス持つように変わってるみたいですね(vm_method.c#512)。

んで、実際にクラスが更新されたら rb_clear_method_cache_by_class なりが叩かれて、rb_class_increment_sequence に飛んでクラスのシーケンスが変わると(vm_method.c#27)。

ただこれ、 seq をインクリメントし続けるのが不安な感じするけど大丈夫なのかな。オーバーフローしそうな気がするけど、大丈夫なのかな……

以上、メモでした。

これが Ruby 2.1.0 に入ると僕の uninclude gem は動かなくなりますね……どうしようかな……追従するべきだろうな……でも subclasses とかが追加されてるから大変そうだ……