[vmkit-commits] [PATCH 2/3] Unsafe.inc: Rearrange code into related groups of methods.

Will Dietz wdietz2 at illinois.edu
Tue Nov 15 15:15:57 PST 2011


Inlined below.

No functionality change other than switching baseToPtr to fieldPtr.

This patch mostly is to make the next patch cleaner.

~Will

>From 0c7a31e4a5fecae30ddf92cb4d2886e8f5cfae76 Mon Sep 17 00:00:00 2001
From: Will Dietz <w at wdtz.org>
Date: Tue, 15 Nov 2011 16:55:11 -0600
Subject: [PATCH 2/3] Unsafe.inc: Rearrange code into related groups of
 methods.

Also, rename baseToPtr, with more useful fieldPtr.
---
 lib/J3/ClassLib/Unsafe.inc |  371 ++++++++++++++++++++++++--------------------
 1 files changed, 203 insertions(+), 168 deletions(-)

diff --git a/lib/J3/ClassLib/Unsafe.inc b/lib/J3/ClassLib/Unsafe.inc
index dcccc65..5fe64db 100644
--- a/lib/J3/ClassLib/Unsafe.inc
+++ b/lib/J3/ClassLib/Unsafe.inc
@@ -10,107 +10,175 @@
 #include "VMStaticInstance.h"
 #include <stdlib.h>

-// Convert a 'base' JavaObject to its pointer representation.
-// Handles our special VMStaticInstance wrapper.
-static inline uint8 *baseToPtr(JavaObject *base) {
-  if (VMStaticInstance::isVMStaticInstance(base))
-    return (uint8*)((VMStaticInstance*)base)->getStaticInstance();
+/// fieldPtr - Compute the address of the field specified by the given
+/// base/offset pair.  Non-trivial due to our handling of static instances,
+/// and this also handles null-checking as required.
+///
+static inline uint8 *fieldPtr(JavaObject *base, long long offset,
+  bool throwOnNull = true) {
+
+  // For most uses, a 'null' base should throw an exception.
+  if (throwOnNull) verifyNull(base);
+
+  if (base && VMStaticInstance::isVMStaticInstance(base))
+    return (uint8*)((VMStaticInstance*)base)->getStaticInstance() + offset;
   else
-    return (uint8*)base;
+    return (uint8*)base + offset;
 }

 extern "C" {

-// Never throws.
-JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapLong(
-#ifdef NATIVE_JNI
-JNIEnv *env,
-#endif
-JavaObject* unsafe, JavaObject* obj, jlong offset, jlong expect,
jlong update) {
+//===--- Base/Offset methods
----------------------------------------------===//

+/// staticFieldOffset - Return the offset of a particular static field
+/// Only valid to be used with the corresponding staticFieldBase
+///
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_staticFieldOffset(
+JavaObject* unsafe, JavaObjectField* _field) {
   llvm_gcroot(unsafe, 0);
-  llvm_gcroot(obj, 0);
-  jlong *ptr;
-  jlong  value;
+  llvm_gcroot(_field, 0);

-  ptr = (jlong *) (((uint8 *) obj) + offset);
+  jlong res = 0;
+  BEGIN_NATIVE_EXCEPTION(0)

-  value = *ptr;
+  JavaField * field = JavaObjectField::getInternalField(_field);
+  assert(field);

-  if (value == expect) {
-    *ptr = update;
-    return true;
-  } else {
-    return false;
-  }
+  res = field->ptrOffset;

+  END_NATIVE_EXCEPTION;
+
+  return res;
 }

-// Never throws.
-JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapInt(
+/// staticFieldBase - Return a JavaObject* representing the static instance.
+/// Note that our static instances aren't actually java objects, so we use
+/// a placeholder object "VMStaticInstance" that also ensures that
+/// the corresponding class doesn't get GC'd underneath it.
+///
+JNIEXPORT JavaObject* JNICALL Java_sun_misc_Unsafe_staticFieldBase(
+JavaObject* unsafe, JavaObjectField* _field) {
+  JavaObject* res = 0;
+  llvm_gcroot(unsafe, 0);
+  llvm_gcroot(_field, 0);
+  llvm_gcroot(res, 0);
+  BEGIN_NATIVE_EXCEPTION(0)
+
+  JavaField * field = JavaObjectField::getInternalField(_field);
+  assert(field);
+  field->classDef->initialiseClass(JavaThread::get()->getJVM());
+
+  res = VMStaticInstance::allocate(field->classDef);
+
+  END_NATIVE_EXCEPTION;
+
+  return res;
+}
+
+/// arrayBaseOffset - Offset from the array object where the actual
+/// element data begins.
+///
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_arrayBaseOffset(
+JavaObject* unsafe, JavaObject* clazz) {
+  // Array starts at beginning of object
+  return 0;
+}
+
+/// arrayIndexScale - Indexing scale for the element type in
+/// the specified array.  For use with arrayBaseOffset,
+/// NthElementPtr = ArrayObject + BaseOffset + N*IndexScale
+/// Return '0' if our JVM stores the elements in a way that
+/// makes this type of access impossible or unsupported.
+///
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_arrayIndexScale(
+JavaObject* unsafe, JavaObject* clazz) {
+  // For now, just return '0', indicating we don't support this indexing.
+  // TODO: Implement this for the array types we /do/ support this way.
+  return 0;
+}
+
+
+
+/// objectFieldOffset - Pointer offset of the specified field
+///
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_objectFieldOffset(
 #ifdef NATIVE_JNI
 JNIEnv *env,
 #endif
-JavaObject* unsafe, JavaObject* obj, jlong offset, jint expect, jint update) {
+JavaObject* Unsafe, JavaObjectField* Field) {

-  llvm_gcroot(unsafe, 0);
-  llvm_gcroot(obj, 0);
-  jint *ptr;
+  llvm_gcroot(Field, 0);
+  llvm_gcroot(Unsafe, 0);

-  ptr = (jint *) (((uint8 *) obj) + offset);
+  JavaField* field = JavaObjectField::getInternalField(Field);
+  return (jlong)field->ptrOffset;
+}

-  return __sync_bool_compare_and_swap(ptr, expect, update);
+//===--- Double-register addressing field accessors
-----------------------===//
+// See objectFieldOffset, staticFieldOffset, staticFieldBase
+// Can also be an array, if/when we support arrayIndexScale/arrayBaseOffset
+#define GET_PUT_OFFSET(Type,jtype,shorttype) \
+JNIEXPORT jtype JNICALL Java_sun_misc_Unsafe_get ## Type ##
__Ljava_lang_Object_2J( \
+JavaObject* unsafe, JavaObject* base, jlong offset) { \
+  jtype res = 0; \
+  BEGIN_NATIVE_EXCEPTION(0) \
+  jtype* ptr = (jtype*)fieldPtr(base,offset); \
+  res = *ptr; \
+  END_NATIVE_EXCEPTION \
+  return res; \
+} \
+ \
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_put ## Type ##
__Ljava_lang_Object_2J ## shorttype( \
+JavaObject* unsafe, JavaObject* base, jlong offset, jtype val) { \
+  BEGIN_NATIVE_EXCEPTION(0) \
+  jtype* ptr = (jtype*)fieldPtr(base, offset); \
+  *ptr = val; \
+  END_NATIVE_EXCEPTION \
 }

+GET_PUT_OFFSET(Boolean,jboolean,Z)
+GET_PUT_OFFSET(Byte,jbyte,B)
+GET_PUT_OFFSET(Char,jchar,C)
+GET_PUT_OFFSET(Short,jshort,S)
+GET_PUT_OFFSET(Int,jint,I)
+GET_PUT_OFFSET(Long,jlong,J)
+GET_PUT_OFFSET(Float,jfloat,F)
+GET_PUT_OFFSET(Double,jdouble,D)
+
+//===--- Get/Put of Objects, due to GC needs special handling
-------------===//
+// JavaObject field accessors:
 // Never throws.
-JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapObject(
-#ifdef NATIVE_JNI
-JNIEnv *env,
-#endif
-JavaObject* unsafe, JavaObject* obj, jlong offset, JavaObject* expect,
-JavaObject* update) {
+JNIEXPORT JavaObject* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(
+JavaObject* unsafe, JavaObject* base, jlong offset) {
+  JavaObject * res = 0;
   llvm_gcroot(unsafe, 0);
-  llvm_gcroot(obj, 0);
-  llvm_gcroot(expect, 0);
-  llvm_gcroot(update, 0);
+  llvm_gcroot(base, 0);
+  llvm_gcroot(res, 0);

-  JavaObject** ptr = (JavaObject**) (((uint8 *) obj) + offset);
+  BEGIN_NATIVE_EXCEPTION(0)
+  JavaObject** ptr = (JavaObject**)fieldPtr(base, offset);
+  res = *ptr;
+  END_NATIVE_EXCEPTION;

-  return mvm::Collector::objectReferenceTryCASBarrier((gc*)obj,
(gc**)ptr, (gc*)expect, (gc*)update);
+  return res;
 }

+// Volatile JavaObject field accessors:
 // Never throws.
 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObjectVolatile(
 #ifdef NATIVE_JNI
 JNIEnv *env,
 #endif
-JavaObject* unsafe, JavaObject* obj, jlong offset, JavaObject* value) {
+JavaObject* unsafe, JavaObject* base, jlong offset, JavaObject* value) {
   llvm_gcroot(unsafe, 0);
-  llvm_gcroot(obj, 0);
+  llvm_gcroot(base, 0);
   llvm_gcroot(value, 0);

-  JavaObject** ptr = (JavaObject**) (((uint8 *) obj) + offset);
-  mvm::Collector::objectReferenceWriteBarrier((gc*)obj, (gc**)ptr, (gc*)value);
-}
-
-JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_allocateMemory(
-JavaObject* unsafe, jlong size) {
-  // TODO: Invalid size/OOM/etc handling!
-  jlong res = 0;
-  BEGIN_NATIVE_EXCEPTION(0)
-  res = (jlong)malloc(size);
-  END_NATIVE_EXCEPTION
-  return res;
-}
-
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_freeMemory(
-JavaObject* unsafe, jlong ptr) {
-  // TODO: Exception handling...
-  BEGIN_NATIVE_EXCEPTION(0)
-  free((void*)ptr);
-  END_NATIVE_EXCEPTION
+  JavaObject** ptr = (JavaObject**)fieldPtr(base, offset);
+  mvm::Collector::objectReferenceWriteBarrier((gc*)base, (gc**)ptr,
(gc*)value);
 }

+//===--- Misc get/put defined, TODO: generalize!
--------------------------===//
 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong__JJ(
 JavaObject* unsafe, jlong ptr, jlong value) {
   BEGIN_NATIVE_EXCEPTION(0)
@@ -128,104 +196,78 @@ JavaObject* unsafe, jlong ptr) {
   return res;
 }

-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_ensureClassInitialized(
-JavaObject* unsafe, JavaObject* clazz) {
-  llvm_gcroot(unsafe, 0);
-  llvm_gcroot(clazz, 0);
-  BEGIN_NATIVE_EXCEPTION(0)
-
-  Jnjvm* vm = JavaThread::get()->getJVM();

-  CommonClass * cl = JavaObject::getClass(clazz);
-  assert(cl && cl->isClass());
-  cl->asClass()->resolveClass();
-  cl->asClass()->initialiseClass(vm);
-
-  END_NATIVE_EXCEPTION;
-}
+//===--- CompareAndSwap field accessors
-----------------------------------===//
+// Never throws.
+JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapLong(
+JavaObject* unsafe, JavaObject* obj, jlong offset, jlong expect,
jlong update) {

-JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_staticFieldOffset(
-JavaObject* unsafe, JavaObjectField* _field) {
   llvm_gcroot(unsafe, 0);
-  llvm_gcroot(_field, 0);
-
-  jlong res = 0;
-  BEGIN_NATIVE_EXCEPTION(0)
+  llvm_gcroot(obj, 0);
+  jlong *ptr;
+  jlong  value;

-  JavaField * field = JavaObjectField::getInternalField(_field);
-  assert(field);
+  ptr = (jlong *) (((uint8 *) obj) + offset);

-  res = field->ptrOffset;
+  value = *ptr;

-  END_NATIVE_EXCEPTION;
+  if (value == expect) {
+    *ptr = update;
+    return true;
+  } else {
+    return false;
+  }

-  return res;
 }

-JNIEXPORT JavaObject* JNICALL Java_sun_misc_Unsafe_staticFieldBase(
-JavaObject* unsafe, JavaObjectField* _field) {
-  JavaObject* res = 0;
-  llvm_gcroot(unsafe, 0);
-  llvm_gcroot(_field, 0);
-  llvm_gcroot(res, 0);
-  BEGIN_NATIVE_EXCEPTION(0)
-
-  JavaField * field = JavaObjectField::getInternalField(_field);
-  assert(field);
-  field->classDef->initialiseClass(JavaThread::get()->getJVM());
+// Never throws.
+JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapInt(
+#ifdef NATIVE_JNI
+JNIEnv *env,
+#endif
+JavaObject* unsafe, JavaObject* obj, jlong offset, jint expect, jint update) {

-  res = VMStaticInstance::allocate(field->classDef);
+  llvm_gcroot(unsafe, 0);
+  llvm_gcroot(obj, 0);
+  jint *ptr;

-  END_NATIVE_EXCEPTION;
+  ptr = (jint *) (((uint8 *) obj) + offset);

-  return res;
+  return __sync_bool_compare_and_swap(ptr, expect, update);
 }

-/// objectFieldOffset - Pointer offset of the specified field
-///
-JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_objectFieldOffset(
+// Never throws.
+JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapObject(
 #ifdef NATIVE_JNI
 JNIEnv *env,
 #endif
-JavaObject* Unsafe, JavaObjectField* Field) {
+JavaObject* unsafe, JavaObject* obj, jlong offset, JavaObject* expect,
+JavaObject* update) {
+  llvm_gcroot(unsafe, 0);
+  llvm_gcroot(obj, 0);
+  llvm_gcroot(expect, 0);
+  llvm_gcroot(update, 0);

-  llvm_gcroot(Field, 0);
-  llvm_gcroot(Unsafe, 0);
+  JavaObject** ptr = (JavaObject**) (((uint8 *) obj) + offset);

-  JavaField* field = JavaObjectField::getInternalField(Field);
-  return (jlong)field->ptrOffset;
+  return mvm::Collector::objectReferenceTryCASBarrier((gc*)obj,
(gc**)ptr, (gc*)expect, (gc*)update);
 }

-JNIEXPORT JavaObject* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(
-JavaObject* unsafe, JavaObject* base, jlong offset) {
-  JavaObject * res = 0;
+//===--- Class-related functions
------------------------------------------===//
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_ensureClassInitialized(
+JavaObject* unsafe, JavaObject* clazz) {
   llvm_gcroot(unsafe, 0);
-  llvm_gcroot(base, 0);
-  llvm_gcroot(res, 0);
-
+  llvm_gcroot(clazz, 0);
   BEGIN_NATIVE_EXCEPTION(0)
-  JavaObject** ptr = (JavaObject**) (baseToPtr(base) + offset);
-  res = *ptr;
-  END_NATIVE_EXCEPTION;

-  return res;
-}
+  Jnjvm* vm = JavaThread::get()->getJVM();

-JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_arrayBaseOffset(
-JavaObject* unsafe, JavaObject* clazz) {
-  // Array starts at beginning of object
-  return 0;
-}
+  CommonClass * cl = JavaObject::getClass(clazz);
+  assert(cl && cl->isClass());
+  cl->asClass()->resolveClass();
+  cl->asClass()->initialiseClass(vm);

-JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_arrayIndexScale(
-#ifdef NATIVE_JNI
-JNIEnv *env,
-#endif
-JavaObject* unsafe, JavaObject* clazz) {
-  // Return '0' if we don't support indexing this way.
-  // (We might pack fields specially, etc)
-  // TODO: Implement this for the array types we support this way
-  return 0;
+  END_NATIVE_EXCEPTION;
 }

 JNIEXPORT JavaObject* JNICALL
Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2(
@@ -281,6 +323,31 @@ JavaObject* unsafe, JavaObjectClass * clazz) {
 }


+//===--- Memory functions
-------------------------------------------------===//
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_allocateMemory(
+JavaObject* unsafe, jlong size) {
+  // TODO: Invalid size/OOM/etc handling!
+  jlong res = 0;
+  BEGIN_NATIVE_EXCEPTION(0)
+  res = (jlong)malloc(size);
+  END_NATIVE_EXCEPTION
+  return res;
+}
+
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_freeMemory(
+JavaObject* unsafe, jlong ptr) {
+  // TODO: Exception handling...
+  BEGIN_NATIVE_EXCEPTION(0)
+  free((void*)ptr);
+  END_NATIVE_EXCEPTION
+}
+
+
+//===--- Misc support functions
-------------------------------------------===//
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_registerNatives(JavaObject*) {
+  // Nothing, we define the Unsafe methods with the expected signatures.
+}
+
 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_throwException(
 JavaObject* unsafe, JavaObject * obj) {
   llvm_gcroot(unsafe, 0);
@@ -289,38 +356,6 @@ JavaObject* unsafe, JavaObject * obj) {
   JavaThread::get()->throwException(obj);
 }

-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_registerNatives(JavaObject*) {
-  // Nothing
-}
-
-// TODO: Add the Volatile variants
-#define GET_PUT_OFFSET(Type,jtype,shorttype) \
-JNIEXPORT jtype JNICALL Java_sun_misc_Unsafe_get ## Type ##
__Ljava_lang_Object_2J( \
-JavaObject* unsafe, JavaObject* base, jlong offset) { \
-  jtype res = 0; \
-  BEGIN_NATIVE_EXCEPTION(0) \
-  jtype* ptr = (jtype*) (baseToPtr(base) + offset); \
-  res = *ptr; \
-  END_NATIVE_EXCEPTION \
- \
-  return res; \
-} \
- \
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_put ## Type ##
__Ljava_lang_Object_2J ## shorttype( \
-JavaObject* unsafe, JavaObject* base, jlong offset, jtype val) { \
-  BEGIN_NATIVE_EXCEPTION(0) \
-  jtype* ptr = (jtype*) (baseToPtr(base) + offset); \
-  *ptr = val; \
-  END_NATIVE_EXCEPTION \
-}

-GET_PUT_OFFSET(Boolean,jboolean,Z)
-GET_PUT_OFFSET(Byte,jbyte,B)
-GET_PUT_OFFSET(Char,jchar,C)
-GET_PUT_OFFSET(Short,jshort,S)
-GET_PUT_OFFSET(Int,jint,I)
-GET_PUT_OFFSET(Long,jlong,J)
-GET_PUT_OFFSET(Float,jfloat,F)
-GET_PUT_OFFSET(Double,jdouble,D)

 }
-- 
1.7.5.1



More information about the vmkit-commits mailing list