Good news, bad news

Charles Oliver Nutter headius at headius.com
Mon May 23 15:39:56 PDT 2011


> On Mon, May 23, 2011 at 5:20 PM, Tom Rodriguez <tom.rodriguez at oracle.com> wrote:
>> Actually my guess is that the selectAlternative machinery is what's screwing it up.  That code gets emitted as:

Same benchmark but instead of binding a direct handle via a GWT, I
force it to fail over to an inline cache immediately (still behind
invokedynamic):

~/projects/jruby ➔ jruby --server -X+C -Xinvokedynamic.maxfail=0
bench/language/bench_method_dispatch_only.rb
Test ruby method: 1000k loops calling self's foo 10 times
  0.515000   0.000000   0.515000 (  0.403000)
  0.174000   0.000000   0.174000 (  0.174000)
  0.136000   0.000000   0.136000 (  0.136000)
  0.138000   0.000000   0.138000 (  0.138000)
  0.164000   0.000000   0.164000 (  0.164000)
  0.156000   0.000000   0.156000 (  0.157000)
  0.150000   0.000000   0.150000 (  0.150000)
  0.145000   0.000000   0.145000 (  0.145000)
  0.130000   0.000000   0.130000 (  0.130000)
  0.124000   0.000000   0.124000 (  0.124000)

"maxfail" here indicates how many GWT it will attempt to chain for a
polymorphic call site before bailing out to a simple inline caching
target. That inline caching target is bound *directly* into the
invokedynamic call site, with no GWT in front of it. And as expected,
performance is basically the same as JRuby with inline caching only.
So it seems GWT may be the culprit.

Inlining graph for the above run, showing that the inline cache logic
("fail" methods in InvokeDynamicSupport in JRuby) all inline into the
invokedynamic call site:

1%   bench.language.bench_method_dispatch_only::method__1$RUBY$invoking
@ 18 (177 bytes)
    @ 23 java.lang.invoke.MethodHandle::invokeExact (0 bytes)
    @ 23 java.lang.invoke.MethodHandle::invokeExact (13 bytes)
      @ 6 org.jruby.runtime.invokedynamic.InvokeDynamicSupport::fail (97 bytes)
        @ 2 org.jruby.runtime.invokedynamic.InvokeDynamicSupport::pollAndGetClass
(13 bytes)
          @ 1 org.jruby.runtime.ThreadContext::callThreadPoll (23 bytes)
            @ 19 org.jruby.runtime.ThreadContext::pollThreadEvents
executed < MinInliningThreshold times
          @ 5 org.jruby.runtime.builtin.IRubyObject::getMetaClass (0 bytes)
           type profile org/jruby/runtime/builtin/IRubyObject ->
org/jruby/RubyObject (100%)
          @ 5 org.jruby.RubyBasicObject::getMetaClass (5 bytes)
        @ 17 org.jruby.runtime.callsite.CacheEntry::typeOk (6 bytes)
          @ 2 org.jruby.runtime.callsite.CacheEntry::typeOk (17 bytes)
            @ 5 org.jruby.RubyModule::getCacheToken (5 bytes)
        @ 34 org.jruby.internal.runtime.methods.DynamicMethod::call (13 bytes)
         type profile org/jruby/internal/runtime/methods/DynamicMethod
-> bench$language$bench_method_dispatch_only$method__0$RUBY$foo (100%)
        @ 34 bench$language$bench_method_dispatch_only$method__0$RUBY$foo::call
(13 bytes)
          @ 9 bench$language$bench_method_dispatch_only$method__0$RUBY$foo::call
(21 bytes)
            @ 17
bench.language.bench_method_dispatch_only::method__0$RUBY$foo (2
bytes)
        @ 42 org.jruby.RubyModule::searchWithCache call site not reached
        @ 50 org.jruby.runtime.invokedynamic.InvokeDynamicSupport$JRubyCallSite::callType
(5 bytes)
        @ 56 org.jruby.runtime.invokedynamic.InvokeDynamicSupport::methodMissing
executed < MinInliningThreshold times
        @ 65 org.jruby.runtime.invokedynamic.InvokeDynamicSupport$JRubyCallSite::callType
(5 bytes)
        @ 72 org.jruby.runtime.invokedynamic.InvokeDynamicSupport::callMethodMissing
never executed
        @ 93 org.jruby.internal.runtime.methods.DynamicMethod::call (13 bytes)

Note that "foo" is shown inlining here as well, but I think that's
only because this particular inline-caching call path has only seen
one target at this point.

- Charlie


More information about the mlvm-dev mailing list