41 #include "jfr/jfrEvents.hpp"
42 #include "jfr/support/jfrThreadId.hpp"
43 #include "logging/log.hpp"
44 #include "memory/allocation.hpp"
45 #include "memory/allocation.inline.hpp"
46 #include "memory/oopFactory.hpp"
47 #include "memory/resourceArea.hpp"
48 #include "memory/universe.hpp"
49 #include "oops/access.inline.hpp"
50 #include "oops/arrayOop.inline.hpp"
51 #include "oops/instanceKlass.hpp"
52 #include "oops/instanceOop.hpp"
53 #include "oops/markWord.hpp"
54 #include "oops/method.hpp"
55 #include "oops/objArrayKlass.hpp"
56 #include "oops/objArrayOop.inline.hpp"
57 #include "oops/oop.inline.hpp"
58 #include "oops/symbol.hpp"
59 #include "oops/typeArrayKlass.hpp"
60 #include "oops/typeArrayOop.inline.hpp"
61 #include "oops/valueKlass.inline.hpp"
62 #include "prims/jniCheck.hpp"
63 #include "prims/jniExport.hpp"
64 #include "prims/jniFastGetField.hpp"
65 #include "prims/jvm_misc.hpp"
66 #include "prims/jvmtiExport.hpp"
67 #include "prims/jvmtiThreadState.hpp"
68 #include "runtime/atomic.hpp"
69 #include "runtime/compilationPolicy.hpp"
70 #include "runtime/fieldDescriptor.inline.hpp"
71 #include "runtime/handles.inline.hpp"
72 #include "runtime/interfaceSupport.inline.hpp"
73 #include "runtime/java.hpp"
74 #include "runtime/javaCalls.hpp"
75 #include "runtime/jfieldIDWorkaround.hpp"
76 #include "runtime/jniHandles.inline.hpp"
77 #include "runtime/orderAccess.hpp"
78 #include "runtime/reflection.hpp"
79 #include "runtime/safepointVerifiers.hpp"
80 #include "runtime/sharedRuntime.hpp"
480 int modifiers = java_lang_reflect_Field::modifiers(reflected);
481
482 // Make sure class is initialized before handing id's out to fields
483 k1->initialize(CHECK_NULL);
484
485 // First check if this is a static field
486 if (modifiers & JVM_ACC_STATIC) {
487 intptr_t offset = InstanceKlass::cast(k1)->field_offset( slot );
488 JNIid* id = InstanceKlass::cast(k1)->jni_id_for(offset);
489 assert(id != NULL, "corrupt Field object");
490 debug_only(id->set_is_static_field_id();)
491 // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
492 ret = jfieldIDWorkaround::to_static_jfieldID(id);
493 return ret;
494 }
495
496 // The slot is the index of the field description in the field-array
497 // The jfieldID is the offset of the field within the object
498 // It may also have hash bits for k, if VerifyJNIFields is turned on.
499 intptr_t offset = InstanceKlass::cast(k1)->field_offset( slot );
500 assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object");
501 ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset);
502 return ret;
503 JNI_END
504
505
506 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
507 , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
508
509 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
510 JNIWrapper("ToReflectedMethod");
511
512 HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(env, cls, (uintptr_t) method_id, isStatic);
513
514 jobject ret = NULL;
515 DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
516
517 methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
518 assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
519 oop reflection_method;
520 if (m->is_object_constructor()) {
521 reflection_method = Reflection::new_constructor(m, CHECK_NULL);
2033 // table. If they're not there, the field doesn't exist.
2034 TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
2035 TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
2036 if (fieldname == NULL || signame == NULL) {
2037 ResourceMark rm;
2038 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
2039 }
2040
2041 // Make sure class is initialized before handing id's out to fields
2042 k->initialize(CHECK_NULL);
2043
2044 fieldDescriptor fd;
2045 if (!k->is_instance_klass() ||
2046 !InstanceKlass::cast(k)->find_field(fieldname, signame, false, &fd)) {
2047 ResourceMark rm;
2048 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
2049 }
2050
2051 // A jfieldID for a non-static field is simply the offset of the field within the instanceOop
2052 // It may also have hash bits for k, if VerifyJNIFields is turned on.
2053 ret = jfieldIDWorkaround::to_instance_jfieldID(k, fd.offset());
2054 return ret;
2055 JNI_END
2056
2057
2058 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
2059 JNIWrapper("GetObjectField");
2060 HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID);
2061 oop o = JNIHandles::resolve_non_null(obj);
2062 Klass* k = o->klass();
2063 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2064 // Keep JVMTI addition small and only check enabled flag here.
2065 // jni_GetField_probe() assumes that is okay to create handles.
2066 if (JvmtiExport::should_post_field_access()) {
2067 o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
2068 }
2069 oop loaded_obj = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(o, offset);
2070 jobject ret = JNIHandles::make_local(env, loaded_obj);
2071 HOTSPOT_JNI_GETOBJECTFIELD_RETURN(ret);
2072 return ret;
2073 JNI_END
2074
2075
2076
2077 #define DEFINE_GETFIELD(Return,Fieldname,Result \
2078 , EntryProbe, ReturnProbe) \
2079 \
2080 DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return \
2081 , ReturnProbe); \
2082 \
2083 JNI_ENTRY_NO_PRESERVE(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \
2084 JNIWrapper("Get" XSTR(Result) "Field"); \
2085 \
2086 EntryProbe; \
2087 Return ret = 0;\
2088 DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\
2089 \
2090 oop o = JNIHandles::resolve_non_null(obj); \
2148 return (address)jni_GetFloatField;
2149 }
2150 address jni_GetDoubleField_addr() {
2151 return (address)jni_GetDoubleField;
2152 }
2153
2154 JNI_ENTRY_NO_PRESERVE(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
2155 JNIWrapper("SetObjectField");
2156 HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID, value);
2157 oop o = JNIHandles::resolve_non_null(obj);
2158 Klass* k = o->klass();
2159 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2160 // Keep JVMTI addition small and only check enabled flag here.
2161 // jni_SetField_probe_nh() assumes that is not okay to create handles
2162 // and creates a ResetNoHandleMark.
2163 if (JvmtiExport::should_post_field_modification()) {
2164 jvalue field_value;
2165 field_value.l = value;
2166 o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, 'L', (jvalue *)&field_value);
2167 }
2168 HeapAccess<ON_UNKNOWN_OOP_REF>::oop_store_at(o, offset, JNIHandles::resolve(value));
2169 HOTSPOT_JNI_SETOBJECTFIELD_RETURN();
2170 JNI_END
2171
2172
2173 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
2174 , EntryProbe, ReturnProbe) \
2175 \
2176 JNI_ENTRY_NO_PRESERVE(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
2177 JNIWrapper("Set" XSTR(Result) "Field"); \
2178 \
2179 EntryProbe; \
2180 \
2181 oop o = JNIHandles::resolve_non_null(obj); \
2182 Klass* k = o->klass(); \
2183 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \
2184 /* Keep JVMTI addition small and only check enabled flag here. */ \
2185 /* jni_SetField_probe_nh() assumes that is not okay to create handles */ \
2186 /* and creates a ResetNoHandleMark. */ \
2187 if (JvmtiExport::should_post_field_modification()) { \
2188 jvalue field_value; \
2585 ObjArrayKlass::cast(ak)->initialize(CHECK_NULL);
2586 objArrayOop result = ObjArrayKlass::cast(ak)->allocate(length, CHECK_NULL);
2587 oop initial_value = JNIHandles::resolve(initialElement);
2588 if (initial_value != NULL) { // array already initialized with NULL
2589 for (int index = 0; index < length; index++) {
2590 result->obj_at_put(index, initial_value);
2591 }
2592 }
2593 ret = (jobjectArray) JNIHandles::make_local(env, result);
2594 return ret;
2595 JNI_END
2596
2597 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
2598 , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
2599
2600 JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
2601 JNIWrapper("GetObjectArrayElement");
2602 HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(env, array, index);
2603 jobject ret = NULL;
2604 DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
2605 objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2606 if (a->is_within_bounds(index)) {
2607 ret = JNIHandles::make_local(env, a->obj_at(index));
2608 return ret;
2609 } else {
2610 ResourceMark rm(THREAD);
2611 stringStream ss;
2612 ss.print("Index %d out of bounds for length %d", index, a->length());
2613 THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2614 }
2615 JNI_END
2616
2617 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
2618 , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
2619
2620 JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
2621 JNIWrapper("SetObjectArrayElement");
2622 HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(env, array, index, value);
2623 DT_VOID_RETURN_MARK(SetObjectArrayElement);
2624
2625 objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2626 oop v = JNIHandles::resolve(value);
2627 if (a->is_within_bounds(index)) {
2628 if (v == NULL || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) {
2629 a->obj_at_put(index, v);
2630 } else {
2631 ResourceMark rm(THREAD);
2632 stringStream ss;
2633 Klass *bottom_kl = ObjArrayKlass::cast(a->klass())->bottom_klass();
2634 ss.print("type mismatch: can not store %s to %s[%d]",
2635 v->klass()->external_name(),
2636 bottom_kl->is_typeArray_klass() ? type2name_tab[ArrayKlass::cast(bottom_kl)->element_type()] : bottom_kl->external_name(),
2637 index);
2638 for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
2639 ss.print("[]");
2640 }
2641 THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
2642 }
2643 } else {
2644 ResourceMark rm(THREAD);
2645 stringStream ss;
2646 ss.print("Index %d out of bounds for length %d", index, a->length());
2647 THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2648 }
2649 JNI_END
2650
2651
2652
2653 #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result \
2654 ,EntryProbe,ReturnProbe) \
2655 \
2656 DT_RETURN_MARK_DECL(New##Result##Array, Return \
2657 , ReturnProbe); \
2658 \
2659 JNI_ENTRY(Return, \
2660 jni_New##Result##Array(JNIEnv *env, jsize len)) \
2661 JNIWrapper("New" XSTR(Result) "Array"); \
2662 EntryProbe; \
2663 Return ret = NULL;\
2664 DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
2665 \
2666 oop obj= oopFactory::Allocator(len, CHECK_0); \
|
41 #include "jfr/jfrEvents.hpp"
42 #include "jfr/support/jfrThreadId.hpp"
43 #include "logging/log.hpp"
44 #include "memory/allocation.hpp"
45 #include "memory/allocation.inline.hpp"
46 #include "memory/oopFactory.hpp"
47 #include "memory/resourceArea.hpp"
48 #include "memory/universe.hpp"
49 #include "oops/access.inline.hpp"
50 #include "oops/arrayOop.inline.hpp"
51 #include "oops/instanceKlass.hpp"
52 #include "oops/instanceOop.hpp"
53 #include "oops/markWord.hpp"
54 #include "oops/method.hpp"
55 #include "oops/objArrayKlass.hpp"
56 #include "oops/objArrayOop.inline.hpp"
57 #include "oops/oop.inline.hpp"
58 #include "oops/symbol.hpp"
59 #include "oops/typeArrayKlass.hpp"
60 #include "oops/typeArrayOop.inline.hpp"
61 #include "oops/valueArrayOop.inline.hpp"
62 #include "oops/valueKlass.inline.hpp"
63 #include "prims/jniCheck.hpp"
64 #include "prims/jniExport.hpp"
65 #include "prims/jniFastGetField.hpp"
66 #include "prims/jvm_misc.hpp"
67 #include "prims/jvmtiExport.hpp"
68 #include "prims/jvmtiThreadState.hpp"
69 #include "runtime/atomic.hpp"
70 #include "runtime/compilationPolicy.hpp"
71 #include "runtime/fieldDescriptor.inline.hpp"
72 #include "runtime/handles.inline.hpp"
73 #include "runtime/interfaceSupport.inline.hpp"
74 #include "runtime/java.hpp"
75 #include "runtime/javaCalls.hpp"
76 #include "runtime/jfieldIDWorkaround.hpp"
77 #include "runtime/jniHandles.inline.hpp"
78 #include "runtime/orderAccess.hpp"
79 #include "runtime/reflection.hpp"
80 #include "runtime/safepointVerifiers.hpp"
81 #include "runtime/sharedRuntime.hpp"
481 int modifiers = java_lang_reflect_Field::modifiers(reflected);
482
483 // Make sure class is initialized before handing id's out to fields
484 k1->initialize(CHECK_NULL);
485
486 // First check if this is a static field
487 if (modifiers & JVM_ACC_STATIC) {
488 intptr_t offset = InstanceKlass::cast(k1)->field_offset( slot );
489 JNIid* id = InstanceKlass::cast(k1)->jni_id_for(offset);
490 assert(id != NULL, "corrupt Field object");
491 debug_only(id->set_is_static_field_id();)
492 // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
493 ret = jfieldIDWorkaround::to_static_jfieldID(id);
494 return ret;
495 }
496
497 // The slot is the index of the field description in the field-array
498 // The jfieldID is the offset of the field within the object
499 // It may also have hash bits for k, if VerifyJNIFields is turned on.
500 intptr_t offset = InstanceKlass::cast(k1)->field_offset( slot );
501 bool is_flattened = InstanceKlass::cast(k1)->field_is_flattened(slot);
502 assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object");
503 ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset, is_flattened);
504 return ret;
505 JNI_END
506
507
508 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
509 , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
510
511 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
512 JNIWrapper("ToReflectedMethod");
513
514 HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(env, cls, (uintptr_t) method_id, isStatic);
515
516 jobject ret = NULL;
517 DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
518
519 methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
520 assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
521 oop reflection_method;
522 if (m->is_object_constructor()) {
523 reflection_method = Reflection::new_constructor(m, CHECK_NULL);
2035 // table. If they're not there, the field doesn't exist.
2036 TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
2037 TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
2038 if (fieldname == NULL || signame == NULL) {
2039 ResourceMark rm;
2040 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
2041 }
2042
2043 // Make sure class is initialized before handing id's out to fields
2044 k->initialize(CHECK_NULL);
2045
2046 fieldDescriptor fd;
2047 if (!k->is_instance_klass() ||
2048 !InstanceKlass::cast(k)->find_field(fieldname, signame, false, &fd)) {
2049 ResourceMark rm;
2050 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
2051 }
2052
2053 // A jfieldID for a non-static field is simply the offset of the field within the instanceOop
2054 // It may also have hash bits for k, if VerifyJNIFields is turned on.
2055 ret = jfieldIDWorkaround::to_instance_jfieldID(k, fd.offset(), fd.is_flattened());
2056 return ret;
2057 JNI_END
2058
2059
2060 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
2061 JNIWrapper("GetObjectField");
2062 HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID);
2063 oop o = JNIHandles::resolve_non_null(obj);
2064 Klass* k = o->klass();
2065 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2066 oop res = NULL;
2067 // Keep JVMTI addition small and only check enabled flag here.
2068 // jni_GetField_probe() assumes that is okay to create handles.
2069 if (JvmtiExport::should_post_field_access()) {
2070 o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
2071 }
2072 if (!jfieldIDWorkaround::is_flattened_field(fieldID)) {
2073 res = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(o, offset);
2074 } else {
2075 assert(k->is_instance_klass(), "Only instance can have flattened fields");
2076 InstanceKlass* ik = InstanceKlass::cast(k);
2077 fieldDescriptor fd;
2078 ik->find_field_from_offset(offset, false, &fd); // performance bottleneck
2079 InstanceKlass* holder = fd.field_holder();
2080 ValueKlass* field_vklass = ValueKlass::cast(holder->get_value_field_klass(fd.index()));
2081 res = field_vklass->read_flattened_field(o, ik->field_offset(fd.index()), CHECK_NULL);
2082 }
2083 jobject ret = JNIHandles::make_local(env, res);
2084 HOTSPOT_JNI_GETOBJECTFIELD_RETURN(ret);
2085 return ret;
2086 JNI_END
2087
2088
2089
2090 #define DEFINE_GETFIELD(Return,Fieldname,Result \
2091 , EntryProbe, ReturnProbe) \
2092 \
2093 DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return \
2094 , ReturnProbe); \
2095 \
2096 JNI_ENTRY_NO_PRESERVE(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \
2097 JNIWrapper("Get" XSTR(Result) "Field"); \
2098 \
2099 EntryProbe; \
2100 Return ret = 0;\
2101 DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\
2102 \
2103 oop o = JNIHandles::resolve_non_null(obj); \
2161 return (address)jni_GetFloatField;
2162 }
2163 address jni_GetDoubleField_addr() {
2164 return (address)jni_GetDoubleField;
2165 }
2166
2167 JNI_ENTRY_NO_PRESERVE(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
2168 JNIWrapper("SetObjectField");
2169 HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID, value);
2170 oop o = JNIHandles::resolve_non_null(obj);
2171 Klass* k = o->klass();
2172 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2173 // Keep JVMTI addition small and only check enabled flag here.
2174 // jni_SetField_probe_nh() assumes that is not okay to create handles
2175 // and creates a ResetNoHandleMark.
2176 if (JvmtiExport::should_post_field_modification()) {
2177 jvalue field_value;
2178 field_value.l = value;
2179 o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, 'L', (jvalue *)&field_value);
2180 }
2181 if (!jfieldIDWorkaround::is_flattened_field(fieldID)) {
2182 HeapAccess<ON_UNKNOWN_OOP_REF>::oop_store_at(o, offset, JNIHandles::resolve(value));
2183 } else {
2184 assert(k->is_instance_klass(), "Only instances can have flattened fields");
2185 InstanceKlass* ik = InstanceKlass::cast(k);
2186 fieldDescriptor fd;
2187 ik->find_field_from_offset(offset, false, &fd);
2188 InstanceKlass* holder = fd.field_holder();
2189 ValueKlass* vklass = ValueKlass::cast(holder->get_value_field_klass(fd.index()));
2190 oop v = JNIHandles::resolve_non_null(value);
2191 vklass->write_flattened_field(o, offset, v, CHECK);
2192 }
2193 HOTSPOT_JNI_SETOBJECTFIELD_RETURN();
2194 JNI_END
2195
2196
2197 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
2198 , EntryProbe, ReturnProbe) \
2199 \
2200 JNI_ENTRY_NO_PRESERVE(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
2201 JNIWrapper("Set" XSTR(Result) "Field"); \
2202 \
2203 EntryProbe; \
2204 \
2205 oop o = JNIHandles::resolve_non_null(obj); \
2206 Klass* k = o->klass(); \
2207 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \
2208 /* Keep JVMTI addition small and only check enabled flag here. */ \
2209 /* jni_SetField_probe_nh() assumes that is not okay to create handles */ \
2210 /* and creates a ResetNoHandleMark. */ \
2211 if (JvmtiExport::should_post_field_modification()) { \
2212 jvalue field_value; \
2609 ObjArrayKlass::cast(ak)->initialize(CHECK_NULL);
2610 objArrayOop result = ObjArrayKlass::cast(ak)->allocate(length, CHECK_NULL);
2611 oop initial_value = JNIHandles::resolve(initialElement);
2612 if (initial_value != NULL) { // array already initialized with NULL
2613 for (int index = 0; index < length; index++) {
2614 result->obj_at_put(index, initial_value);
2615 }
2616 }
2617 ret = (jobjectArray) JNIHandles::make_local(env, result);
2618 return ret;
2619 JNI_END
2620
2621 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
2622 , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
2623
2624 JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
2625 JNIWrapper("GetObjectArrayElement");
2626 HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(env, array, index);
2627 jobject ret = NULL;
2628 DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
2629 oop res = NULL;
2630 arrayOop arr((arrayOop)JNIHandles::resolve_non_null(array));
2631 if (arr->is_within_bounds(index)) {
2632 if (arr->is_valueArray()) {
2633 valueArrayOop a = valueArrayOop(JNIHandles::resolve_non_null(array));
2634 arrayHandle ah(THREAD, a);
2635 valueArrayHandle vah(thread, a);
2636 res = valueArrayOopDesc::value_alloc_copy_from_index(vah, index, CHECK_NULL);
2637 assert(res != NULL, "Must be set in one of two paths above");
2638 } else {
2639 assert(arr->is_objArray(), "If not a valueArray. must be an objArray");
2640 objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2641 res = a->obj_at(index);
2642 }
2643 } else {
2644 ResourceMark rm(THREAD);
2645 stringStream ss;
2646 ss.print("Index %d out of bounds for length %d", index,arr->length());
2647 THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2648 }
2649 ret = JNIHandles::make_local(env, res);
2650 return ret;
2651 JNI_END
2652
2653 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
2654 , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
2655
2656 JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
2657 JNIWrapper("SetObjectArrayElement");
2658 HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(env, array, index, value);
2659 DT_VOID_RETURN_MARK(SetObjectArrayElement);
2660
2661 bool oob = false;
2662 int length = -1;
2663 oop res = NULL;
2664 arrayOop arr((arrayOop)JNIHandles::resolve_non_null(array));
2665 if (arr->is_within_bounds(index)) {
2666 if (arr->is_valueArray()) {
2667 valueArrayOop a = valueArrayOop(JNIHandles::resolve_non_null(array));
2668 oop v = JNIHandles::resolve(value);
2669 ValueArrayKlass* vaklass = ValueArrayKlass::cast(a->klass());
2670 ValueKlass* element_vklass = vaklass->element_klass();
2671 if (v != NULL && v->is_a(element_vklass)) {
2672 a->value_copy_to_index(v, index);
2673 } else {
2674 ResourceMark rm(THREAD);
2675 stringStream ss;
2676 Klass *kl = ValueArrayKlass::cast(a->klass());
2677 ss.print("type mismatch: can not store %s to %s[%d]",
2678 v->klass()->external_name(),
2679 kl->external_name(),
2680 index);
2681 for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
2682 ss.print("[]");
2683 }
2684 THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
2685 }
2686 } else {
2687 assert(arr->is_objArray(), "If not a valueArray. must be an objArray");
2688 objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2689 oop v = JNIHandles::resolve(value);
2690 if (v == NULL || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) {
2691 a->obj_at_put(index, v);
2692 } else {
2693 ResourceMark rm(THREAD);
2694 stringStream ss;
2695 Klass *bottom_kl = ObjArrayKlass::cast(a->klass())->bottom_klass();
2696 ss.print("type mismatch: can not store %s to %s[%d]",
2697 v->klass()->external_name(),
2698 bottom_kl->is_typeArray_klass() ? type2name_tab[ArrayKlass::cast(bottom_kl)->element_type()] : bottom_kl->external_name(),
2699 index);
2700 for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
2701 ss.print("[]");
2702 }
2703 THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
2704 }
2705 }
2706 } else {
2707 ResourceMark rm(THREAD);
2708 stringStream ss;
2709 ss.print("Index %d out of bounds for length %d", index, arr->length());
2710 THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2711 }
2712 JNI_END
2713
2714
2715
2716 #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result \
2717 ,EntryProbe,ReturnProbe) \
2718 \
2719 DT_RETURN_MARK_DECL(New##Result##Array, Return \
2720 , ReturnProbe); \
2721 \
2722 JNI_ENTRY(Return, \
2723 jni_New##Result##Array(JNIEnv *env, jsize len)) \
2724 JNIWrapper("New" XSTR(Result) "Array"); \
2725 EntryProbe; \
2726 Return ret = NULL;\
2727 DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
2728 \
2729 oop obj= oopFactory::Allocator(len, CHECK_0); \
|