28 #include "classfile/classLoader.hpp"
29 #include "classfile/classLoaderData.inline.hpp"
30 #include "classfile/javaAssertions.hpp"
31 #include "classfile/javaClasses.inline.hpp"
32 #include "classfile/moduleEntry.hpp"
33 #include "classfile/modules.hpp"
34 #include "classfile/packageEntry.hpp"
35 #include "classfile/stringTable.hpp"
36 #include "classfile/systemDictionary.hpp"
37 #include "classfile/vmSymbols.hpp"
38 #include "gc/shared/collectedHeap.inline.hpp"
39 #include "interpreter/bytecode.hpp"
40 #include "jfr/jfrEvents.hpp"
41 #include "logging/log.hpp"
42 #include "memory/heapShared.hpp"
43 #include "memory/oopFactory.hpp"
44 #include "memory/referenceType.hpp"
45 #include "memory/resourceArea.hpp"
46 #include "memory/universe.hpp"
47 #include "oops/access.inline.hpp"
48 #include "oops/fieldStreams.hpp"
49 #include "oops/instanceKlass.hpp"
50 #include "oops/method.hpp"
51 #include "oops/objArrayKlass.hpp"
52 #include "oops/objArrayOop.inline.hpp"
53 #include "oops/oop.inline.hpp"
54 #include "prims/jvm_misc.hpp"
55 #include "prims/jvmtiExport.hpp"
56 #include "prims/jvmtiThreadState.hpp"
57 #include "prims/nativeLookup.hpp"
58 #include "prims/privilegedStack.hpp"
59 #include "prims/stackwalk.hpp"
60 #include "runtime/arguments.hpp"
61 #include "runtime/atomic.hpp"
62 #include "runtime/handles.inline.hpp"
63 #include "runtime/init.hpp"
64 #include "runtime/interfaceSupport.inline.hpp"
65 #include "runtime/java.hpp"
66 #include "runtime/javaCalls.hpp"
67 #include "runtime/jfieldIDWorkaround.hpp"
1983 else {
1984 assert(host == ck, "must be singleton nest");
1985 }
1986 return (jobjectArray)JNIHandles::make_local(THREAD, result());
1987 }
1988 }
1989 JVM_END
1990
1991 // Constant pool access //////////////////////////////////////////////////////////
1992
1993 JVM_ENTRY(jobject, JVM_GetClassConstantPool(JNIEnv *env, jclass cls))
1994 {
1995 JVMWrapper("JVM_GetClassConstantPool");
1996 JvmtiVMObjectAllocEventCollector oam;
1997
1998 // Return null for primitives and arrays
1999 if (!java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {
2000 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
2001 if (k->is_instance_klass()) {
2002 InstanceKlass* k_h = InstanceKlass::cast(k);
2003 Handle jcp = reflect_ConstantPool::create(CHECK_NULL);
2004 reflect_ConstantPool::set_cp(jcp(), k_h->constants());
2005 return JNIHandles::make_local(jcp());
2006 }
2007 }
2008 return NULL;
2009 }
2010 JVM_END
2011
2012
2013 JVM_ENTRY(jint, JVM_ConstantPoolGetSize(JNIEnv *env, jobject obj, jobject unused))
2014 {
2015 JVMWrapper("JVM_ConstantPoolGetSize");
2016 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2017 return cp->length();
2018 }
2019 JVM_END
2020
2021
2022 JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject obj, jobject unused, jint index))
2023 {
2024 JVMWrapper("JVM_ConstantPoolGetClassAt");
2025 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2026 bounds_check(cp, index, CHECK_NULL);
2027 constantTag tag = cp->tag_at(index);
2028 if (!tag.is_klass() && !tag.is_unresolved_klass()) {
2029 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2030 }
2031 Klass* k = cp->klass_at(index, CHECK_NULL);
2032 return (jclass) JNIHandles::make_local(k->java_mirror());
2033 }
2034 JVM_END
2035
2036 JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAtIfLoaded(JNIEnv *env, jobject obj, jobject unused, jint index))
2037 {
2038 JVMWrapper("JVM_ConstantPoolGetClassAtIfLoaded");
2039 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2040 bounds_check(cp, index, CHECK_NULL);
2041 constantTag tag = cp->tag_at(index);
2042 if (!tag.is_klass() && !tag.is_unresolved_klass()) {
2043 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2044 }
2045 Klass* k = ConstantPool::klass_at_if_loaded(cp, index);
2046 if (k == NULL) return NULL;
2047 return (jclass) JNIHandles::make_local(k->java_mirror());
2048 }
2049 JVM_END
2050
2051 static jobject get_method_at_helper(const constantPoolHandle& cp, jint index, bool force_resolution, TRAPS) {
2052 constantTag tag = cp->tag_at(index);
2053 if (!tag.is_method() && !tag.is_interface_method()) {
2054 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2055 }
2056 int klass_ref = cp->uncached_klass_ref_index_at(index);
2057 Klass* k_o;
2058 if (force_resolution) {
2059 k_o = cp->klass_at(klass_ref, CHECK_NULL);
2060 } else {
2061 k_o = ConstantPool::klass_at_if_loaded(cp, klass_ref);
2062 if (k_o == NULL) return NULL;
2063 }
2064 InstanceKlass* k = InstanceKlass::cast(k_o);
2065 Symbol* name = cp->uncached_name_ref_at(index);
2066 Symbol* sig = cp->uncached_signature_ref_at(index);
2067 methodHandle m (THREAD, k->find_method(name, sig));
2068 if (m.is_null()) {
2069 THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), "Unable to look up method in target class");
2070 }
2071 oop method;
2072 if (!m->is_initializer() || m->is_static()) {
2073 method = Reflection::new_method(m, true, CHECK_NULL);
2074 } else {
2075 method = Reflection::new_constructor(m, CHECK_NULL);
2076 }
2077 return JNIHandles::make_local(method);
2078 }
2079
2080 JVM_ENTRY(jobject, JVM_ConstantPoolGetMethodAt(JNIEnv *env, jobject obj, jobject unused, jint index))
2081 {
2082 JVMWrapper("JVM_ConstantPoolGetMethodAt");
2083 JvmtiVMObjectAllocEventCollector oam;
2084 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2085 bounds_check(cp, index, CHECK_NULL);
2086 jobject res = get_method_at_helper(cp, index, true, CHECK_NULL);
2087 return res;
2088 }
2089 JVM_END
2090
2091 JVM_ENTRY(jobject, JVM_ConstantPoolGetMethodAtIfLoaded(JNIEnv *env, jobject obj, jobject unused, jint index))
2092 {
2093 JVMWrapper("JVM_ConstantPoolGetMethodAtIfLoaded");
2094 JvmtiVMObjectAllocEventCollector oam;
2095 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2096 bounds_check(cp, index, CHECK_NULL);
2097 jobject res = get_method_at_helper(cp, index, false, CHECK_NULL);
2098 return res;
2099 }
2100 JVM_END
2101
2102 static jobject get_field_at_helper(constantPoolHandle cp, jint index, bool force_resolution, TRAPS) {
2103 constantTag tag = cp->tag_at(index);
2104 if (!tag.is_field()) {
2105 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2106 }
2107 int klass_ref = cp->uncached_klass_ref_index_at(index);
2108 Klass* k_o;
2109 if (force_resolution) {
2110 k_o = cp->klass_at(klass_ref, CHECK_NULL);
2111 } else {
2112 k_o = ConstantPool::klass_at_if_loaded(cp, klass_ref);
2113 if (k_o == NULL) return NULL;
2114 }
2115 InstanceKlass* k = InstanceKlass::cast(k_o);
2116 Symbol* name = cp->uncached_name_ref_at(index);
2117 Symbol* sig = cp->uncached_signature_ref_at(index);
2118 fieldDescriptor fd;
2119 Klass* target_klass = k->find_field(name, sig, &fd);
2120 if (target_klass == NULL) {
2121 THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), "Unable to look up field in target class");
2122 }
2123 oop field = Reflection::new_field(&fd, CHECK_NULL);
2124 return JNIHandles::make_local(field);
2125 }
2126
2127 JVM_ENTRY(jobject, JVM_ConstantPoolGetFieldAt(JNIEnv *env, jobject obj, jobject unusedl, jint index))
2128 {
2129 JVMWrapper("JVM_ConstantPoolGetFieldAt");
2130 JvmtiVMObjectAllocEventCollector oam;
2131 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2132 bounds_check(cp, index, CHECK_NULL);
2133 jobject res = get_field_at_helper(cp, index, true, CHECK_NULL);
2134 return res;
2135 }
2136 JVM_END
2137
2138 JVM_ENTRY(jobject, JVM_ConstantPoolGetFieldAtIfLoaded(JNIEnv *env, jobject obj, jobject unused, jint index))
2139 {
2140 JVMWrapper("JVM_ConstantPoolGetFieldAtIfLoaded");
2141 JvmtiVMObjectAllocEventCollector oam;
2142 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2143 bounds_check(cp, index, CHECK_NULL);
2144 jobject res = get_field_at_helper(cp, index, false, CHECK_NULL);
2145 return res;
2146 }
2147 JVM_END
2148
2149 JVM_ENTRY(jobjectArray, JVM_ConstantPoolGetMemberRefInfoAt(JNIEnv *env, jobject obj, jobject unused, jint index))
2150 {
2151 JVMWrapper("JVM_ConstantPoolGetMemberRefInfoAt");
2152 JvmtiVMObjectAllocEventCollector oam;
2153 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2154 bounds_check(cp, index, CHECK_NULL);
2155 constantTag tag = cp->tag_at(index);
2156 if (!tag.is_field_or_method()) {
2157 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2158 }
2159 int klass_ref = cp->uncached_klass_ref_index_at(index);
2160 Symbol* klass_name = cp->klass_name_at(klass_ref);
2161 Symbol* member_name = cp->uncached_name_ref_at(index);
2162 Symbol* member_sig = cp->uncached_signature_ref_at(index);
2163 objArrayOop dest_o = oopFactory::new_objArray(SystemDictionary::String_klass(), 3, CHECK_NULL);
2164 objArrayHandle dest(THREAD, dest_o);
2165 Handle str = java_lang_String::create_from_symbol(klass_name, CHECK_NULL);
2166 dest->obj_at_put(0, str());
2167 str = java_lang_String::create_from_symbol(member_name, CHECK_NULL);
2168 dest->obj_at_put(1, str());
2169 str = java_lang_String::create_from_symbol(member_sig, CHECK_NULL);
2170 dest->obj_at_put(2, str());
2171 return (jobjectArray) JNIHandles::make_local(dest());
2172 }
2173 JVM_END
2174
2175 JVM_ENTRY(jint, JVM_ConstantPoolGetClassRefIndexAt(JNIEnv *env, jobject obj, jobject unused, jint index))
2176 {
2177 JVMWrapper("JVM_ConstantPoolGetClassRefIndexAt");
2178 JvmtiVMObjectAllocEventCollector oam;
2179 constantPoolHandle cp(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2180 bounds_check(cp, index, CHECK_0);
2181 constantTag tag = cp->tag_at(index);
2182 if (!tag.is_field_or_method()) {
2183 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2184 }
2185 return (jint) cp->uncached_klass_ref_index_at(index);
2186 }
2187 JVM_END
2188
2189 JVM_ENTRY(jint, JVM_ConstantPoolGetNameAndTypeRefIndexAt(JNIEnv *env, jobject obj, jobject unused, jint index))
2190 {
2191 JVMWrapper("JVM_ConstantPoolGetNameAndTypeRefIndexAt");
2192 JvmtiVMObjectAllocEventCollector oam;
2193 constantPoolHandle cp(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2194 bounds_check(cp, index, CHECK_0);
2195 constantTag tag = cp->tag_at(index);
2196 if (!tag.is_invoke_dynamic() && !tag.is_field_or_method()) {
2197 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2198 }
2199 return (jint) cp->uncached_name_and_type_ref_index_at(index);
2200 }
2201 JVM_END
2202
2203 JVM_ENTRY(jobjectArray, JVM_ConstantPoolGetNameAndTypeRefInfoAt(JNIEnv *env, jobject obj, jobject unused, jint index))
2204 {
2205 JVMWrapper("JVM_ConstantPoolGetNameAndTypeRefInfoAt");
2206 JvmtiVMObjectAllocEventCollector oam;
2207 constantPoolHandle cp(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2208 bounds_check(cp, index, CHECK_NULL);
2209 constantTag tag = cp->tag_at(index);
2210 if (!tag.is_name_and_type()) {
2211 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2212 }
2213 Symbol* member_name = cp->symbol_at(cp->name_ref_index_at(index));
2214 Symbol* member_sig = cp->symbol_at(cp->signature_ref_index_at(index));
2215 objArrayOop dest_o = oopFactory::new_objArray(SystemDictionary::String_klass(), 2, CHECK_NULL);
2216 objArrayHandle dest(THREAD, dest_o);
2217 Handle str = java_lang_String::create_from_symbol(member_name, CHECK_NULL);
2218 dest->obj_at_put(0, str());
2219 str = java_lang_String::create_from_symbol(member_sig, CHECK_NULL);
2220 dest->obj_at_put(1, str());
2221 return (jobjectArray) JNIHandles::make_local(dest());
2222 }
2223 JVM_END
2224
2225 JVM_ENTRY(jint, JVM_ConstantPoolGetIntAt(JNIEnv *env, jobject obj, jobject unused, jint index))
2226 {
2227 JVMWrapper("JVM_ConstantPoolGetIntAt");
2228 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2229 bounds_check(cp, index, CHECK_0);
2230 constantTag tag = cp->tag_at(index);
2231 if (!tag.is_int()) {
2232 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2233 }
2234 return cp->int_at(index);
2235 }
2236 JVM_END
2237
2238 JVM_ENTRY(jlong, JVM_ConstantPoolGetLongAt(JNIEnv *env, jobject obj, jobject unused, jint index))
2239 {
2240 JVMWrapper("JVM_ConstantPoolGetLongAt");
2241 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2242 bounds_check(cp, index, CHECK_(0L));
2243 constantTag tag = cp->tag_at(index);
2244 if (!tag.is_long()) {
2245 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2246 }
2247 return cp->long_at(index);
2248 }
2249 JVM_END
2250
2251 JVM_ENTRY(jfloat, JVM_ConstantPoolGetFloatAt(JNIEnv *env, jobject obj, jobject unused, jint index))
2252 {
2253 JVMWrapper("JVM_ConstantPoolGetFloatAt");
2254 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2255 bounds_check(cp, index, CHECK_(0.0f));
2256 constantTag tag = cp->tag_at(index);
2257 if (!tag.is_float()) {
2258 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2259 }
2260 return cp->float_at(index);
2261 }
2262 JVM_END
2263
2264 JVM_ENTRY(jdouble, JVM_ConstantPoolGetDoubleAt(JNIEnv *env, jobject obj, jobject unused, jint index))
2265 {
2266 JVMWrapper("JVM_ConstantPoolGetDoubleAt");
2267 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2268 bounds_check(cp, index, CHECK_(0.0));
2269 constantTag tag = cp->tag_at(index);
2270 if (!tag.is_double()) {
2271 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2272 }
2273 return cp->double_at(index);
2274 }
2275 JVM_END
2276
2277 JVM_ENTRY(jstring, JVM_ConstantPoolGetStringAt(JNIEnv *env, jobject obj, jobject unused, jint index))
2278 {
2279 JVMWrapper("JVM_ConstantPoolGetStringAt");
2280 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2281 bounds_check(cp, index, CHECK_NULL);
2282 constantTag tag = cp->tag_at(index);
2283 if (!tag.is_string()) {
2284 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2285 }
2286 oop str = cp->string_at(index, CHECK_NULL);
2287 return (jstring) JNIHandles::make_local(str);
2288 }
2289 JVM_END
2290
2291 JVM_ENTRY(jstring, JVM_ConstantPoolGetUTF8At(JNIEnv *env, jobject obj, jobject unused, jint index))
2292 {
2293 JVMWrapper("JVM_ConstantPoolGetUTF8At");
2294 JvmtiVMObjectAllocEventCollector oam;
2295 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2296 bounds_check(cp, index, CHECK_NULL);
2297 constantTag tag = cp->tag_at(index);
2298 if (!tag.is_symbol()) {
2299 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2300 }
2301 Symbol* sym = cp->symbol_at(index);
2302 Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL);
2303 return (jstring) JNIHandles::make_local(str());
2304 }
2305 JVM_END
2306
2307 JVM_ENTRY(jbyte, JVM_ConstantPoolGetTagAt(JNIEnv *env, jobject obj, jobject unused, jint index))
2308 {
2309 JVMWrapper("JVM_ConstantPoolGetTagAt");
2310 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2311 bounds_check(cp, index, CHECK_0);
2312 constantTag tag = cp->tag_at(index);
2313 jbyte result = tag.value();
2314 // If returned tag values are not from the JVM spec, e.g. tags from 100 to 105,
2315 // they are changed to the corresponding tags from the JVM spec, so that java code in
2316 // sun.reflect.ConstantPool will return only tags from the JVM spec, not internal ones.
2317 if (tag.is_klass_or_reference()) {
2318 result = JVM_CONSTANT_Class;
2319 } else if (tag.is_string_index()) {
2320 result = JVM_CONSTANT_String;
2321 } else if (tag.is_method_type_in_error()) {
2322 result = JVM_CONSTANT_MethodType;
2323 } else if (tag.is_method_handle_in_error()) {
2324 result = JVM_CONSTANT_MethodHandle;
2325 } else if (tag.is_dynamic_constant_in_error()) {
2326 result = JVM_CONSTANT_Dynamic;
2327 }
2328 return result;
2329 }
2330 JVM_END
2331
2332 // Assertion support. //////////////////////////////////////////////////////////
2333
2334 JVM_ENTRY(jboolean, JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls))
2335 JVMWrapper("JVM_DesiredAssertionStatus");
2336 assert(cls != NULL, "bad class");
2337
2338 oop r = JNIHandles::resolve(cls);
2339 assert(! java_lang_Class::is_primitive(r), "primitive classes not allowed");
2340 if (java_lang_Class::is_primitive(r)) return false;
2341
2342 Klass* k = java_lang_Class::as_Klass(r);
2343 assert(k->is_instance_klass(), "must be an instance klass");
2344 if (!k->is_instance_klass()) return false;
2345
2346 ResourceMark rm(THREAD);
2347 const char* name = k->name()->as_C_string();
2348 bool system_class = k->class_loader() == NULL;
2349 return JavaAssertions::enabled(name, system_class);
2350
2351 JVM_END
|
28 #include "classfile/classLoader.hpp"
29 #include "classfile/classLoaderData.inline.hpp"
30 #include "classfile/javaAssertions.hpp"
31 #include "classfile/javaClasses.inline.hpp"
32 #include "classfile/moduleEntry.hpp"
33 #include "classfile/modules.hpp"
34 #include "classfile/packageEntry.hpp"
35 #include "classfile/stringTable.hpp"
36 #include "classfile/systemDictionary.hpp"
37 #include "classfile/vmSymbols.hpp"
38 #include "gc/shared/collectedHeap.inline.hpp"
39 #include "interpreter/bytecode.hpp"
40 #include "jfr/jfrEvents.hpp"
41 #include "logging/log.hpp"
42 #include "memory/heapShared.hpp"
43 #include "memory/oopFactory.hpp"
44 #include "memory/referenceType.hpp"
45 #include "memory/resourceArea.hpp"
46 #include "memory/universe.hpp"
47 #include "oops/access.inline.hpp"
48 #include "oops/constantPool.inline.hpp"
49 #include "oops/fieldStreams.hpp"
50 #include "oops/instanceKlass.hpp"
51 #include "oops/method.hpp"
52 #include "oops/objArrayKlass.hpp"
53 #include "oops/objArrayOop.inline.hpp"
54 #include "oops/oop.inline.hpp"
55 #include "prims/jvm_misc.hpp"
56 #include "prims/jvmtiExport.hpp"
57 #include "prims/jvmtiThreadState.hpp"
58 #include "prims/nativeLookup.hpp"
59 #include "prims/privilegedStack.hpp"
60 #include "prims/stackwalk.hpp"
61 #include "runtime/arguments.hpp"
62 #include "runtime/atomic.hpp"
63 #include "runtime/handles.inline.hpp"
64 #include "runtime/init.hpp"
65 #include "runtime/interfaceSupport.inline.hpp"
66 #include "runtime/java.hpp"
67 #include "runtime/javaCalls.hpp"
68 #include "runtime/jfieldIDWorkaround.hpp"
1984 else {
1985 assert(host == ck, "must be singleton nest");
1986 }
1987 return (jobjectArray)JNIHandles::make_local(THREAD, result());
1988 }
1989 }
1990 JVM_END
1991
1992 // Constant pool access //////////////////////////////////////////////////////////
1993
1994 JVM_ENTRY(jobject, JVM_GetClassConstantPool(JNIEnv *env, jclass cls))
1995 {
1996 JVMWrapper("JVM_GetClassConstantPool");
1997 JvmtiVMObjectAllocEventCollector oam;
1998
1999 // Return null for primitives and arrays
2000 if (!java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {
2001 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
2002 if (k->is_instance_klass()) {
2003 InstanceKlass* k_h = InstanceKlass::cast(k);
2004 Handle jcp = reflect_ConstantPool::create_from_pool(k_h->constants(), CHECK_NULL);
2005 return JNIHandles::make_local(THREAD, jcp());
2006 }
2007 }
2008 return NULL;
2009 }
2010 JVM_END
2011
2012
2013 // The name "ConstantPool1" means the successor to the original JVM_ConstantPool* API.
2014 // That API had a confusing pair of arguments to specify the constant pool.
2015 // This API has a single normal 'this' argument.
2016
2017 JVM_ENTRY(jclass, JVM_ConstantPool1GetHolder(JNIEnv *env, jobject obj))
2018 {
2019 JVMWrapper("JVM_ConstantPoolGetHolder");
2020 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2021 return (jclass) JNIHandles::make_local(THREAD, cp->pool_holder()->java_mirror());
2022 }
2023 JVM_END
2024
2025
2026 JVM_ENTRY(jint, JVM_ConstantPool1GetSize(JNIEnv *env, jobject obj))
2027 {
2028 JVMWrapper("JVM_ConstantPoolGetSize");
2029 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2030 return cp->length();
2031 }
2032 JVM_END
2033
2034
2035 static jint ref_word_count_at_helper(constantPoolHandle cp, jint index) {
2036 if (!cp->is_within_bounds(index)) return 0;
2037 switch (cp->tag_at(index).classfile_value()) {
2038 case JVM_CONSTANT_Utf8:
2039 case JVM_CONSTANT_Class:
2040 case JVM_CONSTANT_String:
2041 case JVM_CONSTANT_MethodType:
2042 return 1;
2043
2044 case JVM_CONSTANT_Fieldref:
2045 case JVM_CONSTANT_Methodref:
2046 case JVM_CONSTANT_InterfaceMethodref:
2047 return 5; // { klass, nat, klass_sym, name_sym, type_sym }
2048
2049 case JVM_CONSTANT_NameAndType:
2050 return 2; // { name_sym, type_sym }
2051
2052 case JVM_CONSTANT_MethodHandle:
2053 return 2; // { ref_kind, ref_index }
2054
2055 case JVM_CONSTANT_InvokeDynamic:
2056 case JVM_CONSTANT_Dynamic:
2057 int word_count = 6; // { bsms_attr, nat, bsm, name_sym, type_sym, argc, arg* }
2058 word_count += cp->bootstrap_argument_count_at(index); // arg*
2059 return word_count;
2060 }
2061
2062 return 0;
2063 }
2064
2065 static void word_bounds_check(const constantPoolHandle& cp, jint index, jint word, jint word_count, TRAPS) {
2066 assert(word_count == ref_word_count_at_helper(cp, index), "");
2067 if (word < 0 || word >= word_count) {
2068 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Constant pool field request out of bounds");
2069 }
2070 }
2071
2072 static jint get_ref_index_at_helper(constantPoolHandle cp, jint index, jint word,
2073 jint* non_ref_word, TRAPS) {
2074 int ref_index = -1;
2075 int word_limit = 1;
2076 switch (cp->tag_at(index).classfile_value()) {
2077 case JVM_CONSTANT_Utf8:
2078 // A Utf8 string is its own reference index, but return zero
2079 // If you ask for the string itself, you'll see that string.
2080 ref_index = 0;
2081 break;
2082 case JVM_CONSTANT_Class:
2083 // Unwrap the Class and return the underlying name
2084 ref_index = cp->klass_name_index_at(index);
2085 break;
2086 case JVM_CONSTANT_String:
2087 // The CP does not record Utf8 indexes for strings, so just return zero.
2088 ref_index = 0;
2089 break;
2090
2091 case JVM_CONSTANT_Fieldref:
2092 case JVM_CONSTANT_Methodref:
2093 case JVM_CONSTANT_InterfaceMethodref:
2094 {
2095 // Unwrap the field or method to reveal three Utf8 strings.
2096 word_limit = 5;
2097 int klass_ref = cp->uncached_klass_ref_index_at(index);
2098 int nat_ref = cp->uncached_name_and_type_ref_index_at(index);
2099 switch (word) {
2100 case 0: return klass_ref;
2101 case 1: return nat_ref;
2102 // Flatten out the structure to reveal Utf8 references.
2103 case 2: return cp->klass_name_index_at(klass_ref);
2104 case 3: return cp->name_ref_index_at(nat_ref);
2105 case 4: return cp->signature_ref_index_at(nat_ref);
2106 }
2107 }
2108 ref_index = 0; // trigger the correct error
2109 break;
2110
2111 case JVM_CONSTANT_NameAndType:
2112 // Unwrap the NameAndType to reveal two Utf8 strings.
2113 {
2114 word_limit = 2;
2115 ref_index = (word == 0
2116 ? cp->name_ref_index_at(index)
2117 : cp->signature_ref_index_at(index));
2118 }
2119 break;
2120
2121 case JVM_CONSTANT_MethodType:
2122 // Unwrap the MethodType and return the underlying descriptor.
2123 ref_index = cp->method_type_index_at(index);
2124 break;
2125
2126 case JVM_CONSTANT_MethodHandle:
2127 // Unwrap the MH and return the member kind.
2128 if (word == 0) {
2129 int ref_kind = cp->method_handle_ref_kind_at(index);
2130 assert(ref_kind > 0 && ref_kind <= JVM_REF_invokeInterface, "");
2131 (*non_ref_word) = ref_kind;
2132 return 0;
2133 }
2134 ref_index = cp->method_handle_index_at(index);
2135 word_limit = 2;
2136 break;
2137
2138 case JVM_CONSTANT_InvokeDynamic:
2139 case JVM_CONSTANT_Dynamic:
2140 // Unwrap { bsms_attr, nat, bsm, name_sym, type_sym, argc, arg* }
2141 switch (word) {
2142 case 0: (*non_ref_word) = cp->bootstrap_methods_attribute_index(index); return 0;
2143 case 1: return cp->bootstrap_name_and_type_ref_index_at(index);
2144 case 2: return cp->bootstrap_method_ref_index_at(index);
2145 case 3: return cp->name_ref_index_at(cp->bootstrap_name_and_type_ref_index_at(index));
2146 case 4: return cp->signature_ref_index_at(cp->bootstrap_name_and_type_ref_index_at(index));
2147 case 5: (*non_ref_word) = cp->bootstrap_argument_count_at(index); return 0;
2148 }
2149 word_limit = 6 + cp->bootstrap_argument_count_at(index);
2150 if (word >= 0 && word < word_limit) {
2151 return cp->bootstrap_argument_index_at(index, word - 6);
2152 }
2153 ref_index = 0; // trigger the correct error
2154 break;
2155 }
2156
2157 // Perform final checks and return result.
2158 if (ref_index == -1) {
2159 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2160 }
2161 word_bounds_check(cp, index, word, word_limit, CHECK_0);
2162 return ref_index;
2163 }
2164
2165 static jint get_word_at_helper(constantPoolHandle cp, jint index, jint word, TRAPS) {
2166 jint non_ref_word = 0;
2167 jint ref_index = get_ref_index_at_helper(cp, index, word, &non_ref_word, CHECK_0);
2168 return (ref_index != 0) ? ref_index : non_ref_word;
2169 }
2170
2171 static jstring get_utf8_at_helper(constantPoolHandle cp, jint index, jint word, TRAPS) {
2172 Symbol* sym = NULL;
2173 if (cp->tag_at(index).is_symbol() && word == 0) {
2174 // Just report the Utf8 string that's here.
2175 sym = cp->symbol_at(index);
2176 } else if (cp->tag_at(index).is_string() && word == 0) {
2177 // Report the String, as a resolved value if possible.
2178 if (cp->resolved_references_or_null() != NULL
2179 && cp->cp_to_object_index(index) >= 0) {
2180 oop str = cp->resolved_string_at(index);
2181 if (java_lang_String::is_instance(str)) {
2182 // In this one case, return the actual interned string.
2183 return (jstring) JNIHandles::make_local(THREAD, str);
2184 }
2185 }
2186 sym = cp->unresolved_string_at(index);
2187 } else {
2188 jint ignore_non_ref_word = 0;
2189 jint ref_index = get_ref_index_at_helper(cp, index, word, &ignore_non_ref_word, CHECK_NULL);
2190 if (ref_index != 0 && !cp->tag_at(ref_index).is_symbol()) {
2191 return NULL; // there is a word here, but it is not a Utf8 index
2192 }
2193 sym = cp->symbol_at(ref_index);
2194 }
2195 // Build a java.lang.String to hold the Utf8 spelling.
2196 Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL);
2197 return (jstring) JNIHandles::make_local(THREAD, str());
2198 }
2199
2200
2201 static jobject get_method_at_helper(const constantPoolHandle& cp, jint index, bool force_resolution, TRAPS) {
2202 constantTag tag = cp->tag_at(index);
2203 if (!tag.is_method() && !tag.is_interface_method()) {
2204 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2205 }
2206 int klass_ref = cp->uncached_klass_ref_index_at(index);
2207 Klass* k_o;
2208 if (force_resolution) {
2209 k_o = cp->klass_at(klass_ref, CHECK_NULL);
2210 } else {
2211 k_o = ConstantPool::klass_at_if_loaded(cp, klass_ref);
2212 if (k_o == NULL) return NULL;
2213 }
2214 InstanceKlass* k = InstanceKlass::cast(k_o);
2215 Symbol* name = cp->uncached_name_ref_at(index);
2216 Symbol* sig = cp->uncached_signature_ref_at(index);
2217 methodHandle m (THREAD, k->find_method(name, sig));
2218 if (m.is_null()) {
2219 THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), "Unable to look up method in target class");
2220 }
2221 oop method;
2222 if (!m->is_initializer() || m->is_static()) {
2223 method = Reflection::new_method(m, true, CHECK_NULL);
2224 } else {
2225 method = Reflection::new_constructor(m, CHECK_NULL);
2226 }
2227 return JNIHandles::make_local(THREAD, method);
2228 }
2229
2230 static jobject get_field_at_helper(constantPoolHandle cp, jint index, bool force_resolution, TRAPS) {
2231 constantTag tag = cp->tag_at(index);
2232 if (!tag.is_field()) {
2233 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2234 }
2235 int klass_ref = cp->uncached_klass_ref_index_at(index);
2236 Klass* k_o;
2237 if (force_resolution) {
2238 k_o = cp->klass_at(klass_ref, CHECK_NULL);
2239 } else {
2240 k_o = ConstantPool::klass_at_if_loaded(cp, klass_ref);
2241 if (k_o == NULL) return NULL;
2242 }
2243 InstanceKlass* k = InstanceKlass::cast(k_o);
2244 Symbol* name = cp->uncached_name_ref_at(index);
2245 Symbol* sig = cp->uncached_signature_ref_at(index);
2246 fieldDescriptor fd;
2247 Klass* target_klass = k->find_field(name, sig, &fd);
2248 if (target_klass == NULL) {
2249 THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), "Unable to look up field in target class");
2250 }
2251 oop field = Reflection::new_field(&fd, CHECK_NULL);
2252 return JNIHandles::make_local(THREAD, field);
2253 }
2254
2255 // when get_ref is pointed at word#0 we just fetch the value:
2256 static jobject get_value_at_helper(constantPoolHandle cp, jint index,
2257 bool force_resolution, jobject if_not_present,
2258 TRAPS) {
2259 constantTag tag = cp->tag_at(index);
2260 jobject result = NULL;
2261 switch (tag.classfile_value()) {
2262 case JVM_CONSTANT_Utf8:
2263 case JVM_CONSTANT_String:
2264 return get_utf8_at_helper(cp, index, 0, CHECK_NULL);
2265
2266 case JVM_CONSTANT_Class:
2267 {
2268 if (!tag.is_klass() && !tag.is_unresolved_klass()) break;
2269 Klass* k = NULL;
2270 if (force_resolution) {
2271 k = cp->klass_at(index, CHECK_NULL);
2272 } else {
2273 k = ConstantPool::klass_at_if_loaded(cp, index);
2274 if (k == NULL) return if_not_present;
2275 }
2276 assert(k != NULL, "");
2277 return JNIHandles::make_local(THREAD, k->java_mirror());
2278 }
2279
2280 case JVM_CONSTANT_Integer:
2281 case JVM_CONSTANT_Long:
2282 case JVM_CONSTANT_Float:
2283 case JVM_CONSTANT_Double:
2284 case JVM_CONSTANT_MethodType:
2285 case JVM_CONSTANT_MethodHandle:
2286 case JVM_CONSTANT_Dynamic:
2287 //case JVM_CONSTANT_InvokeDynamic:
2288 {
2289 oop ref_oop = NULL;
2290 if (force_resolution) {
2291 ref_oop = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);
2292 } else {
2293 bool found_it = false;
2294 ref_oop = cp->find_cached_constant_at(index, found_it, CHECK_NULL);
2295 if (!found_it) return if_not_present;
2296 }
2297 return JNIHandles::make_local(THREAD, ref_oop);
2298 }
2299
2300 case JVM_CONSTANT_Methodref:
2301 case JVM_CONSTANT_InterfaceMethodref:
2302 result = get_method_at_helper(cp, index, force_resolution, CHECK_NULL);
2303 if (result == NULL) result = if_not_present;
2304 return result;
2305
2306 case JVM_CONSTANT_Fieldref:
2307 result = get_field_at_helper(cp, index, force_resolution, CHECK_NULL);
2308 if (result == NULL) result = if_not_present;
2309 return result;
2310
2311 case JVM_CONSTANT_NameAndType:
2312 // This one is lame. Just make up a 2-array of the component strings.
2313 {
2314 objArrayOop result_oop = oopFactory::new_objArray(SystemDictionary::String_klass(), 2, CHECK_NULL);
2315 objArrayHandle result(THREAD, result_oop);
2316 for (int word = 0; word < 2; word++) {
2317 int ignore_non_ref_word = 0;
2318 jobject ref = get_utf8_at_helper(cp, index, word, CHECK_NULL);
2319 result->obj_at_put(word, JNIHandles::resolve(ref));
2320 }
2321 return JNIHandles::make_local(THREAD, result());
2322 }
2323 }
2324
2325 return NULL;
2326 }
2327
2328
2329 // Extract an underlying reference object (or Utf8 string) for a CP entry
2330 // of type Class, Fieldref, [Interface]Methodref, [Invoke]Dynamic, etc.
2331 // If word is -1, extract the value of the CP entry itself.
2332 static jobject get_ref_at_helper(const constantPoolHandle& cp, jint index, jint word,
2333 bool force_resolution, jobject if_not_present,
2334 TRAPS) {
2335 if (word != -1) {
2336 jint non_ref_word = 0;
2337 jint ref_index = get_ref_index_at_helper(cp, index, word, &non_ref_word, CHECK_NULL);
2338 if (ref_index == 0) return NULL;
2339 index = ref_index; // and fall through:
2340 }
2341 return get_value_at_helper(cp, index, force_resolution, if_not_present, THREAD);
2342 }
2343
2344 JVM_ENTRY(jint, JVM_ConstantPool1GetWordCountAt(JNIEnv *env, jobject obj, jint index))
2345 {
2346 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2347 bounds_check(cp, index, CHECK_0);
2348 return ref_word_count_at_helper(cp, index);
2349 }
2350 JVM_END
2351
2352 JVM_ENTRY(jint, JVM_ConstantPool1GetWordAt(JNIEnv *env, jobject obj, jint index, jint word))
2353 {
2354 JVMWrapper("JVM_ConstantPoolGetWordAt");
2355 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2356 bounds_check(cp, index, CHECK_0);
2357 return get_word_at_helper(cp, index, word, CHECK_0);
2358 }
2359 JVM_END
2360
2361 JVM_ENTRY(jobject, JVM_ConstantPool1GetRefAt(JNIEnv *env, jobject obj, jint index, jint word,
2362 jbyte resolving, jobject if_not_present))
2363 {
2364 JVMWrapper("JVM_ConstantPoolGetRefAt");
2365 JvmtiVMObjectAllocEventCollector oam;
2366 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2367 bounds_check(cp, index, CHECK_NULL);
2368 switch (resolving) {
2369 case ConstantPool::R_SYMREF:
2370 // Caller must handle symbolic refs other than Utf8.
2371 return get_utf8_at_helper(cp, index, word, THREAD);
2372 case ConstantPool::R_FORCE:
2373 return get_ref_at_helper(cp, index, word, true, NULL, THREAD);
2374 case ConstantPool::R_IFPRESENT:
2375 return get_ref_at_helper(cp, index, word, false, if_not_present, THREAD);
2376 }
2377 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "resolving mode must be 0, 1, or 2");
2378 return NULL;
2379 }
2380 JVM_END
2381
2382
2383 JVM_ENTRY(void, JVM_ConstantPool1CopyOutRefsAt(JNIEnv *env, jobject obj, jint index, jint start_word, jint end_word,
2384 jobject buf_jobject, jint buf_pos, jbyte resolving,
2385 jobject if_not_present, jobject if_null_constant, jboolean skip_non_null))
2386 {
2387 JVMWrapper("JVM_ConstantPoolCopyOutRefsAt");
2388 JvmtiVMObjectAllocEventCollector oam;
2389 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2390 bounds_check(cp, index, CHECK);
2391 objArrayHandle obj_buf; // set to buf if type Object[]
2392 typeArrayHandle int_buf; // set to buf if type int[]
2393 bool force_resolution = (resolving == ConstantPool::R_FORCE);
2394 jint buf_len = 0;
2395 if (buf_jobject != NULL) {
2396 oop buf = JNIHandles::resolve_non_null(buf_jobject);
2397 switch (resolving) {
2398 case ConstantPool::R_IFPRESENT: // mode = do not resolve new values
2399 case ConstantPool::R_FORCE: // mode = resolve any requested values (cf. skip_non_null)
2400 if (buf->klass() == Universe::objectArrayKlassObj())
2401 obj_buf = objArrayHandle(THREAD, (objArrayOop) buf);
2402 break;
2403 case ConstantPool::R_SYMREF: // mode = return only CP indexes (symbolic refs)
2404 if (buf->klass() == Universe::intArrayKlassObj())
2405 int_buf = typeArrayHandle(THREAD, (typeArrayOop) buf);
2406 break;
2407 default:
2408 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "resolving mode must be 0, 1, or 2");
2409 }
2410 if (obj_buf.not_null())
2411 buf_len = obj_buf->length();
2412 else if (int_buf.not_null())
2413 buf_len = int_buf->length();
2414 }
2415 jint word_limit = ref_word_count_at_helper(cp, index);
2416 jint word_count = (end_word - start_word);
2417 if ((obj_buf.is_null() && int_buf.is_null()) ||
2418 0 > start_word || start_word > end_word || end_word > word_limit ||
2419 0 > buf_pos || buf_pos + word_count > buf_len) {
2420 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "bad buffer index");
2421 }
2422 if (int_buf.not_null()) {
2423 for (int word = start_word; word < end_word; word++) {
2424 int result = get_word_at_helper(cp, index, word, CHECK);
2425 int_buf->int_at_put(buf_pos++, result);
2426 }
2427 } else {
2428 for (int word = start_word; word < end_word; word++) {
2429 if (skip_non_null && obj_buf->obj_at(buf_pos) != NULL) {
2430 ++buf_pos; continue;
2431 }
2432 jobject sentinel = obj; // safely unique: pool doesn't contain itself
2433 jobject result = get_ref_at_helper(cp, index, word, force_resolution, sentinel, CHECK);
2434 if (result == sentinel)
2435 result = if_not_present;
2436 else if (result == NULL) // note that if_not_present might also be NULL
2437 result = if_null_constant;
2438 obj_buf->obj_at_put(buf_pos++, JNIHandles::resolve(result));
2439 }
2440 }
2441 }
2442 JVM_END
2443
2444
2445 JVM_ENTRY(jint, JVM_ConstantPool1GetIntAt(JNIEnv *env, jobject obj, jint index))
2446 {
2447 JVMWrapper("JVM_ConstantPoolGetIntAt");
2448 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2449 bounds_check(cp, index, CHECK_0);
2450 constantTag tag = cp->tag_at(index);
2451 if (!tag.is_int()) {
2452 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2453 }
2454 return cp->int_at(index);
2455 }
2456 JVM_END
2457
2458 JVM_ENTRY(jlong, JVM_ConstantPool1GetLongAt(JNIEnv *env, jobject obj, jint index))
2459 {
2460 JVMWrapper("JVM_ConstantPoolGetLongAt");
2461 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2462 bounds_check(cp, index, CHECK_(0L));
2463 constantTag tag = cp->tag_at(index);
2464 if (!tag.is_long()) {
2465 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2466 }
2467 return cp->long_at(index);
2468 }
2469 JVM_END
2470
2471 JVM_ENTRY(jfloat, JVM_ConstantPool1GetFloatAt(JNIEnv *env, jobject obj, jint index))
2472 {
2473 JVMWrapper("JVM_ConstantPoolGetFloatAt");
2474 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2475 bounds_check(cp, index, CHECK_(0.0f));
2476 constantTag tag = cp->tag_at(index);
2477 if (!tag.is_float()) {
2478 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2479 }
2480 return cp->float_at(index);
2481 }
2482 JVM_END
2483
2484 JVM_ENTRY(jdouble, JVM_ConstantPool1GetDoubleAt(JNIEnv *env, jobject obj, jint index))
2485 {
2486 JVMWrapper("JVM_ConstantPoolGetDoubleAt");
2487 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2488 bounds_check(cp, index, CHECK_(0.0));
2489 constantTag tag = cp->tag_at(index);
2490 if (!tag.is_double()) {
2491 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
2492 }
2493 return cp->double_at(index);
2494 }
2495 JVM_END
2496
2497 JVM_ENTRY(jbyte, JVM_ConstantPool1GetTagAt(JNIEnv *env, jobject obj, jint index))
2498 {
2499 JVMWrapper("JVM_ConstantPoolGetTagAt");
2500 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2501 bounds_check(cp, index, CHECK_0);
2502 constantTag tag = cp->tag_at(index);
2503 // If returned tag values are not from the JVM spec, e.g. tags from 100 to 105,
2504 // they are changed to the corresponding tags from the JVM spec, so that java code in
2505 // sun.reflect.ConstantPool will return only tags from the JVM spec, not internal ones.
2506 return tag.classfile_value();
2507 }
2508 JVM_END
2509
2510
2511 JVM_ENTRY(jbyteArray, JVM_ConstantPool1GetTags(JNIEnv *env, jobject obj))
2512 {
2513 JVMWrapper("JVM_ConstantPoolGetTags");
2514 constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
2515 jint length = cp->length();
2516 typeArrayOop result_oop = oopFactory::new_typeArray(T_BYTE, length, CHECK_NULL);
2517 for (jint index = 0; index < length; index++) {
2518 result_oop->byte_at_put(index, cp->tag_at(index).classfile_value());
2519 }
2520 return (jbyteArray) JNIHandles::make_local(THREAD, result_oop);
2521 }
2522 JVM_END
2523
2524
2525 // Assertion support. //////////////////////////////////////////////////////////
2526
2527 JVM_ENTRY(jboolean, JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls))
2528 JVMWrapper("JVM_DesiredAssertionStatus");
2529 assert(cls != NULL, "bad class");
2530
2531 oop r = JNIHandles::resolve(cls);
2532 assert(! java_lang_Class::is_primitive(r), "primitive classes not allowed");
2533 if (java_lang_Class::is_primitive(r)) return false;
2534
2535 Klass* k = java_lang_Class::as_Klass(r);
2536 assert(k->is_instance_klass(), "must be an instance klass");
2537 if (!k->is_instance_klass()) return false;
2538
2539 ResourceMark rm(THREAD);
2540 const char* name = k->name()->as_C_string();
2541 bool system_class = k->class_loader() == NULL;
2542 return JavaAssertions::enabled(name, system_class);
2543
2544 JVM_END
|