I'll give that a shot, Tom, thanks. Should have thought of it myself. On Wed, Sep 8, 2010 at 12:04 AM, Tom Rodriguez <[email protected]> wrote: > Did you run with -XX:+PrintInlining? That will report why we didn't inline. > > tom > > On Sep 7, 2010, at 2:44 PM, Charles Oliver Nutter wrote: > >> I've been working on JRuby performance lately and ran into a peculiar >> situation. >> >> I have a static utility method in JRuby that checks whether a given >> object's class is the same as the when the compiler optimized it. So >> for a snippit of code like this: >> >> def foo >> bar >> end >> >> def bar >> # whatever >> end >> >> After running for some time, the "foo" call will be compiled, the >> compiler will see that the "bar" call has a cached method handle, and >> it will emit both a dynamic call and a static-typed call plus guard. >> The static-typed call looks like this: >> >> ALOAD 8 >> LDC 446 >> INVOKESTATIC >> org/jruby/javasupport/util/RuntimeHelpers.isGenerationEqual >> (Lorg/jruby/runtime/builtin/IRubyObject;I)Z >> IFNE L2 >> ALOAD 8 >> CHECKCAST org/jruby/RubyFixnum >> ALOAD 1 >> LDC 1 >> INVOKEVIRTUAL org/jruby/RubyFixnum.op_plus >> (Lorg/jruby/runtime/ThreadContext;J)Lorg/jruby/runtime/builtin/IRubyObject; >> >> And the isGenerationEqual method looks like this: >> >> public static boolean isGenerationEqual(IRubyObject object, int >> generation) { >> return object.getMetaClass().getCacheToken() == generation; >> } >> >> While running benchmarks, I noticed a peculiar thing happening. For >> "fib", the method JITs in JRuby very quickly and is soon after JITed >> by Hotspot. But later compiles cause "fib" to get deoptimized and >> marked not-entrant. Around the same time, isGenerationEqual gets >> marked not entrant. Unfortunately, when fib re-optimizes, it does so >> without inlining the isGenerationEqual call, and I can see that where >> it was inlined before, it now actually does a CALL in assembly. >> >> Manually inlining the same bytecode everywhere isGenerationEqual would >> be called does not seem to be subject to the same effect. >> >> Any thoughts? The only theory I have is that early in optimization >> Hotspot sees that the target object type (IRubyObject object in the >> method def) is the same, and so it optimizes based on that. Later, as >> other compiled methods start to hit this code, the tyoe of "object" >> changes. But the logic behind the scenes should be identical in every >> case... IRubyObject.getMetaClass() only has one final implementation >> on org.jruby.RubyBasicObject, and getCacheToken() has only one final >> implementation on org.jruby.RubyModule, which simply returns an int >> field. >> >> So I'm stumped why at least isGenerationEqual would not inline in all cases. >> >> - Charlie > >
-- You received this message because you are subscribed to the Google Groups "JVM Languages" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/jvm-languages?hl=en.
