< prev index next >
src/hotspot/share/prims/jni.cpp
Print this page
*** 56,65 ****
--- 56,66 ----
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
#include "oops/typeArrayKlass.hpp"
#include "oops/typeArrayOop.inline.hpp"
+ #include "oops/valueArrayOop.inline.hpp"
#include "oops/valueKlass.inline.hpp"
#include "prims/jniCheck.hpp"
#include "prims/jniExport.hpp"
#include "prims/jniFastGetField.hpp"
#include "prims/jvm_misc.hpp"
*** 495,506 ****
// The slot is the index of the field description in the field-array
// The jfieldID is the offset of the field within the object
// It may also have hash bits for k, if VerifyJNIFields is turned on.
intptr_t offset = InstanceKlass::cast(k1)->field_offset( slot );
assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object");
! ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset);
return ret;
JNI_END
DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
--- 496,508 ----
// The slot is the index of the field description in the field-array
// The jfieldID is the offset of the field within the object
// It may also have hash bits for k, if VerifyJNIFields is turned on.
intptr_t offset = InstanceKlass::cast(k1)->field_offset( slot );
+ bool is_flattened = InstanceKlass::cast(k1)->field_is_flattened(slot);
assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object");
! ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset, is_flattened);
return ret;
JNI_END
DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
*** 2048,2075 ****
THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
}
// A jfieldID for a non-static field is simply the offset of the field within the instanceOop
// It may also have hash bits for k, if VerifyJNIFields is turned on.
! ret = jfieldIDWorkaround::to_instance_jfieldID(k, fd.offset());
return ret;
JNI_END
JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
JNIWrapper("GetObjectField");
HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID);
oop o = JNIHandles::resolve_non_null(obj);
Klass* k = o->klass();
int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
// Keep JVMTI addition small and only check enabled flag here.
// jni_GetField_probe() assumes that is okay to create handles.
if (JvmtiExport::should_post_field_access()) {
o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
}
! oop loaded_obj = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(o, offset);
! jobject ret = JNIHandles::make_local(env, loaded_obj);
HOTSPOT_JNI_GETOBJECTFIELD_RETURN(ret);
return ret;
JNI_END
--- 2050,2098 ----
THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
}
// A jfieldID for a non-static field is simply the offset of the field within the instanceOop
// It may also have hash bits for k, if VerifyJNIFields is turned on.
! ret = jfieldIDWorkaround::to_instance_jfieldID(k, fd.offset(), fd.is_flattened());
return ret;
JNI_END
JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
JNIWrapper("GetObjectField");
HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID);
oop o = JNIHandles::resolve_non_null(obj);
Klass* k = o->klass();
int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
+ oop res = NULL;
// Keep JVMTI addition small and only check enabled flag here.
// jni_GetField_probe() assumes that is okay to create handles.
if (JvmtiExport::should_post_field_access()) {
o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
}
! if (!jfieldIDWorkaround::is_flattened_field(fieldID)) {
! res = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(o, offset);
! } else {
! assert(k->is_instance_klass(), "Only instance can have flattened fields");
! InstanceKlass* ik = InstanceKlass::cast(k);
! fieldDescriptor fd;
! ik->find_field_from_offset(offset, false, &fd);
! InstanceKlass* holder = fd.field_holder();
! ValueKlass* field_vklass = ValueKlass::cast(holder->get_value_field_klass(fd.index()));
! assert(field_vklass->is_initialized(), "Must be initialized at this point");
!
! Handle obj_h(THREAD, o);
! if (field_vklass->is_empty_value()) {
! res = (instanceOop)field_vklass->default_value();
! } else {
! // allocate instance
! res = field_vklass->allocate_instance(CHECK_NULL);
! // copy value
! field_vklass->value_copy_payload_to_new_oop(((char*)(oopDesc*)obj_h()) + ik->field_offset(fd.index()), res);
! }
! }
! jobject ret = JNIHandles::make_local(env, res);
HOTSPOT_JNI_GETOBJECTFIELD_RETURN(ret);
return ret;
JNI_END
*** 2163,2173 ****
--- 2186,2207 ----
if (JvmtiExport::should_post_field_modification()) {
jvalue field_value;
field_value.l = value;
o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, 'L', (jvalue *)&field_value);
}
+ if (!jfieldIDWorkaround::is_flattened_field(fieldID)) {
HeapAccess<ON_UNKNOWN_OOP_REF>::oop_store_at(o, offset, JNIHandles::resolve(value));
+ } else {
+ assert(k->is_instance_klass(), "Only instances can have flattened fields");
+ InstanceKlass* ik = InstanceKlass::cast(k);
+ fieldDescriptor fd;
+ ik->find_field_from_offset(offset, false, &fd);
+ InstanceKlass* holder = fd.field_holder();
+ ValueKlass* vklass = ValueKlass::cast(holder->get_value_field_klass(fd.index()));
+ oop v = JNIHandles::resolve_non_null(value);
+ vklass->value_copy_oop_to_payload(v, ((char*)(oopDesc*)o) + offset);
+ }
HOTSPOT_JNI_SETOBJECTFIELD_RETURN();
JNI_END
#define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
*** 2600,2632 ****
JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
JNIWrapper("GetObjectArrayElement");
HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(env, array, index);
jobject ret = NULL;
DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
! if (a->is_within_bounds(index)) {
! ret = JNIHandles::make_local(env, a->obj_at(index));
! return ret;
} else {
ResourceMark rm(THREAD);
stringStream ss;
! ss.print("Index %d out of bounds for length %d", index, a->length());
THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
}
JNI_END
DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
, HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
JNIWrapper("SetObjectArrayElement");
HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(env, array, index, value);
DT_VOID_RETURN_MARK(SetObjectArrayElement);
objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
oop v = JNIHandles::resolve(value);
- if (a->is_within_bounds(index)) {
if (v == NULL || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) {
a->obj_at_put(index, v);
} else {
ResourceMark rm(THREAD);
stringStream ss;
--- 2634,2704 ----
JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
JNIWrapper("GetObjectArrayElement");
HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(env, array, index);
jobject ret = NULL;
DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
+ oop res = NULL;
+ arrayOop arr((arrayOop)JNIHandles::resolve_non_null(array));
+ if (arr->is_within_bounds(index)) {
+ if (arr->is_valueArray()) {
+ valueArrayOop a = valueArrayOop(JNIHandles::resolve_non_null(array));
+ arrayHandle ah(THREAD, a);
+ valueArrayHandle vah(thread, a);
+ res = valueArrayOopDesc::value_alloc_copy_from_index(vah, index, CHECK_NULL);
+ assert(res != NULL, "Must be set in one of two paths above");
+ } else {
+ assert(arr->is_objArray(), "If not a valueArray. must be an objArray");
objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
! res = a->obj_at(index);
! }
} else {
ResourceMark rm(THREAD);
stringStream ss;
! ss.print("Index %d out of bounds for length %d", index,arr->length());
THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
}
+ ret = JNIHandles::make_local(env, res);
+ return ret;
JNI_END
DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
, HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
JNIWrapper("SetObjectArrayElement");
HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(env, array, index, value);
DT_VOID_RETURN_MARK(SetObjectArrayElement);
+ bool oob = false;
+ int length = -1;
+ oop res = NULL;
+ arrayOop arr((arrayOop)JNIHandles::resolve_non_null(array));
+ if (arr->is_within_bounds(index)) {
+ if (arr->is_valueArray()) {
+ valueArrayOop a = valueArrayOop(JNIHandles::resolve_non_null(array));
+ oop v = JNIHandles::resolve(value);
+ ValueArrayKlass* vaklass = ValueArrayKlass::cast(a->klass());
+ ValueKlass* element_vklass = vaklass->element_klass();
+ if (v != NULL && v->is_a(element_vklass)) {
+ a->value_copy_to_index(v, index);
+ } else {
+ ResourceMark rm(THREAD);
+ stringStream ss;
+ Klass *kl = ValueArrayKlass::cast(a->klass());
+ ss.print("type mismatch: can not store %s to %s[%d]",
+ v->klass()->external_name(),
+ kl->external_name(),
+ index);
+ for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
+ ss.print("[]");
+ }
+ THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
+ }
+ } else {
+ assert(arr->is_objArray(), "If not a valueArray. must be an objArray");
objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
oop v = JNIHandles::resolve(value);
if (v == NULL || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) {
a->obj_at_put(index, v);
} else {
ResourceMark rm(THREAD);
stringStream ss;
*** 2638,2651 ****
for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
ss.print("[]");
}
THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
}
} else {
ResourceMark rm(THREAD);
stringStream ss;
! ss.print("Index %d out of bounds for length %d", index, a->length());
THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
}
JNI_END
--- 2710,2724 ----
for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
ss.print("[]");
}
THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
}
+ }
} else {
ResourceMark rm(THREAD);
stringStream ss;
! ss.print("Index %d out of bounds for length %d", index, arr->length());
THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
}
JNI_END
< prev index next >