From: SASADA Koichi Date: 2012-11-12T17:10:40+09:00 Subject: [ruby-dev:46493] Re: Fwd: [ruby-changes:25559] shugo:r37616 (trunk): * vm_core.h (rb_call_info_t::refinements), compile.c (new_callinfo):  ささだです. (2012/11/12 16:42), Shugo Maeda wrote: > すみません、いったんrevertしました。 > テストはskipする状態で残してありますが、このテストが通らない場合はmodule_eval > のブロックでrefinementsを有効にする機能は削るつもりです。 > >>  動くので「大問題」ではないと思いますが,このままリリースするには抵抗が >> あります. > > リリースするまでに性能の問題がクリアできない場合は機能を削ることを考えて > いましたが、ささださんの作業を考えると一時的にでも入れるべきではなかった > ですね。すみません。  個人的には,「マイクロベンチマーク以外には効かないんだからいいよ」とい う意見もありだろうと思うので,機能か性能か,の決定はどなたかにお任せした いところです.  どちらかというと,個人的な印象の話になってしまうのですが,性能よりも, 「メソッド探索の根幹に関わる部分にようわからん処理で埋まる」というの は,Ruby という言語をどんどん理解しがたいものにするので反対したい,とい うのがあります.理解しがたい言語や機能は誤解されたり不幸にしかならない感じ. >>> * refineした時にrefine対象クラスにメソッドがない時はどうするか >>> メソッドがない時も常にrefineされたことを示すmethod entryを追加する? >> >>  その点,私もあのあと気づいたのですが,refine されるメソッドは追加する >> と良いと思います. > > 追加しない場合、メソッド探索失敗時もrefinementsの探索パスを通すことに > なるかなと思いますが、後でrefine対象のクラスにメソッドが追加されたりすると > まずそうなので、やっぱりrefineした時点でメソッドを追加しておかないと > まずそうです。  その場合のコストは現状と変わらないですよね.現状でも,必ず refinement を気にするので. >> (そもそも,refine されるべきメソッドがないのに refine できる,って仕様 >> はどうなの,という気もしましたが.まぁ,そういうシチュエーションもあるの >> かなぁ) > > refineの対象はメソッドではなくクラスなので、新規メソッドの追加も仕様と > したいと考えています。 > 具体的なユースケースとしては、例えばRSpecのshouldのようなものがあります。  了解です.  ちなみに,先日お会いしたときにいった refine C, :foo do |...| ... end のような表記はどうか,という話をしましたが,これは method を修飾する,と いう発想からでした. >>> * refineされたメソッドの呼出時にrb_call_info_tにどういう情報を格納するか >>> Twitterでは、refineされたことを示すmethod entryを入れておくということでしたが、 >>> 今のvm_call_methodの構造だとrb_call_info_tの中身を書き換えてgotoするような >>> 形になっているので、どういう変更を意図されているのかよくわかりませんでした。 >> >>  goto は無いですが,この辺は特に変更は不要な気がします. > > vm_call_methodに分岐を増やして、 > > case VM_METHOD_TYPE_REFINED:{ > rb_call_info_t cie = *ci; > ci = &cie; > > ci->me = (refinementsから探索したmethod entry、または元のクラスのmethod entry); > if (ci->me != 0) { > goto normal_method_dispatch; > } > else { > /* refinementsからメソッドが見つからず、元のクラスにもメソッド定義がない場合 */ > goto start_method_dispatch; > } > > とするようなイメージで合っていますか?  はい.ちなみに,rb_call_info_t を引き回す設計には問題があることがわ かっている(メソッド呼び出し途中で to_proc や to_a を読んだとき,破壊さ れる可能性がある)ため,今代替案を検討中です.  else 節のほうは,super class を探索しないといけないので,ちょっと違う ような気がしますが,「または元のクラスのmethod entry」が super class 探 索を含意している気もしますね. > refinementsから探索したmethod entryは通常のインラインキャッシュには > 載らないのですよね? > # できれば別のところにキャッシュを置いた方がいいかもしれないですけど。  yes.インラインキャッシュには乗りません.なので,色々シンプルになると 思います.  性能で問題になるようなら,refinement 用の global cache を用意すれば良 いかと思います. >>  結論が出たら,私が実装しますかね. > > 意図を正しく理解できているか不安ではありますが、ささださんは他にも作業が > たくさんありそうなので、いったん私がやってみましょうか?  もし,お時間がありそうであれば(前田さんもお忙しいと思いますが...). あと,上述したとおり,rb_call_info_t を引き回す設計を改造する予定なの で,その作業後から取りかかった方がいいかもしれません.少なくとも,今週中 には直します. > あと、本題と関係ありませんが、コードを読んでいて以下の疑問がありました。 > > * rb_iseq_t::ic_entriesはまだ使われていますか?  はい.ic_entry はインラインキャッシュ用であり,インラインメソッド キャッシュ(IMC)専用のものではありません.  以前は IMC もこれで使っていましたが,他にもインスタンス変数のインデッ クスのキャッシュ,定数キャッシュなどで利用しています. > * callinfoとcall_infoで名前の付け方に揺れがあるのは意図的ですか?  これ迷ったんですよねぇ.rb_callinfo_t に抵抗があったんです が,prefix/suffix 的に使う場合に call_info ってのには変だと思い.  全部 callinfo に付け替えようかなぁ. -- // SASADA Koichi at atdot dot net