BACKGROUND:
AfterJDK-8350550, all AOT-linked classes are loaded during VM bootstrap, before any Java bytecodes. They are initially in the "loaded" state, not "linked"
After we starting executing Java bytecodes, some of these classes are linked as a side effect of executing the invokestatic/getstatic/putstatic/new bytecodes.
Later, when AOTLinkedClassBulkLoader::link_or_init_javabase_classe() is called (after about 48,000 bytecodes have been executed), all AOT-linked classes in java.base are linked.
The remaining AOT-linked classes will be linked when AOTLinkedClassBulkLoader::link_or_init_non_javabase_classes() is called (after about 70,000 bytecodes have been executed).
PROBLEM:
If we have an AOT-initialized Java 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 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.
SOLUTION:
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.
After
After we starting executing Java bytecodes, some of these classes are linked as a side effect of executing the invokestatic/getstatic/putstatic/new bytecodes.
Later, when AOTLinkedClassBulkLoader::link_or_init_javabase_classe() is called (after about 48,000 bytecodes have been executed), all AOT-linked classes in java.base are linked.
The remaining AOT-linked classes will be linked when AOTLinkedClassBulkLoader::link_or_init_non_javabase_classes() is called (after about 70,000 bytecodes have been executed).
PROBLEM:
If we have an AOT-initialized Java 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 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.
SOLUTION:
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.
- relates to
-
JDK-8365645 AOT Cache Snapshot Model
-
- Open
-
- links to
-
Review(master) openjdk/jdk/27783