For "old" classes (InstanceKlass::major_version() < 50), currently we only support storing them in CDS when the class is in the "loaded" state. At runtime, the class will be verified with the "old" verified (libverify.so).
This is slow because the class needs to be verified and rewritten at runtime.
For "new" classes (InstanceKlass::major_version() >= 50), we verify them with the "new verifier" at dump time and also store the "verification constraints" in the archive. See https://github.com/openjdk/jdk/blob/457e1cb827f4d0a28da2fb76bff760401d677bef/src/hotspot/share/classfile/verificationType.cpp#L112-L119 , where
VerificationType::is_reference_assignable_from() calls SystemDictionaryShared::add_verification_constraint()
*************************************
Proposal: we can implement something similar in the "old verifier", which is under here
https://github.com/openjdk/jdk/tree/457e1cb827f4d0a28da2fb76bff760401d677bef/src/java.base/share/native/libverify
We have two choices:
[1] Intercept all equivalent "is assignable" calls in the old verifier and record them with SystemDictionaryShared::add_verification_constraint. This probably means adding hooks into merge_fullinfo_types():
https://github.com/openjdk/jdk/blob/457e1cb827f4d0a28da2fb76bff760401d677bef/src/java.base/share/native/libverify/check_code.c#L3895
[2] When the old verifier verifies a class X, it resolves all of the types referenced by X using JVM_FindClassFromClass(). We can remember the result of all of these resolutions for X. I.e., we record that
- When X was verified at dump time, the old verifier resolved types A, B and C.
At runtime, before we load X from the archive, we resolved types A, B and C. If they are resolved to the exact same types as those seen at dump time, we can conclude that the old verifier would make the exact same decision as in dump time (i.e., X is verifiable).
If any of A, B, or C are resolved to different types, then we will give up loading X from the archive, and revert to loading X from the JAR file.
(resolved to the exact same type means: for the symbolic name "A", we resolve the InstanceKlass from the CDS archive -- which would be the same InstanceKlass that was seen during dump time).
[2] Seems to be the easier solution as we don't need to change anything in the old verifier and risk introducing new bugs there.