8308464: Shared array class should not always be loaded in boot loader
Reviewed-by: dholmes, iklam
This commit is contained in:
parent
69d1feb83f
commit
1cb2cc6587
@ -175,7 +175,6 @@ void ArrayKlass::remove_java_mirror() {
|
||||
}
|
||||
|
||||
void ArrayKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
|
||||
assert(loader_data == ClassLoaderData::the_null_class_loader_data(), "array classes belong to null loader");
|
||||
Klass::restore_unshareable_info(loader_data, protection_domain, CHECK);
|
||||
// Klass recreates the component mirror also
|
||||
|
||||
|
@ -2703,10 +2703,11 @@ void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handl
|
||||
if (array_klasses() != nullptr) {
|
||||
// To get a consistent list of classes we need MultiArray_lock to ensure
|
||||
// array classes aren't observed while they are being restored.
|
||||
MutexLocker ml(MultiArray_lock);
|
||||
MutexLocker ml(MultiArray_lock);
|
||||
assert(this == array_klasses()->bottom_klass(), "sanity");
|
||||
// Array classes have null protection domain.
|
||||
// --> see ArrayKlass::complete_create_array_klass()
|
||||
array_klasses()->restore_unshareable_info(ClassLoaderData::the_null_class_loader_data(), Handle(), CHECK);
|
||||
array_klasses()->restore_unshareable_info(class_loader_data(), Handle(), CHECK);
|
||||
}
|
||||
|
||||
// Initialize @ValueBased class annotation
|
||||
|
@ -570,7 +570,9 @@ void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protec
|
||||
JFR_ONLY(RESTORE_ID(this);)
|
||||
if (log_is_enabled(Trace, cds, unshareable)) {
|
||||
ResourceMark rm(THREAD);
|
||||
log_trace(cds, unshareable)("restore: %s", external_name());
|
||||
oop class_loader = loader_data->class_loader();
|
||||
log_trace(cds, unshareable)("restore: %s with class loader: %s", external_name(),
|
||||
class_loader != nullptr ? class_loader->klass()->external_name() : "boot");
|
||||
}
|
||||
|
||||
// If an exception happened during CDS restore, some of these fields may already be
|
||||
|
@ -44,8 +44,10 @@ public class ArrayKlasses extends DynamicArchiveTestBase {
|
||||
|
||||
static void test() throws Exception {
|
||||
String topArchiveName = getNewArchiveName();
|
||||
String appJar = ClassFileInstaller.getJarPath("ArrayKlasses.jar");
|
||||
String mainClass = "ArrayKlassesApp";
|
||||
final String appJar = ClassFileInstaller.getJarPath("ArrayKlasses.jar");
|
||||
final String mainClass = "ArrayKlassesApp";
|
||||
final String runtimeLogOptions =
|
||||
"-Xlog:class+load,class+load+array=debug,cds+dynamic=debug,cds=debug,cds+unshareable=trace";
|
||||
|
||||
// Case 1
|
||||
// Create a dynamic archive with the ArrayKlassesApp app class and its
|
||||
@ -62,14 +64,17 @@ public class ArrayKlasses extends DynamicArchiveTestBase {
|
||||
// Case 1
|
||||
// At runtime , the ArrayKlasesApp and its array class should be loaded
|
||||
// from the dynamic archive.
|
||||
run2(null, topArchiveName,
|
||||
"-Xlog:class+load,class+load+array=debug,cds+dynamic=debug,cds=debug",
|
||||
run2(null, topArchiveName, runtimeLogOptions,
|
||||
"-cp", appJar, mainClass)
|
||||
.assertNormalExit(output -> {
|
||||
output.shouldContain("ArrayKlassesApp source: shared objects file (top)")
|
||||
.shouldContain("restore: ArrayKlassesApp with class loader: jdk.internal.loader.ClassLoaders$AppClassLoader")
|
||||
.shouldContain("[LArrayKlassesApp; source: shared objects file (top)")
|
||||
.shouldContain("restore: [LArrayKlassesApp; with class loader: jdk.internal.loader.ClassLoaders$AppClassLoader")
|
||||
.shouldContain("[[LArrayKlassesApp; source: shared objects file (top)")
|
||||
.shouldContain("restore: [[LArrayKlassesApp; with class loader: jdk.internal.loader.ClassLoaders$AppClassLoader")
|
||||
.shouldContain("[[[LArrayKlassesApp; source: shared objects file (top)")
|
||||
.shouldContain("restore: [[[LArrayKlassesApp; with class loader: jdk.internal.loader.ClassLoaders$AppClassLoader")
|
||||
.shouldHaveExitValue(0);
|
||||
});
|
||||
|
||||
@ -90,14 +95,17 @@ public class ArrayKlasses extends DynamicArchiveTestBase {
|
||||
// Case 2
|
||||
// At runtime, the java/util/Date class should be loaded from the default
|
||||
// CDS archive; its array class should be loaded from the dynamic archive.
|
||||
run2(null, topArchiveName,
|
||||
"-Xlog:class+load,class+load+array=debug,cds+dynamic=debug,cds=debug",
|
||||
run2(null, topArchiveName, runtimeLogOptions,
|
||||
"-cp", appJar, mainClass, "system")
|
||||
.assertNormalExit(output -> {
|
||||
output.shouldContain("java.util.Date source: shared objects file")
|
||||
.shouldContain("restore: java.util.Date with class loader: boot")
|
||||
.shouldContain("[Ljava.util.Date; source: shared objects file (top)")
|
||||
.shouldContain("restore: [Ljava.util.Date; with class loader: boot")
|
||||
.shouldContain("[[Ljava.util.Date; source: shared objects file (top)")
|
||||
.shouldContain("restore: [[Ljava.util.Date; with class loader: boot")
|
||||
.shouldContain("[[[Ljava.util.Date; source: shared objects file (top)")
|
||||
.shouldContain("restore: [[[Ljava.util.Date; with class loader: boot")
|
||||
.shouldHaveExitValue(0);
|
||||
});
|
||||
|
||||
@ -116,13 +124,15 @@ public class ArrayKlasses extends DynamicArchiveTestBase {
|
||||
// Case 3
|
||||
// At runtime, the [J should be loaded from the default CDS archive;
|
||||
// the higher-dimension array should be loaded from the dynamic archive.
|
||||
run2(null, topArchiveName,
|
||||
"-Xlog:class+load,class+load+array=debug,cds+dynamic=debug,cds=debug",
|
||||
run2(null, topArchiveName, runtimeLogOptions,
|
||||
"-cp", appJar, mainClass, "primitive")
|
||||
.assertNormalExit(output -> {
|
||||
output.shouldContain("[J source: shared objects file")
|
||||
.shouldContain("restore: [J with class loader: boot")
|
||||
.shouldContain("[[J source: shared objects file (top)")
|
||||
.shouldContain("restore: [[J with class loader: boot")
|
||||
.shouldContain("[[[J source: shared objects file (top)")
|
||||
.shouldContain("restore: [[[J with class loader: boot")
|
||||
.shouldHaveExitValue(0);
|
||||
});
|
||||
|
||||
@ -142,13 +152,18 @@ public class ArrayKlasses extends DynamicArchiveTestBase {
|
||||
// Case 4
|
||||
// At runtime, the 4-dimension array of java/lang/Integer should be
|
||||
// loaded from the dynamic archive.
|
||||
run2(null, topArchiveName,
|
||||
"-Xlog:class+load,class+load+array=debug,cds+dynamic=debug,cds=debug",
|
||||
run2(null, topArchiveName, runtimeLogOptions,
|
||||
"-cp", appJar, mainClass, "integer-array")
|
||||
.assertNormalExit(output -> {
|
||||
output.shouldContain("[[Ljava.lang.Integer; source: shared objects file (top)")
|
||||
output.shouldContain("java.lang.Integer source: shared objects file")
|
||||
.shouldContain("restore: java.lang.Integer with class loader: boot")
|
||||
.shouldContain("restore: [Ljava.lang.Integer; with class loader: boot")
|
||||
.shouldContain("[[Ljava.lang.Integer; source: shared objects file (top)")
|
||||
.shouldContain("restore: [[Ljava.lang.Integer; with class loader: boot")
|
||||
.shouldContain("[[[Ljava.lang.Integer; source: shared objects file (top)")
|
||||
.shouldContain("restore: [[[Ljava.lang.Integer; with class loader: boot")
|
||||
.shouldContain("[[[[Ljava.lang.Integer; source: shared objects file (top)")
|
||||
.shouldContain("restore: [[[[Ljava.lang.Integer; with class loader: boot")
|
||||
.shouldHaveExitValue(0);
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user