< 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 >