[13] RFR (S): 8188133: C2: Static field accesses in clinit can trigger deoptimizations
Vladimir Ivanov
vladimir.x.ivanov at oracle.com
Mon Feb 4 18:42:40 UTC 2019
On 01/02/2019 10:32, Vladimir Kozlov wrote:
> I am more concern about C2 hidden assumptions about classes it compiles
> and static fields accesses order than about Java correctness of
> executing code in static initializers.
>
> On other hand we are at the beginning of JDK 13 and can do this
> experiment to see how it goes. Okay but please test it may be up-to
> tier7 before push.
>
> Changes itself seem fine.
Thanks, Vladimir. Tier1-7 testing finished successully. Will push the
patch today.
Best regards,
Vladimir Ivanov
> On 2/1/19 10:13 AM, Vladimir Ivanov wrote:
>>
>>> So this is the case for OSR compilation of <clinit> with hot loop
>>> (iterations > 10000). Should we care about such cases?
>>> We want people to write simple <clinit> so we can serialize results -
>>> this case is opposite direction.
>>
>> It's definitely a corner case and having long-running static
>> initializers is discouraged, but I don't agree that it should be
>> ignored by JITs.
>>
>> The faster <clinit> is finished the better for startup & warmup: as
>> you noted, <clinit> serializes execution and may end up blocking the
>> rest of the program. So, there are clear incentives to optimize
>> <clinit>, though it may not be the most important case to care about.
>>
>>> I understand that JITed code should perform better than Interpreter.
>>> And we should fix regression in jdk 9.
>>
>> Regression is handled separately (JDK-8192070) and it is not specific
>> to static initializers. With this enhancement, I'm interested solely
>> in how JITs handle <clinit>.
>>
>>> There are several conditions for inlining. What if a called method is
>>> not inlined even with your relaxed condition? We will still
>>> deoptimize it on each iteration. Right?
>>
>> Yes, proposed patch doesn't solve the general case. It just extends
>> existing heuristics. If iniling fails, callee has to deoptimize.
>>
>>> I am fine to allow access to static fields from <clinit> code but I
>>> am not sure about allowing to inline general methods when class is
>>> not fully initialized. Can we limit what methods should be inlined?
>>> Leaf methods? Small code? No loops?
>>
>> We definitely can, but I don't see compelling reasons to do so. It's
>> perfectly fine to run any code in the context of static initializer.
>> The only limitation is - only the thread which runs clinit is allowed
>> to do so. I believe having clinit as the root of compilation is a
>> strong guarantee of that invariant.
>>
>>> I would prefer to not compile such <clinit> at all (if it has hot
>>> calls).
>>
>> It would have negative consequences on startup and warmup.
>> In this particular case, the problem is not in clinit itself, but the
>> code it calls. Methods accessing static members have the very same
>> problem when compiled into a separate nmethod.
>>
>> Best regards,
>> Vladimir Ivanov
>>
>>> On 1/31/19 11:29 AM, Vladimir Ivanov wrote:
>>>> http://cr.openjdk.java.net/~vlivanov/8188133/webrev.00
>>>> https://bugs.openjdk.java.net/browse/JDK-8188133
>>>>
>>>> The test case in the bug demonstrates a pathological case with
>>>> long-running static initializer: though it's allowed to access
>>>> static fields from the thread performing the initialization, C2
>>>> can't prove that in general.
>>>>
>>>> While solving the general problem doesn't seem worth the effort
>>>> (requires barriers on method entries), I propose to extend the logic
>>>> to cover simple cases: when static initializer is the root of the
>>>> compilation, all accesses to static fields of the corresponding
>>>> class are allowed. It extends the coverage to all inlinees from OSR
>>>> compilation of clinit.
>>>>
>>>> Testing: hs-precheckin-comp, tier1-5
>>>>
>>>> Best regards,
>>>> Vladimir Ivanov
More information about the hotspot-compiler-dev
mailing list