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_version
は VALUE
だったんですけど、 ruby_vm_sequence
とかは vm_state_version_t
という型になっています。中身は unsigned long long
か uint64_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 とかが追加されてるから大変そうだ……