RFR: 8293187: Store initialized Enum classes in AOTCache [v4]

Ioi Lam iklam at openjdk.org
Wed Sep 18 01:03:42 UTC 2024


> This is the 4th PR for [JEP 483: Ahead-of-Time Class Loading & Linking](https://bugs.openjdk.org/browse/JDK-8315737).
> 
> **Problem:**
> 
> This PR is necessary to support [JDK-8293336: AOT-linking of invokedynamic for lambda expression and string concat](https://bugs.openjdk.org/browse/JDK-8293336), which needs to store [`sun.invoke.util.Wrapper`](https://github.com/openjdk/jdk/blob/c3711dc90980fb3e63ff199612c201c4464626bf/src/java.base/share/classes/sun/invoke/util/Wrapper.java) enums in the AOT cache. Although CDS has some limited support for storing enums, the `Wrapper` type is too complex for the existing solution to handle. Please see the JBS issue for details.
> 
> **Solution:**
> 
> In the assembly phase, we store the initialized states of the `Wrapper` class (captured in a `java.lang.Class` object, a.k.a. the *mirror* of this class) into the AOT cache. 
> 
> In production run, we no longer execute `Wrapper::<clinit>`, because all the static fields (contained in its mirror) are already initialized.
> 
> **Review Notes:**
> 
> - The new capability is controlled by `CDSConfig::is_initing_classes_at_dump_time()`. We can aot-initialize classes only if `-XX:+AOTClassLinking`  is enabled.
>     - The old (more limited) support for enums is still there (it's required when `AOTClassLinking` is disabled). See the call to `CDSEnumKlass::handle_enum_obj()` in heapShared.cpp. 
> - `AOTClassInitializer::can_archive_initialized_mirror()` decides what classes can be aot-initialized. This is currently a very small set of classes, but will expand in [JDK-8293336](https://bugs.openjdk.org/browse/JDK-8293336)
> - Before, `HeapShared::archive_java_mirrors()` would clear out all the states in the archived mirrors. With this PR, the states of aot-initialized classes are preserved via `HeapShared::copy_aot_initialized_mirror()`.
> - During the early state of the production run, `AOTLinkedClassBulkLoader::init_required_classes_for_loader()` is called to make sure that:
>     - all aot-initialized classes are moved into the `initialized` state (without executing its `<clinit>` method). This is done in `InstanceKlass::initialize_from_cds()`
>     - the classes of all the objects that are reachable from the aot-initialized mirrors are initialized. See comments above ` HeapShared::init_classes_reachable_from_archived_mirrors()` 
> 
> **Caveats:**
> 
> Not all Enum classes can be stored in the initialized state. E.g., some Enums might have static fields that depend on the environment:
> 
> 
> enum Foo {
>     [....]
>     static fin...

Ioi Lam has updated the pull request incrementally with one additional commit since the last revision:

  Improved in-line comments

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

Changes:
  - all: https://git.openjdk.org/jdk/pull/20958/files
  - new: https://git.openjdk.org/jdk/pull/20958/files/e15e76cd..21b8f6f9

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=jdk&pr=20958&range=03
 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=20958&range=02-03

  Stats: 14 lines in 2 files changed: 11 ins; 0 del; 3 mod
  Patch: https://git.openjdk.org/jdk/pull/20958.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/20958/head:pull/20958

PR: https://git.openjdk.org/jdk/pull/20958


More information about the hotspot-dev mailing list