[jvm-l] Re: Small static method marked not entrant, inlining reversed?

Charles Oliver Nutter headius at headius.com
Wed Sep 8 05:43:44 PDT 2010


On Wed, Sep 8, 2010 at 2:29 AM, John Rose <john.r.rose at oracle.com> wrote:
> That's exactly right.  Sounds like CHA (class hierarchy analysis) under interfaces would bail you out, at least until you created too many (>1 or >2) disjoint IRubyObject implementations.

Yes, it sounds like exactly what I want. I'm guessing this is a "nice
to have but not currently being worked" sort of problem, but it seems
like a very generally-applicable improvement to Hotspot, since it's
probably common (this would be easy to measure) to have an
invokeinterface that receives multiple types but those types'
implementations of that interface mostly boil down to the same
superclass. As far as I understand it, it would help any case where
you've extended an existing type but pass it around via some
superclass's interface.

A simple analysis could be done quickly too: resolve the type profile
to the actual implementer of the interface, rather than to the exact
type. Since invokeinterface knows what interface it's looking for, it
could do a quick hierarchy scan to find the class that first claims to
implement it. Generally when extending a class that already implements
an interface, you don't re-add "implements", so this would work in a
high percentage of cases. Does the type profile at present support
resolving to a superclass, or does it only support resolving to an
object's exact class?

> A related problem may be either (a) the type profile doesn't collect general-enough information or (b) we don't have enough type profile points to collect specific-enough information.  We can fix (a) by collecting ever fancier profile information or (b) by splitting profile points during inlining in early tiers.

(a) could be the "find real implementer" above as a short-term
improvement, and later "find common superclass that implements the
target signature". I assume the latter already works because the
following also avoids the deopt I saw:

    public static boolean isGenerationEqual(IRubyObject object, int
generation) {
        return ((RubyObject)object).getMetaClass().getCacheToken() ==
generation;
    }

Presumably the type profile here is able to handle arbitrarily many
subclasses of RubyObject. The above code really ought to optimize (at
least in my case) the same as:

    public static boolean isGenerationEqual(IRubyObject object, int
generation) {
        return object.getMetaClass().getCacheToken() == generation;
    }

I would love to see that happen (and I'm willing to help, after the
necessary C2 learning period!), but for now I'll have to make some
hard decisions in the JRuby codebase and compiler :(

> (Or (c) use an explicitly controlled templating mechanism like anonymous classes.  That may prematurely multiply bytecodes, though.)

By this you mean using a class template to specialize a piece of code
to a common superclass *before* passing it to the optimizer?

For what it's worth, the following code is only slightly slower than
the fastest non-hacked implementation and not subject to the
deoptimization:

    public static boolean isGenerationEqual(IRubyObject object, int
generation) {
        RubyClass metaClass;
        if (object instanceof RubyBasicObject) {
            metaClass = ((RubyBasicObject)object).getMetaClass();
        } else {
            metaClass = object.getMetaClass();
        }
        return metaClass.getCacheToken() == generation;
    }

But I may end up having the JRuby compiler do this since in order to
do a direct (non-dynamic) call it has to cast to a concrete type
anyway.

- Charlie


More information about the hotspot-compiler-dev mailing list