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

Nicolas Geoffray nicolas.geoffray at gmail.com
Tue Nov 15 12:26:36 PST 2011


Hi Will,

With this patch, it's hard to know what you added. Could you commit a first
patch that just moves files around, and then add your new code in a new
patch?

Thanks!
Nicolas

On Tue, Nov 15, 2011 at 9:12 PM, Will Dietz <wdietz2 at illinois.edu> wrote:

> 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
>
> _______________________________________________
> vmkit-commits mailing list
> vmkit-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/vmkit-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/vmkit-commits/attachments/20111115/9f1e4872/attachment.html>


More information about the vmkit-commits mailing list