# HG changeset patch # User redestad # Date 1497963100 -7200 # Tue Jun 20 14:51:40 2017 +0200 # Node ID e6ec82eea491ce95a85b86f9dae0522cb9ee1759 # Parent 06994badeb24e4140322b814c3dcde2a71ed4023 8182487: Add Unsafe.objectFieldOffset(Class, String) Reviewed-by: dsimms diff --git a/src/share/vm/prims/unsafe.cpp b/src/share/vm/prims/unsafe.cpp --- a/src/share/vm/prims/unsafe.cpp +++ b/src/share/vm/prims/unsafe.cpp @@ -27,6 +27,7 @@ #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" @@ -575,6 +576,21 @@ ////// Random queries +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); +} + UNSAFE_LEAF(jint, Unsafe_AddressSize0(JNIEnv *env, jobject unsafe)) { return sizeof(void*); } UNSAFE_END @@ -583,6 +599,29 @@ return os::vm_page_size(); } UNSAFE_END +static jint find_field_offset(JNIEnv *env, 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_new(env, "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"); @@ -607,6 +646,10 @@ 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(env, 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 @@ -710,22 +753,6 @@ 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); -} - static jclass Unsafe_DefineClass_impl(JNIEnv *env, jstring name, jbyteArray data, int offset, int length, jobject loader, jobject pd) { // Code lifted from JDK 1.3 ClassLoader.c @@ -1182,6 +1209,7 @@ {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)},