1000 jobject loader, const jbyte *buf, jsize len, jobject pd,
1001 jboolean init, int flags, jobject classData, TRAPS) {
1002 assert(THREAD->is_Java_thread(), "must be a JavaThread");
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_weak = (flags & WEAK_CLASS) == WEAK_CLASS;
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)->runtime_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_weak ? "weak" : "strong",
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 }
2034 JVM_ENTRY(jboolean, JVM_AreNestMates(JNIEnv *env, jclass current, jclass member))
2035 {
2036 JVMWrapper("JVM_AreNestMates");
2037 Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current));
2038 assert(c->is_instance_klass(), "must be");
2039 InstanceKlass* ck = InstanceKlass::cast(c);
2040 Klass* m = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(member));
2041 assert(m->is_instance_klass(), "must be");
2042 InstanceKlass* mk = InstanceKlass::cast(m);
2043 return ck->has_nestmate_access_to(mk, THREAD);
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 // Don't post exceptions if validation fails
2055 InstanceKlass* host = ck->nest_host(NULL, THREAD);
2056 return (jclass) (host == NULL ? NULL :
2057 JNIHandles::make_local(THREAD, host->java_mirror()));
2058 }
2059 JVM_END
2060
2061 JVM_ENTRY(jobjectArray, JVM_GetNestMembers(JNIEnv* env, jclass current))
2062 {
2063 // current is not a primitive or array class
2064 JVMWrapper("JVM_GetNestMembers");
2065 Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current));
2066 assert(c->is_instance_klass(), "must be");
2067 InstanceKlass* ck = InstanceKlass::cast(c);
2068 // Get the nest host for this nest - throw ICCE if validation fails
2069 Symbol* icce = vmSymbols::java_lang_IncompatibleClassChangeError();
2070 InstanceKlass* host = ck->nest_host(icce, CHECK_NULL);
2071
2072 {
2073 JvmtiVMObjectAllocEventCollector oam;
2074 Array<u2>* members = host->nest_members();
2075 int length = members == NULL ? 0 : members->length();
2076 // nest host is first in the array so make it one bigger
2077 objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(),
2078 length + 1, CHECK_NULL);
2079 objArrayHandle result (THREAD, r);
2080 result->obj_at_put(0, host->java_mirror());
2081 if (length != 0) {
2082 int i;
2083 for (i = 0; i < length; i++) {
2084 int cp_index = members->at(i);
2085 Klass* k = host->constants()->klass_at(cp_index, CHECK_NULL);
2086 if (k->is_instance_klass()) {
2087 InstanceKlass* nest_host_k =
2088 InstanceKlass::cast(k)->nest_host(icce, CHECK_NULL);
2089 if (nest_host_k == host) {
2090 result->obj_at_put(i+1, k->java_mirror());
2091 }
2092 else {
2093 // k's nest host is legal but it isn't our host so
2094 // throw ICCE
2095 ResourceMark rm(THREAD);
2096 Exceptions::fthrow(THREAD_AND_LOCATION,
2097 icce,
2098 "%s.getNestMembers: Nest member %s in %s declares a different nest host of %s",
2099 c->external_name(),
2100 k->external_name(),
2101 host->external_name(),
2102 nest_host_k->external_name()
2103 );
2104 return NULL;
2105 }
2106 }
2107 else {
2108 // we have a bad nest member entry - throw ICCE
2109 ResourceMark rm(THREAD);
2110 Exceptions::fthrow(THREAD_AND_LOCATION,
2111 icce,
2112 "Class %s can not be a nest member of %s",
2113 k->external_name(),
2114 host->external_name()
2115 );
2116 return NULL;
2117 }
2118 }
2119 }
2120 else {
2121 assert(host == ck || ck->is_hidden(), "must be singleton nest or dynamic nestmate");
2122 }
2123 return (jobjectArray)JNIHandles::make_local(THREAD, result());
2124 }
2125 }
2126 JVM_END
2127
2128 // Constant pool access //////////////////////////////////////////////////////////
2129
2130 JVM_ENTRY(jobject, JVM_GetClassConstantPool(JNIEnv *env, jclass cls))
2131 {
2132 JVMWrapper("JVM_GetClassConstantPool");
2133 JvmtiVMObjectAllocEventCollector oam;
2134
2135 // Return null for primitives and arrays
2136 if (!java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {
2137 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
|
1000 jobject loader, const jbyte *buf, jsize len, jobject pd,
1001 jboolean init, int flags, jobject classData, TRAPS) {
1002 assert(THREAD->is_Java_thread(), "must be a JavaThread");
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_weak = (flags & WEAK_CLASS) == WEAK_CLASS;
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(THREAD);
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_weak ? "weak" : "strong",
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 }
2034 JVM_ENTRY(jboolean, JVM_AreNestMates(JNIEnv *env, jclass current, jclass member))
2035 {
2036 JVMWrapper("JVM_AreNestMates");
2037 Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current));
2038 assert(c->is_instance_klass(), "must be");
2039 InstanceKlass* ck = InstanceKlass::cast(c);
2040 Klass* m = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(member));
2041 assert(m->is_instance_klass(), "must be");
2042 InstanceKlass* mk = InstanceKlass::cast(m);
2043 return ck->has_nestmate_access_to(mk, THREAD);
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 assert(host != NULL, "host should never be NULL");
2056 return (jclass) 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 (doLog) {
2098 ResourceMark rm(THREAD);
2099 stringStream ss;
2100 char* target_member_class = host->constants()->klass_name_at(cp_index)->as_C_string();
2101 ss.print(" - resolution of nest member %s failed: ", target_member_class);
2102 java_lang_Throwable::print(PENDING_EXCEPTION, &ss);
2103 log_trace(class, nestmates)("%s", ss.as_string());
2104 }
2105 CLEAR_PENDING_EXCEPTION;
2106 continue;
2107 }
2108 if (k->is_instance_klass()) {
2109 InstanceKlass* ik = InstanceKlass::cast(k);
2110 InstanceKlass* nest_host_k = ik->nest_host(THREAD);
2111 if (nest_host_k == host) {
2112 result->obj_at_put(count+1, k->java_mirror());
2113 count++;
2114 if (doLog) {
2115 ResourceMark rm(THREAD);
2116 log_trace(class, nestmates)(" - [%d] = %s", count, ik->external_name());
2117 }
2118 } else {
2119 if (doLog) {
2120 ResourceMark rm(THREAD);
2121 log_trace(class, nestmates)(" - skipping member %s with different host %s",
2122 ik->external_name(), nest_host_k->external_name());
2123 }
2124 }
2125 } else {
2126 if (doLog) {
2127 ResourceMark rm(THREAD);
2128 log_trace(class, nestmates)(" - skipping member %s that is not an instance class",
2129 k->external_name());
2130 }
2131 }
2132 }
2133 if (count < length) {
2134 // we had invalid entries so we need to compact the array
2135 if (doLog) {
2136 ResourceMark rm(THREAD);
2137 log_trace(class, nestmates)(" - compacting array from length %d to %d",
2138 length + 1, count + 1);
2139 }
2140 objArrayOop r2 = oopFactory::new_objArray(SystemDictionary::Class_klass(),
2141 count + 1, CHECK_NULL);
2142 objArrayHandle result2(THREAD, r2);
2143 for (int i = 0; i < count + 1; i++) {
2144 result2->obj_at_put(i, result->obj_at(i));
2145 }
2146 return (jobjectArray)JNIHandles::make_local(THREAD, result2());
2147 }
2148 }
2149 else {
2150 assert(host == ck || ck->is_hidden(), "must be singleton nest or dynamic nestmate");
2151 }
2152 return (jobjectArray)JNIHandles::make_local(THREAD, result());
2153 }
2154 }
2155 JVM_END
2156
2157 // Constant pool access //////////////////////////////////////////////////////////
2158
2159 JVM_ENTRY(jobject, JVM_GetClassConstantPool(JNIEnv *env, jclass cls))
2160 {
2161 JVMWrapper("JVM_GetClassConstantPool");
2162 JvmtiVMObjectAllocEventCollector oam;
2163
2164 // Return null for primitives and arrays
2165 if (!java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {
2166 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
|