--- old/src/hotspot/share/prims/jvm.cpp 2020-03-11 01:21:54.436423923 -0400 +++ new/src/hotspot/share/prims/jvm.cpp 2020-03-11 01:21:51.114386894 -0400 @@ -1017,7 +1017,7 @@ 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(CHECK_NULL); } if (log_is_enabled(Info, class, nestmates)) { @@ -2051,8 +2051,7 @@ 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); + InstanceKlass* host = ck->nest_host(THREAD); return (jclass) (host == NULL ? NULL : JNIHandles::make_local(THREAD, host->java_mirror())); } @@ -2065,56 +2064,89 @@ 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* 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 cp_index = members->at(i); - Klass* k = host->constants()->klass_at(cp_index, CHECK_NULL); - if (k->is_instance_klass()) { - InstanceKlass* nest_host_k = - InstanceKlass::cast(k)->nest_host(icce, CHECK_NULL); - if (nest_host_k == host) { - result->obj_at_put(i+1, k->java_mirror()); - } - else { - // k's nest host is legal but it isn't our host so - // throw ICCE - 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; - } - } - else { - // we have a bad nest member entry - throw ICCE - 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; - } + int count = 0; + for (int i = 0; i < length; i++) { + int cp_index = members->at(i); + Klass* k = host->constants()->klass_at(cp_index, THREAD); + if (HAS_PENDING_EXCEPTION) { + if (PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass())) { + return NULL; // propagate VMEs + } + 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* ik = InstanceKlass::cast(k); + InstanceKlass* nest_host_k = ik->nest_host(CHECK_NULL); + if (nest_host_k == host) { + 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 { + if (doLog) { + ResourceMark rm(THREAD); + log_trace(class, nestmates)(" - skipping member %s with different host %s", + ik->external_name(), nest_host_k->external_name()); + } + } + } else { + if (doLog) { + ResourceMark rm(THREAD); + 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 {