1003 JavaThread* jt = (JavaThread*) THREAD; 1004 ResourceMark rm(THREAD); 1005 1006 Klass* lookup_k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(lookup)); 1007 // Lookup class must be a non-null instance 1008 if (lookup_k == NULL) { 1009 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Lookup class is null"); 1010 } 1011 assert(lookup_k->is_instance_klass(), "Lookup class must be an instance klass"); 1012 1013 jboolean is_nestmate = (flags & NESTMATE) == NESTMATE; 1014 jboolean is_hidden = (flags & HIDDEN_CLASS) == HIDDEN_CLASS; 1015 jboolean is_strong = (flags & STRONG_LOADER_LINK) == STRONG_LOADER_LINK; 1016 jboolean vm_annotations = (flags & ACCESS_VM_ANNOTATIONS) == ACCESS_VM_ANNOTATIONS; 1017 1018 InstanceKlass* host_class = NULL; 1019 if (is_nestmate) { 1020 host_class = InstanceKlass::cast(lookup_k)->nest_host(CHECK_NULL); 1021 } 1022 1023 if (log_is_enabled(Info, class, nestmates)) { 1024 log_info(class, nestmates)("LookupDefineClass: %s - %s%s, %s, %s, %s", 1025 name, 1026 is_nestmate ? "with dynamic nest-host " : "non-nestmate", 1027 is_nestmate ? host_class->external_name() : "", 1028 is_hidden ? "hidden" : "not hidden", 1029 is_strong ? "strong" : "weak", 1030 vm_annotations ? "with vm annotations" : "without vm annotation"); 1031 } 1032 1033 if (!is_hidden) { 1034 // classData is only applicable for hidden classes 1035 if (classData != NULL) { 1036 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "classData is only applicable for hidden classes"); 1037 } 1038 if (is_nestmate) { 1039 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "dynamic nestmate is only applicable for hidden classes"); 1040 } 1041 if (!is_strong) { 1042 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "an ordinary class must be strongly referenced by its defining loader"); 1043 } 1044 if (vm_annotations) { 1045 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "vm annotations only allowed for hidden classes"); 1046 } 1047 if (flags != STRONG_LOADER_LINK) { 1048 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), 1049 err_msg("invalid flag 0x%x", flags)); 1050 } 1051 } 2044 } 2045 JVM_END 2046 2047 JVM_ENTRY(jclass, JVM_GetNestHost(JNIEnv* env, jclass current)) 2048 { 2049 // current is not a primitive or array class 2050 JVMWrapper("JVM_GetNestHost"); 2051 Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current)); 2052 assert(c->is_instance_klass(), "must be"); 2053 InstanceKlass* ck = InstanceKlass::cast(c); 2054 InstanceKlass* host = ck->nest_host(THREAD); 2055 return (jclass) (host == NULL ? NULL : 2056 JNIHandles::make_local(THREAD, host->java_mirror())); 2057 } 2058 JVM_END 2059 2060 JVM_ENTRY(jobjectArray, JVM_GetNestMembers(JNIEnv* env, jclass current)) 2061 { 2062 // current is not a primitive or array class 2063 JVMWrapper("JVM_GetNestMembers"); 2064 Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current)); 2065 assert(c->is_instance_klass(), "must be"); 2066 InstanceKlass* ck = InstanceKlass::cast(c); 2067 InstanceKlass* host = ck->nest_host(THREAD); 2068 2069 const bool doLog = log_is_enabled(Trace, class, nestmates); 2070 2071 if (doLog) { 2072 ResourceMark rm(THREAD); 2073 log_trace(class, nestmates)("Calling GetNestMembers for type %s with nest-host %s", 2074 ck->external_name(), host->external_name()); 2075 } 2076 2077 { 2078 JvmtiVMObjectAllocEventCollector oam; 2079 Array<u2>* members = host->nest_members(); 2080 int length = members == NULL ? 0 : members->length(); 2081 2082 if (doLog) { 2083 log_trace(class, nestmates)(" - host has %d listed nest members", length); 2084 } 2085 2086 // nest host is first in the array so make it one bigger 2087 objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(), 2088 length + 1, CHECK_NULL); 2089 objArrayHandle result(THREAD, r); 2090 result->obj_at_put(0, host->java_mirror()); 2091 if (length != 0) { 2092 int count = 0; 2093 for (int i = 0; i < length; i++) { 2094 int cp_index = members->at(i); 2095 Klass* k = host->constants()->klass_at(cp_index, THREAD); 2096 if (HAS_PENDING_EXCEPTION) { 2097 if (PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass())) { 2098 return NULL; // propagate VMEs 2099 } 2100 if (doLog) { 2101 ResourceMark rm(THREAD); 2102 stringStream ss; 2103 char* target_member_class = host->constants()->klass_name_at(cp_index)->as_C_string(); 2104 ss.print(" - resolution of nest member %s failed: ", target_member_class); 2105 java_lang_Throwable::print(PENDING_EXCEPTION, &ss); 2106 log_trace(class, nestmates)("%s", ss.as_string()); 2107 } 2108 CLEAR_PENDING_EXCEPTION; 2109 continue; 2110 } 2111 if (k->is_instance_klass()) { 2112 InstanceKlass* ik = InstanceKlass::cast(k); 2113 InstanceKlass* nest_host_k = ik->nest_host(CHECK_NULL); 2114 if (nest_host_k == host) { 2115 result->obj_at_put(count+1, k->java_mirror()); 2116 count++; 2117 if (doLog) { 2118 ResourceMark rm(THREAD); 2119 log_trace(class, nestmates)(" - [%d] = %s", count, ik->external_name()); 2120 } 2121 } else { 2122 if (doLog) { 2123 ResourceMark rm(THREAD); 2124 log_trace(class, nestmates)(" - skipping member %s with different host %s", 2125 ik->external_name(), nest_host_k->external_name()); 2126 } 2127 } 2128 } else { 2129 if (doLog) { 2130 ResourceMark rm(THREAD); 2131 log_trace(class, nestmates)(" - skipping member %s that is not an instance class", 2132 k->external_name()); 2133 } 2134 } 2135 } 2136 if (count < length) { 2137 // we had invalid entries so we need to compact the array 2138 if (doLog) { 2139 ResourceMark rm(THREAD); 2140 log_trace(class, nestmates)(" - compacting array from length %d to %d", 2141 length + 1, count + 1); 2142 } 2143 objArrayOop r2 = oopFactory::new_objArray(SystemDictionary::Class_klass(), 2144 count + 1, CHECK_NULL); 2145 objArrayHandle result2(THREAD, r2); 2146 for (int i = 0; i < count + 1; i++) { 2147 result2->obj_at_put(i, result->obj_at(i)); 2148 } 2149 return (jobjectArray)JNIHandles::make_local(THREAD, result2()); 2150 } 2151 } 2152 else { 2153 assert(host == ck || ck->is_hidden(), "must be singleton nest or dynamic nestmate"); 2154 } 2155 return (jobjectArray)JNIHandles::make_local(THREAD, result()); 2156 } 2157 } 2158 JVM_END 2159 2160 // Constant pool access ////////////////////////////////////////////////////////// 2161 2162 JVM_ENTRY(jobject, JVM_GetClassConstantPool(JNIEnv *env, jclass cls)) | 1003 JavaThread* jt = (JavaThread*) THREAD; 1004 ResourceMark rm(THREAD); 1005 1006 Klass* lookup_k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(lookup)); 1007 // Lookup class must be a non-null instance 1008 if (lookup_k == NULL) { 1009 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Lookup class is null"); 1010 } 1011 assert(lookup_k->is_instance_klass(), "Lookup class must be an instance klass"); 1012 1013 jboolean is_nestmate = (flags & NESTMATE) == NESTMATE; 1014 jboolean is_hidden = (flags & HIDDEN_CLASS) == HIDDEN_CLASS; 1015 jboolean is_strong = (flags & STRONG_LOADER_LINK) == STRONG_LOADER_LINK; 1016 jboolean vm_annotations = (flags & ACCESS_VM_ANNOTATIONS) == ACCESS_VM_ANNOTATIONS; 1017 1018 InstanceKlass* host_class = NULL; 1019 if (is_nestmate) { 1020 host_class = InstanceKlass::cast(lookup_k)->nest_host(CHECK_NULL); 1021 } 1022 1023 log_info(class, nestmates)("LookupDefineClass: %s - %s%s, %s, %s, %s", 1024 name, 1025 is_nestmate ? "with dynamic nest-host " : "non-nestmate", 1026 is_nestmate ? host_class->external_name() : "", 1027 is_hidden ? "hidden" : "not hidden", 1028 is_strong ? "strong" : "weak", 1029 vm_annotations ? "with vm annotations" : "without vm annotation"); 1030 1031 if (!is_hidden) { 1032 // classData is only applicable for hidden classes 1033 if (classData != NULL) { 1034 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "classData is only applicable for hidden classes"); 1035 } 1036 if (is_nestmate) { 1037 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "dynamic nestmate is only applicable for hidden classes"); 1038 } 1039 if (!is_strong) { 1040 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "an ordinary class must be strongly referenced by its defining loader"); 1041 } 1042 if (vm_annotations) { 1043 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "vm annotations only allowed for hidden classes"); 1044 } 1045 if (flags != STRONG_LOADER_LINK) { 1046 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), 1047 err_msg("invalid flag 0x%x", flags)); 1048 } 1049 } 2042 } 2043 JVM_END 2044 2045 JVM_ENTRY(jclass, JVM_GetNestHost(JNIEnv* env, jclass current)) 2046 { 2047 // current is not a primitive or array class 2048 JVMWrapper("JVM_GetNestHost"); 2049 Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current)); 2050 assert(c->is_instance_klass(), "must be"); 2051 InstanceKlass* ck = InstanceKlass::cast(c); 2052 InstanceKlass* host = ck->nest_host(THREAD); 2053 return (jclass) (host == NULL ? NULL : 2054 JNIHandles::make_local(THREAD, host->java_mirror())); 2055 } 2056 JVM_END 2057 2058 JVM_ENTRY(jobjectArray, JVM_GetNestMembers(JNIEnv* env, jclass current)) 2059 { 2060 // current is not a primitive or array class 2061 JVMWrapper("JVM_GetNestMembers"); 2062 ResourceMark rm(THREAD); 2063 Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current)); 2064 assert(c->is_instance_klass(), "must be"); 2065 InstanceKlass* ck = InstanceKlass::cast(c); 2066 InstanceKlass* host = ck->nest_host(THREAD); 2067 2068 log_trace(class, nestmates)("Calling GetNestMembers for type %s with nest-host %s", 2069 ck->external_name(), host->external_name()); 2070 { 2071 JvmtiVMObjectAllocEventCollector oam; 2072 Array<u2>* members = host->nest_members(); 2073 int length = members == NULL ? 0 : members->length(); 2074 2075 log_trace(class, nestmates)(" - host has %d listed nest members", length); 2076 2077 // nest host is first in the array so make it one bigger 2078 objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(), 2079 length + 1, CHECK_NULL); 2080 objArrayHandle result(THREAD, r); 2081 result->obj_at_put(0, host->java_mirror()); 2082 if (length != 0) { 2083 int count = 0; 2084 for (int i = 0; i < length; i++) { 2085 int cp_index = members->at(i); 2086 Klass* k = host->constants()->klass_at(cp_index, THREAD); 2087 if (HAS_PENDING_EXCEPTION) { 2088 if (PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass())) { 2089 return NULL; // propagate VMEs 2090 } 2091 if (log_is_enabled(Trace, class, nestmates)) { 2092 stringStream ss; 2093 char* target_member_class = host->constants()->klass_name_at(cp_index)->as_C_string(); 2094 ss.print(" - resolution of nest member %s failed: ", target_member_class); 2095 java_lang_Throwable::print(PENDING_EXCEPTION, &ss); 2096 log_trace(class, nestmates)("%s", ss.as_string()); 2097 } 2098 CLEAR_PENDING_EXCEPTION; 2099 continue; 2100 } 2101 if (k->is_instance_klass()) { 2102 InstanceKlass* ik = InstanceKlass::cast(k); 2103 InstanceKlass* nest_host_k = ik->nest_host(CHECK_NULL); 2104 if (nest_host_k == host) { 2105 result->obj_at_put(count+1, k->java_mirror()); 2106 count++; 2107 log_trace(class, nestmates)(" - [%d] = %s", count, ik->external_name()); 2108 } else { 2109 log_trace(class, nestmates)(" - skipping member %s with different host %s", 2110 ik->external_name(), nest_host_k->external_name()); 2111 } 2112 } else { 2113 log_trace(class, nestmates)(" - skipping member %s that is not an instance class", 2114 k->external_name()); 2115 } 2116 } 2117 if (count < length) { 2118 // we had invalid entries so we need to compact the array 2119 log_trace(class, nestmates)(" - compacting array from length %d to %d", 2120 length + 1, count + 1); 2121 2122 objArrayOop r2 = oopFactory::new_objArray(SystemDictionary::Class_klass(), 2123 count + 1, CHECK_NULL); 2124 objArrayHandle result2(THREAD, r2); 2125 for (int i = 0; i < count + 1; i++) { 2126 result2->obj_at_put(i, result->obj_at(i)); 2127 } 2128 return (jobjectArray)JNIHandles::make_local(THREAD, result2()); 2129 } 2130 } 2131 else { 2132 assert(host == ck || ck->is_hidden(), "must be singleton nest or dynamic nestmate"); 2133 } 2134 return (jobjectArray)JNIHandles::make_local(THREAD, result()); 2135 } 2136 } 2137 JVM_END 2138 2139 // Constant pool access ////////////////////////////////////////////////////////// 2140 2141 JVM_ENTRY(jobject, JVM_GetClassConstantPool(JNIEnv *env, jclass cls)) |