On Feb 18, 2011, at 12:52 PM, Charles Oliver Nutter wrote: > On Fri, Feb 18, 2011 at 5:24 AM, Rémi Forax <[email protected]> wrote: >> Good news ! >> Charles does it mean that JRuby's invokedynamic now works without >> using the previously existing logic. >> I mean, you use only method handles from the callsite to the target method. > > More and more, but definitely not completely. I'd estimate that *most* > calls are dispatched with indy, and of those about *half* are direct > with recent commits. > > Methods that can bind all the way from caller to target must fit these > criteria: > > * Fixed arity > * No block passed (block passing tends to require extra structures my > direct indy logic doesn't set up yet) > * One of a handful of standard signatures (just having wired all up yet) > > And note that this only applies to plain calls like foo.bar; calls > that perform dynamic dispatch but combined with other logic, like a.b > += c, do not yet use indy at all. > > I did just land another revision that allows Ruby to Ruby calls > meeting the above criteria to bind all the way through, and > performance dropped precipitously: > > Stock JRuby: > > ~/projects/jruby ➔ > JAVA_HOME=../mlvm/sources/build/bsd-i586/j2sdk-image/ jruby -X+C > -J-XX:MaxInlineSize=150 -J-XX:InlineSmallCode=5000 > bench/bench_fib_recursive.rb 10832040 > 0.354000 0.000000 0.354000 ( 0.284000) > 832040 > 0.174000 0.000000 0.174000 ( 0.174000) > 832040 > 0.173000 0.000000 0.173000 ( 0.173000) > 832040 > 0.169000 0.000000 0.169000 ( 0.169000) > 832040 > 0.173000 0.000000 0.173000 ( 0.173000) > > JRuby + indy, no ruby-to-ruby calls binding directly: > > ~/projects/jruby ➔ > JAVA_HOME=../mlvm/sources/build/bsd-i586/j2sdk-image/ jruby -X+C > -Xcompile.invokedynamic=true -J-XX:+UnlockExperimentalVMOptions > -J-XX:+EnableInvokeDynamic -J-XX:MaxInlineSize=150 > -J-XX:InlineSmallCode=5000 bench/bench_fib_recursive.rb 10 > 832040 > 0.340000 0.000000 0.340000 ( 0.274000) > 832040 > 0.150000 0.000000 0.150000 ( 0.150000) > 832040 > 0.148000 0.000000 0.148000 ( 0.148000) > 832040 > 0.147000 0.000000 0.147000 ( 0.147000) > 832040 > 0.147000 0.000000 0.147000 ( 0.147000) > > JRuby + indy, ruby calls binding directly: > > ~/projects/jruby ➔ > JAVA_HOME=../mlvm/sources/build/bsd-i586/j2sdk-image/ jruby -X+C > -Xcompile.invokedynamic=true -J-XX:+UnlockExperimentalVMOptions > -J-XX:+EnableInvokeDynamic -J-XX:MaxInlineSize=150 > -J-XX:InlineSmallCode=5000 bench/bench_fib_recursive.rb 10 > 832040 > 0.883000 0.000000 0.883000 ( 0.818000) > 832040 > 0.463000 0.000000 0.463000 ( 0.463000) > 832040 > 0.463000 0.000000 0.463000 ( 0.463000) > 832040 > 0.472000 0.000000 0.472000 ( 0.473000) > 832040 > 0.459000 0.000000 0.459000 ( 0.459000) > > I have not investigated asm output, but it seems pretty clear that > something very bad happens when I bind directly rather than binding > via JRuby DynamicMethod stubs. Indeed, in the Java trace, I do see GWT > should up: > > at > sun.dyn.MethodHandleImpl$GuardWithTest.invoke_L4(MethodHandleImpl.java:982) > at ruby.__dash_e__.method__0$RUBY$foo(-e:1) > at > sun.dyn.MethodHandleImpl$GuardWithTest.invoke_L4(MethodHandleImpl.java:982) > at ruby.__dash_e__.method__0$RUBY$foo(-e:1) > at > sun.dyn.MethodHandleImpl$GuardWithTest.invoke_L4(MethodHandleImpl.java:982) > at ruby.__dash_e__.method__0$RUBY$foo(-e:1) > at > sun.dyn.MethodHandleImpl$GuardWithTest.invoke_L4(MethodHandleImpl.java:982) > > But the non-direct logic includes *even more* sun.dyn and JRuby calls > in it. How can it be so much faster? A recursive "foo" call looks like > this: > > at ruby.__dash_e__.method__0$RUBY$foo(-e:1) > at > ruby___dash_e__Invokermethod__0$RUBY$fooFixed0.call(ruby___dash_e__Invokermethod__0$RUBY$fooFixed0#foo:65535) > at > ruby___dash_e__Invokermethod__0$RUBY$fooFixed0.call(ruby___dash_e__Invokermethod__0$RUBY$fooFixed0#foo:65535) > at sun.dyn.FilterGeneric$F6.invoke_F6(FilterGeneric.java:754) > at sun.dyn.FilterGeneric$F5.invoke_F5(FilterGeneric.java:678) > at > sun.dyn.MethodHandleImpl$GuardWithTest.invoke_L4(MethodHandleImpl.java:982) > at ruby.__dash_e__.method__0$RUBY$foo(-e:1) > > With JRuby's call-site caching logic: > > at ruby.__dash_e__.method__0$RUBY$foo(-e:1) > at > ruby___dash_e__Invokermethod__0$RUBY$fooFixed0.call(ruby___dash_e__Invokermethod__0$RUBY$fooFixed0#foo:65535) > at > ruby___dash_e__Invokermethod__0$RUBY$fooFixed0.call(ruby___dash_e__Invokermethod__0$RUBY$fooFixed0#foo:65535) > at > org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:103) > at ruby.__dash_e__.method__0$RUBY$foo(-e:1) > > And with JRuby's "dynopt" mode, which emits guard, target, and > fallback logic directly into the compiled body: > > at rubyjit.foo_7F1E71544C0BFF52B6020F56F3C0D1A11E173AF5.__file__(-e:1) > at rubyjit.foo_7F1E71544C0BFF52B6020F56F3C0D1A11E173AF5.__file__(-e:1) > at rubyjit.foo_7F1E71544C0BFF52B6020F56F3C0D1A11E173AF5.__file__(-e:1) > at rubyjit.foo_7F1E71544C0BFF52B6020F56F3C0D1A11E173AF5.__file__(-e:1) > > Needless to day, "dynopt" (which can only do this for recursive calls) > is still fastest on the recursive fib and tak benchmarks, but I'm a > little confused by the degradation from directly binding ruby-to-ruby > calls with indy. Any flags I can toss in to get you JVM guys more > info? > > And yes...this is all on JRuby master. Should be able to see the same > effect right now.
Is there a switch to turn direct ruby-to-ruby calls on and off? I'd like to compare inlining trees and maybe code output. -- Christian _______________________________________________ mlvm-dev mailing list [email protected] http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
