< prev index next >
src/hotspot/share/prims/jni.cpp
Print this page
*** 3597,3606 ****
--- 3597,3798 ----
*isFlattened = fd.is_flattened();
}
return (jsize)offset;
JNI_END
+ JNI_ENTRY(jobject, jni_CreateSubElementSelector(JNIEnv* env, jarray array))
+ JNIWrapper("jni_CreateSubElementSelector");
+
+ arrayOop ar = arrayOop(JNIHandles::resolve_non_null(array));
+ if (!ar->is_array()) {
+ THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "Not an array");
+ }
+ if (!ar->is_valueArray()) {
+ THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "Not a flattened array");
+ }
+ Klass* ses_k = SystemDictionary::resolve_or_null(vmSymbols::jdk_internal_vm_jni_SubElementSelector(),
+ Handle(THREAD, SystemDictionary::java_system_loader()), Handle(), CHECK_NULL);
+ InstanceKlass* ses_ik = InstanceKlass::cast(ses_k);
+ ses_ik->initialize(CHECK_NULL);
+ Klass* elementKlass = ArrayKlass::cast(ar->klass())->element_klass();
+ oop ses = ses_ik->allocate_instance(CHECK_NULL);
+ Handle ses_h(THREAD, ses);
+ jdk_internal_vm_jni_SubElementSelector::setArrayElementType(ses_h(), elementKlass->java_mirror());
+ jdk_internal_vm_jni_SubElementSelector::setSubElementType(ses_h(), elementKlass->java_mirror());
+ jdk_internal_vm_jni_SubElementSelector::setOffset(ses_h(), 0);
+ jdk_internal_vm_jni_SubElementSelector::setIsFlattened(ses_h(), true); // by definition, top element of a flattened array is flattened
+ jdk_internal_vm_jni_SubElementSelector::setIsFlattenable(ses_h(), true); // by definition, top element of a flattened array is flattenable
+ return JNIHandles::make_local(ses_h());
+ JNI_END
+
+ JNI_ENTRY(jobject, jni_GetSubElementSelector(JNIEnv* env, jobject selector, const char* name, const char* signature))
+ JNIWrapper("jni_GetSubElementSelector");
+
+ oop slct = JNIHandles::resolve_non_null(selector);
+ if (slct->klass()->name() != vmSymbols::jdk_internal_vm_jni_SubElementSelector()) {
+ THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "Not a SubElementSelector");
+ }
+ jboolean isflattened = jdk_internal_vm_jni_SubElementSelector::getIsFlattened(slct);
+ if (!isflattened) {
+ THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "SubElement is not flattened");
+ }
+ oop semirror = jdk_internal_vm_jni_SubElementSelector::getSubElementType(slct);
+ Klass* k = java_lang_Class::as_Klass(semirror);
+ if (!k->is_value()) {
+ ResourceMark rm;
+ THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), err_msg("%s is not an inline type", k->external_name()));
+ }
+ ValueKlass* vk = ValueKlass::cast(k);
+ TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
+ TempNewSymbol signame = SymbolTable::probe(signature, (int)strlen(signature));
+ if (fieldname == NULL || signame == NULL) {
+ ResourceMark rm;
+ THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", vk->external_name(), name, signature));
+ }
+ assert(vk->is_initialized(), "If a flattened array has been created, the element klass must have been initialized");
+ fieldDescriptor fd;
+ if (!vk->is_instance_klass() ||
+ !InstanceKlass::cast(vk)->find_field(fieldname, signame, false, &fd)) {
+ ResourceMark rm;
+ THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", vk->external_name(), name, signature));
+ }
+ Handle arrayElementMirror(THREAD, jdk_internal_vm_jni_SubElementSelector::getArrayElementType(slct));
+ // offset of the SubElement is offset of the original SubElement plus the offset of the field inside the element
+ int offset = fd.offset() - vk->first_field_offset() + jdk_internal_vm_jni_SubElementSelector::getOffset(slct);
+ InstanceKlass* sesklass = InstanceKlass::cast(JNIHandles::resolve_non_null(selector)->klass());
+ oop res = sesklass->allocate_instance(CHECK_NULL);
+ Handle res_h(THREAD, res);
+ jdk_internal_vm_jni_SubElementSelector::setArrayElementType(res_h(), arrayElementMirror());
+ InstanceKlass* holder = fd.field_holder();
+ BasicType bt = char2type(fd.signature()->char_at(0));
+ if (is_java_primitive(bt)) {
+ jdk_internal_vm_jni_SubElementSelector::setSubElementType(res_h(), java_lang_Class::primitive_mirror(bt));
+ } else {
+ Klass* fieldKlass = SystemDictionary::resolve_or_fail(fd.signature(), Handle(THREAD, holder->class_loader()),
+ Handle(THREAD, holder->protection_domain()), true, CHECK_NULL);
+ jdk_internal_vm_jni_SubElementSelector::setSubElementType(res_h(),fieldKlass->java_mirror());
+ }
+ jdk_internal_vm_jni_SubElementSelector::setOffset(res_h(), offset);
+ jdk_internal_vm_jni_SubElementSelector::setIsFlattened(res_h(), fd.is_flattened());
+ jdk_internal_vm_jni_SubElementSelector::setIsFlattenable(res_h(), fd.is_flattenable());
+ return JNIHandles::make_local(res_h());
+ JNI_END
+
+ JNI_ENTRY(jobject, jni_GetObjectSubElement(JNIEnv* env, jarray array, jobject selector, int index))
+ JNIWrapper("jni_GetObjectSubElement");
+
+ valueArrayOop ar = (valueArrayOop)JNIHandles::resolve_non_null(array);
+ oop slct = JNIHandles::resolve_non_null(selector);
+ ValueArrayKlass* vak = ValueArrayKlass::cast(ar->klass());
+ if (jdk_internal_vm_jni_SubElementSelector::getArrayElementType(slct) != vak->element_klass()->java_mirror()) {
+ THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "Array/Selector mismatch");
+ }
+ oop res = NULL;
+ if (!jdk_internal_vm_jni_SubElementSelector::getIsFlattened(slct)) {
+ int offset = (address)ar->base() - (address)ar + index * vak->element_byte_size()
+ + jdk_internal_vm_jni_SubElementSelector::getOffset(slct);
+ res = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(ar, offset);
+ } else {
+ ValueKlass* fieldKlass = ValueKlass::cast(java_lang_Class::as_Klass(jdk_internal_vm_jni_SubElementSelector::getSubElementType(slct)));
+ res = fieldKlass->allocate_instance(CHECK_NULL);
+ // The array might have been moved by the GC, refreshing the arrayOop
+ ar = (valueArrayOop)JNIHandles::resolve_non_null(array);
+ address addr = (address)ar->value_at_addr(index, vak->layout_helper())
+ + jdk_internal_vm_jni_SubElementSelector::getOffset(slct);
+ fieldKlass->value_copy_payload_to_new_oop(addr, res);
+ }
+ return JNIHandles::make_local(res);
+ JNI_END
+
+ JNI_ENTRY(void, jni_SetObjectSubElement(JNIEnv* env, jarray array, jobject selector, int index, jobject value))
+ JNIWrapper("jni_SetObjectSubElement");
+
+ valueArrayOop ar = (valueArrayOop)JNIHandles::resolve_non_null(array);
+ oop slct = JNIHandles::resolve_non_null(selector);
+ ValueArrayKlass* vak = ValueArrayKlass::cast(ar->klass());
+ if (jdk_internal_vm_jni_SubElementSelector::getArrayElementType(slct) != vak->element_klass()->java_mirror()) {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Array/Selector mismatch");
+ }
+ oop val = JNIHandles::resolve(value);
+ if (val == NULL) {
+ if (jdk_internal_vm_jni_SubElementSelector::getIsFlattenable(slct)) {
+ THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), "null cannot be stored in a flattened array");
+ }
+ } else {
+ if (!val->is_a(java_lang_Class::as_Klass(jdk_internal_vm_jni_SubElementSelector::getSubElementType(slct)))) {
+ THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), "type mismatch");
+ }
+ }
+ if (!jdk_internal_vm_jni_SubElementSelector::getIsFlattened(slct)) {
+ int offset = (address)ar->base() - (address)ar + index * vak->element_byte_size()
+ + jdk_internal_vm_jni_SubElementSelector::getOffset(slct);
+ HeapAccess<ON_UNKNOWN_OOP_REF>::oop_store_at(ar, offset, JNIHandles::resolve(value));
+ } else {
+ ValueKlass* fieldKlass = ValueKlass::cast(java_lang_Class::as_Klass(jdk_internal_vm_jni_SubElementSelector::getSubElementType(slct)));
+ address addr = (address)ar->value_at_addr(index, vak->layout_helper())
+ + jdk_internal_vm_jni_SubElementSelector::getOffset(slct);
+ fieldKlass->value_copy_oop_to_payload(JNIHandles::resolve_non_null(value), addr);
+ }
+ JNI_END
+
+ #define DEFINE_GETSUBELEMENT(ElementType,Result,ElementBasicType) \
+ \
+ JNI_ENTRY(ElementType, \
+ jni_Get##Result##SubElement(JNIEnv *env, jarray array, jobject selector, int index)) \
+ JNIWrapper("Get" XSTR(Result) "SubElement"); \
+ valueArrayOop ar = (valueArrayOop)JNIHandles::resolve_non_null(array); \
+ oop slct = JNIHandles::resolve_non_null(selector); \
+ ValueArrayKlass* vak = ValueArrayKlass::cast(ar->klass()); \
+ if (jdk_internal_vm_jni_SubElementSelector::getArrayElementType(slct) != vak->element_klass()->java_mirror()) { \
+ THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Array/Selector mismatch"); \
+ } \
+ if (jdk_internal_vm_jni_SubElementSelector::getSubElementType(slct) != java_lang_Class::primitive_mirror(ElementBasicType)) { \
+ THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong SubElement type"); \
+ } \
+ address addr = (address)ar->value_at_addr(index, vak->layout_helper()) \
+ + jdk_internal_vm_jni_SubElementSelector::getOffset(slct); \
+ ElementType result = *(ElementType*)addr; \
+ return result; \
+ JNI_END
+
+ DEFINE_GETSUBELEMENT(jboolean, Boolean,T_BOOLEAN)
+ DEFINE_GETSUBELEMENT(jbyte, Byte, T_BYTE)
+ DEFINE_GETSUBELEMENT(jshort, Short,T_SHORT)
+ DEFINE_GETSUBELEMENT(jchar, Char,T_CHAR)
+ DEFINE_GETSUBELEMENT(jint, Int,T_INT)
+ DEFINE_GETSUBELEMENT(jlong, Long,T_LONG)
+ DEFINE_GETSUBELEMENT(jfloat, Float,T_FLOAT)
+ DEFINE_GETSUBELEMENT(jdouble, Double,T_DOUBLE)
+
+ #define DEFINE_SETSUBELEMENT(ElementType,Result,ElementBasicType) \
+ \
+ JNI_ENTRY(void, \
+ jni_Set##Result##SubElement(JNIEnv *env, jarray array, jobject selector, int index, ElementType value)) \
+ JNIWrapper("Get" XSTR(Result) "SubElement"); \
+ valueArrayOop ar = (valueArrayOop)JNIHandles::resolve_non_null(array); \
+ oop slct = JNIHandles::resolve_non_null(selector); \
+ ValueArrayKlass* vak = ValueArrayKlass::cast(ar->klass()); \
+ if (jdk_internal_vm_jni_SubElementSelector::getArrayElementType(slct) != vak->element_klass()->java_mirror()) { \
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Array/Selector mismatch"); \
+ } \
+ if (jdk_internal_vm_jni_SubElementSelector::getSubElementType(slct) != java_lang_Class::primitive_mirror(ElementBasicType)) { \
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Wrong SubElement type"); \
+ } \
+ address addr = (address)ar->value_at_addr(index, vak->layout_helper()) \
+ + jdk_internal_vm_jni_SubElementSelector::getOffset(slct); \
+ *(ElementType*)addr = value; \
+ JNI_END
+
+ DEFINE_SETSUBELEMENT(jboolean, Boolean,T_BOOLEAN)
+ DEFINE_SETSUBELEMENT(jbyte, Byte, T_BYTE)
+ DEFINE_SETSUBELEMENT(jshort, Short,T_SHORT)
+ DEFINE_SETSUBELEMENT(jchar, Char,T_CHAR)
+ DEFINE_SETSUBELEMENT(jint, Int,T_INT)
+ DEFINE_SETSUBELEMENT(jlong, Long,T_LONG)
+ DEFINE_SETSUBELEMENT(jfloat, Float,T_FLOAT)
+ DEFINE_SETSUBELEMENT(jdouble, Double,T_DOUBLE)
+
// Structure containing all jni functions
struct JNINativeInterface_ jni_NativeInterface = {
NULL,
NULL,
NULL,
*** 3888,3898 ****
jni_GetFlattenedArrayElements,
jni_ReleaseFlattenedArrayElements,
jni_GetFlattenedArrayElementClass,
jni_GetFlattenedArrayElementSize,
! jni_GetFieldOffsetInFlattenedLayout
};
// For jvmti use to modify jni function table.
// Java threads in native contiues to run until it is transitioned
--- 4080,4113 ----
jni_GetFlattenedArrayElements,
jni_ReleaseFlattenedArrayElements,
jni_GetFlattenedArrayElementClass,
jni_GetFlattenedArrayElementSize,
! jni_GetFieldOffsetInFlattenedLayout,
!
! jni_CreateSubElementSelector,
! jni_GetSubElementSelector,
! jni_GetObjectSubElement,
! jni_SetObjectSubElement,
!
! jni_GetBooleanSubElement,
! jni_GetByteSubElement,
! jni_GetShortSubElement,
! jni_GetCharSubElement,
! jni_GetIntSubElement,
! jni_GetLongSubElement,
! jni_GetFloatSubElement,
! jni_GetDoubleSubElement,
!
! jni_SetBooleanSubElement,
! jni_SetByteSubElement,
! jni_SetShortSubElement,
! jni_SetCharSubElement,
! jni_SetIntSubElement,
! jni_SetLongSubElement,
! jni_SetFloatSubElement,
! jni_SetDoubleSubElement
};
// For jvmti use to modify jni function table.
// Java threads in native contiues to run until it is transitioned
< prev index next >