[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