< prev index next >

src/hotspot/share/prims/jni.cpp

Print this page

  37 #include "classfile/modules.hpp"
  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 "oops/access.inline.hpp"
  56 #include "oops/arrayOop.hpp"


  57 #include "oops/instanceKlass.inline.hpp"
  58 #include "oops/instanceOop.hpp"
  59 #include "oops/klass.inline.hpp"
  60 #include "oops/markWord.hpp"
  61 #include "oops/method.hpp"
  62 #include "oops/objArrayKlass.hpp"
  63 #include "oops/objArrayOop.inline.hpp"
  64 #include "oops/oop.inline.hpp"
  65 #include "oops/symbol.hpp"
  66 #include "oops/typeArrayKlass.hpp"
  67 #include "oops/typeArrayOop.inline.hpp"
  68 #include "prims/jniCheck.hpp"
  69 #include "prims/jniExport.hpp"
  70 #include "prims/jniFastGetField.hpp"
  71 #include "prims/jvm_misc.hpp"
  72 #include "prims/jvmtiExport.hpp"
  73 #include "prims/jvmtiThreadState.hpp"
  74 #include "runtime/arguments.hpp"
  75 #include "runtime/atomic.hpp"
  76 #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     intptr_t 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   intptr_t 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;

 483          "java_super computation depends on interface, array, other super");
 484   obj = (super == nullptr) ? nullptr : (jclass) JNIHandles::make_local(THREAD, super->java_mirror());
 485   return obj;
 486 JNI_END
 487 
 488 JNI_ENTRY_NO_PRESERVE(jboolean, jni_IsAssignableFrom(JNIEnv *env, jclass sub, jclass super))
 489   HOTSPOT_JNI_ISASSIGNABLEFROM_ENTRY(env, sub, super);
 490 
 491   oop sub_mirror   = JNIHandles::resolve_non_null(sub);
 492   oop super_mirror = JNIHandles::resolve_non_null(super);
 493   if (java_lang_Class::is_primitive(sub_mirror) ||
 494       java_lang_Class::is_primitive(super_mirror)) {
 495     jboolean ret = (sub_mirror == super_mirror);
 496 
 497     HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
 498     return ret;
 499   }
 500   Klass* sub_klass   = java_lang_Class::as_Klass(sub_mirror);
 501   Klass* super_klass = java_lang_Class::as_Klass(super_mirror);
 502   assert(sub_klass != nullptr && super_klass != nullptr, "invalid arguments to jni_IsAssignableFrom");
 503   jboolean ret = sub_klass->is_subtype_of(super_klass) ?
 504                    JNI_TRUE : JNI_FALSE;
 505 









 506   HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
 507   return ret;
 508 JNI_END
 509 
 510 
 511 DT_RETURN_MARK_DECL(Throw, jint
 512                     , HOTSPOT_JNI_THROW_RETURN(_ret_ref));
 513 
 514 JNI_ENTRY(jint, jni_Throw(JNIEnv *env, jthrowable obj))
 515   HOTSPOT_JNI_THROW_ENTRY(env, obj);
 516 
 517   jint ret = JNI_OK;
 518   DT_RETURN_MARK(Throw, jint, (const jint&)ret);
 519 
 520   THROW_OOP_(JNIHandles::resolve(obj), JNI_OK);
 521   ShouldNotReachHere();
 522   return 0;  // Mute compiler.
 523 JNI_END
 524 
 525 

 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,

 961 JNI_ENTRY(jobject, jni_AllocObject(JNIEnv *env, jclass clazz))
 962   HOTSPOT_JNI_ALLOCOBJECT_ENTRY(env, clazz);
 963 
 964   jobject ret = nullptr;
 965   DT_RETURN_MARK(AllocObject, jobject, (const jobject&)ret);
 966 
 967   instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
 968   ret = JNIHandles::make_local(THREAD, i);
 969   return ret;
 970 JNI_END
 971 
 972 DT_RETURN_MARK_DECL(NewObjectA, jobject
 973                     , HOTSPOT_JNI_NEWOBJECTA_RETURN(_ret_ref));
 974 
 975 JNI_ENTRY(jobject, jni_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args))
 976   HOTSPOT_JNI_NEWOBJECTA_ENTRY(env, clazz, (uintptr_t) methodID);
 977 
 978   jobject obj = nullptr;
 979   DT_RETURN_MARK(NewObjectA, jobject, (const jobject&)obj);
 980 
 981   instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
 982   obj = JNIHandles::make_local(THREAD, i);
 983   JavaValue jvalue(T_VOID);
 984   JNI_ArgumentPusherArray ap(methodID, args);
 985   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);














 986   return obj;
 987 JNI_END
 988 
 989 
 990 DT_RETURN_MARK_DECL(NewObjectV, jobject
 991                     , HOTSPOT_JNI_NEWOBJECTV_RETURN(_ret_ref));
 992 
 993 JNI_ENTRY(jobject, jni_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args))
 994   HOTSPOT_JNI_NEWOBJECTV_ENTRY(env, clazz, (uintptr_t) methodID);
 995 
 996   jobject obj = nullptr;
 997   DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj);
 998 
 999   instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
1000   obj = JNIHandles::make_local(THREAD, i);
1001   JavaValue jvalue(T_VOID);
1002   JNI_ArgumentPusherVaArg ap(methodID, args);
1003   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);














1004   return obj;
1005 JNI_END
1006 
1007 
1008 DT_RETURN_MARK_DECL(NewObject, jobject
1009                     , HOTSPOT_JNI_NEWOBJECT_RETURN(_ret_ref));
1010 
1011 JNI_ENTRY(jobject, jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...))
1012   HOTSPOT_JNI_NEWOBJECT_ENTRY(env, clazz, (uintptr_t) methodID);
1013 
1014   jobject obj = nullptr;
1015   DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj);
1016 
1017   instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
1018   obj = JNIHandles::make_local(THREAD, i);
1019   va_list args;
1020   va_start(args, methodID);
1021   JavaValue jvalue(T_VOID);
1022   JNI_ArgumentPusherVaArg ap(methodID, args);
1023   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1024   va_end(args);

















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

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

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










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

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











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

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









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


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



























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

  37 #include "classfile/modules.hpp"
  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 "oops/access.inline.hpp"
  56 #include "oops/arrayOop.hpp"
  57 #include "oops/flatArrayOop.inline.hpp"
  58 #include "oops/inlineKlass.inline.hpp"
  59 #include "oops/instanceKlass.inline.hpp"
  60 #include "oops/instanceOop.hpp"
  61 #include "oops/klass.inline.hpp"
  62 #include "oops/markWord.hpp"
  63 #include "oops/method.hpp"
  64 #include "oops/objArrayKlass.hpp"
  65 #include "oops/objArrayOop.inline.hpp"
  66 #include "oops/oop.inline.hpp"
  67 #include "oops/symbol.hpp"
  68 #include "oops/typeArrayKlass.hpp"
  69 #include "oops/typeArrayOop.inline.hpp"
  70 #include "prims/jniCheck.hpp"
  71 #include "prims/jniExport.hpp"
  72 #include "prims/jniFastGetField.hpp"
  73 #include "prims/jvm_misc.hpp"
  74 #include "prims/jvmtiExport.hpp"
  75 #include "prims/jvmtiThreadState.hpp"
  76 #include "runtime/arguments.hpp"
  77 #include "runtime/atomic.hpp"
  78 #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     intptr_t 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   intptr_t 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() || m->is_static_vnew_factory()) {
 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;

 486          "java_super computation depends on interface, array, other super");
 487   obj = (super == nullptr) ? nullptr : (jclass) JNIHandles::make_local(THREAD, super->java_mirror());
 488   return obj;
 489 JNI_END
 490 
 491 JNI_ENTRY_NO_PRESERVE(jboolean, jni_IsAssignableFrom(JNIEnv *env, jclass sub, jclass super))
 492   HOTSPOT_JNI_ISASSIGNABLEFROM_ENTRY(env, sub, super);
 493 
 494   oop sub_mirror   = JNIHandles::resolve_non_null(sub);
 495   oop super_mirror = JNIHandles::resolve_non_null(super);
 496   if (java_lang_Class::is_primitive(sub_mirror) ||
 497       java_lang_Class::is_primitive(super_mirror)) {
 498     jboolean ret = (sub_mirror == super_mirror);
 499 
 500     HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
 501     return ret;
 502   }
 503   Klass* sub_klass   = java_lang_Class::as_Klass(sub_mirror);
 504   Klass* super_klass = java_lang_Class::as_Klass(super_mirror);
 505   assert(sub_klass != nullptr && super_klass != nullptr, "invalid arguments to jni_IsAssignableFrom");
 506   jboolean ret;
 507   if (sub_klass == super_klass && sub_klass->is_inline_klass()) {
 508     // val type is a subtype of ref type
 509     InlineKlass* ik = InlineKlass::cast(sub_klass);
 510     if (sub_mirror == super_mirror || (ik->val_mirror() == sub_mirror && ik->ref_mirror() == super_mirror)) {
 511       ret = JNI_TRUE;
 512     } else {
 513       ret = JNI_FALSE;
 514     }
 515   } else {
 516     ret = sub_klass->is_subtype_of(super_klass) ? JNI_TRUE : JNI_FALSE;
 517   }
 518   HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
 519   return ret;
 520 JNI_END
 521 
 522 
 523 DT_RETURN_MARK_DECL(Throw, jint
 524                     , HOTSPOT_JNI_THROW_RETURN(_ret_ref));
 525 
 526 JNI_ENTRY(jint, jni_Throw(JNIEnv *env, jthrowable obj))
 527   HOTSPOT_JNI_THROW_ENTRY(env, obj);
 528 
 529   jint ret = JNI_OK;
 530   DT_RETURN_MARK(Throw, jint, (const jint&)ret);
 531 
 532   THROW_OOP_(JNIHandles::resolve(obj), JNI_OK);
 533   ShouldNotReachHere();
 534   return 0;  // Mute compiler.
 535 JNI_END
 536 
 537 

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

 975 JNI_ENTRY(jobject, jni_AllocObject(JNIEnv *env, jclass clazz))
 976   HOTSPOT_JNI_ALLOCOBJECT_ENTRY(env, clazz);
 977 
 978   jobject ret = nullptr;
 979   DT_RETURN_MARK(AllocObject, jobject, (const jobject&)ret);
 980 
 981   instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
 982   ret = JNIHandles::make_local(THREAD, i);
 983   return ret;
 984 JNI_END
 985 
 986 DT_RETURN_MARK_DECL(NewObjectA, jobject
 987                     , HOTSPOT_JNI_NEWOBJECTA_RETURN(_ret_ref));
 988 
 989 JNI_ENTRY(jobject, jni_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args))
 990   HOTSPOT_JNI_NEWOBJECTA_ENTRY(env, clazz, (uintptr_t) methodID);
 991 
 992   jobject obj = nullptr;
 993   DT_RETURN_MARK(NewObjectA, jobject, (const jobject&)obj);
 994 
 995   oop clazzoop = JNIHandles::resolve_non_null(clazz);
 996   Klass* k = java_lang_Class::as_Klass(clazzoop);
 997   if (k == nullptr) {
 998     ResourceMark rm(THREAD);
 999     THROW_(vmSymbols::java_lang_InstantiationException(), nullptr);
1000   }
1001 
1002   if (!k->is_inline_klass()) {
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   } else {
1009     JavaValue jvalue(T_PRIMITIVE_OBJECT);
1010     JNI_ArgumentPusherArray ap(methodID, args);
1011     jni_invoke_static(env, &jvalue, nullptr, JNI_STATIC, methodID, &ap, CHECK_NULL);
1012     obj = jvalue.get_jobject();
1013   }
1014   return obj;
1015   JNI_END
1016 
1017 
1018 DT_RETURN_MARK_DECL(NewObjectV, jobject
1019                     , HOTSPOT_JNI_NEWOBJECTV_RETURN(_ret_ref));
1020 
1021 JNI_ENTRY(jobject, jni_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args))
1022   HOTSPOT_JNI_NEWOBJECTV_ENTRY(env, clazz, (uintptr_t) methodID);
1023 
1024   jobject obj = nullptr;
1025   DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj);
1026 
1027   oop clazzoop = JNIHandles::resolve_non_null(clazz);
1028   Klass* k = java_lang_Class::as_Klass(clazzoop);
1029   if (k == nullptr) {
1030     ResourceMark rm(THREAD);
1031     THROW_(vmSymbols::java_lang_InstantiationException(), nullptr);
1032   }
1033 
1034   if (!k->is_inline_klass()) {
1035     instanceOop i = InstanceKlass::allocate_instance(clazzoop, CHECK_NULL);
1036     obj = JNIHandles::make_local(THREAD, i);
1037     JavaValue jvalue(T_VOID);
1038     JNI_ArgumentPusherVaArg ap(methodID, args);
1039     jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1040   } else {
1041     JavaValue jvalue(T_PRIMITIVE_OBJECT);
1042     JNI_ArgumentPusherVaArg ap(methodID, args);
1043     jni_invoke_static(env, &jvalue, nullptr, JNI_STATIC, methodID, &ap, CHECK_NULL);
1044     obj = jvalue.get_jobject();
1045   }
1046   return obj;
1047 JNI_END
1048 
1049 
1050 DT_RETURN_MARK_DECL(NewObject, jobject
1051                     , HOTSPOT_JNI_NEWOBJECT_RETURN(_ret_ref));
1052 
1053 JNI_ENTRY(jobject, jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...))
1054   HOTSPOT_JNI_NEWOBJECT_ENTRY(env, clazz, (uintptr_t) methodID);
1055 
1056   jobject obj = nullptr;
1057   DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj);
1058 
1059   oop clazzoop = JNIHandles::resolve_non_null(clazz);
1060   Klass* k = java_lang_Class::as_Klass(clazzoop);
1061   if (k == nullptr) {
1062     ResourceMark rm(THREAD);
1063     THROW_(vmSymbols::java_lang_InstantiationException(), nullptr);
1064   }
1065 
1066   if (!k->is_inline_klass()) {
1067     instanceOop i = InstanceKlass::allocate_instance(clazzoop, CHECK_NULL);
1068     obj = JNIHandles::make_local(THREAD, i);
1069     va_list args;
1070     va_start(args, methodID);
1071     JavaValue jvalue(T_VOID);
1072     JNI_ArgumentPusherVaArg ap(methodID, args);
1073     jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1074     va_end(args);
1075   } else {
1076     va_list args;
1077     va_start(args, methodID);
1078     JavaValue jvalue(T_PRIMITIVE_OBJECT);
1079     JNI_ArgumentPusherVaArg ap(methodID, args);
1080     jni_invoke_static(env, &jvalue, nullptr, JNI_STATIC, methodID, &ap, CHECK_NULL);
1081     va_end(args);
1082     obj = jvalue.get_jobject();
1083   }
1084   return obj;
1085 JNI_END
1086 
1087 
1088 JNI_ENTRY(jclass, jni_GetObjectClass(JNIEnv *env, jobject obj))
1089   HOTSPOT_JNI_GETOBJECTCLASS_ENTRY(env, obj);
1090 
1091   Klass* k = JNIHandles::resolve_non_null(obj)->klass();
1092   jclass ret =
1093     (jclass) JNIHandles::make_local(THREAD, k->java_mirror());
1094 
1095   HOTSPOT_JNI_GETOBJECTCLASS_RETURN(ret);
1096   return ret;
1097 JNI_END
1098 
1099 JNI_ENTRY_NO_PRESERVE(jboolean, jni_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz))
1100   HOTSPOT_JNI_ISINSTANCEOF_ENTRY(env, obj, clazz);
1101 
1102   jboolean ret = JNI_TRUE;
1103   if (obj != nullptr) {

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

1933   return (address)jni_GetLongField;
1934 }
1935 address jni_GetFloatField_addr() {
1936   return (address)jni_GetFloatField;
1937 }
1938 address jni_GetDoubleField_addr() {
1939   return (address)jni_GetDoubleField;
1940 }
1941 
1942 JNI_ENTRY_NO_PRESERVE(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
1943   HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID, value);
1944   oop o = JNIHandles::resolve_non_null(obj);
1945   Klass* k = o->klass();
1946   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
1947   // Keep JVMTI addition small and only check enabled flag here.
1948   if (JvmtiExport::should_post_field_modification()) {
1949     jvalue field_value;
1950     field_value.l = value;
1951     o = JvmtiExport::jni_SetField_probe(thread, obj, o, k, fieldID, false, JVM_SIGNATURE_CLASS, (jvalue *)&field_value);
1952   }
1953   if (!jfieldIDWorkaround::is_flat_jfieldID(fieldID)) {
1954     HeapAccess<ON_UNKNOWN_OOP_REF>::oop_store_at(o, offset, JNIHandles::resolve(value));
1955   } else {
1956     assert(k->is_instance_klass(), "Only instances can have flat fields");
1957     InstanceKlass* ik = InstanceKlass::cast(k);
1958     fieldDescriptor fd;
1959     ik->find_field_from_offset(offset, false, &fd);
1960     InstanceKlass* holder = fd.field_holder();
1961     InlineKlass* vklass = InlineKlass::cast(holder->get_inline_type_field_klass(fd.index()));
1962     oop v = JNIHandles::resolve_non_null(value);
1963     vklass->write_flat_field(o, offset, v, CHECK);
1964   }
1965   HOTSPOT_JNI_SETOBJECTFIELD_RETURN();
1966 JNI_END
1967 
1968 
1969 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
1970                         , EntryProbe, ReturnProbe) \
1971 \
1972 JNI_ENTRY_NO_PRESERVE(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
1973 \
1974   EntryProbe; \
1975 \
1976   oop o = JNIHandles::resolve_non_null(obj); \
1977   Klass* k = o->klass(); \
1978   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
1979   /* Keep JVMTI addition small and only check enabled flag here.       */ \
1980   if (JvmtiExport::should_post_field_modification()) { \
1981     jvalue field_value; \
1982     field_value.unionType = value; \
1983     o = JvmtiExport::jni_SetField_probe(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \
1984   } \

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