CHA for interfaces in C2 compiler

Vitaly Davidovich vitalyd at gmail.com
Wed Apr 15 17:40:18 UTC 2015


So I'm not worried about null checks because they're actually handled
really well.  They're also typically a quick test against a register if not
using implicit checking via trap.

As for propagating type information, I'm assuming this information is
propagated into the inlined code only -- if anything fails to inline, it
will not receive this information and will perform the same type check, is
that right? It's hard to argue against "this is a microbenchmark, larger
code won't notice the difference", but when you have code that's
"scattered" around (i.e. not all inlined in the same place) then it sounds
like this check will still be performed at each of those places.  In a
complex call graph, it's not realistic to expect the entire thing to inline
(for good reason) -- there are going to be islands.  My thinking here is
that given this analysis exists for classes (and works really well),
extending it to interfaces (using a heuristic like Remi's, a flag, etc)
would be profitable in some places.


On Wed, Apr 15, 2015 at 1:02 PM, Vladimir Ivanov <
vladimir.x.ivanov at oracle.com> wrote:

> Nothing changed in 8 & 9 in this respect.
>
> You are looking on a microbenchmark, where you have a trivial method with
> contains just a single call. My point is that it's a corner case and you
> shouldn't notice the difference in a larger application.
>
> Null checks are pervasive on Java level, but for JIT compiler it is enough
> to perform it only once on a value to known the value is non-null
> afterwards.
>
> The same applies to exact type checks: dominating exact type check
> eliminates the need to repeat the type check. It is recorded in C2 type
> system and propagated to all usages.
>
> Every place where type profiling for that interface happens a single exact
> type will be recorded.
>
> Please, note that CHA is more generic and covers the cases when numerous
> classes have a single method implementation. Type profiling is usually
> useless in such case.
>
> But in your example there's a single implementing class, so type profile
> works fine.
>
> Best regards,
> Vladimir Ivanov
>
>
> On 4/15/15 7:37 PM, Vitaly Davidovich wrote:
>
>> Hi Vladimir,
>>
>> Here's what I see on 7u60:
>>
>> private static int doIt(final Foo f) {
>> return f.num();
>>      }
>>
>>      interface Foo
>>      {
>> int num();
>>      }
>>
>>      final class FooImpl implements Foo
>>      {
>> @Override
>> public int num() {
>>     return 1;
>> }
>>      }
>>
>> Running a simple test where only FooImpl is loaded (in fact, it's the
>> only impl period) produces the following asm (stripped down to
>> essentials):
>>
>>    0x00007f0b31e14a6c: mov    0x8(%rsi),%r10d    ; implicit exception:
>> dispatches to 0x00007f0b31e14a9d
>>    0x00007f0b31e14a70: cmp    $0x71c9e068,%r10d  ;   {oop('FooImpl')}
>>    0x00007f0b31e14a77: jne    0x00007f0b31e14a8a
>>    0x00007f0b31e14a79: mov    $0x1,%eax
>>    0x00007f0b31e14a7e: add    $0x10,%rsp
>>    0x00007f0b31e14a82: pop    %rbp
>>
>> If I change Foo to be an abstract class, we get this:
>>
>> 0x00007f0209deb18c: test   %rsi,%rsi
>>    0x00007f0209deb18f: je     0x00007f0209deb1a2
>>    0x00007f0209deb191: mov    $0x1,%eax
>>    0x00007f0209deb196: add    $0x10,%rsp
>>    0x00007f0209deb19a: pop    %rbp
>>
>> So there's an explicit null check but no type check.
>>
>> Did something change in java 8 or 9 that leads you to say "completely
>> eliminated"?
>>
>> Thanks
>>
>> On Wed, Apr 15, 2015 at 12:26 PM, Vladimir Ivanov
>> <vladimir.x.ivanov at oracle.com <mailto:vladimir.x.ivanov at oracle.com>>
>> wrote:
>>
>>     Vitaly,
>>
>>     Type profiling reliably detects single interface implementation
>>     cases and type check overhead is completely eliminated in most of
>>     the cases (type checks are aggressively commoned).
>>
>>     Do you still think it is worth an effort?
>>
>>     Best regards,
>>     Vladimir Ivanov
>>
>>
>>     On 4/15/15 5:10 PM, Vitaly Davidovich wrote:
>>
>>         Hi guys,
>>
>>         So CHA on classes works nicely in the case of only one subtype
>>         loaded.
>>         What about interfaces? Currently, it looks like no such
>>         optimization/analysis is done.  In my experience, there's a
>>         substantial
>>         amount of code that exposes an interface via some API, but then
>>         loads
>>         only implementation of it.  The interface is used instead of
>>         abstract
>>         class to allow more flexibility in the future.
>>
>>         I fully realize that lots of interfaces have more than 1
>> implementer
>>         loaded at runtime, but I also think it's worthwhile to attempt
>>         CHA for them.
>>
>>         Is this something that's feasible to do? It would require more
>> class
>>         loading dependencies to be tracked, but I'm also fine with
>>         having this
>>         be an extra flag that I can use to enable/disable this
>> optimization.
>>
>>         Thoughts?
>>
>>         Thanks
>>
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20150415/9ec35b3e/attachment-0001.html>


More information about the hotspot-compiler-dev mailing list