RFR: 8369742: Link AOT-linked classes at JVM bootstrap [v3]
Ioi Lam
iklam at openjdk.org
Thu Oct 16 03:56:49 UTC 2025
> **PROBLEM**
>
> If we have an AOT-initialized class like this in java.base
>
>
> @AOTSafeClassInitializer
> class Foo {
> static Bar b = new Bar(); // AOT-cached
> static void doit() {
> b.toString(); /// invokevirtual Bar::toString()Ljava/lang/String;
> }
> }
>
>
> If `Foo.doit()` is called before `AOTLinkedClassBulkLoader::link_or_init_javabase_classe()`, it's possible for the `Bar` class to be not yet linked. The `invokevirtual` bytecode will crash because the vtable of the object `b` is not yet initialized.
>
> **FIX**
>
> Before we execute the first Java bytecode, unconditionally link all AOT-linked classes. This will ensure that the `Bar` class will have an initialized vtable for the above example.
>
> **NOTES**
>
> - The scenario in the above example does not affect JDK 24, 25 or the current JDK mainline (26). We are lucky that in all the bytecode execution up to `AOTLinkedClassBulkLoader::link_or_init_javabase_classe()`, whenever we do a vtable/itable dispatch on an AOT-cached heap object, we happen to have already linked its class (either by explicit calls from the JVM, or as side effect of invokestatic/getstatic/putstatic/new). However, this is a potential problem that should be fixed. I have run into this problem when implementing [JDK-8368199](https://bugs.openjdk.org/browse/JDK-8368199), which changes the bytecodes that are executed in early VM bootstrap.
> - I had to enable `CDSConfig::is_preserving_verification_constraints()` to for the static CDS archive. The reason is to avoid class loading. Please see the new comments in `AOTLinkedClassBulkLoader::link_classes_in_table()`.
> - The change in `AdapterHandlerLibrary::create_native_wrapper` is for supporting JVMTI. The offending methods are `jdk.internal.vm.Continuation::enterSpecial` and `jdk.internal.vm.Continuation::doYield`. These are "continuation native intrinsic" methods that are usually linked much later after the ServiceThread have been started.
Ioi Lam has updated the pull request incrementally with one additional commit since the last revision:
@vnkozlov comment - move delay nmethod event posting to nmethod.cpp
-------------
Changes:
- all: https://git.openjdk.org/jdk/pull/27783/files
- new: https://git.openjdk.org/jdk/pull/27783/files/1f3f9d44..a3923263
Webrevs:
- full: https://webrevs.openjdk.org/?repo=jdk&pr=27783&range=02
- incr: https://webrevs.openjdk.org/?repo=jdk&pr=27783&range=01-02
Stats: 83 lines in 6 files changed: 44 ins; 37 del; 2 mod
Patch: https://git.openjdk.org/jdk/pull/27783.diff
Fetch: git fetch https://git.openjdk.org/jdk.git pull/27783/head:pull/27783
PR: https://git.openjdk.org/jdk/pull/27783
More information about the hotspot-dev
mailing list