Getting back into invokedynamic in JRuby
Charles Oliver Nutter
headius at headius.com
Mon Mar 15 19:37:39 PDT 2010
I'm finally getting back into invokedynamic/mlvm stuff in JRuby! I
have started updating our indy support and run into a few questions...
I was under the impression that JavaMethod handle would be a good way
to replace all the handle composition I was doing before. Is this
I will explain...
Previously, when bootstrapping a call site, I used all MethodHandles.*
methods to compose a chain of direct method handles from the call site
all the way to the target method object, with no non-leaf Java code in
that call path. This was necessary, I believed, to allow inlining all
the way through the dynamic call site.
The structure was roughly like this:
Guard With Test
Test (leaf Java method
Various chained handles to unpack arguments (via leaf Java methods)
Actual target method
Recache and invoke (non-leaf Java method
For the success path, it would then be all direct handles straight
through from caller to called method.
The logic for this version can be seen here:
This structure seemed to work well last fall, and on most
microbenchmarks it was as fast or faster than the trampolining version
in non-indy JRuby (where a CachingCallSite sits directly in the call
path). However, when I ran this code on current MLVM, the performance
was extremely slow...as much as ten times slower than it had been (and
ten times slower than my non-indy logic).
So today I did a rework using a Java method handle and all the
caching+call logic built directly into the handle I provide it. This
drastically reduced the complexity of my invokedynamic logic (since I
didn't have to do all that handle composition) and improved
performance, but it's still not as fast as last fall's MLVM plus the
You can see the new version here:
I'm trying to find the right way to phrase my question to make sure I
get the right answer...
1. Do I need to use all direct method handles to get inlining from the
caller to the callee?
2. If I have a Java method handle that does a MethodHandle.invoke call
in its body, will that invoked handle get inlined all the way back for
3. Does the body of the method pointed at by a JavaMethodHandle get
specialized for all call sites, so that it doesn't appear to be a
single body of code with a megamorphic invocation of a separate
Am I making my question clear enough?
Also, additional questions:
4. I still needed to bump up inlining budgets considerably to get
anything to inline across the dynamic call. Will that always be the
case, or is there still a plan to get dynamic call plumbing excluded
from that budget?
5. What can I do to investigate why current MLVM is, in all cases,
slower than what we had last fall?
I'm very interested in getting this stuff going again.
More information about the mlvm-dev