< prev index next >

src/hotspot/share/prims/jvm.cpp

Print this page
rev 52749 : Bootstrap method consolidation
* clean up and simplify JDK support code for BSM invocation
* simplify JVM bootstrap handshake: use BootstrapCallInfo only
* remove unused JVM paths and data fields
* move bootstrap argument processing from MethodHandleNatives to ConstantPool
* remove ConstantGroup; merge argument access into BootstrapCallInfo
* adjust BSM argument access: remove copyArguments, add argumentRef API
* add metadata-free BSM modes, including symbolic arguments from CP


  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


< prev index next >