changeset 52831:8c1871e941dc nestmates

Pass the lookupClass through to the VM and switch to the nest-host on the VM side so that all vaildation exceptions are thrown as expected and we only ever set a valid nest host. Reviewed-by: mchung
author dholmes
date Wed, 07 Nov 2018 23:02:10 -0500
parents 248cd28491c1
children f38af7d9a194
files src/hotspot/share/prims/jvm.cpp src/java.base/share/classes/java/lang/invoke/MethodHandles.java
diffstat 2 files changed, 23 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/prims/jvm.cpp	Wed Nov 07 15:09:20 2018 -0800
+++ b/src/hotspot/share/prims/jvm.cpp	Wed Nov 07 23:02:10 2018 -0500
@@ -970,13 +970,20 @@
     THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Lookup class is null");
   }
   assert(k->is_instance_klass(), "Lookup class must be an instance klass");
-  InstanceKlass* lookup_class = InstanceKlass::cast(k);
 
   jboolean is_nestmate = (flags & NESTMATE) == NESTMATE;
   jboolean is_nonfindable = (flags & NONFINDABLE_CLASS) == NONFINDABLE_CLASS;
   jboolean is_weak = (flags & WEAK_CLASS) == WEAK_CLASS;
   jboolean vm_annotations = (flags & ACCESS_VM_ANNOTATIONS) == ACCESS_VM_ANNOTATIONS;
 
+  InstanceKlass* host_class = NULL;
+  if (is_nestmate) {
+    // we need to find the true nest-host of the lookup class,
+    // so any exceptions in nest validation must be thrown
+    Symbol* icce = vmSymbols::java_lang_IncompatibleClassChangeError();
+    host_class = InstanceKlass::cast(k)->nest_host(icce, CHECK_NULL);
+  }
+
   // classData (constant pool patching replacement) is only applicable for nonfindable classes
   if (classData != NULL && !is_nonfindable) {
     THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "classData is only applicable for nonfindable classes");
@@ -988,8 +995,13 @@
   }
 
   if (log_is_enabled(Info, class, nestmates)) {
-    log_info(class, nestmates)("Lookup define class %s is_nestmate %d is_nonfindable %d is_weak %d vm annotations %d name %s",
-                                lookup_class->external_name(), is_nestmate, is_nonfindable, is_weak, vm_annotations, name);
+    log_info(class, nestmates)("LookupDefineClass: %s - %s%s, %s, %s, %s",
+                               name,
+                               is_nestmate ? "with dynamic nest-host " : "non-nestmate",
+                               is_nestmate ? host_class->external_name() : "",
+                               is_nonfindable ? "non-findable" : "findable",
+                               is_weak ? "weak" : "strong",
+                               vm_annotations ? "with vm annotations" : "without vm annotation");
   }
 
   // Since exceptions can be thrown, class initialization can take place
@@ -1012,7 +1024,7 @@
 
   Handle class_loader (THREAD, JNIHandles::resolve(loader));
   Handle protection_domain (THREAD, JNIHandles::resolve(pd));
-  const char* source = is_nestmate ? lookup_class->external_name() : "__JVM_LookupDefineClass__";
+  const char* source = is_nestmate ? host_class->external_name() : "__JVM_LookupDefineClass__";
   ClassFileStream st((u1*)buf, len, source, ClassFileStream::verify);
 
   if (!is_nonfindable) {
@@ -1020,7 +1032,7 @@
                                               class_loader,
                                               protection_domain,
                                               &st,
-                                              is_nestmate ? lookup_class : NULL,
+                                              host_class,
                                               CHECK_NULL);
 
     if (log_is_enabled(Debug, class, resolve) && k != NULL) {
@@ -1035,8 +1047,8 @@
                                        NULL, // cp_patches
                                        is_nonfindable,
                                        is_weak,
-                                       vm_annotations, 
-                                       is_nestmate ? lookup_class : NULL,
+                                       vm_annotations,
+                                       host_class,
                                        CHECK_NULL);
     if (k == NULL) {
       THROW_MSG_0(vmSymbols::java_lang_Error(), "Failure to define a nonfindable class");
@@ -1055,7 +1067,7 @@
     log_debug(class, nestmates)("Dynamic nestmate: %s/%s, nest_host %s, %s",
                                 module_name,
                                 ik->external_name(),
-                                lookup_class->external_name(),
+                                host_class->external_name(),
                                 ik->is_nonfindable() ? "is non-findable" : "is findable");
   }
 
@@ -2102,7 +2114,8 @@
              ResourceMark rm(THREAD);
              Exceptions::fthrow(THREAD_AND_LOCATION,
                                 icce,
-                                "Nest member %s in %s declares a different nest host of %s",
+                                "%s.getNestMembers: Nest member %s in %s declares a different nest host of %s",
+                                c->external_name(),
                                 k->external_name(),
                                 host->external_name(),
                                 nest_host_k->external_name()
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Wed Nov 07 15:09:20 2018 -0800
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Wed Nov 07 23:02:10 2018 -0500
@@ -1253,12 +1253,6 @@
                 throw new IllegalArgumentException(cn + " not in same package as lookup class: " + lookupClass.getName());
             }
 
-            Class<?> host = lookupClass;
-            if ((flags & NESTMATE_CLASS) != 0) {
-                // cached in the Class object
-                host = lookupClass.getNestHost();
-            }
-
             if ((flags & NONFINDABLE_CLASS) != 0) {
                 // ## TODO use '/' as in the name of the VM anonymous class.
                 cn = cn + '\\' + ++seq;
@@ -1267,7 +1261,7 @@
             // invoke the class loader's defineClass method
             ClassLoader loader = lookupClass.getClassLoader();
             ProtectionDomain pd = (loader != null) ? lookupClassProtectionDomain() : null;
-            Class<?> clazz = JLA.defineClass(loader, host, cn, bytes, pd, flags, classData);
+            Class<?> clazz = JLA.defineClass(loader, lookupClass, cn, bytes, pd, flags, classData);
             assert clazz.getClassLoader() == lookupClass.getClassLoader()
                    && clazz.getPackageName().equals(lookupClass.getPackageName());