< prev index next >
src/share/vm/prims/unsafe.cpp
Print this page
rev 13113 : 8182487: Add Unsafe.objectFieldOffset(Class, String)
Reviewed-by: dsimms, twisti, bchristi, mgerdin
*** 25,34 ****
--- 25,35 ----
#include "precompiled.hpp"
#include "classfile/classFileStream.hpp"
#include "classfile/vmSymbols.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
+ #include "oops/fieldStreams.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "prims/jni.h"
#include "prims/jvm.h"
#include "prims/unsafe.hpp"
*** 581,590 ****
--- 582,614 ----
UNSAFE_LEAF(jint, Unsafe_PageSize()) {
return os::vm_page_size();
} UNSAFE_END
+ static jint find_field_offset(jclass clazz, jstring name, TRAPS) {
+ assert(clazz != NULL, "clazz must not be NULL");
+ assert(name != NULL, "name must not be NULL");
+
+ ResourceMark rm(THREAD);
+ char *utf_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
+
+ InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
+
+ jint offset = -1;
+ for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
+ Symbol *name = fs.name();
+ if (name->equals(utf_name)) {
+ offset = fs.offset();
+ break;
+ }
+ }
+ if (offset < 0) {
+ THROW_0(vmSymbols::java_lang_InternalError());
+ }
+ return field_offset_from_byte_offset(offset);
+ }
+
static jint find_field_offset(jobject field, int must_be_static, TRAPS) {
assert(field != NULL, "field must not be NULL");
oop reflected = JNIHandles::resolve_non_null(field);
oop mirror = java_lang_reflect_Field::clazz(reflected);
*** 605,614 ****
--- 629,642 ----
UNSAFE_ENTRY(jlong, Unsafe_ObjectFieldOffset0(JNIEnv *env, jobject unsafe, jobject field)) {
return find_field_offset(field, 0, THREAD);
} UNSAFE_END
+ UNSAFE_ENTRY(jlong, Unsafe_ObjectFieldOffset1(JNIEnv *env, jobject unsafe, jclass c, jstring name)) {
+ return find_field_offset(c, name, THREAD);
+ } UNSAFE_END
+
UNSAFE_ENTRY(jlong, Unsafe_StaticFieldOffset0(JNIEnv *env, jobject unsafe, jobject field)) {
return find_field_offset(field, 1, THREAD);
} UNSAFE_END
UNSAFE_ENTRY(jobject, Unsafe_StaticFieldBase0(JNIEnv *env, jobject unsafe, jobject field)) {
*** 710,727 ****
return field_offset_from_byte_offset(scale) - field_offset_from_byte_offset(0);
} UNSAFE_END
static inline void throw_new(JNIEnv *env, const char *ename) {
! char buf[100];
!
! jio_snprintf(buf, 100, "%s%s", "java/lang/", ename);
!
! jclass cls = env->FindClass(buf);
if (env->ExceptionCheck()) {
env->ExceptionClear();
! tty->print_cr("Unsafe: cannot throw %s because FindClass has failed", buf);
return;
}
env->ThrowNew(cls, NULL);
}
--- 738,751 ----
return field_offset_from_byte_offset(scale) - field_offset_from_byte_offset(0);
} UNSAFE_END
static inline void throw_new(JNIEnv *env, const char *ename) {
! jclass cls = env->FindClass(ename);
if (env->ExceptionCheck()) {
env->ExceptionClear();
! tty->print_cr("Unsafe: cannot throw %s because FindClass has failed", ename);
return;
}
env->ThrowNew(cls, NULL);
}
*** 741,751 ****
ClassLoader::unsafe_defineClassCallCounter()->inc();
}
body = NEW_C_HEAP_ARRAY(jbyte, length, mtInternal);
if (body == NULL) {
! throw_new(env, "OutOfMemoryError");
return 0;
}
env->GetByteArrayRegion(data, offset, length, body);
if (env->ExceptionOccurred()) {
--- 765,775 ----
ClassLoader::unsafe_defineClassCallCounter()->inc();
}
body = NEW_C_HEAP_ARRAY(jbyte, length, mtInternal);
if (body == NULL) {
! throw_new(env, "java/lang/OutOfMemoryError");
return 0;
}
env->GetByteArrayRegion(data, offset, length, body);
if (env->ExceptionOccurred()) {
*** 757,767 ****
int unicode_len = env->GetStringLength(name);
if (len >= sizeof(buf)) {
utfName = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
if (utfName == NULL) {
! throw_new(env, "OutOfMemoryError");
goto free_body;
}
} else {
utfName = buf;
}
--- 781,791 ----
int unicode_len = env->GetStringLength(name);
if (len >= sizeof(buf)) {
utfName = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
if (utfName == NULL) {
! throw_new(env, "java/lang/OutOfMemoryError");
goto free_body;
}
} else {
utfName = buf;
}
*** 1180,1189 ****
--- 1204,1214 ----
{CC "allocateMemory0", CC "(J)" ADR, FN_PTR(Unsafe_AllocateMemory0)},
{CC "reallocateMemory0", CC "(" ADR "J)" ADR, FN_PTR(Unsafe_ReallocateMemory0)},
{CC "freeMemory0", CC "(" ADR ")V", FN_PTR(Unsafe_FreeMemory0)},
{CC "objectFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_ObjectFieldOffset0)},
+ {CC "objectFieldOffset1", CC "(" CLS LANG "String;)J", FN_PTR(Unsafe_ObjectFieldOffset1)},
{CC "staticFieldOffset0", CC "(" FLD ")J", FN_PTR(Unsafe_StaticFieldOffset0)},
{CC "staticFieldBase0", CC "(" FLD ")" OBJ, FN_PTR(Unsafe_StaticFieldBase0)},
{CC "ensureClassInitialized0", CC "(" CLS ")V", FN_PTR(Unsafe_EnsureClassInitialized0)},
{CC "arrayBaseOffset0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayBaseOffset0)},
{CC "arrayIndexScale0", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayIndexScale0)},
< prev index next >