JDK-8317269 : Store old classes in linked state in AOT cache
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2023-09-28
  • Updated: 2025-08-13
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 26
26Unresolved
Related Reports
Blocks :  
Relates :  
Relates :  
Relates :  
Description
BACKGROUND:

Before this RFE, the AOT cache stores "old" classes (InstanceKlass::major_version() < 50) the "unlinked" state, to be verified by the inference verifier at runtime. At runtime, it's possible for such classes to fail verification if some of their verification constraints cannot be satisfied.

E.g., assuming we have created a CDS archive A.jsa that contains the classes OldX, Super, and Sub:

    class OldX { // class file version = 49
        Super get() {
            return new Sub();
       }
    }

During the verification of OldX, the verifier would load Super and Sub to check, and require that Sub is indeed a subtype of Super. Such a requirement is called a "verification constraint" of OldX.

When the application runs with the archive A.jsa, before it uses OldX, it can dynamically load an alternative version of Sub that's not a subtype of Super. As a result, when the application tries to use OldX later, it will get a VerifyError because the verification constraints of X have been violated.

IMPACT TO LEYDEN:

In Leyden, we plan to archive heap objects that are instances of application classes. Many of today's applications still use "old" classes (usually due to usage of older class libraries). If we happen to archive an object instance of X, but X becomes unverifiable due to verification constraint violations, the archived heap objects may become unusable.

PROPOSAL:

If the class OldX is loaded by the boot, platform, or app class loader, *and* AOT class linking is enabled for the AOT cache:
 
- In the AOT cache assembly phase, we record all the classes that are resolved by the old verifier during the verification of OldX. This can be done by intercepting JVM_FindClassFromClass(). Such classes are called the "verification dependencies" of OldX.

- Before writing OldX into the AOT cache, we check if any of its verification dependency classes are excluded. If so, OldX is also excluded from the AOT cache. Otherwise, OldX is stored in the AOT cache in the "linked" state.

- During the production run, due to the AOT class linking optimization, OldX and all of its verification dependency classes are unconditionally loaded during VM bootstrap. It's impossible for the application to replace any of the verification dependency classes. This means that the verification result of OldX computed in the assembly phase will remain valid in the production run.


Comments
A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/26754 Date: 2025-08-12 23:55:19 +0000
13-08-2025

Initial support has been implemented in the premain repo: (test) https://github.com/openjdk/leyden/commit/173181cce34cc486c8d2517cf4205947fef4b3b6 https://github.com/openjdk/leyden/commit/5fdfef1df3bbcded1001fd1f0be8cce46d3bb35e (code) https://github.com/openjdk/leyden/commit/cae8bbcd7aecf97b3a67cabba16df3e0f03f5167 // Preserve all states that were examined used during dumptime verification, such // that the verification result (pass or fail) cannot be changed at runtime. // // For example, if the verification of ik requires that class A must be a subtype of B, // then this relationship between A and B cannot be changed at runtime. I.e., the app // cannot load alternative versions of A and B such that A is not a subtype of B. bool CDSConfig::preserve_all_dumptime_verification_states(const InstanceKlass* ik) { return PreloadSharedClasses && SystemDictionaryShared::is_builtin(ik); } More clean up may be needed
09-07-2024