JDK-8288334 : Support old classes in dynamic CDS
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 20
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2022-06-13
  • Updated: 2024-06-20
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.
Other
tbdUnresolved
Related Reports
Relates :  
Relates :  
Relates :  
Description
Symptom:

When old classes (i.e., class version is lower than 50) are loaded during dynamic CDS dump, they are usually linked during app execution. As part of linking, the class is verified by the old verifier, which is not supported by CDS. As a result, these old classes are not stored in the CDS image. A typical message is like this:

$ java -cp Test.jar -XX:ArchiveClassesAtExit=test.jsa TestApp
...
[warning][cds] Skipping MyOldClass: Old class has been linked. 
...

Proposed fix:
Revert the linked old classes to unlinked state, so that they can be verified again during runtime.

This can be done by parsing the class again and storing the newly parsed (but not linked) InstanceKlass into the CDS archive. Something similar to

https://github.com/openjdk/jdk/blob/8e4ef818a90de35ae75e7f82a780653d623bb29c/src/hotspot/share/cds/lambdaFormInvokers.cpp#L186





Comments
The following test cases (under test/hotspot/jtreg/runtime/cds/appcds/) contain "[warning][cds] Skipping ClassName: Old class has been linked" dynamicArchive/LambdaContainsOldInf.java dynamicArchive/methodHandles/MethodHandlesAsCollectorTest.java dynamicArchive/methodHandles/MethodHandlesCastFailureTest.java dynamicArchive/methodHandles/MethodHandlesGeneralTest.java dynamicArchive/methodHandles/MethodHandlesInvokersTest.java dynamicArchive/methodHandles/MethodHandlesPermuteArgumentsTest.java dynamicArchive/methodHandles/MethodHandlesSpreadArgumentsTest.java dynamicArchive/NestHostOldInf.java dynamicArchive/RedefineCallerClassTest.java jvmti/dumpingWithAgent/OldClassWithJavaAgent.java LambdaContainsOldInf.java
26-07-2023

JDK-8309074 may be a more preferable solution than this RFE.
30-05-2023

JDK-8308463 will make it easier to manage the regenerated (re-parsed) version of the old class.
25-05-2023

Reproducer: https://github.com/iklam/tools/tree/main/bench/picocli-hello # Using CDS (static) $ java -XX:DumpLoadedClassList=classlist -Xshare:off -cp ./target/picocli-hello-1.0-SNAPSHOT-jar-with-dependencies.jar app.App 1 $ java -XX:SharedArchiveFile=app_s.jsa -XX:SharedClassListFile=classlist -Xshare:dump -cp ./target/picocli-hello-1.0-SNAPSHOT-jar-with-dependencies.jar $ perf stat -r 10 java -XX:SharedArchiveFile=app_s.jsa -cp ./target/picocli-hello-1.0-SNAPSHOT-jar-with-dependencies.jar app.App 1 > /dev/null Performance counter stats for 'jdk/bin/java -XX:SharedArchiveFile=app_s.jsa -cp ./target/picocli-hello-1.0-SNAPSHOT-jar-with-dependencies.jar app.App 1' (10 runs): 103.57 msec task-clock # 1.667 CPUs utilized ( +- 0.17% ) 901 context-switches # 8.709 K/sec ( +- 4.14% ) 12 cpu-migrations # 115.991 /sec ( +- 4.68% ) 4,968 page-faults # 48.020 K/sec ( +- 0.24% ) 471,907,508 cycles # 4.561 GHz ( +- 0.18% ) 521,107,586 instructions # 1.10 insn per cycle ( +- 0.11% ) 102,776,826 branches # 993.429 M/sec ( +- 0.12% ) 4,392,800 branch-misses # 4.29% of all branches ( +- 0.21% ) 0.06212 +- 0.00141 seconds time elapsed ( +- 2.28% ) # Using CDS (dynamic) $ java -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=app.jsa -cp ./target/picocli-hello-1.0-SNAPSHOT-jar-with-dependencies.jar app.App 1 $ perf stat -r 10 java -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=app.jsa -cp ./target/picocli-hello-1.0-SNAPSHOT-jar-with-dependencies.jar app.App 1 > /dev/null Performance counter stats for 'java -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=app.jsa -cp ./target/picocli-hello-1.0-SNAPSHOT-jar-with-dependencies.jar app.App 1' (10 runs): 145.93 msec task-clock # 1.759 CPUs utilized ( +- 0.77% ) 690 context-switches # 4.685 K/sec ( +- 5.37% ) 8 cpu-migrations # 54.318 /sec ( +- 5.73% ) 5,963 page-faults # 40.487 K/sec ( +- 0.14% ) 666,824,665 cycles # 4.528 GHz ( +- 0.77% ) 720,088,737 instructions # 1.07 insn per cycle ( +- 0.08% ) 142,292,418 branches # 966.129 M/sec ( +- 0.08% ) 6,935,192 branch-misses # 4.88% of all branches ( +- 0.26% ) 0.08296 +- 0.00141 seconds time elapsed ( +- 1.70% ) Notes: with dynamic CDS archive, there are lots of warnings which lead to lower performance than static CDS. [0.120s][warning][cds] Skipping picocli/CommandLine$RegexTransformer: Old class has been linked [0.120s][warning][cds] Skipping picocli/CommandLine$ParseResult$GroupMatchContainer: Old class has been linked [0.120s][warning][cds] Skipping picocli/CommandLine$Model$CaseAwareLinkedMap$CaseAwareKeySet: Old class has been linked [0.120s][warning][cds] Skipping picocli/CommandLine$BuiltIn$BooleanConverter: Old class has been linked
13-06-2022