RFR: 8350550: Preload classes from AOT cache during VM bootstrap

Ioi Lam iklam at openjdk.org
Fri Aug 22 04:13:55 UTC 2025


On Mon, 18 Aug 2025 18:11:11 GMT, Dan Heidinga <heidinga at openjdk.org> wrote:

>> This PR loads the classes for the boot/platform/app loaders with `AOTLinkedClassBulkLoader::preload_classes()`. This happens at the very beginning of `vmClasses::resolve_all()`, before any Java code is executed. 
>> 
>> - We essentially iterate over all the classes inside the `AOTLinkedClassTable` and adds them into the system dictionary using the new method `SystemDictionary::preload_class()`.
>> - `SystemDictionary::preload_class(..., k)` is lightweight because it's called in a single thread after all super types of `k` have been loaded. So most of the complicated work (such as place holders, circularity detection, etc) in `SystemDictionary::resolve_or_null(..., k)` can be skipped. We also don't need to call into `ClassLoader::load_class()` as the boot/platform/app loaders are well-behaved.
>> - In the assembly phase, we record the mirror, package, protection domain, code source, etc, of these classes. So there's no need to programmatically create them in the production run. See `HeapShared::copy_java_mirror()` and also changes in ClassLoader.java and SecureClassLoader.java.
>
> src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp line 96:
> 
>> 94:   // later in load_javabase_classes() and load_non_javabase_classes().
>> 95:   preload_classes_in_table(AOTLinkedClassTable::for_static_archive()->boot1(), "boot1", Handle(), CHECK);
>> 96:   preload_classes_in_table(AOTLinkedClassTable::for_static_archive()->boot2(), "boot2", Handle(), CHECK);
> 
> why do we maintain both a `boot1` and `boot2` set here when both are loaded before executing any Java code?  Is the distinction meaningful for preloaded classes given both are loaded into the same classloader?

This is still meaningful as the `boot1` classes from the dynamic CDS archive are still loaded at the end of `vmClasses::resolve_all()`, after some bytecodes are executed.

> src/hotspot/share/cds/cdsHeapVerifier.cpp line 241:
> 
>> 239:           }
>> 240:           if (field_ik == vmClasses::Boolean_klass()) {
>> 241:             // TODO: check if is TRUE or FALSE
> 
> Are we canonicalizing Boolean.TRUE & Boolean.FALSE and thus don't care if a static field points to them?  And Boolean.TYPE isn't getting the same treatment?

Yes.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/26375#discussion_r2292643055
PR Review Comment: https://git.openjdk.org/jdk/pull/26375#discussion_r2292643019


More information about the hotspot-dev mailing list