< prev index next >

src/share/vm/prims/unsafe.cpp

Print this page
rev 13102 : 8182487: Add Unsafe.objectFieldOffset(Class, String)
Reviewed-by: dsimms

@@ -25,10 +25,11 @@
 #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"

@@ -573,18 +574,56 @@
   }
 } UNSAFE_END
 
 ////// 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
 
 UNSAFE_LEAF(jint, Unsafe_PageSize()) {
   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");
 
   oop reflected   = JNIHandles::resolve_non_null(field);
   oop mirror      = java_lang_reflect_Field::clazz(reflected);

@@ -605,10 +644,14 @@
 
 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(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
 
 UNSAFE_ENTRY(jobject, Unsafe_StaticFieldBase0(JNIEnv *env, jobject unsafe, jobject field)) {

@@ -708,26 +751,10 @@
   // The following allows for a pretty general fieldOffset cookie scheme,
   // but requires it to be linear in byte offset.
   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
 
   jbyte *body;
   char *utfName = NULL;

@@ -1180,10 +1207,11 @@
     {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 >