Longjumps considered inexpensive...until they aren't
Charles Oliver Nutter
charles.nutter at sun.com
Tue Jun 3 16:56:06 PDT 2008
John Rose wrote:
> I see two paths here:
>
> 1. Force the JIT to inline the code patterns you care about. (One
> logical Ruby method should be compiled in one JIT compilation task.)
>
> 2. Make the JVM process the exceptions you care about more
> efficiently, in the out-of-line case.
>
> Both should be investigated. Both are probably good graduate
> theses... Anyone?
>
> The easiest one to try first is #1, since we already have a compiler
> oracle, and could quickly wire up the right guidance statements (in a
> JVM tweak), if we could figure out what Ruby wants to say to the JVM
> about inlining.
Ok, I've done some investigation with a LogCompilation tool and noticed
a few things.
- We have a few key methods in the call path that are "too big" in the
log output...important stuff like InlineCachingCallSite.call. Those will
be obvious areas we can look to fix. For now I've continued some
investigation setting MaxInlineSize up a bit.
- The max inline level seems to be a larger problem. It appears in my
OpenJDK source that the default max level is 9. If you look at the
traces I provided in earlier emails we're looking at a bare minimum of
8-9 calls in the simpliest case of a non-local return, and there's very
little I can do to reduce that on pre-invokedynamic JVMs:
at ruby.__dash_e__.block_0$RUBY$__block__(-e:1)
at ruby.__dash_e__BlockCallback$block_0$RUBY$__block__xx1.call(Unknown
Source)
at org.jruby.runtime.CompiledBlockLight.yield(CompiledBlockLight.java:107)
at org.jruby.runtime.CompiledBlockLight.yield(CompiledBlockLight.java:88)
at org.jruby.runtime.Block.yield(Block.java:109)
at org.jruby.RubyInteger.times(RubyInteger.java:163)
at org.jruby.RubyIntegerInvoker$times_method_0_0.call(Unknown Source)
at org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:312)
at ruby.__dash_e__.method__0$RUBY$foo(-e:1)
So in this simple case, there's a pretty slim chance the throw and the
catch would ever get inlined into the same body of code. And from what
I'm seeing, there's almost no chance since the "sliding window" of where
it bases the inlining appears unlikely to land exactly on the "foo"
method where the non-local return should end up.
Based on these two findings, I tried bumping up the inline level but
have not been able to re-profile yet. I'd like to know if I'm on the
right track. Obviously we want to do whatever we can to reduce the
length of the call path, but it seems like even the best case for us now
is going to be a few levels deeper than the standard inlining process
can handle.
Are there other settings I might want to look at for tweaking this? I
have a build of OpenJDK7 I can fiddle with.
More information about the mlvm-dev
mailing list