< 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_object_initializer()) {
 448     reflection_method = Reflection::new_constructor(m, CHECK_NULL);
 449   } else {
 450     // Note: Static initializers can theoretically be here, if JNI users manage
 451     // to get their jmethodID. Record them as plain methods.
 452     reflection_method = Reflection::new_method(m, false, CHECK_NULL);
 453   }
 454   ret = JNIHandles::make_local(THREAD, reflection_method);
 455   return ret;
 456 JNI_END
 457 
 458 DT_RETURN_MARK_DECL(GetSuperclass, jclass
 459                     , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));
 460 
 461 JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
 462   HOTSPOT_JNI_GETSUPERCLASS_ENTRY(env, sub);
 463 
 464   jclass obj = nullptr;
 465   DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
 466 
 467   oop mirror = JNIHandles::resolve_non_null(sub);

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

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

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






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







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

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







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

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







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

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

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

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











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

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












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

2295   Klass* ak = ek->array_klass(CHECK_NULL);
2296   ObjArrayKlass::cast(ak)->initialize(CHECK_NULL);
2297   objArrayOop result = ObjArrayKlass::cast(ak)->allocate(length, CHECK_NULL);
2298   oop initial_value = JNIHandles::resolve(initialElement);
2299   if (initial_value != nullptr) {  // array already initialized with null
2300     for (int index = 0; index < length; index++) {
2301       result->obj_at_put(index, initial_value);
2302     }
2303   }
2304   ret = (jobjectArray) JNIHandles::make_local(THREAD, result);
2305   return ret;
2306 JNI_END
2307 
2308 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
2309                     , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
2310 
2311 JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
2312  HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(env, array, index);
2313   jobject ret = nullptr;
2314   DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
2315   objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2316   if (a->is_within_bounds(index)) {
2317     ret = JNIHandles::make_local(THREAD, a->obj_at(index));
2318     return ret;









2319   } else {
2320     ResourceMark rm(THREAD);
2321     stringStream ss;
2322     ss.print("Index %d out of bounds for length %d", index, a->length());
2323     THROW_MSG_NULL(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2324   }


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



























2358 JNI_END
2359 
2360 
2361 
2362 #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result \
2363                               ,EntryProbe,ReturnProbe)  \
2364 \
2365   DT_RETURN_MARK_DECL(New##Result##Array, Return \
2366                       , ReturnProbe); \
2367 \
2368 JNI_ENTRY(Return, \
2369           jni_New##Result##Array(JNIEnv *env, jsize len)) \
2370   EntryProbe; \
2371   Return ret = nullptr;\
2372   DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
2373 \
2374   oop obj= oopFactory::Allocator(len, CHECK_NULL); \
2375   ret = (Return) JNIHandles::make_local(THREAD, obj); \
2376   return ret;\
2377 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     // Note: Static initializers can theoretically be here, if JNI users manage
 454     // to get their jmethodID. Record them as plain methods.
 455     reflection_method = Reflection::new_method(m, false, CHECK_NULL);
 456   }
 457   ret = JNIHandles::make_local(THREAD, reflection_method);
 458   return ret;
 459 JNI_END
 460 
 461 DT_RETURN_MARK_DECL(GetSuperclass, jclass
 462                     , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));
 463 
 464 JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
 465   HOTSPOT_JNI_GETSUPERCLASS_ENTRY(env, sub);
 466 
 467   jclass obj = nullptr;
 468   DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
 469 
 470   oop mirror = JNIHandles::resolve_non_null(sub);

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

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

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

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

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