[vmkit-commits] [PATCH] Define all sun.misc.Unsafe methods, refactor into new "Unsafe.inc"

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


Inlined below, and attached.

Besides implementing the rest of Unsafe, move the Classpath-only code
from (what is currently) lib/J3/ClassLib/Classpath.inc into
GNUClasspath.

Thoughts welcome, and sorry for noisy diff.

Thanks!

~Will

>From d5a34423a7f917454af7b759f468dec02925110d Mon Sep 17 00:00:00 2001
From: Will Dietz <w at wdtz.org>
Date: Tue, 8 Nov 2011 19:22:46 -0600
Subject: [PATCH 1/2] Define all sun.misc.Unsafe methods, refactor into new
 "Unsafe.inc"

---
 lib/J3/ClassLib/Classpath.inc                |  588 --------------------------
 lib/J3/ClassLib/ClasspathField.inc           |   14 -
 lib/J3/ClassLib/GNUClasspath/Classpath.inc   |  289 +++++++++++++
 lib/J3/ClassLib/GNUClasspath/JavaUpcalls.cpp |    3 +-
 lib/J3/ClassLib/GNUClasspath/Makefile        |    8 +-
 lib/J3/ClassLib/Makefile                     |    4 +-
 lib/J3/ClassLib/OpenJDK/JavaUpcalls.cpp      |    2 +-
 lib/J3/ClassLib/Unsafe.inc                   |  565 +++++++++++++++++++++++++
 8 files changed, 864 insertions(+), 609 deletions(-)
 delete mode 100644 lib/J3/ClassLib/Classpath.inc
 create mode 100644 lib/J3/ClassLib/GNUClasspath/Classpath.inc
 create mode 100644 lib/J3/ClassLib/Unsafe.inc

diff --git a/lib/J3/ClassLib/Classpath.inc b/lib/J3/ClassLib/Classpath.inc
deleted file mode 100644
index 4fb16a4..0000000
--- a/lib/J3/ClassLib/Classpath.inc
+++ /dev/null
@@ -1,588 +0,0 @@
-//===-------- Classpath.cpp - Configuration for classpath
-------------------===//
-//
-//                            The VMKit project
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-
-
-#include "Classpath.h"
-#include "ClasspathReflect.h"
-#include "JavaClass.h"
-#include "JavaThread.h"
-#include "JavaUpcalls.h"
-#include "Jnjvm.h"
-#include "Reader.h"
-#include "VMStaticInstance.h"
-
-
-using namespace j3;
-
-extern "C" {
-
-// 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();
-  else
-    return (uint8*)base;
-}
-
-// Define hasClassInitializer because of a buggy implementation in Classpath.
-JNIEXPORT bool JNICALL Java_java_io_VMObjectStreamClass_hasClassInitializer(
-#ifdef NATIVE_JNI
-JNIEnv *env,
-jclass clazz,
-#endif
-JavaObject* Cl) {
-
-  llvm_gcroot(Cl, 0);
-  bool res = false;
-  BEGIN_NATIVE_EXCEPTION(0)
-
-  verifyNull(Cl);
-  Jnjvm* vm = JavaThread::get()->getJVM();
-  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, true);
-
-  if (cl->isClass() &&
-      cl->asClass()->lookupMethodDontThrow(vm->bootstrapLoader->clinitName,
-                                           vm->bootstrapLoader->clinitType,
-                                           true, false, 0))
-  res = true;
-
-  END_NATIVE_EXCEPTION
-
-  return res;
-}
-
-
-// Redefine some VMObjectStreamClass functions because of a slow implementation
-// in Classpath.
-
-JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setBooleanNative(
-#ifdef NATIVE_JNI
-JNIEnv *env,
-jclass clazz,
-#endif
-JavaObjectField* Field, JavaObject* obj, jboolean val) {
-
-  llvm_gcroot(Field, 0);
-  llvm_gcroot(obj, 0);
-  BEGIN_NATIVE_EXCEPTION(0)
-
-  verifyNull(obj);
-  JavaField* field = JavaObjectField::getInternalField(Field);
-  field->setInstanceInt8Field(obj, (uint8)val);
-
-  END_NATIVE_EXCEPTION
-}
-
-JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setByteNative(
-#ifdef NATIVE_JNI
-JNIEnv *env,
-jclass clazz,
-#endif
-JavaObjectField* Field, JavaObject* obj, jbyte val) {
-
-  llvm_gcroot(Field, 0);
-  llvm_gcroot(obj, 0);
-  BEGIN_NATIVE_EXCEPTION(0)
-
-  verifyNull(obj);
-  JavaField* field = JavaObjectField::getInternalField(Field);
-  field->setInstanceInt8Field(obj, (uint8)val);
-
-  END_NATIVE_EXCEPTION
-}
-
-JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setCharNative(
-#ifdef NATIVE_JNI
-JNIEnv *env,
-jclass clazz,
-#endif
-JavaObjectField* Field, JavaObject* obj, jchar val) {
-
-  llvm_gcroot(Field, 0);
-  llvm_gcroot(obj, 0);
-  BEGIN_NATIVE_EXCEPTION(0)
-
-  verifyNull(obj);
-  JavaField* field = JavaObjectField::getInternalField(Field);
-  field->setInstanceInt16Field((JavaObject*)obj, (uint16)val);
-
-  END_NATIVE_EXCEPTION
-}
-
-JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setShortNative(
-#ifdef NATIVE_JNI
-JNIEnv *env,
-jclass clazz,
-#endif
-JavaObjectField* Field, JavaObject* obj, jshort val) {
-
-  llvm_gcroot(Field, 0);
-  llvm_gcroot(obj, 0);
-  BEGIN_NATIVE_EXCEPTION(0)
-
-  verifyNull(obj);
-  JavaField* field = JavaObjectField::getInternalField(Field);
-  field->setInstanceInt16Field(obj, (sint16)val);
-
-  END_NATIVE_EXCEPTION
-}
-
-JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setIntNative(
-#ifdef NATIVE_JNI
-JNIEnv *env,
-jclass clazz,
-#endif
-JavaObjectField* Field, JavaObject* obj, jint val) {
-
-  llvm_gcroot(Field, 0);
-  llvm_gcroot(obj, 0);
-  BEGIN_NATIVE_EXCEPTION(0)
-
-  verifyNull(obj);
-  JavaField* field = JavaObjectField::getInternalField(Field);
-  field->setInstanceInt32Field(obj, (sint32)val);
-
-  END_NATIVE_EXCEPTION
-}
-
-JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setLongNative(
-#ifdef NATIVE_JNI
-JNIEnv *env,
-jclass clazz,
-#endif
-JavaObjectField* Field, JavaObject* obj, jlong val) {
-
-  llvm_gcroot(Field, 0);
-  llvm_gcroot(obj, 0);
-  BEGIN_NATIVE_EXCEPTION(0)
-
-  verifyNull(obj);
-  JavaField* field = JavaObjectField::getInternalField(Field);
-  field->setInstanceLongField(obj, (sint64)val);
-
-  END_NATIVE_EXCEPTION
-}
-
-JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setFloatNative(
-#ifdef NATIVE_JNI
-JNIEnv *env,
-jclass clazz,
-#endif
-JavaObjectField* Field, JavaObject* obj, jfloat val) {
-
-  llvm_gcroot(Field, 0);
-  llvm_gcroot(obj, 0);
-  BEGIN_NATIVE_EXCEPTION(0)
-
-  verifyNull(obj);
-  JavaField* field = JavaObjectField::getInternalField(Field);
-  field->setInstanceFloatField(obj, (float)val);
-
-  END_NATIVE_EXCEPTION
-}
-
-JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setDoubleNative(
-#ifdef NATIVE_JNI
-JNIEnv *env,
-jclass clazz,
-#endif
-JavaObjectField* Field, JavaObject* obj, jdouble val) {
-
-  llvm_gcroot(Field, 0);
-  llvm_gcroot(obj, 0);
-  BEGIN_NATIVE_EXCEPTION(0)
-
-  verifyNull(obj);
-  JavaField* field = JavaObjectField::getInternalField(Field);
-  field->setInstanceDoubleField(obj, (double)val);
-
-  END_NATIVE_EXCEPTION
-}
-
-JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setObjectNative(
-#ifdef NATIVE_JNI
-JNIEnv *env,
-jclass clazz,
-#endif
-JavaObjectField* Field, JavaObject* obj, JavaObject* val) {
-
-  llvm_gcroot(Field, 0);
-  llvm_gcroot(obj, 0);
-  llvm_gcroot(val, 0);
-  BEGIN_NATIVE_EXCEPTION(0)
-
-  verifyNull(obj);
-  JavaField* field = JavaObjectField::getInternalField(Field);
-  field->setInstanceObjectField(obj, val);
-
-  END_NATIVE_EXCEPTION
-}
-
-JNIEXPORT JavaObject* JNICALL Java_java_io_VMObjectInputStream_allocateObject(
-#ifdef NATIVE_JNI
-JNIEnv *env,
-jclass clazz,
-#endif
-JavaObject* target, JavaObject* constr, JavaObjectConstructor* cons) {
-
-  JavaObject* res = 0;
-  llvm_gcroot(res, 0);
-  llvm_gcroot(target, 0);
-  llvm_gcroot(constr, 0);
-  llvm_gcroot(cons, 0);
-
-  BEGIN_NATIVE_EXCEPTION(0)
-
-  Jnjvm* vm = JavaThread::get()->getJVM();
-  UserClass* cl =
-    (UserClass*)UserCommonClass::resolvedImplClass(vm, target, true);
-  res = cl->doNew(vm);
-  JavaMethod* meth = JavaObjectConstructor::getInternalMethod(cons);
-  meth->invokeIntSpecial(vm, cl, res);
-
-  END_NATIVE_EXCEPTION
-
-  return res;
-}
-
-JNIEXPORT JavaObject* JNICALL Java_java_lang_reflect_VMArray_createObjectArray(
-#ifdef NATIVE_JNI
-JNIEnv * env,
-jclass thisClass,
-#endif
-JavaObject* arrayType, jint arrayLength) {
-
-  JavaObject* res = 0;
-  llvm_gcroot(arrayType, 0);
-  llvm_gcroot(res, 0);
-
-  BEGIN_NATIVE_EXCEPTION(0)
-
-  Jnjvm* vm = JavaThread::get()->getJVM();
-  UserCommonClass* base =
-    UserCommonClass::resolvedImplClass(vm, arrayType, true);
-  JnjvmClassLoader* loader = base->classLoader;
-  const UTF8* name = base->getName();
-  // -1 because we're adding a new dimension in this method.
-  const int kLimit = 255 - 1;
-  const uint16* elements = name->elements;
-  if (name->size > kLimit && elements[kLimit] == '[') {
-    vm->illegalArgumentException("Too many dimensions for array");
-  }
-  const UTF8* arrayName = loader->constructArrayName(1, name);
-  UserClassArray* array = loader->constructArray(arrayName, base);
-  res = array->doNew(arrayLength, vm);
-
-  END_NATIVE_EXCEPTION
-
-  return res;
-}
-
-
-// Never throws.
-JNIEXPORT
-bool JNICALL Java_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8(
-#ifdef NATIVE_JNI
-JNIEnv *env,
-jclass clazz,
-#endif
-) {
-  return false;
-}
-
-// 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) {
-
-  llvm_gcroot(unsafe, 0);
-  llvm_gcroot(obj, 0);
-  jlong *ptr;
-  jlong  value;
-
-  ptr = (jlong *) (((uint8 *) obj) + offset);
-
-  value = *ptr;
-
-  if (value == expect) {
-    *ptr = update;
-    return true;
-  } else {
-    return false;
-  }
-
-}
-
-// 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) {
-
-  llvm_gcroot(unsafe, 0);
-  llvm_gcroot(obj, 0);
-  jint *ptr;
-
-  ptr = (jint *) (((uint8 *) obj) + offset);
-
-  return __sync_bool_compare_and_swap(ptr, expect, update);
-}
-
-// 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) {
-  llvm_gcroot(unsafe, 0);
-  llvm_gcroot(obj, 0);
-  llvm_gcroot(expect, 0);
-  llvm_gcroot(update, 0);
-
-  JavaObject** ptr = (JavaObject**) (((uint8 *) obj) + offset);
-
-  return mvm::Collector::objectReferenceTryCASBarrier((gc*)obj,
(gc**)ptr, (gc*)expect, (gc*)update);
-}
-
-// Never throws.
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObjectVolatile(
-#ifdef NATIVE_JNI
-JNIEnv *env,
-#endif
-JavaObject* unsafe, JavaObject* obj, jlong offset, JavaObject* value) {
-  llvm_gcroot(unsafe, 0);
-  llvm_gcroot(obj, 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
-}
-
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong__JJ(
-JavaObject* unsafe, jlong ptr, jlong value) {
-  BEGIN_NATIVE_EXCEPTION(0)
-  *(jlong*)ptr = value;
-  END_NATIVE_EXCEPTION
-}
-
-JNIEXPORT jbyte JNICALL Java_sun_misc_Unsafe_getByte__J(
-JavaObject* unsafe, jlong ptr) {
-  jbyte res = 0;
-  BEGIN_NATIVE_EXCEPTION(0)
-  res =  *(jbyte*)ptr;
-  END_NATIVE_EXCEPTION
-
-  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;
-}
-
-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)
-
-  JavaField * field = JavaObjectField::getInternalField(_field);
-  assert(field);
-
-  res = field->ptrOffset;
-
-  END_NATIVE_EXCEPTION;
-
-  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());
-
-  res = VMStaticInstance::allocate(field->classDef);
-
-  END_NATIVE_EXCEPTION;
-
-  return res;
-}
-
-JNIEXPORT JavaObject* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(
-JavaObject* unsafe, JavaObject* base, jlong offset) {
-  JavaObject * res = 0;
-  llvm_gcroot(unsafe, 0);
-  llvm_gcroot(base, 0);
-  llvm_gcroot(res, 0);
-
-  BEGIN_NATIVE_EXCEPTION(0)
-  JavaObject** ptr = (JavaObject**) (baseToPtr(base) + offset);
-  res = *ptr;
-  END_NATIVE_EXCEPTION;
-
-  return res;
-}
-
-JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_arrayBaseOffset(
-JavaObject* unsafe, JavaObject* clazz) {
-  // Array starts at beginning of object
-  return 0;
-}
-
-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;
-}
-
-JNIEXPORT JavaObject* JNICALL
Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2(
-JavaObject* unsafe, JavaString *name, ArrayObject * bytesArr, jint
off, jint len, JavaObject * loader, JavaObject * pd) {
-  JavaObject* res = 0;
-  llvm_gcroot(res, 0);
-  llvm_gcroot(unsafe, 0);
-  llvm_gcroot(name, 0);
-  llvm_gcroot(bytesArr, 0);
-  llvm_gcroot(loader, 0);
-  llvm_gcroot(pd, 0);
-  BEGIN_NATIVE_EXCEPTION(0)
-
-  Jnjvm* vm = JavaThread::get()->getJVM();
-  JnjvmClassLoader* JCL = NULL;
-  JCL = JnjvmClassLoader::getJnjvmLoaderFromJavaObject(loader, vm);
-
-  jint last = off + len;
-  if (last < bytesArr->size) {
-    assert(0 && "What exception to throw here?");
-  }
-  ClassBytes * bytes = new (JCL->allocator, len) ClassBytes(len);
-  memcpy(bytes->elements, JavaArray::getElements(bytesArr)+off, len);
-  const UTF8* utfName = JavaString::javaToInternal(name, JCL->hashUTF8);
-  UserClass *cl = JCL->constructClass(utfName, bytes);
-
-  if (cl) res = (JavaObject*)cl->getClassDelegatee(vm);
-
-  END_NATIVE_EXCEPTION;
-
-  return res;
-}
-
-JNIEXPORT JavaObject* JNICALL
Java_sun_misc_Unsafe_allocateInstance__Ljava_lang_Class_2(
-JavaObject* unsafe, JavaObjectClass * clazz) {
-  JavaObject* res = 0;
-  llvm_gcroot(unsafe, 0);
-  llvm_gcroot(clazz, 0);
-  llvm_gcroot(res, 0);
-
-  BEGIN_NATIVE_EXCEPTION(0)
-
-  JavaThread* th = JavaThread::get();
-  Jnjvm* vm = th->getJVM();
-
-  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
-  if (cl->isClass())
-    res = cl->asClass()->doNew(vm);
-
-  END_NATIVE_EXCEPTION;
-
-  return res;
-}
-
-
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_throwException(
-JavaObject* unsafe, JavaObject * obj) {
-  llvm_gcroot(unsafe, 0);
-  llvm_gcroot(obj, 0);
-
-  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)
-
-}
diff --git a/lib/J3/ClassLib/ClasspathField.inc
b/lib/J3/ClassLib/ClasspathField.inc
index e56c82f..010c54b 100644
--- a/lib/J3/ClassLib/ClasspathField.inc
+++ b/lib/J3/ClassLib/ClasspathField.inc
@@ -1154,18 +1154,4 @@ JavaObjectField* Field, JavaObject* obj, jdouble val) {
  END_NATIVE_EXCEPTION
 }

-// Never throws.
-JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_objectFieldOffset(
-#ifdef NATIVE_JNI
-JNIEnv *env,
-#endif
-JavaObject* Unsafe, JavaObjectField* Field) {
-
-  llvm_gcroot(Field, 0);
-  llvm_gcroot(Unsafe, 0);
-
-  JavaField* field = JavaObjectField::getInternalField(Field);
-  return (jlong)field->ptrOffset;
-}
-
 }
diff --git a/lib/J3/ClassLib/GNUClasspath/Classpath.inc
b/lib/J3/ClassLib/GNUClasspath/Classpath.inc
new file mode 100644
index 0000000..3354774
--- /dev/null
+++ b/lib/J3/ClassLib/GNUClasspath/Classpath.inc
@@ -0,0 +1,289 @@
+//===-------- Classpath.cpp - Configuration for classpath
-------------------===//
+//
+//                            The VMKit project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+
+#include "Classpath.h"
+#include "ClasspathReflect.h"
+#include "JavaClass.h"
+#include "JavaThread.h"
+#include "JavaUpcalls.h"
+#include "Jnjvm.h"
+#include "Reader.h"
+
+using namespace j3;
+
+extern "C" {
+
+// Define hasClassInitializer because of a buggy implementation in Classpath.
+JNIEXPORT bool JNICALL Java_java_io_VMObjectStreamClass_hasClassInitializer(
+#ifdef NATIVE_JNI
+JNIEnv *env,
+jclass clazz,
+#endif
+JavaObject* Cl) {
+
+  llvm_gcroot(Cl, 0);
+  bool res = false;
+  BEGIN_NATIVE_EXCEPTION(0)
+
+  verifyNull(Cl);
+  Jnjvm* vm = JavaThread::get()->getJVM();
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, true);
+
+  if (cl->isClass() &&
+      cl->asClass()->lookupMethodDontThrow(vm->bootstrapLoader->clinitName,
+                                           vm->bootstrapLoader->clinitType,
+                                           true, false, 0))
+  res = true;
+
+  END_NATIVE_EXCEPTION
+
+  return res;
+}
+
+
+// Redefine some VMObjectStreamClass functions because of a slow implementation
+// in Classpath.
+
+JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setBooleanNative(
+#ifdef NATIVE_JNI
+JNIEnv *env,
+jclass clazz,
+#endif
+JavaObjectField* Field, JavaObject* obj, jboolean val) {
+
+  llvm_gcroot(Field, 0);
+  llvm_gcroot(obj, 0);
+  BEGIN_NATIVE_EXCEPTION(0)
+
+  verifyNull(obj);
+  JavaField* field = JavaObjectField::getInternalField(Field);
+  field->setInstanceInt8Field(obj, (uint8)val);
+
+  END_NATIVE_EXCEPTION
+}
+
+JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setByteNative(
+#ifdef NATIVE_JNI
+JNIEnv *env,
+jclass clazz,
+#endif
+JavaObjectField* Field, JavaObject* obj, jbyte val) {
+
+  llvm_gcroot(Field, 0);
+  llvm_gcroot(obj, 0);
+  BEGIN_NATIVE_EXCEPTION(0)
+
+  verifyNull(obj);
+  JavaField* field = JavaObjectField::getInternalField(Field);
+  field->setInstanceInt8Field(obj, (uint8)val);
+
+  END_NATIVE_EXCEPTION
+}
+
+JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setCharNative(
+#ifdef NATIVE_JNI
+JNIEnv *env,
+jclass clazz,
+#endif
+JavaObjectField* Field, JavaObject* obj, jchar val) {
+
+  llvm_gcroot(Field, 0);
+  llvm_gcroot(obj, 0);
+  BEGIN_NATIVE_EXCEPTION(0)
+
+  verifyNull(obj);
+  JavaField* field = JavaObjectField::getInternalField(Field);
+  field->setInstanceInt16Field((JavaObject*)obj, (uint16)val);
+
+  END_NATIVE_EXCEPTION
+}
+
+JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setShortNative(
+#ifdef NATIVE_JNI
+JNIEnv *env,
+jclass clazz,
+#endif
+JavaObjectField* Field, JavaObject* obj, jshort val) {
+
+  llvm_gcroot(Field, 0);
+  llvm_gcroot(obj, 0);
+  BEGIN_NATIVE_EXCEPTION(0)
+
+  verifyNull(obj);
+  JavaField* field = JavaObjectField::getInternalField(Field);
+  field->setInstanceInt16Field(obj, (sint16)val);
+
+  END_NATIVE_EXCEPTION
+}
+
+JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setIntNative(
+#ifdef NATIVE_JNI
+JNIEnv *env,
+jclass clazz,
+#endif
+JavaObjectField* Field, JavaObject* obj, jint val) {
+
+  llvm_gcroot(Field, 0);
+  llvm_gcroot(obj, 0);
+  BEGIN_NATIVE_EXCEPTION(0)
+
+  verifyNull(obj);
+  JavaField* field = JavaObjectField::getInternalField(Field);
+  field->setInstanceInt32Field(obj, (sint32)val);
+
+  END_NATIVE_EXCEPTION
+}
+
+JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setLongNative(
+#ifdef NATIVE_JNI
+JNIEnv *env,
+jclass clazz,
+#endif
+JavaObjectField* Field, JavaObject* obj, jlong val) {
+
+  llvm_gcroot(Field, 0);
+  llvm_gcroot(obj, 0);
+  BEGIN_NATIVE_EXCEPTION(0)
+
+  verifyNull(obj);
+  JavaField* field = JavaObjectField::getInternalField(Field);
+  field->setInstanceLongField(obj, (sint64)val);
+
+  END_NATIVE_EXCEPTION
+}
+
+JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setFloatNative(
+#ifdef NATIVE_JNI
+JNIEnv *env,
+jclass clazz,
+#endif
+JavaObjectField* Field, JavaObject* obj, jfloat val) {
+
+  llvm_gcroot(Field, 0);
+  llvm_gcroot(obj, 0);
+  BEGIN_NATIVE_EXCEPTION(0)
+
+  verifyNull(obj);
+  JavaField* field = JavaObjectField::getInternalField(Field);
+  field->setInstanceFloatField(obj, (float)val);
+
+  END_NATIVE_EXCEPTION
+}
+
+JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setDoubleNative(
+#ifdef NATIVE_JNI
+JNIEnv *env,
+jclass clazz,
+#endif
+JavaObjectField* Field, JavaObject* obj, jdouble val) {
+
+  llvm_gcroot(Field, 0);
+  llvm_gcroot(obj, 0);
+  BEGIN_NATIVE_EXCEPTION(0)
+
+  verifyNull(obj);
+  JavaField* field = JavaObjectField::getInternalField(Field);
+  field->setInstanceDoubleField(obj, (double)val);
+
+  END_NATIVE_EXCEPTION
+}
+
+JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setObjectNative(
+#ifdef NATIVE_JNI
+JNIEnv *env,
+jclass clazz,
+#endif
+JavaObjectField* Field, JavaObject* obj, JavaObject* val) {
+
+  llvm_gcroot(Field, 0);
+  llvm_gcroot(obj, 0);
+  llvm_gcroot(val, 0);
+  BEGIN_NATIVE_EXCEPTION(0)
+
+  verifyNull(obj);
+  JavaField* field = JavaObjectField::getInternalField(Field);
+  field->setInstanceObjectField(obj, val);
+
+  END_NATIVE_EXCEPTION
+}
+
+JNIEXPORT JavaObject* JNICALL Java_java_io_VMObjectInputStream_allocateObject(
+#ifdef NATIVE_JNI
+JNIEnv *env,
+jclass clazz,
+#endif
+JavaObject* target, JavaObject* constr, JavaObjectConstructor* cons) {
+
+  JavaObject* res = 0;
+  llvm_gcroot(res, 0);
+  llvm_gcroot(target, 0);
+  llvm_gcroot(constr, 0);
+  llvm_gcroot(cons, 0);
+
+  BEGIN_NATIVE_EXCEPTION(0)
+
+  Jnjvm* vm = JavaThread::get()->getJVM();
+  UserClass* cl =
+    (UserClass*)UserCommonClass::resolvedImplClass(vm, target, true);
+  res = cl->doNew(vm);
+  JavaMethod* meth = JavaObjectConstructor::getInternalMethod(cons);
+  meth->invokeIntSpecial(vm, cl, res);
+
+  END_NATIVE_EXCEPTION
+
+  return res;
+}
+
+JNIEXPORT JavaObject* JNICALL Java_java_lang_reflect_VMArray_createObjectArray(
+#ifdef NATIVE_JNI
+JNIEnv * env,
+jclass thisClass,
+#endif
+JavaObject* arrayType, jint arrayLength) {
+
+  JavaObject* res = 0;
+  llvm_gcroot(arrayType, 0);
+  llvm_gcroot(res, 0);
+
+  BEGIN_NATIVE_EXCEPTION(0)
+
+  Jnjvm* vm = JavaThread::get()->getJVM();
+  UserCommonClass* base =
+    UserCommonClass::resolvedImplClass(vm, arrayType, true);
+  JnjvmClassLoader* loader = base->classLoader;
+  const UTF8* name = base->getName();
+  // -1 because we're adding a new dimension in this method.
+  const int kLimit = 255 - 1;
+  const uint16* elements = name->elements;
+  if (name->size > kLimit && elements[kLimit] == '[') {
+    vm->illegalArgumentException("Too many dimensions for array");
+  }
+  const UTF8* arrayName = loader->constructArrayName(1, name);
+  UserClassArray* array = loader->constructArray(arrayName, base);
+  res = array->doNew(arrayLength, vm);
+
+  END_NATIVE_EXCEPTION
+
+  return res;
+}
+
+// Never throws.
+JNIEXPORT
+bool JNICALL Java_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8(
+#ifdef NATIVE_JNI
+JNIEnv *env,
+jclass clazz,
+#endif
+) {
+  return false;
+}
+
+}
diff --git a/lib/J3/ClassLib/GNUClasspath/JavaUpcalls.cpp
b/lib/J3/ClassLib/GNUClasspath/JavaUpcalls.cpp
index bc797d1..57197c4 100644
--- a/lib/J3/ClassLib/GNUClasspath/JavaUpcalls.cpp
+++ b/lib/J3/ClassLib/GNUClasspath/JavaUpcalls.cpp
@@ -1071,8 +1071,8 @@ void Classpath::InitializeSystem(Jnjvm * jvm) {

 }

-#include "ClasspathConstructor.inc"
 #include "Classpath.inc"
+#include "ClasspathConstructor.inc"
 #include "ClasspathField.inc"
 #include "ClasspathMethod.inc"
 #include "ClasspathVMClass.inc"
@@ -1084,3 +1084,4 @@ void Classpath::InitializeSystem(Jnjvm * jvm) {
 #include "ClasspathVMSystemProperties.inc"
 #include "ClasspathVMThread.inc"
 #include "ClasspathVMThrowable.inc"
+#include "Unsafe.inc"
diff --git a/lib/J3/ClassLib/GNUClasspath/Makefile
b/lib/J3/ClassLib/GNUClasspath/Makefile
index be80b9e..f5939c9 100644
--- a/lib/J3/ClassLib/GNUClasspath/Makefile
+++ b/lib/J3/ClassLib/GNUClasspath/Makefile
@@ -9,9 +9,11 @@
 LEVEL = ../../../..


-EXTRA_DIST = ClasspathVMClass.inc ClasspathVMClassLoader.inc
ClasspathVMObject.inc \
-            ClasspathVMRuntime.inc ClasspathVMStackWalker.inc
ClasspathVMSystem.inc \
-            ClasspathVMSystemProperties.inc ClasspathVMThread.inc
ClasspathVMThrowable.inc
+EXTRA_DIST = Classpath.inc ClasspathVMClass.inc ClasspathVMClassLoader.inc \
+             ClasspathVMObject.inc ClasspathVMRuntime.inc \
+             ClasspathVMStackWalker.inc ClasspathVMSystem.inc \
+             ClasspathVMSystemProperties.inc ClasspathVMThread.inc \
+             ClasspathVMThrowable.inc

 include $(LEVEL)/Makefile.config

diff --git a/lib/J3/ClassLib/Makefile b/lib/J3/ClassLib/Makefile
index 8252b92..8fd7e2a 100644
--- a/lib/J3/ClassLib/Makefile
+++ b/lib/J3/ClassLib/Makefile
@@ -12,9 +12,9 @@ EXTRA_DIST = ArrayCopy.inc \
             ClassContext.inc \
             ClasspathConstructor.inc \
             ClasspathField.inc \
-             Classpath.inc \
             ClasspathMethod.inc \
-             SetProperties.inc
+             SetProperties.inc \
+             Unsafe.inc

 include $(LEVEL)/Makefile.config

diff --git a/lib/J3/ClassLib/OpenJDK/JavaUpcalls.cpp
b/lib/J3/ClassLib/OpenJDK/JavaUpcalls.cpp
index 22db276..3fa6390 100644
--- a/lib/J3/ClassLib/OpenJDK/JavaUpcalls.cpp
+++ b/lib/J3/ClassLib/OpenJDK/JavaUpcalls.cpp
@@ -897,7 +897,7 @@ void Classpath::InitializeSystem(Jnjvm * jvm) {


 #include "ClasspathConstructor.inc"
-#include "Classpath.inc"
 #include "ClasspathField.inc"
 #include "ClasspathMethod.inc"
 #include "OpenJDK.inc"
+#include "Unsafe.inc"
diff --git a/lib/J3/ClassLib/Unsafe.inc b/lib/J3/ClassLib/Unsafe.inc
new file mode 100644
index 0000000..44ffe73
--- /dev/null
+++ b/lib/J3/ClassLib/Unsafe.inc
@@ -0,0 +1,565 @@
+//===-------- Unsafe.inc - sun.misc.Unsafe implementation
-----------------===//
+//
+//                            The VMKit project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "VMStaticInstance.h"
+#include <stdlib.h>
+
+/// 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 + offset;
+}
+
+extern "C" {
+
+//===--- 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(_field, 0);
+
+  jlong res = 0;
+  BEGIN_NATIVE_EXCEPTION(0)
+
+  JavaField * field = JavaObjectField::getInternalField(_field);
+  assert(field);
+
+  res = field->ptrOffset;
+
+  END_NATIVE_EXCEPTION;
+
+  return res;
+}
+
+/// 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(
+#ifdef NATIVE_JNI
+JNIEnv *env,
+#endif
+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, JavaObjectField* Field) {
+
+  llvm_gcroot(Field, 0);
+  llvm_gcroot(Unsafe, 0);
+
+  JavaField* field = JavaObjectField::getInternalField(Field);
+  return (jlong)field->ptrOffset;
+}
+
+//===--- 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 \
+}
+
+//===--- Direct address read/write acccessors
-----------------------------===//
+#define GET_PUT_DIRECT(Type,jtype,shorttype) \
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_put ## Type ## __J ## shorttype( \
+JavaObject* unsafe, jlong ptr, jtype val) { \
+  BEGIN_NATIVE_EXCEPTION(0) \
+  *(jtype*)ptr = val; \
+  END_NATIVE_EXCEPTION \
+} \
+ \
+JNIEXPORT jtype JNICALL Java_sun_misc_Unsafe_get ## Type ## __J( \
+JavaObject* unsafe, jlong ptr) { \
+  jtype res = 0; \
+  BEGIN_NATIVE_EXCEPTION(0) \
+  res = *(jtype*)ptr; \
+  END_NATIVE_EXCEPTION \
+  return res; \
+}
+
+//===--- Volatile variant of field accessors
------------------------------===//
+// Memory barriers after writes to ensure new value is seen elsewhere
+#define GET_PUT_OFFSET_VOLATILE(Type,jtype,shorttype) \
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_put ## Type ##
Volatile__J ## shorttype( \
+JavaObject* unsafe, jlong ptr, jtype val) { \
+  BEGIN_NATIVE_EXCEPTION(0) \
+  *(volatile jtype*)ptr = val; \
+  __sync_synchronize(); \
+  END_NATIVE_EXCEPTION \
+} \
+ \
+JNIEXPORT jtype JNICALL Java_sun_misc_Unsafe_get ## Type ## Volatile__J( \
+JavaObject* unsafe, jlong ptr) { \
+  jtype res = 0; \
+  BEGIN_NATIVE_EXCEPTION(0) \
+  res = *(volatile jtype*)ptr; \
+  END_NATIVE_EXCEPTION \
+  return res; \
+}
+
+//===--- Volatile variant of direct address accessors
---------------------===//
+#define GET_PUT_DIRECT_VOLATILE(Type,jtype,shorttype) \
+JNIEXPORT jtype JNICALL Java_sun_misc_Unsafe_get ## Type ##
Volatile__Ljava_lang_Object_2J( \
+JavaObject* unsafe, JavaObject* base, jlong offset) { \
+  jtype res = 0; \
+  BEGIN_NATIVE_EXCEPTION(0) \
+  volatile jtype* ptr = (volatile jtype*)fieldPtr(base,offset); \
+  res = *ptr; \
+  END_NATIVE_EXCEPTION \
+ \
+  return res; \
+} \
+ \
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_put ## Type ##
Volatile__Ljava_lang_Object_2J ## shorttype( \
+JavaObject* unsafe, JavaObject* base, jlong offset, jtype val) { \
+  BEGIN_NATIVE_EXCEPTION(0) \
+  volatile jtype* ptr = (volatile jtype*)fieldPtr(base,offset); \
+  *ptr = val; \
+  __sync_synchronize(); \
+  END_NATIVE_EXCEPTION \
+}
+
+//===--- Ordered variant of field accessors
-------------------------------===//
+#define GET_PUT_FIELD_ORDERED(Type,jtype,shorttype) \
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrdered ## Type( \
+JavaObject* unsafe, JavaObject* base, jlong offset, jtype val) { \
+  BEGIN_NATIVE_EXCEPTION(0) \
+  volatile jtype* ptr = (volatile jtype*)fieldPtr(base,offset); \
+  *ptr = val; \
+  /* No memory barrier */ \
+  END_NATIVE_EXCEPTION \
+}
+
+#define GET_PUT_ALL(Type,jtype,shorttype) \
+  GET_PUT_OFFSET(Type,jtype,shorttype) \
+  GET_PUT_DIRECT(Type,jtype,shorttype) \
+  GET_PUT_OFFSET_VOLATILE(Type,jtype,shorttype) \
+  GET_PUT_DIRECT_VOLATILE(Type,jtype,shorttype)
+
+GET_PUT_ALL(Boolean,jboolean,Z)
+GET_PUT_ALL(Byte,jbyte,B)
+GET_PUT_ALL(Char,jchar,C)
+GET_PUT_ALL(Short,jshort,S)
+GET_PUT_ALL(Int,jint,I)
+GET_PUT_ALL(Long,jlong,J) // TODO: Long needs special handling!
+GET_PUT_ALL(Float,jfloat,F)
+GET_PUT_ALL(Double,jdouble,D)
+
+// Ordered:
+GET_PUT_FIELD_ORDERED(Int,jint,I)
+GET_PUT_FIELD_ORDERED(Long,jlong,J)
+
+//===--- Get/Put of Objects, due to GC needs special handling
-------------===//
+// JavaObject field accessors:
+JNIEXPORT void JNICALL
Java_sun_misc_Unsafe_putObject__Ljava_lang_Object_2JLjava_lang_Object_2(
+#ifdef NATIVE_JNI
+JNIEnv *env,
+#endif
+JavaObject* unsafe, JavaObject* base, jlong offset, JavaObject* value) {
+  llvm_gcroot(unsafe, 0);
+  llvm_gcroot(base, 0);
+  llvm_gcroot(value, 0);
+
+  JavaObject** ptr = (JavaObject**)fieldPtr(base, offset);
+  mvm::Collector::objectReferenceWriteBarrier((gc*)base, (gc**)ptr,
(gc*)value);
+}
+
+
+JNIEXPORT JavaObject* JNICALL
Java_sun_misc_Unsafe_getObject__Ljava_lang_Object_2J(
+JavaObject* unsafe, JavaObject* base, jlong offset) {
+  JavaObject * res = 0;
+  llvm_gcroot(unsafe, 0);
+  llvm_gcroot(base, 0);
+  llvm_gcroot(res, 0);
+
+  BEGIN_NATIVE_EXCEPTION(0)
+  JavaObject** ptr = (JavaObject**)fieldPtr(base, offset);
+  res = *ptr;
+  END_NATIVE_EXCEPTION;
+
+  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* base, jlong offset, JavaObject* value) {
+  llvm_gcroot(unsafe, 0);
+  llvm_gcroot(base, 0);
+  llvm_gcroot(value, 0);
+
+  JavaObject** ptr = (JavaObject**)fieldPtr(base, offset);
+  mvm::Collector::objectReferenceWriteBarrier((gc*)base, (gc**)ptr,
(gc*)value);
+  // Ensure this value is seen.
+  __sync_synchronize();
+}
+
+JNIEXPORT JavaObject* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(
+JavaObject* unsafe, JavaObject* base, jlong offset) {
+  JavaObject * res = 0;
+  llvm_gcroot(unsafe, 0);
+  llvm_gcroot(base, 0);
+  llvm_gcroot(res, 0);
+
+  BEGIN_NATIVE_EXCEPTION(0)
+  JavaObject* volatile* ptr = (JavaObject* volatile*)fieldPtr(base, offset);
+  res = *ptr;
+  END_NATIVE_EXCEPTION;
+
+  return res;
+}
+
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrderedObject(
+JavaObject* unsafe, JavaObject* base, jlong offset, JavaObject* value) {
+  llvm_gcroot(unsafe, 0);
+  llvm_gcroot(base, 0);
+  llvm_gcroot(value, 0);
+
+  JavaObject** ptr = (JavaObject**)fieldPtr(base, offset);
+  mvm::Collector::objectReferenceWriteBarrier((gc*)base, (gc**)ptr,
(gc*)value);
+  // No barrier (difference between volatile and ordered)
+}
+
+
+//===--- CompareAndSwap field accessors
-----------------------------------===//
+// Never throws.
+JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapLong(
+#ifdef NATIVE_JNI
+JNIEnv *env,
+#endif
+JavaObject* unsafe, JavaObject* base, jlong offset, jlong expect,
jlong update) {
+
+  llvm_gcroot(unsafe, 0);
+  llvm_gcroot(base, 0);
+  jlong *ptr;
+  jlong  value;
+
+  // TODO: Why isn't this atomic?
+  ptr = (jlong*)fieldPtr(base, offset);
+
+  value = *ptr;
+
+  if (value == expect) {
+    *ptr = update;
+    return true;
+  } else {
+    return false;
+  }
+
+}
+
+// Never throws.
+JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapInt(
+#ifdef NATIVE_JNI
+JNIEnv *env,
+#endif
+JavaObject* unsafe, JavaObject* base, jlong offset, jint expect, jint update) {
+
+  llvm_gcroot(unsafe, 0);
+  llvm_gcroot(base, 0);
+  jint *ptr;
+
+  ptr = (jint *)fieldPtr(base, offset);
+
+  return __sync_bool_compare_and_swap(ptr, expect, update);
+}
+
+// Never throws.
+JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapObject(
+#ifdef NATIVE_JNI
+JNIEnv *env,
+#endif
+JavaObject* unsafe, JavaObject* base, jlong offset, JavaObject* expect,
+JavaObject* update) {
+  llvm_gcroot(unsafe, 0);
+  llvm_gcroot(base, 0);
+  llvm_gcroot(expect, 0);
+  llvm_gcroot(update, 0);
+
+  JavaObject** ptr = (JavaObject**)fieldPtr(base, offset);
+  return mvm::Collector::objectReferenceTryCASBarrier((gc*)base,
(gc**)ptr, (gc*)expect, (gc*)update);
+}
+
+
+//===--- Class-related functions
------------------------------------------===//
+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;
+}
+
+JNIEXPORT JavaObject* JNICALL
Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BII(
+JavaObject* unsafe, JavaString *name, ArrayObject * bytesArr, jint
off, jint len) {
+  UNIMPLEMENTED();
+}
+
+JNIEXPORT JavaObject* JNICALL
Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2(
+JavaObject* unsafe, JavaString *name, ArrayObject * bytesArr, jint
off, jint len, JavaObject * loader, JavaObject * pd) {
+  JavaObject* res = 0;
+  llvm_gcroot(res, 0);
+  llvm_gcroot(unsafe, 0);
+  llvm_gcroot(name, 0);
+  llvm_gcroot(bytesArr, 0);
+  llvm_gcroot(loader, 0);
+  llvm_gcroot(pd, 0);
+  BEGIN_NATIVE_EXCEPTION(0)
+
+  Jnjvm* vm = JavaThread::get()->getJVM();
+  JnjvmClassLoader* JCL = NULL;
+  JCL = JnjvmClassLoader::getJnjvmLoaderFromJavaObject(loader, vm);
+
+  jint last = off + len;
+  if (last < bytesArr->size) {
+    assert(0 && "What exception to throw here?");
+  }
+  ClassBytes * bytes = new (JCL->allocator, len) ClassBytes(len);
+  memcpy(bytes->elements, JavaArray::getElements(bytesArr)+off, len);
+  const UTF8* utfName = JavaString::javaToInternal(name, JCL->hashUTF8);
+  UserClass *cl = JCL->constructClass(utfName, bytes);
+
+  if (cl) res = (JavaObject*)cl->getClassDelegatee(vm);
+
+  END_NATIVE_EXCEPTION;
+
+  return res;
+}
+
+JNIEXPORT JavaObject* JNICALL
Java_sun_misc_Unsafe_allocateInstance__Ljava_lang_Class_2(
+JavaObject* unsafe, JavaObjectClass * clazz) {
+  JavaObject* res = 0;
+  llvm_gcroot(unsafe, 0);
+  llvm_gcroot(clazz, 0);
+  llvm_gcroot(res, 0);
+
+  BEGIN_NATIVE_EXCEPTION(0)
+
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
+
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  if (cl->isClass())
+    res = cl->asClass()->doNew(vm);
+
+  END_NATIVE_EXCEPTION;
+
+  return res;
+}
+
+JNIEXPORT JavaObject* JNICALL Java_sun_Unsafe_defineAnonymousClass(
+JavaObject* unsafe, ...) {
+  UNIMPLEMENTED();
+}
+
+//===--- Memory functions
-------------------------------------------------===//
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_setMemory__JJB(
+JavaObject* unsafe, long address, long bytes, jbyte value) {
+  memset((void*)address, value, bytes);
+}
+
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_copyMemory__JJJ(
+JavaObject* unsafe, jlong src, jlong dst, jlong size) {
+  memcpy((void*)dst, (void*)src, size);
+}
+
+JNIEXPORT void JNICALL
Java_sun_misc_Unsafe_copyMemory__Ljava_lang_Object_2JLjava_lang_Object_2JJ(
+JavaObject* unsafe,
+JavaObject* srcBase, jlong srcOffset,
+JavaObject* dstBase, jlong dstOffset,
+jlong size) {
+  BEGIN_NATIVE_EXCEPTION(0)
+  uint8_t* src = fieldPtr(srcBase, srcOffset, false /* Don't throw on
null base*/ );
+  uint8_t* dst = fieldPtr(dstBase, dstOffset, false /* Don't throw on
null base*/ );
+  memcpy(dst, src, size);
+  END_NATIVE_EXCEPTION
+}
+
+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 jlong JNICALL Java_sun_misc_Unsafe_reallocateMemory(
+JavaObject* unsafe, jlong ptr, jlong newsize) {
+  // TODO: Invalid size/OOM/etc handling!
+  jlong res = 0;
+  BEGIN_NATIVE_EXCEPTION(0)
+  res = (jlong)realloc((void*)ptr, newsize);
+  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
+}
+
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_getAddress(
+JavaObject* unsafe, jlong ptr) {
+  return (jlong)*(void**)ptr;
+}
+
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_putAddress(
+JavaObject* unsafe, jlong ptr, jlong val) {
+  *(void**)ptr = (void*)val;
+}
+
+//===--- Park/Unpark thread support
---------------------------------------===//
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_park(
+JavaObject* unsafe, jboolean isAbsolute, jlong time) {
+  // Nothing, for now.
+}
+
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_unpark(
+JavaObject* unsafe, JavaObject* thread) {
+  // Nothing, for now.
+}
+
+//===--- Monitor support
--------------------------------------------------===//
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_tryMonitorEnter(
+JavaObject* unsafe, JavaObject * obj) {
+  //TODO: Implement me!
+  UNIMPLEMENTED();
+}
+
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_monitorEnter(
+JavaObject* unsafe, JavaObject * obj) {
+  //TODO: Implement me!
+  UNIMPLEMENTED();
+}
+
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_monitorExit(
+JavaObject* unsafe, JavaObject * obj) {
+  //TODO: Implement me!
+  UNIMPLEMENTED();
+}
+
+//===--- 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);
+  llvm_gcroot(obj, 0);
+
+  JavaThread::get()->throwException(obj);
+}
+
+JNIEXPORT jint JNICALL Java_sun_misc_Unsafe_pageSize(
+JavaObject* unsafe) {
+  return mvm::System::GetPageSize();
+}
+
+JNIEXPORT jint JNICALL Java_sun_misc_Unsafe_addressSize(
+JavaObject* unsafe) {
+  return mvm::kWordSize;
+}
+
+JNIEXPORT jint JNICALL Java_sun_misc_Unsafe_getLoadAverage(
+JavaObject* unsafe, ...) {
+  UNIMPLEMENTED();
+}
+
+}
--
1.7.5.1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Define-all-sun.misc.Unsafe-methods-refactor-into-new.patch
Type: application/octet-stream
Size: 44834 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/vmkit-commits/attachments/20111115/47e5fc63/attachment.obj>


More information about the vmkit-commits mailing list