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

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


Sure thing :).

~Will

On Tue, Nov 15, 2011 at 2:26 PM, Nicolas Geoffray
<nicolas.geoffray at gmail.com> wrote:
> 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
>>
>
>




More information about the vmkit-commits mailing list