RFR (S): 8188133: C2: Static field accesses in clinit can trigger deoptimizations
vladimir.x.ivanov at oracle.com
Fri Feb 1 18:13:16 UTC 2019
> 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
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.
> On 1/31/19 11:29 AM, Vladimir Ivanov wrote:
>> 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