< prev index next >
src/hotspot/share/classfile/systemDictionary.cpp
Print this page
@@ -701,11 +701,11 @@
}
}
return NULL;
}
-static void post_class_load_event(EventClassLoad* event, const InstanceKlass* k, const ClassLoaderData* init_cld) {
+void SystemDictionary::post_class_load_event(EventClassLoad* event, const InstanceKlass* k, const ClassLoaderData* init_cld) {
assert(event != NULL, "invariant");
assert(k != NULL, "invariant");
assert(event->should_commit(), "invariant");
event->set_loadedClass(k);
event->set_definingClassLoader(k->class_loader_data());
@@ -1253,17 +1253,23 @@
"Cannot use sharing if java.base is patched");
ResourceMark rm(THREAD);
int path_index = ik->shared_classpath_index();
ClassLoaderData* loader_data = class_loader_data(class_loader);
if (path_index < 0) {
- // path_index < 0 indicates that the class is intended for a custom loader
- // and should not be loaded by boot/platform/app loaders
+ // path_index < 0 indicates that
+ // 1) the class is intended for a custom loader and should not be loaded by boot/platform/app loaders
+ // or
+ // 2) the class is a hidden lambda proxy class which would be loaded by boot/platform/app loaders
if (loader_data->is_builtin_class_loader_data()) {
+ if (!SystemDictionaryShared::is_hidden_lambda_proxy(ik)) {
return false;
} else {
return true;
}
+ } else {
+ return true;
+ }
}
SharedClassPathEntry* ent =
(SharedClassPathEntry*)FileMapInfo::shared_path(path_index);
if (!Universe::is_module_initialized()) {
assert(ent != NULL && ent->is_modules_image(),
@@ -1367,10 +1373,41 @@
}
return true;
}
+InstanceKlass* SystemDictionary::load_shared_lambda_proxy_class(InstanceKlass* ik,
+ Handle class_loader,
+ Handle protection_domain,
+ PackageEntry* pkg_entry,
+ TRAPS) {
+ InstanceKlass* shared_nest_host = SystemDictionaryShared::get_shared_nest_host(ik);
+ assert(shared_nest_host->is_shared(), "nest host must be in CDS archive");
+ Symbol* cn = shared_nest_host->name();
+ Klass *s = resolve_or_fail(cn, class_loader, protection_domain, true, CHECK_NULL);
+ if (s != shared_nest_host) {
+ // The dynamically resolved nest_host is not the same as the one we used during dump time,
+ // so we cannot use ik.
+ return NULL;
+ } else {
+ assert(s->is_shared(), "must be");
+ }
+
+ // The lambda proxy class and its nest host have the same class loader and class loader data,
+ // as verified in SystemDictionaryShared::add_lambda_proxy_class()
+ assert(shared_nest_host->class_loader() == class_loader(), "mismatched class loader");
+ assert(shared_nest_host->class_loader_data() == ClassLoaderData::class_loader_data(class_loader()), "mismatched class loader data");
+ ik->set_nest_host(shared_nest_host, THREAD);
+
+ InstanceKlass* loaded_ik = load_shared_class(ik, class_loader, protection_domain, NULL, pkg_entry, CHECK_NULL);
+
+ assert(shared_nest_host->is_same_class_package(ik),
+ "lambda proxy class and its nest host must be in the same package");
+
+ return loaded_ik;
+}
+
InstanceKlass* SystemDictionary::load_shared_class(InstanceKlass* ik,
Handle class_loader,
Handle protection_domain,
const ClassFileStream *cfs,
PackageEntry* pkg_entry,
@@ -1387,12 +1424,17 @@
if (!check_shared_class_super_types(ik, class_loader, protection_domain, THREAD)) {
return NULL;
}
- InstanceKlass* new_ik = KlassFactory::check_shared_class_file_load_hook(
+ InstanceKlass* new_ik = NULL;
+ // CFLH check is skipped for VM hidden or anonymous classes (see KlassFactory::create_from_stream).
+ // It will be skipped for shared VM hidden lambda proxy classes.
+ if (!SystemDictionaryShared::is_hidden_lambda_proxy(ik)) {
+ new_ik = KlassFactory::check_shared_class_file_load_hook(
ik, class_name, class_loader, protection_domain, cfs, CHECK_NULL);
+ }
if (new_ik != NULL) {
// The class is changed by CFLH. Return the new class. The shared class is
// not used.
return new_ik;
}
@@ -1428,10 +1470,16 @@
// For boot loader, ensure that GetSystemPackage knows that a class in this
// package was loaded.
if (loader_data->is_the_null_class_loader_data()) {
int path_index = ik->shared_classpath_index();
+ if (path_index < 0) {
+ if (SystemDictionaryShared::is_hidden_lambda_proxy(ik)) {
+ InstanceKlass* nest_host = SystemDictionaryShared::get_shared_nest_host(ik);
+ path_index = nest_host->shared_classpath_index();
+ }
+ }
ik->set_classpath_index(path_index, THREAD);
}
if (DumpLoadedClassList != NULL && classlist_file->is_open()) {
// Only dump the classes that can be stored into CDS archive
< prev index next >