JDK-8293798 : Fix test bugs due to incompatibility with -XX:+AlwaysIncrementalInline
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 17,20
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2022-09-14
  • Updated: 2025-01-30
  • Resolved: 2022-09-21
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 17 JDK 20
17.0.12-oracleFixed 20 b16Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Description
A number of tests seem to fail in combination with compile flag "-XX:+AlwaysIncrementalInline".

compiler/uncommontrap/Decompile.java
   java.lang.RuntimeException: Wrong compilation status.: expected false to equal true
   Quick Analysis: it seems that we don't to bimorphic inlining of function calls (2 static inlinings, uncommon_trap for others). Instead, we create two LateInlineCallGenerator, one for a class (hit), and one for the other cases (miss). LateInlineCallGenerator has is_inline false, so we do not go into the bimorphic inlining case (would require both receivers to have is_inline true). Instead, we generate a static call for one class (hit), and a virtual call for the rest (miss). Therefore, when the third class comes along the function does not trap, and not deopt either.
    For now, we will just deactivate the flag in the test. But more discussion is required if we want this flag to change the inline behavior in this way.

compiler/intrinsics/klass/CastNullCheckDroppingsTest.java
    java.lang.AssertionError: compilation must  not  get deoptimized
    Seems usually we don't put the null_check with a trap, but with this flag we do have a null_check trap, which then triggers (with mark_non_entrant -> deopt). And the test expects that there is no deoptimization.
    Closer Analysis:
    We are in GraphKit::gen_checkcast.
    We have a cast that is wrapped in a MethodHandle. Normally, this would get directly inlined, and the output is deduced to be String*. With the flag, however, we do not inline, but create a JavaStaticCall, which represents invokeExact. This has 4 Object* inputs and 1 Object* output. So now the result of the cast is a Object*.
    Now we have a String* in the normal case, and Object* in the flag case. We now do a local cast to String*. For that we first check subtyping.
    switch (C->static_subtype_check(tk, objtp->as_klass_type())) {
    In the normal case, we have a perfect match - so we rely on profiling and do speculative String::NonNull*. But in the flag case, we see Object* is not subtype of String*, and continue. So we continue on, and find that profiling has determined never_see_null = true, so we set an uncommon_trap for the null_check.
    Somehow, the speculative profiling case does not lead to a trap - not sure why yet.
    Of course in the test we eventually do feed in Null - in the regular case there is no trap, in the flag case we trap and deopt, breaking the test assumption.
    At any rate, this really looks like a test bug - the flag can change the decisions that have an impact on the asserts of the test. I will disable the flag.

compiler/ciReplay/TestInliningProtectionDomain.java
    java.lang.RuntimeException: assertTrue: expected true, was false
    this is from an assertTrue.
    Asserts.assertTrue(inlineesReplay.get(4).compare("compiler.ciReplay.InliningBar", "bar2", inlineesReplay.get(4).isForcedByReplay()));
    Turns out isForcedByReplay() returns false because the "reason" is expected to be "force inline by ciReplay", but we get a reason "force (incremental) inline by ciReplay". seems expected. Test Bug. Replace assert with:
    Asserts.assertTrue(inlineesReplay.get(4).compare("compiler.ciReplay.InliningBar", "bar2", inlineesReplay.get(4).isForcedByReplay() || inlineesReplay.get(4).isForcedIncrementalInlineByReplay()));


First found in JDK-8291775
Now rediscovered during JDK-8256540
Comments
A pull request was submitted for review. URL: https://git.openjdk.org/jdk17u-dev/pull/2508 Date: 2024-05-29 14:37:04 +0000
29-05-2024

A pull request was submitted for review. URL: https://git.openjdk.org/jdk17u-dev/pull/2376 Date: 2024-04-06 19:54:46 +0000
06-04-2024

Changeset: 12e3510f Author: Emanuel Peter <epeter@openjdk.org> Date: 2022-09-21 07:21:27 +0000 URL: https://git.openjdk.org/jdk/commit/12e3510f63b46db1559d240a331d66f15fe91363
21-09-2022

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/10310 Date: 2022-09-16 13:50:02 +0000
19-09-2022

compiler/cha/DefaultRootMethod.java compiler/cha/AbstractRootMethod.java May also have test bugs with AlwaysIncrementalInline. They both test the compilation of a megamorphic call site, and expect it to be decompiled once an additional class is introduced. From what I have seen, I would expect that late inlining does not allow for megamorphic (inlining?).
16-09-2022

ILW = test failure; with -XX:+AlwaysIncrementalInline; no workaround = MMH = P3
14-09-2022