< prev index next >

src/hotspot/share/classfile/systemDictionary.cpp

Print this page
rev 59477 : [mq]: cds_lambda

@@ -1249,17 +1249,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(),

@@ -1363,10 +1369,36 @@
   }
 
   return true;
 }
 
+InstanceKlass* SystemDictionary::load_shared_lambda_proxy_class(InstanceKlass* ik,
+                                                                Handle class_loader,
+                                                                Handle protection_domain,
+                                                                PackageEntry* pkg_entry,
+                                                                TRAPS) {
+  InstanceKlass* shared_n_h = SystemDictionaryShared::get_shared_nest_host(ik);
+  assert(shared_n_h->is_shared(), "nest host must be in CDS archive");
+  Symbol* cn = shared_n_h->name();
+  Klass *s = resolve_or_fail(cn, class_loader, protection_domain, true, CHECK_NULL);
+  if (s != shared_n_h) {
+    // 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_n_h->class_loader() == class_loader(), "mismatched class loader");
+  assert(shared_n_h->class_loader_data() == ClassLoaderData::class_loader_data(class_loader()), "mismatched class loader data");
+  ik->set_nest_host(shared_n_h, THREAD);
+
+  return load_shared_class(ik, class_loader, protection_domain, NULL, pkg_entry, CHECK_NULL);
+}
+
 InstanceKlass* SystemDictionary::load_shared_class(InstanceKlass* ik,
                                                    Handle class_loader,
                                                    Handle protection_domain,
                                                    const ClassFileStream *cfs,
                                                    PackageEntry* pkg_entry,

@@ -1383,12 +1415,15 @@
 
   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;
+  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;
   }

@@ -1424,10 +1459,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 >