< prev index next >

src/hotspot/share/prims/jni.cpp

Print this page




  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); \


< prev index next >