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.