JDK-8275868 : ciReplay: Inlining fails with "unloaded signature classes" due to wrong protection domains
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 11,17,18
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2021-10-25
  • Updated: 2024-03-29
  • Resolved: 2021-11-01
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 18
17.0.12Fixed 18 b22Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Description
Given the simple example in Test.java and run with (referred to as normal run):

$  java -XX:CompileCommand=quiet -Xbatch -XX:+PrintCompilation -XX:-TieredCompilation -XX:CompileOnly=Test -XX:+PrintInlining Test

When normally running Test.java, C2 successfully inlines bar():

   2729   25    b        Test::test (5 bytes)
                            @ 0   Test::bar (2 bytes)   inline (hot)

However, when replay compiling test(), it fails to inline bar():

   2734   24    b  4       Test::test (5 bytes)
                              @ 0   Test::bar (2 bytes)   unloaded signature classes

The reason is that replay compilation fails to resolve Integer (which is initially resolved with no protection domain because it belongs to the Java API) with the protection domain of class Test. In the initialization of ciReplay, we only resolve InstanceKlasses without a protection domain:

CompileReplay(const char* filename, TRAPS) {
  ...
  _protection_domain = Handle();
  ...
}

When doing replay compilation of test(), we try to inline bar() and check if all classes in the signature are loaded. This is done by calling ciMethod::has_unloaded_classes_in_signature() by using the protection domain of class Test. But since we have not resolved class Integer with the protection domain of Test, we fail this check and do not perform inlining.

There are different variations of the same problem depending on which Java API class is used in the signature of the inlinee and which methods were already compiled by C2 in the normal run:

1) bar() was already compiled before test():
In this case, C2 has already called Method::load_signature_classes() for bar() and successfully resolved Integer with the protection domain of Test (protection domain Test newly added for String).

2) bar() was not compiled and is public:
Before invoking main(), it is validated by java.base/LauncherHelper::validateMainClass(). It tries to find main() by calling getMethod() which eventually calls the native method getDeclaredMethods0() into the VM to get the list of all public methods inside Test. In this process, all the classes in the method signatures are resolved.

3) bar() was not compiled, is private and we use String instead of Integer:
Same as 2) but this time, bar() is private and therefore ignored by getDeclaredMethods0(). Thus, bar() will not initiate the resolution of String. Instead, the method main() itself does that because it has String[] as parameter.

To fix this, we need to make sure to resolve all classes used in signatures of inlinees with the protection domain of the holder class of the method to be replay compiled in order to inline them.


Comments
Fix request [17u] I backport this to fix this issue in ciReplay. Well reproducible. Follow up JDK;8276227 also backported. Low risk. Change mostly to debugging functionality, changes in ciEnv add printout and new accessors which should not break normal execution. Small adaptions and takover of testing and debugging functionality from changes I don't want to backport. Test passes and fails without the fix. SAP nightly testing passed.
29-03-2024

A pull request was submitted for review. URL: https://git.openjdk.org/jdk17u-dev/pull/2334 Date: 2024-03-27 09:01:21 +0000
27-03-2024

Changeset: 5bb1992b Author: Christian Hagedorn <chagedorn@openjdk.org> Date: 2021-11-01 08:22:59 +0000 URL: https://git.openjdk.java.net/jdk/commit/5bb1992b8408a0d196b1afa308bc00d007458dbd
01-11-2021

ILW = Compiler replay could fail to reproduce an error due to incorrect inlining decisions, low, no workaround = MLH = P4
25-10-2021