< prev index next >

src/hotspot/share/prims/jni.cpp

Print this page

  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 "jfr/jfrEvents.hpp"
  48 #include "jfr/support/jfrThreadId.hpp"
  49 #include "jni.h"
  50 #include "jvm.h"
  51 #include "logging/log.hpp"
  52 #include "memory/allocation.hpp"
  53 #include "memory/allocation.inline.hpp"
  54 #include "memory/oopFactory.hpp"
  55 #include "memory/resourceArea.hpp"
  56 #include "memory/universe.hpp"
  57 #include "oops/access.inline.hpp"
  58 #include "oops/arrayOop.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"

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

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

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









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

 784   }
 785 
 786   friend class SignatureIterator;  // so do_parameters_on can call do_type
 787   void do_type(BasicType type) {
 788     switch (type) {
 789     // these are coerced to int when using va_arg
 790     case T_BYTE:
 791     case T_CHAR:
 792     case T_SHORT:
 793     case T_INT:         push_int(va_arg(_ap, jint)); break;
 794     case T_BOOLEAN:     push_boolean((jboolean) va_arg(_ap, jint)); break;
 795 
 796     // each of these paths is exercised by the various jck Call[Static,Nonvirtual,][Void,Int,..]Method[A,V,] tests
 797 
 798     case T_LONG:        push_long(va_arg(_ap, jlong)); break;
 799     // float is coerced to double w/ va_arg
 800     case T_FLOAT:       push_float((jfloat) va_arg(_ap, jdouble)); break;
 801     case T_DOUBLE:      push_double(va_arg(_ap, jdouble)); break;
 802 
 803     case T_ARRAY:
 804     case T_OBJECT:      push_object(va_arg(_ap, jobject)); break;

 805     default:            ShouldNotReachHere();
 806     }
 807   }
 808 
 809  public:
 810   JNI_ArgumentPusherVaArg(jmethodID method_id, va_list rap)
 811       : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)) {
 812     set_ap(rap);
 813   }
 814 
 815   ~JNI_ArgumentPusherVaArg() {
 816     va_end(_ap);
 817   }
 818 
 819   virtual void push_arguments_on(JavaCallArguments* arguments) {
 820     _arguments = arguments;
 821     do_parameters_on(this);
 822   }
 823 };
 824 
 825 
 826 class JNI_ArgumentPusherArray : public JNI_ArgumentPusher {
 827  protected:
 828   const jvalue *_ap;
 829 
 830   inline void set_ap(const jvalue *rap) { _ap = rap; }
 831 
 832   friend class SignatureIterator;  // so do_parameters_on can call do_type
 833   void do_type(BasicType type) {
 834     switch (type) {
 835     case T_CHAR:        push_int((_ap++)->c); break;
 836     case T_SHORT:       push_int((_ap++)->s); break;
 837     case T_BYTE:        push_int((_ap++)->b); break;
 838     case T_INT:         push_int((_ap++)->i); break;
 839     case T_BOOLEAN:     push_boolean((_ap++)->z); break;
 840     case T_LONG:        push_long((_ap++)->j); break;
 841     case T_FLOAT:       push_float((_ap++)->f); break;
 842     case T_DOUBLE:      push_double((_ap++)->d); break;
 843     case T_ARRAY:
 844     case T_OBJECT:      push_object((_ap++)->l); break;

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

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














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














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

















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

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

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










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

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











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

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









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


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



























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

  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 "jfr/jfrEvents.hpp"
  48 #include "jfr/support/jfrThreadId.hpp"
  49 #include "jni.h"
  50 #include "jvm.h"
  51 #include "logging/log.hpp"
  52 #include "memory/allocation.hpp"
  53 #include "memory/allocation.inline.hpp"
  54 #include "memory/oopFactory.hpp"
  55 #include "memory/resourceArea.hpp"
  56 #include "memory/universe.hpp"
  57 #include "oops/access.inline.hpp"
  58 #include "oops/arrayOop.hpp"
  59 #include "oops/flatArrayOop.inline.hpp"
  60 #include "oops/inlineKlass.inline.hpp"
  61 #include "oops/instanceKlass.inline.hpp"
  62 #include "oops/instanceOop.hpp"
  63 #include "oops/klass.inline.hpp"
  64 #include "oops/markWord.hpp"
  65 #include "oops/method.hpp"
  66 #include "oops/objArrayKlass.hpp"
  67 #include "oops/objArrayOop.inline.hpp"
  68 #include "oops/oop.inline.hpp"
  69 #include "oops/symbol.hpp"
  70 #include "oops/typeArrayKlass.hpp"
  71 #include "oops/typeArrayOop.inline.hpp"
  72 #include "prims/jniCheck.hpp"
  73 #include "prims/jniExport.hpp"
  74 #include "prims/jniFastGetField.hpp"
  75 #include "prims/jvm_misc.hpp"
  76 #include "prims/jvmtiExport.hpp"
  77 #include "prims/jvmtiThreadState.hpp"
  78 #include "runtime/arguments.hpp"
  79 #include "runtime/atomic.hpp"
  80 #include "runtime/fieldDescriptor.inline.hpp"

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

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

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

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

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

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

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