38 #include "classfile/symbolTable.hpp"
39 #include "classfile/systemDictionary.hpp"
40 #include "classfile/vmClasses.hpp"
41 #include "classfile/vmSymbols.hpp"
42 #include "compiler/compiler_globals.hpp"
43 #include "gc/shared/collectedHeap.hpp"
44 #include "gc/shared/gcLocker.inline.hpp"
45 #include "gc/shared/stringdedup/stringDedup.hpp"
46 #include "interpreter/linkResolver.hpp"
47 #include "jni.h"
48 #include "jvm.h"
49 #include "logging/log.hpp"
50 #include "memory/allocation.hpp"
51 #include "memory/allocation.inline.hpp"
52 #include "memory/oopFactory.hpp"
53 #include "memory/resourceArea.hpp"
54 #include "memory/universe.hpp"
55 #include "nmt/memTracker.hpp"
56 #include "oops/access.inline.hpp"
57 #include "oops/arrayOop.hpp"
58 #include "oops/instanceKlass.inline.hpp"
59 #include "oops/instanceOop.hpp"
60 #include "oops/klass.inline.hpp"
61 #include "oops/markWord.hpp"
62 #include "oops/method.hpp"
63 #include "oops/objArrayKlass.hpp"
64 #include "oops/objArrayOop.inline.hpp"
65 #include "oops/oop.inline.hpp"
66 #include "oops/symbol.hpp"
67 #include "oops/typeArrayKlass.hpp"
68 #include "oops/typeArrayOop.inline.hpp"
69 #include "prims/jniCheck.hpp"
70 #include "prims/jniExport.hpp"
71 #include "prims/jniFastGetField.hpp"
72 #include "prims/jvm_misc.hpp"
73 #include "prims/jvmtiExport.hpp"
74 #include "prims/jvmtiThreadState.hpp"
75 #include "runtime/arguments.hpp"
76 #include "runtime/atomic.hpp"
77 #include "runtime/fieldDescriptor.inline.hpp"
409 int modifiers = java_lang_reflect_Field::modifiers(reflected);
410
411 // Make sure class is initialized before handing id's out to fields
412 k1->initialize(CHECK_NULL);
413
414 // First check if this is a static field
415 if (modifiers & JVM_ACC_STATIC) {
416 int offset = InstanceKlass::cast(k1)->field_offset( slot );
417 JNIid* id = InstanceKlass::cast(k1)->jni_id_for(offset);
418 assert(id != nullptr, "corrupt Field object");
419 debug_only(id->set_is_static_field_id();)
420 // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
421 ret = jfieldIDWorkaround::to_static_jfieldID(id);
422 return ret;
423 }
424
425 // The slot is the index of the field description in the field-array
426 // The jfieldID is the offset of the field within the object
427 // It may also have hash bits for k, if VerifyJNIFields is turned on.
428 int offset = InstanceKlass::cast(k1)->field_offset( slot );
429 assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object");
430 ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset);
431 return ret;
432 JNI_END
433
434
435 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
436 , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
437
438 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
439 HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(env, cls, (uintptr_t) method_id, isStatic);
440
441 jobject ret = nullptr;
442 DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
443
444 methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
445 assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
446 oop reflection_method;
447 if (m->is_initializer()) {
448 reflection_method = Reflection::new_constructor(m, CHECK_NULL);
449 } else {
450 reflection_method = Reflection::new_method(m, false, CHECK_NULL);
451 }
452 ret = JNIHandles::make_local(THREAD, reflection_method);
453 return ret;
454 JNI_END
455
456 DT_RETURN_MARK_DECL(GetSuperclass, jclass
457 , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));
458
459 JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
460 HOTSPOT_JNI_GETSUPERCLASS_ENTRY(env, sub);
461
462 jclass obj = nullptr;
463 DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
464
465 oop mirror = JNIHandles::resolve_non_null(sub);
466 // primitive classes return null
467 if (java_lang_Class::is_primitive(mirror)) return nullptr;
785 }
786
787 friend class SignatureIterator; // so do_parameters_on can call do_type
788 void do_type(BasicType type) {
789 switch (type) {
790 // these are coerced to int when using va_arg
791 case T_BYTE:
792 case T_CHAR:
793 case T_SHORT:
794 case T_INT: push_int(va_arg(_ap, jint)); break;
795 case T_BOOLEAN: push_boolean((jboolean) va_arg(_ap, jint)); break;
796
797 // each of these paths is exercised by the various jck Call[Static,Nonvirtual,][Void,Int,..]Method[A,V,] tests
798
799 case T_LONG: push_long(va_arg(_ap, jlong)); break;
800 // float is coerced to double w/ va_arg
801 case T_FLOAT: push_float((jfloat) va_arg(_ap, jdouble)); break;
802 case T_DOUBLE: push_double(va_arg(_ap, jdouble)); break;
803
804 case T_ARRAY:
805 case T_OBJECT: push_object(va_arg(_ap, jobject)); break;
806 default: ShouldNotReachHere();
807 }
808 }
809
810 public:
811 JNI_ArgumentPusherVaArg(jmethodID method_id, va_list rap)
812 : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)) {
813 set_ap(rap);
814 }
815
816 ~JNI_ArgumentPusherVaArg() {
817 va_end(_ap);
818 }
819
820 virtual void push_arguments_on(JavaCallArguments* arguments) {
821 _arguments = arguments;
822 do_parameters_on(this);
823 }
824 };
825
826
827 class JNI_ArgumentPusherArray : public JNI_ArgumentPusher {
828 protected:
829 const jvalue *_ap;
830
831 inline void set_ap(const jvalue *rap) { _ap = rap; }
832
833 friend class SignatureIterator; // so do_parameters_on can call do_type
834 void do_type(BasicType type) {
835 switch (type) {
836 case T_CHAR: push_int((_ap++)->c); break;
837 case T_SHORT: push_int((_ap++)->s); break;
838 case T_BYTE: push_int((_ap++)->b); break;
839 case T_INT: push_int((_ap++)->i); break;
840 case T_BOOLEAN: push_boolean((_ap++)->z); break;
841 case T_LONG: push_long((_ap++)->j); break;
842 case T_FLOAT: push_float((_ap++)->f); break;
843 case T_DOUBLE: push_double((_ap++)->d); break;
844 case T_ARRAY:
845 case T_OBJECT: push_object((_ap++)->l); break;
846 default: ShouldNotReachHere();
847 }
848 }
849
850 public:
851 JNI_ArgumentPusherArray(jmethodID method_id, const jvalue *rap)
852 : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)) {
853 set_ap(rap);
854 }
855
856 virtual void push_arguments_on(JavaCallArguments* arguments) {
857 _arguments = arguments;
858 do_parameters_on(this);
859 }
860 };
861
862
863 enum JNICallType {
864 JNI_STATIC,
865 JNI_VIRTUAL,
947 result->set_type(args->return_type());
948
949 // Invoke the method. Result is returned as oop.
950 JavaCalls::call(result, method, &java_args, CHECK);
951
952 // Convert result
953 if (is_reference_type(result->get_type())) {
954 result->set_jobject(JNIHandles::make_local(THREAD, result->get_oop()));
955 }
956 }
957
958 DT_RETURN_MARK_DECL(AllocObject, jobject
959 , HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref));
960
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 // TODO: make this a template
1888
1889 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
1890 , EntryProbe, ReturnProbe) \
1891 \
1892 JNI_ENTRY_NO_PRESERVE(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
1893 \
1894 EntryProbe; \
1895 \
1896 oop o = JNIHandles::resolve_non_null(obj); \
1897 Klass* k = o->klass(); \
1898 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \
1899 /* Keep JVMTI addition small and only check enabled flag here. */ \
1900 if (JvmtiExport::should_post_field_modification()) { \
1901 jvalue field_value; \
1902 field_value.unionType = value; \
1903 o = JvmtiExport::jni_SetField_probe(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \
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 != nullptr) { // 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 = nullptr;
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 == nullptr || 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 = nullptr;\
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
|
38 #include "classfile/symbolTable.hpp"
39 #include "classfile/systemDictionary.hpp"
40 #include "classfile/vmClasses.hpp"
41 #include "classfile/vmSymbols.hpp"
42 #include "compiler/compiler_globals.hpp"
43 #include "gc/shared/collectedHeap.hpp"
44 #include "gc/shared/gcLocker.inline.hpp"
45 #include "gc/shared/stringdedup/stringDedup.hpp"
46 #include "interpreter/linkResolver.hpp"
47 #include "jni.h"
48 #include "jvm.h"
49 #include "logging/log.hpp"
50 #include "memory/allocation.hpp"
51 #include "memory/allocation.inline.hpp"
52 #include "memory/oopFactory.hpp"
53 #include "memory/resourceArea.hpp"
54 #include "memory/universe.hpp"
55 #include "nmt/memTracker.hpp"
56 #include "oops/access.inline.hpp"
57 #include "oops/arrayOop.hpp"
58 #include "oops/flatArrayOop.inline.hpp"
59 #include "oops/inlineKlass.inline.hpp"
60 #include "oops/instanceKlass.inline.hpp"
61 #include "oops/instanceOop.hpp"
62 #include "oops/klass.inline.hpp"
63 #include "oops/markWord.hpp"
64 #include "oops/method.hpp"
65 #include "oops/objArrayKlass.hpp"
66 #include "oops/objArrayOop.inline.hpp"
67 #include "oops/oop.inline.hpp"
68 #include "oops/symbol.hpp"
69 #include "oops/typeArrayKlass.hpp"
70 #include "oops/typeArrayOop.inline.hpp"
71 #include "prims/jniCheck.hpp"
72 #include "prims/jniExport.hpp"
73 #include "prims/jniFastGetField.hpp"
74 #include "prims/jvm_misc.hpp"
75 #include "prims/jvmtiExport.hpp"
76 #include "prims/jvmtiThreadState.hpp"
77 #include "runtime/arguments.hpp"
78 #include "runtime/atomic.hpp"
79 #include "runtime/fieldDescriptor.inline.hpp"
411 int modifiers = java_lang_reflect_Field::modifiers(reflected);
412
413 // Make sure class is initialized before handing id's out to fields
414 k1->initialize(CHECK_NULL);
415
416 // First check if this is a static field
417 if (modifiers & JVM_ACC_STATIC) {
418 int offset = InstanceKlass::cast(k1)->field_offset( slot );
419 JNIid* id = InstanceKlass::cast(k1)->jni_id_for(offset);
420 assert(id != nullptr, "corrupt Field object");
421 debug_only(id->set_is_static_field_id();)
422 // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
423 ret = jfieldIDWorkaround::to_static_jfieldID(id);
424 return ret;
425 }
426
427 // The slot is the index of the field description in the field-array
428 // The jfieldID is the offset of the field within the object
429 // It may also have hash bits for k, if VerifyJNIFields is turned on.
430 int offset = InstanceKlass::cast(k1)->field_offset( slot );
431 bool is_flat = InstanceKlass::cast(k1)->field_is_flat(slot);
432 assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object");
433 ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset, is_flat);
434 return ret;
435 JNI_END
436
437
438 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
439 , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
440
441 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
442 HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(env, cls, (uintptr_t) method_id, isStatic);
443
444 jobject ret = nullptr;
445 DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
446
447 methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
448 assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
449 oop reflection_method;
450 if (m->is_object_constructor()) {
451 reflection_method = Reflection::new_constructor(m, CHECK_NULL);
452 } else {
453 reflection_method = Reflection::new_method(m, false, CHECK_NULL);
454 }
455 ret = JNIHandles::make_local(THREAD, reflection_method);
456 return ret;
457 JNI_END
458
459 DT_RETURN_MARK_DECL(GetSuperclass, jclass
460 , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));
461
462 JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
463 HOTSPOT_JNI_GETSUPERCLASS_ENTRY(env, sub);
464
465 jclass obj = nullptr;
466 DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
467
468 oop mirror = JNIHandles::resolve_non_null(sub);
469 // primitive classes return null
470 if (java_lang_Class::is_primitive(mirror)) return nullptr;
788 }
789
790 friend class SignatureIterator; // so do_parameters_on can call do_type
791 void do_type(BasicType type) {
792 switch (type) {
793 // these are coerced to int when using va_arg
794 case T_BYTE:
795 case T_CHAR:
796 case T_SHORT:
797 case T_INT: push_int(va_arg(_ap, jint)); break;
798 case T_BOOLEAN: push_boolean((jboolean) va_arg(_ap, jint)); break;
799
800 // each of these paths is exercised by the various jck Call[Static,Nonvirtual,][Void,Int,..]Method[A,V,] tests
801
802 case T_LONG: push_long(va_arg(_ap, jlong)); break;
803 // float is coerced to double w/ va_arg
804 case T_FLOAT: push_float((jfloat) va_arg(_ap, jdouble)); break;
805 case T_DOUBLE: push_double(va_arg(_ap, jdouble)); break;
806
807 case T_ARRAY:
808 case T_OBJECT: push_object(va_arg(_ap, jobject)); break;
809 default: ShouldNotReachHere();
810 }
811 }
812
813 public:
814 JNI_ArgumentPusherVaArg(jmethodID method_id, va_list rap)
815 : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)) {
816 set_ap(rap);
817 }
818
819 ~JNI_ArgumentPusherVaArg() {
820 va_end(_ap);
821 }
822
823 virtual void push_arguments_on(JavaCallArguments* arguments) {
824 _arguments = arguments;
825 do_parameters_on(this);
826 }
827 };
828
829
830 class JNI_ArgumentPusherArray : public JNI_ArgumentPusher {
831 protected:
832 const jvalue *_ap;
833
834 inline void set_ap(const jvalue *rap) { _ap = rap; }
835
836 friend class SignatureIterator; // so do_parameters_on can call do_type
837 void do_type(BasicType type) {
838 switch (type) {
839 case T_CHAR: push_int((_ap++)->c); break;
840 case T_SHORT: push_int((_ap++)->s); break;
841 case T_BYTE: push_int((_ap++)->b); break;
842 case T_INT: push_int((_ap++)->i); break;
843 case T_BOOLEAN: push_boolean((_ap++)->z); break;
844 case T_LONG: push_long((_ap++)->j); break;
845 case T_FLOAT: push_float((_ap++)->f); break;
846 case T_DOUBLE: push_double((_ap++)->d); break;
847 case T_ARRAY:
848 case T_OBJECT:
849 case T_PRIMITIVE_OBJECT: push_object((_ap++)->l); break;
850 default: ShouldNotReachHere();
851 }
852 }
853
854 public:
855 JNI_ArgumentPusherArray(jmethodID method_id, const jvalue *rap)
856 : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)) {
857 set_ap(rap);
858 }
859
860 virtual void push_arguments_on(JavaCallArguments* arguments) {
861 _arguments = arguments;
862 do_parameters_on(this);
863 }
864 };
865
866
867 enum JNICallType {
868 JNI_STATIC,
869 JNI_VIRTUAL,
951 result->set_type(args->return_type());
952
953 // Invoke the method. Result is returned as oop.
954 JavaCalls::call(result, method, &java_args, CHECK);
955
956 // Convert result
957 if (is_reference_type(result->get_type())) {
958 result->set_jobject(JNIHandles::make_local(THREAD, result->get_oop()));
959 }
960 }
961
962 DT_RETURN_MARK_DECL(AllocObject, jobject
963 , HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref));
964
965 JNI_ENTRY(jobject, jni_AllocObject(JNIEnv *env, jclass clazz))
966 HOTSPOT_JNI_ALLOCOBJECT_ENTRY(env, clazz);
967
968 jobject ret = nullptr;
969 DT_RETURN_MARK(AllocObject, jobject, (const jobject&)ret);
970
971 oop clazzoop = JNIHandles::resolve_non_null(clazz);
972 Klass* k = java_lang_Class::as_Klass(clazzoop);
973 if (k == nullptr || k->is_inline_klass()) {
974 ResourceMark rm(THREAD);
975 THROW_(vmSymbols::java_lang_InstantiationException(), nullptr);
976 }
977 instanceOop i = InstanceKlass::allocate_instance(clazzoop, CHECK_NULL);
978 ret = JNIHandles::make_local(THREAD, i);
979 return ret;
980 JNI_END
981
982 DT_RETURN_MARK_DECL(NewObjectA, jobject
983 , HOTSPOT_JNI_NEWOBJECTA_RETURN(_ret_ref));
984
985 JNI_ENTRY(jobject, jni_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args))
986 HOTSPOT_JNI_NEWOBJECTA_ENTRY(env, clazz, (uintptr_t) methodID);
987
988 jobject obj = nullptr;
989 DT_RETURN_MARK(NewObjectA, jobject, (const jobject&)obj);
990
991 oop clazzoop = JNIHandles::resolve_non_null(clazz);
992 Klass* k = java_lang_Class::as_Klass(clazzoop);
993 if (k == nullptr) {
994 ResourceMark rm(THREAD);
995 THROW_(vmSymbols::java_lang_InstantiationException(), nullptr);
996 }
997
998 instanceOop i = InstanceKlass::allocate_instance(clazzoop, CHECK_NULL);
999 obj = JNIHandles::make_local(THREAD, i);
1000 JavaValue jvalue(T_VOID);
1001 JNI_ArgumentPusherArray ap(methodID, args);
1002 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1003
1004 return obj;
1005 JNI_END
1006
1007
1008 DT_RETURN_MARK_DECL(NewObjectV, jobject
1009 , HOTSPOT_JNI_NEWOBJECTV_RETURN(_ret_ref));
1010
1011 JNI_ENTRY(jobject, jni_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args))
1012 HOTSPOT_JNI_NEWOBJECTV_ENTRY(env, clazz, (uintptr_t) methodID);
1013
1014 jobject obj = nullptr;
1015 DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj);
1016
1017 oop clazzoop = JNIHandles::resolve_non_null(clazz);
1018 Klass* k = java_lang_Class::as_Klass(clazzoop);
1019 if (k == nullptr) {
1020 ResourceMark rm(THREAD);
1021 THROW_(vmSymbols::java_lang_InstantiationException(), nullptr);
1022 }
1023
1024 instanceOop i = InstanceKlass::allocate_instance(clazzoop, CHECK_NULL);
1025 obj = JNIHandles::make_local(THREAD, i);
1026 JavaValue jvalue(T_VOID);
1027 JNI_ArgumentPusherVaArg ap(methodID, args);
1028 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1029
1030 return obj;
1031 JNI_END
1032
1033
1034 DT_RETURN_MARK_DECL(NewObject, jobject
1035 , HOTSPOT_JNI_NEWOBJECT_RETURN(_ret_ref));
1036
1037 JNI_ENTRY(jobject, jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...))
1038 HOTSPOT_JNI_NEWOBJECT_ENTRY(env, clazz, (uintptr_t) methodID);
1039
1040 jobject obj = nullptr;
1041 DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj);
1042
1043 oop clazzoop = JNIHandles::resolve_non_null(clazz);
1044 Klass* k = java_lang_Class::as_Klass(clazzoop);
1045 if (k == nullptr) {
1046 ResourceMark rm(THREAD);
1047 THROW_(vmSymbols::java_lang_InstantiationException(), nullptr);
1048 }
1049
1050 instanceOop i = InstanceKlass::allocate_instance(clazzoop, CHECK_NULL);
1051 obj = JNIHandles::make_local(THREAD, i);
1052 va_list args;
1053 va_start(args, methodID);
1054 JavaValue jvalue(T_VOID);
1055 JNI_ArgumentPusherVaArg ap(methodID, args);
1056 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1057 va_end(args);
1058
1059 return obj;
1060 JNI_END
1061
1062
1063 JNI_ENTRY(jclass, jni_GetObjectClass(JNIEnv *env, jobject obj))
1064 HOTSPOT_JNI_GETOBJECTCLASS_ENTRY(env, obj);
1065
1066 Klass* k = JNIHandles::resolve_non_null(obj)->klass();
1067 jclass ret =
1068 (jclass) JNIHandles::make_local(THREAD, k->java_mirror());
1069
1070 HOTSPOT_JNI_GETOBJECTCLASS_RETURN(ret);
1071 return ret;
1072 JNI_END
1073
1074 JNI_ENTRY_NO_PRESERVE(jboolean, jni_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz))
1075 HOTSPOT_JNI_ISINSTANCEOF_ENTRY(env, obj, clazz);
1076
1077 jboolean ret = JNI_TRUE;
1078 if (obj != nullptr) {
1789 // table. If they're not there, the field doesn't exist.
1790 TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
1791 TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
1792 if (fieldname == nullptr || signame == nullptr) {
1793 ResourceMark rm;
1794 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
1795 }
1796
1797 // Make sure class is initialized before handing id's out to fields
1798 k->initialize(CHECK_NULL);
1799
1800 fieldDescriptor fd;
1801 if (!k->is_instance_klass() ||
1802 !InstanceKlass::cast(k)->find_field(fieldname, signame, false, &fd)) {
1803 ResourceMark rm;
1804 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
1805 }
1806
1807 // A jfieldID for a non-static field is simply the offset of the field within the instanceOop
1808 // It may also have hash bits for k, if VerifyJNIFields is turned on.
1809 ret = jfieldIDWorkaround::to_instance_jfieldID(k, fd.offset(), fd.is_flat());
1810 return ret;
1811 JNI_END
1812
1813
1814 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
1815 HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID);
1816 oop o = JNIHandles::resolve_non_null(obj);
1817 Klass* k = o->klass();
1818 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
1819 oop res = nullptr;
1820 // Keep JVMTI addition small and only check enabled flag here.
1821 // jni_GetField_probe() assumes that is okay to create handles.
1822 if (JvmtiExport::should_post_field_access()) {
1823 o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
1824 }
1825 if (!jfieldIDWorkaround::is_flat_jfieldID(fieldID)) {
1826 res = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(o, offset);
1827 } else {
1828 assert(k->is_instance_klass(), "Only instance can have flat fields");
1829 InstanceKlass* ik = InstanceKlass::cast(k);
1830 fieldDescriptor fd;
1831 ik->find_field_from_offset(offset, false, &fd); // performance bottleneck
1832 InstanceKlass* holder = fd.field_holder();
1833 InlineKlass* field_vklass = InlineKlass::cast(holder->get_inline_type_field_klass(fd.index()));
1834 res = field_vklass->read_flat_field(o, ik->field_offset(fd.index()), CHECK_NULL);
1835 }
1836 jobject ret = JNIHandles::make_local(THREAD, res);
1837 HOTSPOT_JNI_GETOBJECTFIELD_RETURN(ret);
1838 return ret;
1839 JNI_END
1840
1841
1842
1843 #define DEFINE_GETFIELD(Return,Fieldname,Result \
1844 , EntryProbe, ReturnProbe) \
1845 \
1846 DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return \
1847 , ReturnProbe); \
1848 \
1849 JNI_ENTRY_NO_PRESERVE(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \
1850 \
1851 EntryProbe; \
1852 Return ret = 0;\
1853 DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\
1854 \
1855 oop o = JNIHandles::resolve_non_null(obj); \
1856 Klass* k = o->klass(); \
1908 return (address)jni_GetLongField;
1909 }
1910 address jni_GetFloatField_addr() {
1911 return (address)jni_GetFloatField;
1912 }
1913 address jni_GetDoubleField_addr() {
1914 return (address)jni_GetDoubleField;
1915 }
1916
1917 JNI_ENTRY_NO_PRESERVE(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
1918 HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID, value);
1919 oop o = JNIHandles::resolve_non_null(obj);
1920 Klass* k = o->klass();
1921 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
1922 // Keep JVMTI addition small and only check enabled flag here.
1923 if (JvmtiExport::should_post_field_modification()) {
1924 jvalue field_value;
1925 field_value.l = value;
1926 o = JvmtiExport::jni_SetField_probe(thread, obj, o, k, fieldID, false, JVM_SIGNATURE_CLASS, (jvalue *)&field_value);
1927 }
1928 if (!jfieldIDWorkaround::is_flat_jfieldID(fieldID)) {
1929 HeapAccess<ON_UNKNOWN_OOP_REF>::oop_store_at(o, offset, JNIHandles::resolve(value));
1930 } else {
1931 assert(k->is_instance_klass(), "Only instances can have flat fields");
1932 InstanceKlass* ik = InstanceKlass::cast(k);
1933 fieldDescriptor fd;
1934 ik->find_field_from_offset(offset, false, &fd);
1935 InstanceKlass* holder = fd.field_holder();
1936 InlineKlass* vklass = InlineKlass::cast(holder->get_inline_type_field_klass(fd.index()));
1937 oop v = JNIHandles::resolve_non_null(value);
1938 vklass->write_flat_field(o, offset, v, CHECK);
1939 }
1940 HOTSPOT_JNI_SETOBJECTFIELD_RETURN();
1941 JNI_END
1942
1943 // TODO: make this a template
1944
1945 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
1946 , EntryProbe, ReturnProbe) \
1947 \
1948 JNI_ENTRY_NO_PRESERVE(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
1949 \
1950 EntryProbe; \
1951 \
1952 oop o = JNIHandles::resolve_non_null(obj); \
1953 Klass* k = o->klass(); \
1954 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \
1955 /* Keep JVMTI addition small and only check enabled flag here. */ \
1956 if (JvmtiExport::should_post_field_modification()) { \
1957 jvalue field_value; \
1958 field_value.unionType = value; \
1959 o = JvmtiExport::jni_SetField_probe(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \
2335 Klass* ak = ek->array_klass(CHECK_NULL);
2336 ObjArrayKlass::cast(ak)->initialize(CHECK_NULL);
2337 objArrayOop result = ObjArrayKlass::cast(ak)->allocate(length, CHECK_NULL);
2338 oop initial_value = JNIHandles::resolve(initialElement);
2339 if (initial_value != nullptr) { // array already initialized with null
2340 for (int index = 0; index < length; index++) {
2341 result->obj_at_put(index, initial_value);
2342 }
2343 }
2344 ret = (jobjectArray) JNIHandles::make_local(THREAD, result);
2345 return ret;
2346 JNI_END
2347
2348 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
2349 , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
2350
2351 JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
2352 HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(env, array, index);
2353 jobject ret = nullptr;
2354 DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
2355 oop res = nullptr;
2356 arrayOop arr((arrayOop)JNIHandles::resolve_non_null(array));
2357 if (arr->is_within_bounds(index)) {
2358 if (arr->is_flatArray()) {
2359 flatArrayOop a = flatArrayOop(JNIHandles::resolve_non_null(array));
2360 flatArrayHandle vah(thread, a);
2361 res = flatArrayOopDesc::value_alloc_copy_from_index(vah, index, CHECK_NULL);
2362 assert(res != nullptr, "Must be set in one of two paths above");
2363 } else {
2364 assert(arr->is_objArray(), "If not a valueArray. must be an objArray");
2365 objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2366 res = a->obj_at(index);
2367 }
2368 } else {
2369 ResourceMark rm(THREAD);
2370 stringStream ss;
2371 ss.print("Index %d out of bounds for length %d", index,arr->length());
2372 THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2373 }
2374 ret = JNIHandles::make_local(THREAD, res);
2375 return ret;
2376 JNI_END
2377
2378 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
2379 , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
2380
2381 JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
2382 HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(env, array, index, value);
2383 DT_VOID_RETURN_MARK(SetObjectArrayElement);
2384
2385 bool oob = false;
2386 int length = -1;
2387 oop res = nullptr;
2388 arrayOop arr((arrayOop)JNIHandles::resolve_non_null(array));
2389 if (arr->is_within_bounds(index)) {
2390 if (arr->is_flatArray()) {
2391 flatArrayOop a = flatArrayOop(JNIHandles::resolve_non_null(array));
2392 oop v = JNIHandles::resolve(value);
2393 FlatArrayKlass* vaklass = FlatArrayKlass::cast(a->klass());
2394 InlineKlass* element_vklass = vaklass->element_klass();
2395 if (v != nullptr && v->is_a(element_vklass)) {
2396 a->value_copy_to_index(v, index);
2397 } else {
2398 ResourceMark rm(THREAD);
2399 stringStream ss;
2400 Klass *kl = FlatArrayKlass::cast(a->klass());
2401 ss.print("type mismatch: can not store %s to %s[%d]",
2402 v->klass()->external_name(),
2403 kl->external_name(),
2404 index);
2405 for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
2406 ss.print("[]");
2407 }
2408 THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
2409 }
2410 } else {
2411 assert(arr->is_objArray(), "If not a valueArray. must be an objArray");
2412 objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2413 oop v = JNIHandles::resolve(value);
2414 if (v == nullptr || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) {
2415 a->obj_at_put(index, v);
2416 } else {
2417 ResourceMark rm(THREAD);
2418 stringStream ss;
2419 Klass *bottom_kl = ObjArrayKlass::cast(a->klass())->bottom_klass();
2420 ss.print("type mismatch: can not store %s to %s[%d]",
2421 v->klass()->external_name(),
2422 bottom_kl->is_typeArray_klass() ? type2name_tab[ArrayKlass::cast(bottom_kl)->element_type()] : bottom_kl->external_name(),
2423 index);
2424 for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
2425 ss.print("[]");
2426 }
2427 THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
2428 }
2429 }
2430 } else {
2431 ResourceMark rm(THREAD);
2432 stringStream ss;
2433 ss.print("Index %d out of bounds for length %d", index, arr->length());
2434 THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2435 }
2436 JNI_END
2437
2438
2439
2440 #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result \
2441 ,EntryProbe,ReturnProbe) \
2442 \
2443 DT_RETURN_MARK_DECL(New##Result##Array, Return \
2444 , ReturnProbe); \
2445 \
2446 JNI_ENTRY(Return, \
2447 jni_New##Result##Array(JNIEnv *env, jsize len)) \
2448 EntryProbe; \
2449 Return ret = nullptr;\
2450 DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
2451 \
2452 oop obj= oopFactory::Allocator(len, CHECK_NULL); \
2453 ret = (Return) JNIHandles::make_local(THREAD, obj); \
2454 return ret;\
2455 JNI_END
|