Charles,

I do something like the interface injection you talk about in HotRuby
too, except it is the CallSite object which I inject methods into, one
for each receiver type.
Here is some pseudo code to show how it works in HotRuby

It's contemplated as a "polymorphic inline cache"; but since we cannot
rewrite java byte code at runtime I put the replaceable code inside a
static which can then be replaced:

At the actual callsite, is a

   static CallSite CALL_SITE1 = new CallSite("+", <info about how to
update the static CALL_SITE1> );

   // A + B becomes
   A . select ( CALL_SITE1 ) . call (A, B).



  // each callsite has it's own class, eventually!  which is re-
compiled in response to
  // call-site statistics reaching some limit.  Here is one for a call-
site that dispatches receiver
  // types Fixnum and Foo.

  class "CallSite#+" implementes CallSite__Fixnum, CallSite_Foo {

     // update the static field that points to this callsite; needed
when
     // this class is recompiled...
     void become(CallSite site) { ... }

     Callable for_Fixnum() { return RubyClass_Fixnum.PLUS_METHOD; /
*this field may be exactly typed */ }
     Callable for_Foo() { return RubyClass_Foo.PLUS_MEHTOD; /*this
field may be exactly typed */ }
  }

... the receiver is the one that chooses the method to run ...

   class RubyClass_Foo {

        Callable select(CallSite site) {
                if (site instanceof CallSite_Foo)
                    return ((CallSite_Foo)site).for_Foo();
                else
                    return slow_lookup(this, site);
        }
   }


Once you've missed the cache at this callsite for a number of times,
it will replace the callsite object with one that implements one or
more of the callback interfaces.

As far as I can see ... For the optimal case, this leaves just only
two virtual dispatches in the invocation path: one to call the
receiver's select method, and then secondly because we cannot
statically type the callsite the instance-of check inside select needs
some runtime checking.


I wrote a little about it in a blog entry some months back
http://www.javalimit.com/2009/12/yet-another-rubyonjvm-implementation.html

... kresten ...


On Jun 6, 4:47 am, Charles Oliver Nutter <[email protected]> wrote:
> On Sat, Jun 5, 2010 at 2:06 PM, Kresten Krab Thorup <[email protected]> wrote:
>
> > Oh, btw, ...
>
> > In HotRuby I do the same.  The codegen for X + B is  X.fast_plus(B,
> > SEL_PLUS).  (SEL_PLUS is statically allocated "Selector" object which
> > is akin to a CallSite object)   And then fast_plus is implemented as a
> > normal dispatch in RubyObject:
>
> >        public IRubyObject fast_plus(IRubyObject arg, Selector selector) {
> >                return this.do_select(selector).call(this, arg);
> >        }
>
> Yup, that looks familiar...I've prototyped this a few times but never
> felt like I wanted to special-case arithmetic quite yet. Now that
> other Ruby implementations are starting to catch up on performance,
> it's time to start tweaking again :)
>
> > See:http://github.com/krestenkrab/hotruby/blob/master/modules/vm-loaded/s...
>
> > In RubyFixnum, it knows you're in an arithmetic plus:
>
> >http://github.com/krestenkrab/hotruby/blob/master/modules/vm-loaded/s...
>
> > So the technique should be adaptable to JRuby as well.
>
> Actually I had a much more ambitious idea at one point that depended
> on interface injection:
>
> * For each method name in the system, generate a one-method (or
> N-method, if splitting up arities) interface that takes all
> IRubyObject and returns IRubyObject
> * As new methods are defined, add additional interfaces
> * Compiled invocation of any dynamic method then is done by calling
> against the appropriate one-method interface, injecting it if it has
> not yet been injected
>
> As the system reaches a steady state, all classes implement N
> interfaces for the N method names they define, and dispatch is as fast
> as interface injection will allow it to be for all calls.
>
> It's perhaps a gross perversion of interface injection, but I thought
> it was a cute idea :)
>
> - Charlie

-- 
You received this message because you are subscribed to the Google Groups "JVM 
Languages" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/jvm-languages?hl=en.

Reply via email to