< prev index next >

src/hotspot/share/prims/jni.cpp

Print this page

  38 #include "classfile/symbolTable.hpp"
  39 #include "classfile/systemDictionary.hpp"
  40 #include "classfile/vmClasses.hpp"
  41 #include "classfile/vmSymbols.hpp"
  42 #include "compiler/compiler_globals.hpp"
  43 #include "gc/shared/collectedHeap.hpp"
  44 #include "gc/shared/gcLocker.inline.hpp"
  45 #include "gc/shared/stringdedup/stringDedup.hpp"
  46 #include "interpreter/linkResolver.hpp"
  47 #include "jni.h"
  48 #include "jvm.h"
  49 #include "logging/log.hpp"
  50 #include "memory/allocation.hpp"
  51 #include "memory/allocation.inline.hpp"
  52 #include "memory/oopFactory.hpp"
  53 #include "memory/resourceArea.hpp"
  54 #include "memory/universe.hpp"
  55 #include "nmt/memTracker.hpp"
  56 #include "oops/access.inline.hpp"
  57 #include "oops/arrayOop.hpp"


  58 #include "oops/instanceKlass.inline.hpp"
  59 #include "oops/instanceOop.hpp"
  60 #include "oops/klass.inline.hpp"
  61 #include "oops/markWord.hpp"
  62 #include "oops/method.hpp"
  63 #include "oops/objArrayKlass.hpp"
  64 #include "oops/objArrayOop.inline.hpp"
  65 #include "oops/oop.inline.hpp"
  66 #include "oops/symbol.hpp"
  67 #include "oops/typeArrayKlass.hpp"
  68 #include "oops/typeArrayOop.inline.hpp"
  69 #include "prims/jniCheck.hpp"
  70 #include "prims/jniExport.hpp"
  71 #include "prims/jniFastGetField.hpp"
  72 #include "prims/jvm_misc.hpp"
  73 #include "prims/jvmtiExport.hpp"
  74 #include "prims/jvmtiThreadState.hpp"
  75 #include "runtime/arguments.hpp"
  76 #include "runtime/atomic.hpp"
  77 #include "runtime/fieldDescriptor.inline.hpp"

 409   int modifiers   = java_lang_reflect_Field::modifiers(reflected);
 410 
 411   // Make sure class is initialized before handing id's out to fields
 412   k1->initialize(CHECK_NULL);
 413 
 414   // First check if this is a static field
 415   if (modifiers & JVM_ACC_STATIC) {
 416     int offset = InstanceKlass::cast(k1)->field_offset( slot );
 417     JNIid* id = InstanceKlass::cast(k1)->jni_id_for(offset);
 418     assert(id != nullptr, "corrupt Field object");
 419     debug_only(id->set_is_static_field_id();)
 420     // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
 421     ret = jfieldIDWorkaround::to_static_jfieldID(id);
 422     return ret;
 423   }
 424 
 425   // The slot is the index of the field description in the field-array
 426   // The jfieldID is the offset of the field within the object
 427   // It may also have hash bits for k, if VerifyJNIFields is turned on.
 428   int offset = InstanceKlass::cast(k1)->field_offset( slot );

 429   assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object");
 430   ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset);
 431   return ret;
 432 JNI_END
 433 
 434 
 435 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
 436                     , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
 437 
 438 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
 439   HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(env, cls, (uintptr_t) method_id, isStatic);
 440 
 441   jobject ret = nullptr;
 442   DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
 443 
 444   methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
 445   assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
 446   oop reflection_method;
 447   if (m->is_initializer()) {
 448     reflection_method = Reflection::new_constructor(m, CHECK_NULL);
 449   } else {
 450     reflection_method = Reflection::new_method(m, false, CHECK_NULL);
 451   }
 452   ret = JNIHandles::make_local(THREAD, reflection_method);
 453   return ret;
 454 JNI_END
 455 
 456 DT_RETURN_MARK_DECL(GetSuperclass, jclass
 457                     , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));
 458 
 459 JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
 460   HOTSPOT_JNI_GETSUPERCLASS_ENTRY(env, sub);
 461 
 462   jclass obj = nullptr;
 463   DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
 464 
 465   oop mirror = JNIHandles::resolve_non_null(sub);
 466   // primitive classes return null
 467   if (java_lang_Class::is_primitive(mirror)) return nullptr;

 785   }
 786 
 787   friend class SignatureIterator;  // so do_parameters_on can call do_type
 788   void do_type(BasicType type) {
 789     switch (type) {
 790     // these are coerced to int when using va_arg
 791     case T_BYTE:
 792     case T_CHAR:
 793     case T_SHORT:
 794     case T_INT:         push_int(va_arg(_ap, jint)); break;
 795     case T_BOOLEAN:     push_boolean((jboolean) va_arg(_ap, jint)); break;
 796 
 797     // each of these paths is exercised by the various jck Call[Static,Nonvirtual,][Void,Int,..]Method[A,V,] tests
 798 
 799     case T_LONG:        push_long(va_arg(_ap, jlong)); break;
 800     // float is coerced to double w/ va_arg
 801     case T_FLOAT:       push_float((jfloat) va_arg(_ap, jdouble)); break;
 802     case T_DOUBLE:      push_double(va_arg(_ap, jdouble)); break;
 803 
 804     case T_ARRAY:
 805     case T_OBJECT:      push_object(va_arg(_ap, jobject)); break;
 806     default:            ShouldNotReachHere();
 807     }
 808   }
 809 
 810  public:
 811   JNI_ArgumentPusherVaArg(jmethodID method_id, va_list rap)
 812       : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)) {
 813     set_ap(rap);
 814   }
 815 
 816   ~JNI_ArgumentPusherVaArg() {
 817     va_end(_ap);
 818   }
 819 
 820   virtual void push_arguments_on(JavaCallArguments* arguments) {
 821     _arguments = arguments;
 822     do_parameters_on(this);
 823   }
 824 };
 825 
 826 
 827 class JNI_ArgumentPusherArray : public JNI_ArgumentPusher {
 828  protected:
 829   const jvalue *_ap;
 830 
 831   inline void set_ap(const jvalue *rap) { _ap = rap; }
 832 
 833   friend class SignatureIterator;  // so do_parameters_on can call do_type
 834   void do_type(BasicType type) {
 835     switch (type) {
 836     case T_CHAR:        push_int((_ap++)->c); break;
 837     case T_SHORT:       push_int((_ap++)->s); break;
 838     case T_BYTE:        push_int((_ap++)->b); break;
 839     case T_INT:         push_int((_ap++)->i); break;
 840     case T_BOOLEAN:     push_boolean((_ap++)->z); break;
 841     case T_LONG:        push_long((_ap++)->j); break;
 842     case T_FLOAT:       push_float((_ap++)->f); break;
 843     case T_DOUBLE:      push_double((_ap++)->d); break;
 844     case T_ARRAY:
 845     case T_OBJECT:      push_object((_ap++)->l); break;

 846     default:            ShouldNotReachHere();
 847     }
 848   }
 849 
 850  public:
 851   JNI_ArgumentPusherArray(jmethodID method_id, const jvalue *rap)
 852       : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)) {
 853     set_ap(rap);
 854   }
 855 
 856   virtual void push_arguments_on(JavaCallArguments* arguments) {
 857     _arguments = arguments;
 858     do_parameters_on(this);
 859   }
 860 };
 861 
 862 
 863 enum JNICallType {
 864   JNI_STATIC,
 865   JNI_VIRTUAL,

 952   result->set_type(args->return_type());
 953 
 954   // Invoke the method. Result is returned as oop.
 955   JavaCalls::call(result, method, &java_args, CHECK);
 956 
 957   // Convert result
 958   if (is_reference_type(result->get_type())) {
 959     result->set_jobject(JNIHandles::make_local(THREAD, result->get_oop()));
 960   }
 961 }
 962 
 963 DT_RETURN_MARK_DECL(AllocObject, jobject
 964                     , HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref));
 965 
 966 JNI_ENTRY(jobject, jni_AllocObject(JNIEnv *env, jclass clazz))
 967   HOTSPOT_JNI_ALLOCOBJECT_ENTRY(env, clazz);
 968 
 969   jobject ret = nullptr;
 970   DT_RETURN_MARK(AllocObject, jobject, (const jobject&)ret);
 971 
 972   instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);






 973   ret = JNIHandles::make_local(THREAD, i);
 974   return ret;
 975 JNI_END
 976 
 977 DT_RETURN_MARK_DECL(NewObjectA, jobject
 978                     , HOTSPOT_JNI_NEWOBJECTA_RETURN(_ret_ref));
 979 
 980 JNI_ENTRY(jobject, jni_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args))
 981   HOTSPOT_JNI_NEWOBJECTA_ENTRY(env, clazz, (uintptr_t) methodID);
 982 
 983   jobject obj = nullptr;
 984   DT_RETURN_MARK(NewObjectA, jobject, (const jobject&)obj);
 985 
 986   instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);







 987   obj = JNIHandles::make_local(THREAD, i);
 988   JavaValue jvalue(T_VOID);
 989   JNI_ArgumentPusherArray ap(methodID, args);
 990   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);

 991   return obj;
 992 JNI_END
 993 
 994 
 995 DT_RETURN_MARK_DECL(NewObjectV, jobject
 996                     , HOTSPOT_JNI_NEWOBJECTV_RETURN(_ret_ref));
 997 
 998 JNI_ENTRY(jobject, jni_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args))
 999   HOTSPOT_JNI_NEWOBJECTV_ENTRY(env, clazz, (uintptr_t) methodID);
1000 
1001   jobject obj = nullptr;
1002   DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj);
1003 
1004   instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);







1005   obj = JNIHandles::make_local(THREAD, i);
1006   JavaValue jvalue(T_VOID);
1007   JNI_ArgumentPusherVaArg ap(methodID, args);
1008   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);

1009   return obj;
1010 JNI_END
1011 
1012 
1013 DT_RETURN_MARK_DECL(NewObject, jobject
1014                     , HOTSPOT_JNI_NEWOBJECT_RETURN(_ret_ref));
1015 
1016 JNI_ENTRY(jobject, jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...))
1017   HOTSPOT_JNI_NEWOBJECT_ENTRY(env, clazz, (uintptr_t) methodID);
1018 
1019   jobject obj = nullptr;
1020   DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj);
1021 
1022   instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);







1023   obj = JNIHandles::make_local(THREAD, i);
1024   va_list args;
1025   va_start(args, methodID);
1026   JavaValue jvalue(T_VOID);
1027   JNI_ArgumentPusherVaArg ap(methodID, args);
1028   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1029   va_end(args);

1030   return obj;
1031 JNI_END
1032 
1033 
1034 JNI_ENTRY(jclass, jni_GetObjectClass(JNIEnv *env, jobject obj))
1035   HOTSPOT_JNI_GETOBJECTCLASS_ENTRY(env, obj);
1036 
1037   Klass* k = JNIHandles::resolve_non_null(obj)->klass();
1038   jclass ret =
1039     (jclass) JNIHandles::make_local(THREAD, k->java_mirror());
1040 
1041   HOTSPOT_JNI_GETOBJECTCLASS_RETURN(ret);
1042   return ret;
1043 JNI_END
1044 
1045 JNI_ENTRY_NO_PRESERVE(jboolean, jni_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz))
1046   HOTSPOT_JNI_ISINSTANCEOF_ENTRY(env, obj, clazz);
1047 
1048   jboolean ret = JNI_TRUE;
1049   if (obj != nullptr) {

1760   // table.  If they're not there, the field doesn't exist.
1761   TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
1762   TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
1763   if (fieldname == nullptr || signame == nullptr) {
1764     ResourceMark rm;
1765     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
1766   }
1767 
1768   // Make sure class is initialized before handing id's out to fields
1769   k->initialize(CHECK_NULL);
1770 
1771   fieldDescriptor fd;
1772   if (!k->is_instance_klass() ||
1773       !InstanceKlass::cast(k)->find_field(fieldname, signame, false, &fd)) {
1774     ResourceMark rm;
1775     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
1776   }
1777 
1778   // A jfieldID for a non-static field is simply the offset of the field within the instanceOop
1779   // It may also have hash bits for k, if VerifyJNIFields is turned on.
1780   ret = jfieldIDWorkaround::to_instance_jfieldID(k, fd.offset());
1781   return ret;
1782 JNI_END
1783 
1784 
1785 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
1786   HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID);
1787   oop o = JNIHandles::resolve_non_null(obj);
1788   Klass* k = o->klass();
1789   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);

1790   // Keep JVMTI addition small and only check enabled flag here.
1791   // jni_GetField_probe() assumes that is okay to create handles.
1792   if (JvmtiExport::should_post_field_access()) {
1793     o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
1794   }
1795   oop loaded_obj = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(o, offset);
1796   jobject ret = JNIHandles::make_local(THREAD, loaded_obj);










1797   HOTSPOT_JNI_GETOBJECTFIELD_RETURN(ret);
1798   return ret;
1799 JNI_END
1800 
1801 
1802 
1803 #define DEFINE_GETFIELD(Return,Fieldname,Result \
1804   , EntryProbe, ReturnProbe) \
1805 \
1806   DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return \
1807   , ReturnProbe); \
1808 \
1809 JNI_ENTRY_NO_PRESERVE(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \
1810 \
1811   EntryProbe; \
1812   Return ret = 0;\
1813   DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\
1814 \
1815   oop o = JNIHandles::resolve_non_null(obj); \
1816   Klass* k = o->klass(); \

1868   return (address)jni_GetLongField;
1869 }
1870 address jni_GetFloatField_addr() {
1871   return (address)jni_GetFloatField;
1872 }
1873 address jni_GetDoubleField_addr() {
1874   return (address)jni_GetDoubleField;
1875 }
1876 
1877 JNI_ENTRY_NO_PRESERVE(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
1878   HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID, value);
1879   oop o = JNIHandles::resolve_non_null(obj);
1880   Klass* k = o->klass();
1881   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
1882   // Keep JVMTI addition small and only check enabled flag here.
1883   if (JvmtiExport::should_post_field_modification()) {
1884     jvalue field_value;
1885     field_value.l = value;
1886     o = JvmtiExport::jni_SetField_probe(thread, obj, o, k, fieldID, false, JVM_SIGNATURE_CLASS, (jvalue *)&field_value);
1887   }
1888   HeapAccess<ON_UNKNOWN_OOP_REF>::oop_store_at(o, offset, JNIHandles::resolve(value));











1889   HOTSPOT_JNI_SETOBJECTFIELD_RETURN();
1890 JNI_END
1891 
1892 // TODO: make this a template
1893 
1894 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
1895                         , EntryProbe, ReturnProbe) \
1896 \
1897 JNI_ENTRY_NO_PRESERVE(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
1898 \
1899   EntryProbe; \
1900 \
1901   oop o = JNIHandles::resolve_non_null(obj); \
1902   Klass* k = o->klass(); \
1903   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
1904   /* Keep JVMTI addition small and only check enabled flag here.       */ \
1905   if (JvmtiExport::should_post_field_modification()) { \
1906     jvalue field_value; \
1907     field_value.unionType = value; \
1908     o = JvmtiExport::jni_SetField_probe(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \

2284   Klass* ak = ek->array_klass(CHECK_NULL);
2285   ObjArrayKlass::cast(ak)->initialize(CHECK_NULL);
2286   objArrayOop result = ObjArrayKlass::cast(ak)->allocate(length, CHECK_NULL);
2287   oop initial_value = JNIHandles::resolve(initialElement);
2288   if (initial_value != nullptr) {  // array already initialized with null
2289     for (int index = 0; index < length; index++) {
2290       result->obj_at_put(index, initial_value);
2291     }
2292   }
2293   ret = (jobjectArray) JNIHandles::make_local(THREAD, result);
2294   return ret;
2295 JNI_END
2296 
2297 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
2298                     , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
2299 
2300 JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
2301  HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(env, array, index);
2302   jobject ret = nullptr;
2303   DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
2304   objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2305   if (a->is_within_bounds(index)) {
2306     ret = JNIHandles::make_local(THREAD, a->obj_at(index));
2307     return ret;









2308   } else {
2309     ResourceMark rm(THREAD);
2310     stringStream ss;
2311     ss.print("Index %d out of bounds for length %d", index, a->length());
2312     THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2313   }


2314 JNI_END
2315 
2316 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
2317                          , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
2318 
2319 JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
2320  HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(env, array, index, value);
2321   DT_VOID_RETURN_MARK(SetObjectArrayElement);
2322 
2323   objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2324   oop v = JNIHandles::resolve(value);
2325   if (a->is_within_bounds(index)) {
2326     if (v == nullptr || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) {
2327       a->obj_at_put(index, v);
2328     } else {
2329       ResourceMark rm(THREAD);
2330       stringStream ss;
2331       Klass *bottom_kl = ObjArrayKlass::cast(a->klass())->bottom_klass();
2332       ss.print("type mismatch: can not store %s to %s[%d]",
2333                v->klass()->external_name(),
2334                bottom_kl->is_typeArray_klass() ? type2name_tab[ArrayKlass::cast(bottom_kl)->element_type()] : bottom_kl->external_name(),
2335                index);
2336       for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
2337         ss.print("[]");
2338       }
2339       THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
2340     }
2341   } else {
2342     ResourceMark rm(THREAD);
2343     stringStream ss;
2344     ss.print("Index %d out of bounds for length %d", index, a->length());
2345     THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2346   }



























2347 JNI_END
2348 
2349 
2350 
2351 #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result \
2352                               ,EntryProbe,ReturnProbe)  \
2353 \
2354   DT_RETURN_MARK_DECL(New##Result##Array, Return \
2355                       , ReturnProbe); \
2356 \
2357 JNI_ENTRY(Return, \
2358           jni_New##Result##Array(JNIEnv *env, jsize len)) \
2359   EntryProbe; \
2360   Return ret = nullptr;\
2361   DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
2362 \
2363   oop obj= oopFactory::Allocator(len, CHECK_NULL); \
2364   ret = (Return) JNIHandles::make_local(THREAD, obj); \
2365   return ret;\
2366 JNI_END

  38 #include "classfile/symbolTable.hpp"
  39 #include "classfile/systemDictionary.hpp"
  40 #include "classfile/vmClasses.hpp"
  41 #include "classfile/vmSymbols.hpp"
  42 #include "compiler/compiler_globals.hpp"
  43 #include "gc/shared/collectedHeap.hpp"
  44 #include "gc/shared/gcLocker.inline.hpp"
  45 #include "gc/shared/stringdedup/stringDedup.hpp"
  46 #include "interpreter/linkResolver.hpp"
  47 #include "jni.h"
  48 #include "jvm.h"
  49 #include "logging/log.hpp"
  50 #include "memory/allocation.hpp"
  51 #include "memory/allocation.inline.hpp"
  52 #include "memory/oopFactory.hpp"
  53 #include "memory/resourceArea.hpp"
  54 #include "memory/universe.hpp"
  55 #include "nmt/memTracker.hpp"
  56 #include "oops/access.inline.hpp"
  57 #include "oops/arrayOop.hpp"
  58 #include "oops/flatArrayOop.inline.hpp"
  59 #include "oops/inlineKlass.inline.hpp"
  60 #include "oops/instanceKlass.inline.hpp"
  61 #include "oops/instanceOop.hpp"
  62 #include "oops/klass.inline.hpp"
  63 #include "oops/markWord.hpp"
  64 #include "oops/method.hpp"
  65 #include "oops/objArrayKlass.hpp"
  66 #include "oops/objArrayOop.inline.hpp"
  67 #include "oops/oop.inline.hpp"
  68 #include "oops/symbol.hpp"
  69 #include "oops/typeArrayKlass.hpp"
  70 #include "oops/typeArrayOop.inline.hpp"
  71 #include "prims/jniCheck.hpp"
  72 #include "prims/jniExport.hpp"
  73 #include "prims/jniFastGetField.hpp"
  74 #include "prims/jvm_misc.hpp"
  75 #include "prims/jvmtiExport.hpp"
  76 #include "prims/jvmtiThreadState.hpp"
  77 #include "runtime/arguments.hpp"
  78 #include "runtime/atomic.hpp"
  79 #include "runtime/fieldDescriptor.inline.hpp"

 411   int modifiers   = java_lang_reflect_Field::modifiers(reflected);
 412 
 413   // Make sure class is initialized before handing id's out to fields
 414   k1->initialize(CHECK_NULL);
 415 
 416   // First check if this is a static field
 417   if (modifiers & JVM_ACC_STATIC) {
 418     int offset = InstanceKlass::cast(k1)->field_offset( slot );
 419     JNIid* id = InstanceKlass::cast(k1)->jni_id_for(offset);
 420     assert(id != nullptr, "corrupt Field object");
 421     debug_only(id->set_is_static_field_id();)
 422     // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
 423     ret = jfieldIDWorkaround::to_static_jfieldID(id);
 424     return ret;
 425   }
 426 
 427   // The slot is the index of the field description in the field-array
 428   // The jfieldID is the offset of the field within the object
 429   // It may also have hash bits for k, if VerifyJNIFields is turned on.
 430   int offset = InstanceKlass::cast(k1)->field_offset( slot );
 431   bool is_flat = InstanceKlass::cast(k1)->field_is_flat(slot);
 432   assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object");
 433   ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset, is_flat);
 434   return ret;
 435 JNI_END
 436 
 437 
 438 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
 439                     , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
 440 
 441 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
 442   HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(env, cls, (uintptr_t) method_id, isStatic);
 443 
 444   jobject ret = nullptr;
 445   DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
 446 
 447   methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
 448   assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
 449   oop reflection_method;
 450   if (m->is_object_constructor()) {
 451     reflection_method = Reflection::new_constructor(m, CHECK_NULL);
 452   } else {
 453     reflection_method = Reflection::new_method(m, false, CHECK_NULL);
 454   }
 455   ret = JNIHandles::make_local(THREAD, reflection_method);
 456   return ret;
 457 JNI_END
 458 
 459 DT_RETURN_MARK_DECL(GetSuperclass, jclass
 460                     , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));
 461 
 462 JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
 463   HOTSPOT_JNI_GETSUPERCLASS_ENTRY(env, sub);
 464 
 465   jclass obj = nullptr;
 466   DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
 467 
 468   oop mirror = JNIHandles::resolve_non_null(sub);
 469   // primitive classes return null
 470   if (java_lang_Class::is_primitive(mirror)) return nullptr;

 788   }
 789 
 790   friend class SignatureIterator;  // so do_parameters_on can call do_type
 791   void do_type(BasicType type) {
 792     switch (type) {
 793     // these are coerced to int when using va_arg
 794     case T_BYTE:
 795     case T_CHAR:
 796     case T_SHORT:
 797     case T_INT:         push_int(va_arg(_ap, jint)); break;
 798     case T_BOOLEAN:     push_boolean((jboolean) va_arg(_ap, jint)); break;
 799 
 800     // each of these paths is exercised by the various jck Call[Static,Nonvirtual,][Void,Int,..]Method[A,V,] tests
 801 
 802     case T_LONG:        push_long(va_arg(_ap, jlong)); break;
 803     // float is coerced to double w/ va_arg
 804     case T_FLOAT:       push_float((jfloat) va_arg(_ap, jdouble)); break;
 805     case T_DOUBLE:      push_double(va_arg(_ap, jdouble)); break;
 806 
 807     case T_ARRAY:
 808     case T_OBJECT: push_object(va_arg(_ap, jobject)); break;
 809     default:            ShouldNotReachHere();
 810     }
 811   }
 812 
 813  public:
 814   JNI_ArgumentPusherVaArg(jmethodID method_id, va_list rap)
 815       : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)) {
 816     set_ap(rap);
 817   }
 818 
 819   ~JNI_ArgumentPusherVaArg() {
 820     va_end(_ap);
 821   }
 822 
 823   virtual void push_arguments_on(JavaCallArguments* arguments) {
 824     _arguments = arguments;
 825     do_parameters_on(this);
 826   }
 827 };
 828 
 829 
 830 class JNI_ArgumentPusherArray : public JNI_ArgumentPusher {
 831  protected:
 832   const jvalue *_ap;
 833 
 834   inline void set_ap(const jvalue *rap) { _ap = rap; }
 835 
 836   friend class SignatureIterator;  // so do_parameters_on can call do_type
 837   void do_type(BasicType type) {
 838     switch (type) {
 839     case T_CHAR:        push_int((_ap++)->c); break;
 840     case T_SHORT:       push_int((_ap++)->s); break;
 841     case T_BYTE:        push_int((_ap++)->b); break;
 842     case T_INT:         push_int((_ap++)->i); break;
 843     case T_BOOLEAN:     push_boolean((_ap++)->z); break;
 844     case T_LONG:        push_long((_ap++)->j); break;
 845     case T_FLOAT:       push_float((_ap++)->f); break;
 846     case T_DOUBLE:      push_double((_ap++)->d); break;
 847     case T_ARRAY:
 848     case T_OBJECT:
 849     case T_PRIMITIVE_OBJECT: push_object((_ap++)->l); break;
 850     default:            ShouldNotReachHere();
 851     }
 852   }
 853 
 854  public:
 855   JNI_ArgumentPusherArray(jmethodID method_id, const jvalue *rap)
 856       : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)) {
 857     set_ap(rap);
 858   }
 859 
 860   virtual void push_arguments_on(JavaCallArguments* arguments) {
 861     _arguments = arguments;
 862     do_parameters_on(this);
 863   }
 864 };
 865 
 866 
 867 enum JNICallType {
 868   JNI_STATIC,
 869   JNI_VIRTUAL,

 956   result->set_type(args->return_type());
 957 
 958   // Invoke the method. Result is returned as oop.
 959   JavaCalls::call(result, method, &java_args, CHECK);
 960 
 961   // Convert result
 962   if (is_reference_type(result->get_type())) {
 963     result->set_jobject(JNIHandles::make_local(THREAD, result->get_oop()));
 964   }
 965 }
 966 
 967 DT_RETURN_MARK_DECL(AllocObject, jobject
 968                     , HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref));
 969 
 970 JNI_ENTRY(jobject, jni_AllocObject(JNIEnv *env, jclass clazz))
 971   HOTSPOT_JNI_ALLOCOBJECT_ENTRY(env, clazz);
 972 
 973   jobject ret = nullptr;
 974   DT_RETURN_MARK(AllocObject, jobject, (const jobject&)ret);
 975 
 976   oop clazzoop = JNIHandles::resolve_non_null(clazz);
 977   Klass* k = java_lang_Class::as_Klass(clazzoop);
 978   if (k == nullptr || k->is_inline_klass()) {
 979     ResourceMark rm(THREAD);
 980     THROW_(vmSymbols::java_lang_InstantiationException(), nullptr);
 981   }
 982   instanceOop i = InstanceKlass::allocate_instance(clazzoop, CHECK_NULL);
 983   ret = JNIHandles::make_local(THREAD, i);
 984   return ret;
 985 JNI_END
 986 
 987 DT_RETURN_MARK_DECL(NewObjectA, jobject
 988                     , HOTSPOT_JNI_NEWOBJECTA_RETURN(_ret_ref));
 989 
 990 JNI_ENTRY(jobject, jni_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args))
 991   HOTSPOT_JNI_NEWOBJECTA_ENTRY(env, clazz, (uintptr_t) methodID);
 992 
 993   jobject obj = nullptr;
 994   DT_RETURN_MARK(NewObjectA, jobject, (const jobject&)obj);
 995 
 996   oop clazzoop = JNIHandles::resolve_non_null(clazz);
 997   Klass* k = java_lang_Class::as_Klass(clazzoop);
 998   if (k == nullptr) {
 999     ResourceMark rm(THREAD);
1000     THROW_(vmSymbols::java_lang_InstantiationException(), nullptr);
1001   }
1002 
1003   instanceOop i = InstanceKlass::allocate_instance(clazzoop, CHECK_NULL);
1004   obj = JNIHandles::make_local(THREAD, i);
1005   JavaValue jvalue(T_VOID);
1006   JNI_ArgumentPusherArray ap(methodID, args);
1007   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1008 
1009   return obj;
1010   JNI_END
1011 
1012 
1013 DT_RETURN_MARK_DECL(NewObjectV, jobject
1014                     , HOTSPOT_JNI_NEWOBJECTV_RETURN(_ret_ref));
1015 
1016 JNI_ENTRY(jobject, jni_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args))
1017   HOTSPOT_JNI_NEWOBJECTV_ENTRY(env, clazz, (uintptr_t) methodID);
1018 
1019   jobject obj = nullptr;
1020   DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj);
1021 
1022   oop clazzoop = JNIHandles::resolve_non_null(clazz);
1023   Klass* k = java_lang_Class::as_Klass(clazzoop);
1024   if (k == nullptr) {
1025     ResourceMark rm(THREAD);
1026     THROW_(vmSymbols::java_lang_InstantiationException(), nullptr);
1027   }
1028 
1029   instanceOop i = InstanceKlass::allocate_instance(clazzoop, CHECK_NULL);
1030   obj = JNIHandles::make_local(THREAD, i);
1031   JavaValue jvalue(T_VOID);
1032   JNI_ArgumentPusherVaArg ap(methodID, args);
1033   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1034 
1035   return obj;
1036 JNI_END
1037 
1038 
1039 DT_RETURN_MARK_DECL(NewObject, jobject
1040                     , HOTSPOT_JNI_NEWOBJECT_RETURN(_ret_ref));
1041 
1042 JNI_ENTRY(jobject, jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...))
1043   HOTSPOT_JNI_NEWOBJECT_ENTRY(env, clazz, (uintptr_t) methodID);
1044 
1045   jobject obj = nullptr;
1046   DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj);
1047 
1048   oop clazzoop = JNIHandles::resolve_non_null(clazz);
1049   Klass* k = java_lang_Class::as_Klass(clazzoop);
1050   if (k == nullptr) {
1051     ResourceMark rm(THREAD);
1052     THROW_(vmSymbols::java_lang_InstantiationException(), nullptr);
1053   }
1054 
1055   instanceOop i = InstanceKlass::allocate_instance(clazzoop, CHECK_NULL);
1056   obj = JNIHandles::make_local(THREAD, i);
1057   va_list args;
1058   va_start(args, methodID);
1059   JavaValue jvalue(T_VOID);
1060   JNI_ArgumentPusherVaArg ap(methodID, args);
1061   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1062   va_end(args);
1063 
1064   return obj;
1065 JNI_END
1066 
1067 
1068 JNI_ENTRY(jclass, jni_GetObjectClass(JNIEnv *env, jobject obj))
1069   HOTSPOT_JNI_GETOBJECTCLASS_ENTRY(env, obj);
1070 
1071   Klass* k = JNIHandles::resolve_non_null(obj)->klass();
1072   jclass ret =
1073     (jclass) JNIHandles::make_local(THREAD, k->java_mirror());
1074 
1075   HOTSPOT_JNI_GETOBJECTCLASS_RETURN(ret);
1076   return ret;
1077 JNI_END
1078 
1079 JNI_ENTRY_NO_PRESERVE(jboolean, jni_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz))
1080   HOTSPOT_JNI_ISINSTANCEOF_ENTRY(env, obj, clazz);
1081 
1082   jboolean ret = JNI_TRUE;
1083   if (obj != nullptr) {

1794   // table.  If they're not there, the field doesn't exist.
1795   TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
1796   TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
1797   if (fieldname == nullptr || signame == nullptr) {
1798     ResourceMark rm;
1799     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
1800   }
1801 
1802   // Make sure class is initialized before handing id's out to fields
1803   k->initialize(CHECK_NULL);
1804 
1805   fieldDescriptor fd;
1806   if (!k->is_instance_klass() ||
1807       !InstanceKlass::cast(k)->find_field(fieldname, signame, false, &fd)) {
1808     ResourceMark rm;
1809     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
1810   }
1811 
1812   // A jfieldID for a non-static field is simply the offset of the field within the instanceOop
1813   // It may also have hash bits for k, if VerifyJNIFields is turned on.
1814   ret = jfieldIDWorkaround::to_instance_jfieldID(k, fd.offset(), fd.is_flat());
1815   return ret;
1816 JNI_END
1817 
1818 
1819 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
1820   HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID);
1821   oop o = JNIHandles::resolve_non_null(obj);
1822   Klass* k = o->klass();
1823   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
1824   oop res = nullptr;
1825   // Keep JVMTI addition small and only check enabled flag here.
1826   // jni_GetField_probe() assumes that is okay to create handles.
1827   if (JvmtiExport::should_post_field_access()) {
1828     o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
1829   }
1830   if (!jfieldIDWorkaround::is_flat_jfieldID(fieldID)) {
1831     res = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(o, offset);
1832   } else {
1833     assert(k->is_instance_klass(), "Only instance can have flat fields");
1834     InstanceKlass* ik = InstanceKlass::cast(k);
1835     fieldDescriptor fd;
1836     ik->find_field_from_offset(offset, false, &fd);  // performance bottleneck
1837     InstanceKlass* holder = fd.field_holder();
1838     InlineKlass* field_vklass = InlineKlass::cast(holder->get_inline_type_field_klass(fd.index()));
1839     res = field_vklass->read_flat_field(o, ik->field_offset(fd.index()), CHECK_NULL);
1840   }
1841   jobject ret = JNIHandles::make_local(THREAD, res);
1842   HOTSPOT_JNI_GETOBJECTFIELD_RETURN(ret);
1843   return ret;
1844 JNI_END
1845 
1846 
1847 
1848 #define DEFINE_GETFIELD(Return,Fieldname,Result \
1849   , EntryProbe, ReturnProbe) \
1850 \
1851   DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return \
1852   , ReturnProbe); \
1853 \
1854 JNI_ENTRY_NO_PRESERVE(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \
1855 \
1856   EntryProbe; \
1857   Return ret = 0;\
1858   DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\
1859 \
1860   oop o = JNIHandles::resolve_non_null(obj); \
1861   Klass* k = o->klass(); \

1913   return (address)jni_GetLongField;
1914 }
1915 address jni_GetFloatField_addr() {
1916   return (address)jni_GetFloatField;
1917 }
1918 address jni_GetDoubleField_addr() {
1919   return (address)jni_GetDoubleField;
1920 }
1921 
1922 JNI_ENTRY_NO_PRESERVE(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
1923   HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID, value);
1924   oop o = JNIHandles::resolve_non_null(obj);
1925   Klass* k = o->klass();
1926   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
1927   // Keep JVMTI addition small and only check enabled flag here.
1928   if (JvmtiExport::should_post_field_modification()) {
1929     jvalue field_value;
1930     field_value.l = value;
1931     o = JvmtiExport::jni_SetField_probe(thread, obj, o, k, fieldID, false, JVM_SIGNATURE_CLASS, (jvalue *)&field_value);
1932   }
1933   if (!jfieldIDWorkaround::is_flat_jfieldID(fieldID)) {
1934     HeapAccess<ON_UNKNOWN_OOP_REF>::oop_store_at(o, offset, JNIHandles::resolve(value));
1935   } else {
1936     assert(k->is_instance_klass(), "Only instances can have flat fields");
1937     InstanceKlass* ik = InstanceKlass::cast(k);
1938     fieldDescriptor fd;
1939     ik->find_field_from_offset(offset, false, &fd);
1940     InstanceKlass* holder = fd.field_holder();
1941     InlineKlass* vklass = InlineKlass::cast(holder->get_inline_type_field_klass(fd.index()));
1942     oop v = JNIHandles::resolve_non_null(value);
1943     vklass->write_flat_field(o, offset, v, CHECK);
1944   }
1945   HOTSPOT_JNI_SETOBJECTFIELD_RETURN();
1946 JNI_END
1947 
1948 // TODO: make this a template
1949 
1950 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
1951                         , EntryProbe, ReturnProbe) \
1952 \
1953 JNI_ENTRY_NO_PRESERVE(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
1954 \
1955   EntryProbe; \
1956 \
1957   oop o = JNIHandles::resolve_non_null(obj); \
1958   Klass* k = o->klass(); \
1959   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
1960   /* Keep JVMTI addition small and only check enabled flag here.       */ \
1961   if (JvmtiExport::should_post_field_modification()) { \
1962     jvalue field_value; \
1963     field_value.unionType = value; \
1964     o = JvmtiExport::jni_SetField_probe(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \

2340   Klass* ak = ek->array_klass(CHECK_NULL);
2341   ObjArrayKlass::cast(ak)->initialize(CHECK_NULL);
2342   objArrayOop result = ObjArrayKlass::cast(ak)->allocate(length, CHECK_NULL);
2343   oop initial_value = JNIHandles::resolve(initialElement);
2344   if (initial_value != nullptr) {  // array already initialized with null
2345     for (int index = 0; index < length; index++) {
2346       result->obj_at_put(index, initial_value);
2347     }
2348   }
2349   ret = (jobjectArray) JNIHandles::make_local(THREAD, result);
2350   return ret;
2351 JNI_END
2352 
2353 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
2354                     , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
2355 
2356 JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
2357  HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(env, array, index);
2358   jobject ret = nullptr;
2359   DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
2360   oop res = nullptr;
2361   arrayOop arr((arrayOop)JNIHandles::resolve_non_null(array));
2362   if (arr->is_within_bounds(index)) {
2363     if (arr->is_flatArray()) {
2364       flatArrayOop a = flatArrayOop(JNIHandles::resolve_non_null(array));
2365       flatArrayHandle vah(thread, a);
2366       res = flatArrayOopDesc::value_alloc_copy_from_index(vah, index, CHECK_NULL);
2367       assert(res != nullptr, "Must be set in one of two paths above");
2368     } else {
2369       assert(arr->is_objArray(), "If not a valueArray. must be an objArray");
2370       objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2371       res = a->obj_at(index);
2372     }
2373   } else {
2374     ResourceMark rm(THREAD);
2375     stringStream ss;
2376     ss.print("Index %d out of bounds for length %d", index,arr->length());
2377     THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2378   }
2379   ret = JNIHandles::make_local(THREAD, res);
2380   return ret;
2381 JNI_END
2382 
2383 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
2384                          , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
2385 
2386 JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
2387  HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(env, array, index, value);
2388   DT_VOID_RETURN_MARK(SetObjectArrayElement);
2389 
2390    bool oob = false;
2391    int length = -1;
2392    oop res = nullptr;
2393    arrayOop arr((arrayOop)JNIHandles::resolve_non_null(array));
2394    if (arr->is_within_bounds(index)) {
2395      if (arr->is_flatArray()) {
2396        flatArrayOop a = flatArrayOop(JNIHandles::resolve_non_null(array));
2397        oop v = JNIHandles::resolve(value);
2398        FlatArrayKlass* vaklass = FlatArrayKlass::cast(a->klass());
2399        InlineKlass* element_vklass = vaklass->element_klass();
2400        if (v != nullptr && v->is_a(element_vklass)) {
2401          a->value_copy_to_index(v, index);
2402        } else {
2403          ResourceMark rm(THREAD);
2404          stringStream ss;
2405          Klass *kl = FlatArrayKlass::cast(a->klass());
2406          ss.print("type mismatch: can not store %s to %s[%d]",
2407              v->klass()->external_name(),
2408              kl->external_name(),
2409              index);
2410          for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
2411            ss.print("[]");
2412          }
2413          THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
2414        }
2415      } else {
2416        assert(arr->is_objArray(), "If not a valueArray. must be an objArray");
2417        objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2418        oop v = JNIHandles::resolve(value);
2419        if (v == nullptr || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) {
2420          a->obj_at_put(index, v);
2421        } else {
2422          ResourceMark rm(THREAD);
2423          stringStream ss;
2424          Klass *bottom_kl = ObjArrayKlass::cast(a->klass())->bottom_klass();
2425          ss.print("type mismatch: can not store %s to %s[%d]",
2426              v->klass()->external_name(),
2427              bottom_kl->is_typeArray_klass() ? type2name_tab[ArrayKlass::cast(bottom_kl)->element_type()] : bottom_kl->external_name(),
2428                  index);
2429          for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
2430            ss.print("[]");
2431          }
2432          THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
2433        }
2434      }
2435    } else {
2436      ResourceMark rm(THREAD);
2437      stringStream ss;
2438      ss.print("Index %d out of bounds for length %d", index, arr->length());
2439      THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2440    }
2441 JNI_END
2442 
2443 
2444 
2445 #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result \
2446                               ,EntryProbe,ReturnProbe)  \
2447 \
2448   DT_RETURN_MARK_DECL(New##Result##Array, Return \
2449                       , ReturnProbe); \
2450 \
2451 JNI_ENTRY(Return, \
2452           jni_New##Result##Array(JNIEnv *env, jsize len)) \
2453   EntryProbe; \
2454   Return ret = nullptr;\
2455   DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
2456 \
2457   oop obj= oopFactory::Allocator(len, CHECK_NULL); \
2458   ret = (Return) JNIHandles::make_local(THREAD, obj); \
2459   return ret;\
2460 JNI_END
< prev index next >