Trying to work newer indy into JRuby

Charles Oliver Nutter charles.nutter at sun.com
Mon May 18 05:33:59 PDT 2009


Ok! I have managed to dispatch single-arg method calls using the new 
invokedynamic!

The logic is fairly primitive right now: http://gist.github.com/113440

Rather than try to introduce method handles throughout the system, this 
current design simply replaces my existing CallSite logic with 
invokedynamic. The dynamic call from Ruby code passes threadcontext, 
caller object, target object, and arguments through invokedynamic, which 
is then bootstrapped with a new dyn.CallSite instance and my 
GuardedMethodHandle. GMH simply asks the cached CacheEntry tuple if it's 
still valid for the incoming type, and then either dispatches through to 
the JRuby DynamicMethod object or re-looks-up the method and reinstalls 
in the dyn.CallSite.

So far it appears to be at least no slower doing it this way, but I'm 
hoping we'll be able to coax more performance out of this.

It's also pretty crashy right now; several tests I tried simply blew up. 
I can provide dumps and reproduction cases on demand.

Comments welcome...time to get some sleep.

Charles Oliver Nutter wrote:
> Ok, talking out loud here...feel free to jump in any time.
> 
> Assuming a totally dynamic class structure that has no relationship to 
> java.lang.Class...
> 
> 1. The initial bootstrap would return an "InitialLookupMethodHandle" 
> that knows how to do two things: do a slow lookup of the method 
> (installing it back into the call site), and return the result of 
> invoking it.
> 2. Upon first call, "ILMH" would grab the metaClass from the receiver 
> object and do appropriate lookup logic. It would then install a 
> GuardedMethodHandle wrapping the target method into the original call 
> site, and proceed to do an initial invocation of the target method.
> 3. GuardedMethodHandle would repeatedly check its invalidation status 
> (my volatile class-hierarchy token) and either go straight through to 
> the wrapped target or cause a re-lookup and re-install of the method
> 4. GuardedMethodHandles could be further broken down into 
> MonomorphicCachingHandle, PolymorphicCachingHandle, and other types like 
> I have in JRuby for Object#send, respond_to?, method_missing and so on.
> 
> Again this all hinges on those intermediate handles not getting in the 
> way of inlining, or the whole thing starts to fall apart.
> 
> Sounding about right?
> 
> - Charlie
> 
> Charles Oliver Nutter wrote:
>> I've read through Fidgety a few times and I think I'm starting to get it.
>>
>> So the idea is that you would install a MethodHandle into the call site 
>> that knows how to handle the incoming objects and (potentially) re-patch 
>> the call site with a new method?
>>
>> Is there any guarantee that the code in the MethodHandle will be inlined 
>> through? I may have missed some discussion on this, but I want to be 
>> absolutely clear on this point. If I wire up things exactly as in 
>> Fidgety's "Guard" method handle, will (e.g.) Hotspot inline all the way 
>> through? What are the edge cases?
>>
>> I may have enough to get this wired now...starting to see where the old 
>> pieces fit into the new structure. Hints still welcome :)
>>
>> - Charlie
>>
>> Charles Oliver Nutter wrote:
>>> Ok, I've been puzzling over the demos for a few hours, and I'm confused.
>>>
>>> With the iteration from this fall, where the full set of args were 
>>> available during the bootstrap, I was able to actually inspect the 
>>> receiver object and get information from it. Now I don't see how I can 
>>> do that.
>>>
>>> Imagine this case:
>>>
>>> * All objects are of type RubyObject
>>> * The method table is just a hash contained within RubyObject#getMetaClass
>>>
>>> When doing a dynamic call against one of those objects, there's now no 
>>> way for me to call getMetaClass on the receiver object to get its method 
>>> table, and no way for me to look up a named method in that table.
>>>
>>> I'll keep hunting, but if someone has a hint I'd appreciate it.
>>>
>>> What I need is essentially this:
>>>
>>> ... bootstrapDynamic(Object receiver, Class caller, String name, 
>>> MethodType type) {
>>>    MethodHandle handle = 
>>> ((RubyClass)receiver).getMetaClass().findMethodHandle(name, type);
>>>    CallSite callSite = new CallSite(caller, name, type);
>>>    callSite.setTarget(handle);
>>>    return callSite;
>>> }
>>>
>>> I just don't see how I can get access to *my* method tables from within 
>>> the bootstrap now, since they don't live on a Class or in a global 
>>> location anywhere. And how would I bootstrap an interpreted method?
>>>
>>> - Charlie
>>> _______________________________________________
>>> mlvm-dev mailing list
>>> mlvm-dev at openjdk.java.net
>>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
>> _______________________________________________
>> mlvm-dev mailing list
>> mlvm-dev at openjdk.java.net
>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
> 
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev




More information about the mlvm-dev mailing list