I imagine it will have a similar effect to me hand-inlining that logic
at the call site (which I'm reluctant to do in general because of the
code bloat). I wanted this to be in a static method to avoid having
the getMetaClass call bulk up the original bytecode.

I'll try another analysis with the getMetaClass pulled out of the method.

On Tue, Sep 7, 2010 at 4:57 PM, Matt Fowles <[email protected]> wrote:
> Charlie~
>
> Dropping hotspot compiler dev as I am suggesting a workaround...
>
> Can you change isGenerationEqual() to
>
> public static boolean isGenerationEqual(MetaClass klass, int
> generation) {
>       return klass.getCacheToken() == generation;
>   }
>
> then call getMetaClass() up one level of call stack?
>
> Matt
>
> On Tue, Sep 7, 2010 at 5:44 PM, Charles Oliver Nutter
> <[email protected]> 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.
>>
>>
>
> --
> 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.
>
>

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

Reply via email to