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
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