< prev index next >

src/hotspot/share/prims/jvm.cpp

Print this page

        

@@ -1015,11 +1015,11 @@
   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) {
-    host_class = InstanceKlass::cast(lookup_k)->runtime_nest_host(CHECK_NULL);
+    host_class = InstanceKlass::cast(lookup_k)->nest_host(THREAD);
   }
 
   if (log_is_enabled(Info, class, nestmates)) {
     log_info(class, nestmates)("LookupDefineClass: %s - %s%s, %s, %s, %s",
                                name,

@@ -2049,74 +2049,103 @@
   // current is not a primitive or array class
   JVMWrapper("JVM_GetNestHost");
   Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current));
   assert(c->is_instance_klass(), "must be");
   InstanceKlass* ck = InstanceKlass::cast(c);
-  // Don't post exceptions if validation fails
-  InstanceKlass* host = ck->nest_host(NULL, THREAD);
-  return (jclass) (host == NULL ? NULL :
-                   JNIHandles::make_local(THREAD, host->java_mirror()));
+  InstanceKlass* host = ck->nest_host(THREAD);
+  assert(host != NULL, "host should never be NULL");
+  return (jclass) JNIHandles::make_local(THREAD, host->java_mirror());
 }
 JVM_END
 
 JVM_ENTRY(jobjectArray, JVM_GetNestMembers(JNIEnv* env, jclass current))
 {
   // current is not a primitive or array class
   JVMWrapper("JVM_GetNestMembers");
   Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current));
   assert(c->is_instance_klass(), "must be");
   InstanceKlass* ck = InstanceKlass::cast(c);
-  // Get the nest host for this nest - throw ICCE if validation fails
-  Symbol* icce = vmSymbols::java_lang_IncompatibleClassChangeError();
-  InstanceKlass* host = ck->nest_host(icce, CHECK_NULL);
+  InstanceKlass* host = ck->nest_host(THREAD);
+
+  const bool doLog = log_is_enabled(Trace, class, nestmates);
+
+  if (doLog) {
+    ResourceMark rm(THREAD);
+    log_trace(class, nestmates)("Calling GetNestMembers for type %s with nest-host %s",
+                                ck->external_name(), host->external_name());
+  }
 
   {
     JvmtiVMObjectAllocEventCollector oam;
     Array<u2>* members = host->nest_members();
     int length = members == NULL ? 0 : members->length();
+
+    if (doLog) {
+      log_trace(class, nestmates)(" - host has %d listed nest members", length);
+    }
+
     // nest host is first in the array so make it one bigger
     objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(),
                                              length + 1, CHECK_NULL);
-    objArrayHandle result (THREAD, r);
+    objArrayHandle result(THREAD, r);
     result->obj_at_put(0, host->java_mirror());
     if (length != 0) {
-      int i;
-      for (i = 0; i < length; i++) {
+      int count = 0;
+      for (int i = 0; i < length; i++) {
          int cp_index = members->at(i);
-         Klass* k = host->constants()->klass_at(cp_index, CHECK_NULL);
+        Klass* k = host->constants()->klass_at(cp_index, THREAD);
+        if (HAS_PENDING_EXCEPTION) {
+          if (doLog) {
+            ResourceMark rm(THREAD);
+            stringStream ss;
+            char* target_member_class = host->constants()->klass_name_at(cp_index)->as_C_string();
+            ss.print(" - resolution of nest member %s failed: ", target_member_class);
+            java_lang_Throwable::print(PENDING_EXCEPTION, &ss);
+            log_trace(class, nestmates)("%s", ss.as_string());
+          }
+          CLEAR_PENDING_EXCEPTION;
+          continue;
+        }
          if (k->is_instance_klass()) {
-           InstanceKlass* nest_host_k =
-             InstanceKlass::cast(k)->nest_host(icce, CHECK_NULL);
+          InstanceKlass* ik = InstanceKlass::cast(k);
+          InstanceKlass* nest_host_k = ik->nest_host(THREAD);
            if (nest_host_k == host) {
-             result->obj_at_put(i+1, k->java_mirror());
+            result->obj_at_put(count+1, k->java_mirror());
+            count++;
+            if (doLog) {
+              ResourceMark rm(THREAD);
+              log_trace(class, nestmates)(" - [%d] = %s", count, ik->external_name());
            }
-           else {
-             // k's nest host is legal but it isn't our host so
-             // throw ICCE
+          } else {
+            if (doLog) {
              ResourceMark rm(THREAD);
-             Exceptions::fthrow(THREAD_AND_LOCATION,
-                                icce,
-                                "%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()
-                           );
-             return NULL;
+              log_trace(class, nestmates)(" - skipping member %s with different host %s",
+                                          ik->external_name(), nest_host_k->external_name());
            }
          }
-         else {
-           // we have a bad nest member entry - throw ICCE
+        } else {
+          if (doLog) {
            ResourceMark rm(THREAD);
-           Exceptions::fthrow(THREAD_AND_LOCATION,
-                              icce,
-                              "Class %s can not be a nest member of %s",
-                              k->external_name(),
-                              host->external_name()
-                              );
-           return NULL;
+            log_trace(class, nestmates)(" - skipping member %s that is not an instance class",
+                                        k->external_name());
+          }
+        }
+      }
+      if (count < length) {
+        // we had invalid entries so we need to compact the array
+        if (doLog) {
+          ResourceMark rm(THREAD);
+          log_trace(class, nestmates)(" - compacting array from length %d to %d",
+                                      length + 1, count + 1);
+        }
+        objArrayOop r2 = oopFactory::new_objArray(SystemDictionary::Class_klass(),
+                                                  count + 1, CHECK_NULL);
+        objArrayHandle result2(THREAD, r2);
+        for (int i = 0; i < count + 1; i++) {
+          result2->obj_at_put(i, result->obj_at(i));
          }
+        return (jobjectArray)JNIHandles::make_local(THREAD, result2());
       }
     }
     else {
       assert(host == ck || ck->is_hidden(), "must be singleton nest or dynamic nestmate");
     }
< prev index next >