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
|