CHA for interfaces in C2 compiler
Vitaly Davidovich
vitalyd at gmail.com
Wed Apr 15 18:39:00 UTC 2015
By the way, just to be clear - my main gripe with the type check is that it
loads memory (class pointer in the header) which can take an unnecessary
cache miss if no instance data is used or instance data to be used is at
least cacheline size bytes away from the header; the cmp+jmp is not ideal
but secondary.
sent from my phone
On Apr 15, 2015 1:40 PM, "Vitaly Davidovich" <vitalyd at gmail.com> wrote:
> 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/53e98c45/attachment.html>
More information about the hotspot-compiler-dev
mailing list