[vmkit-commits] [PATCH] Define all sun.misc.Unsafe methods, refactor into new "Unsafe.inc"
Nicolas Geoffray
nicolas.geoffray at gmail.com
Tue Nov 15 12:26:36 PST 2011
Hi Will,
With this patch, it's hard to know what you added. Could you commit a first
patch that just moves files around, and then add your new code in a new
patch?
Thanks!
Nicolas
On Tue, Nov 15, 2011 at 9:12 PM, Will Dietz <wdietz2 at illinois.edu> wrote:
> Inlined below, and attached.
>
> Besides implementing the rest of Unsafe, move the Classpath-only code
> from (what is currently) lib/J3/ClassLib/Classpath.inc into
> GNUClasspath.
>
> Thoughts welcome, and sorry for noisy diff.
>
> Thanks!
>
> ~Will
>
> >From d5a34423a7f917454af7b759f468dec02925110d Mon Sep 17 00:00:00 2001
> From: Will Dietz <w at wdtz.org>
> Date: Tue, 8 Nov 2011 19:22:46 -0600
> Subject: [PATCH 1/2] Define all sun.misc.Unsafe methods, refactor into new
> "Unsafe.inc"
>
> ---
> lib/J3/ClassLib/Classpath.inc | 588
> --------------------------
> lib/J3/ClassLib/ClasspathField.inc | 14 -
> lib/J3/ClassLib/GNUClasspath/Classpath.inc | 289 +++++++++++++
> lib/J3/ClassLib/GNUClasspath/JavaUpcalls.cpp | 3 +-
> lib/J3/ClassLib/GNUClasspath/Makefile | 8 +-
> lib/J3/ClassLib/Makefile | 4 +-
> lib/J3/ClassLib/OpenJDK/JavaUpcalls.cpp | 2 +-
> lib/J3/ClassLib/Unsafe.inc | 565
> +++++++++++++++++++++++++
> 8 files changed, 864 insertions(+), 609 deletions(-)
> delete mode 100644 lib/J3/ClassLib/Classpath.inc
> create mode 100644 lib/J3/ClassLib/GNUClasspath/Classpath.inc
> create mode 100644 lib/J3/ClassLib/Unsafe.inc
>
> diff --git a/lib/J3/ClassLib/Classpath.inc b/lib/J3/ClassLib/Classpath.inc
> deleted file mode 100644
> index 4fb16a4..0000000
> --- a/lib/J3/ClassLib/Classpath.inc
> +++ /dev/null
> @@ -1,588 +0,0 @@
> -//===-------- Classpath.cpp - Configuration for classpath
> -------------------===//
> -//
> -// The VMKit project
> -//
> -// This file is distributed under the University of Illinois Open Source
> -// License. See LICENSE.TXT for details.
> -//
>
> -//===----------------------------------------------------------------------===//
> -
> -
> -
> -#include "Classpath.h"
> -#include "ClasspathReflect.h"
> -#include "JavaClass.h"
> -#include "JavaThread.h"
> -#include "JavaUpcalls.h"
> -#include "Jnjvm.h"
> -#include "Reader.h"
> -#include "VMStaticInstance.h"
> -
> -
> -using namespace j3;
> -
> -extern "C" {
> -
> -// Convert a 'base' JavaObject to its pointer representation.
> -// Handles our special VMStaticInstance wrapper.
> -static inline uint8 *baseToPtr(JavaObject *base) {
> - if (VMStaticInstance::isVMStaticInstance(base))
> - return (uint8*)((VMStaticInstance*)base)->getStaticInstance();
> - else
> - return (uint8*)base;
> -}
> -
> -// Define hasClassInitializer because of a buggy implementation in
> Classpath.
> -JNIEXPORT bool JNICALL
> Java_java_io_VMObjectStreamClass_hasClassInitializer(
> -#ifdef NATIVE_JNI
> -JNIEnv *env,
> -jclass clazz,
> -#endif
> -JavaObject* Cl) {
> -
> - llvm_gcroot(Cl, 0);
> - bool res = false;
> - BEGIN_NATIVE_EXCEPTION(0)
> -
> - verifyNull(Cl);
> - Jnjvm* vm = JavaThread::get()->getJVM();
> - UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, true);
> -
> - if (cl->isClass() &&
> -
> cl->asClass()->lookupMethodDontThrow(vm->bootstrapLoader->clinitName,
> -
> vm->bootstrapLoader->clinitType,
> - true, false, 0))
> - res = true;
> -
> - END_NATIVE_EXCEPTION
> -
> - return res;
> -}
> -
> -
> -// Redefine some VMObjectStreamClass functions because of a slow
> implementation
> -// in Classpath.
> -
> -JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setBooleanNative(
> -#ifdef NATIVE_JNI
> -JNIEnv *env,
> -jclass clazz,
> -#endif
> -JavaObjectField* Field, JavaObject* obj, jboolean val) {
> -
> - llvm_gcroot(Field, 0);
> - llvm_gcroot(obj, 0);
> - BEGIN_NATIVE_EXCEPTION(0)
> -
> - verifyNull(obj);
> - JavaField* field = JavaObjectField::getInternalField(Field);
> - field->setInstanceInt8Field(obj, (uint8)val);
> -
> - END_NATIVE_EXCEPTION
> -}
> -
> -JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setByteNative(
> -#ifdef NATIVE_JNI
> -JNIEnv *env,
> -jclass clazz,
> -#endif
> -JavaObjectField* Field, JavaObject* obj, jbyte val) {
> -
> - llvm_gcroot(Field, 0);
> - llvm_gcroot(obj, 0);
> - BEGIN_NATIVE_EXCEPTION(0)
> -
> - verifyNull(obj);
> - JavaField* field = JavaObjectField::getInternalField(Field);
> - field->setInstanceInt8Field(obj, (uint8)val);
> -
> - END_NATIVE_EXCEPTION
> -}
> -
> -JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setCharNative(
> -#ifdef NATIVE_JNI
> -JNIEnv *env,
> -jclass clazz,
> -#endif
> -JavaObjectField* Field, JavaObject* obj, jchar val) {
> -
> - llvm_gcroot(Field, 0);
> - llvm_gcroot(obj, 0);
> - BEGIN_NATIVE_EXCEPTION(0)
> -
> - verifyNull(obj);
> - JavaField* field = JavaObjectField::getInternalField(Field);
> - field->setInstanceInt16Field((JavaObject*)obj, (uint16)val);
> -
> - END_NATIVE_EXCEPTION
> -}
> -
> -JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setShortNative(
> -#ifdef NATIVE_JNI
> -JNIEnv *env,
> -jclass clazz,
> -#endif
> -JavaObjectField* Field, JavaObject* obj, jshort val) {
> -
> - llvm_gcroot(Field, 0);
> - llvm_gcroot(obj, 0);
> - BEGIN_NATIVE_EXCEPTION(0)
> -
> - verifyNull(obj);
> - JavaField* field = JavaObjectField::getInternalField(Field);
> - field->setInstanceInt16Field(obj, (sint16)val);
> -
> - END_NATIVE_EXCEPTION
> -}
> -
> -JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setIntNative(
> -#ifdef NATIVE_JNI
> -JNIEnv *env,
> -jclass clazz,
> -#endif
> -JavaObjectField* Field, JavaObject* obj, jint val) {
> -
> - llvm_gcroot(Field, 0);
> - llvm_gcroot(obj, 0);
> - BEGIN_NATIVE_EXCEPTION(0)
> -
> - verifyNull(obj);
> - JavaField* field = JavaObjectField::getInternalField(Field);
> - field->setInstanceInt32Field(obj, (sint32)val);
> -
> - END_NATIVE_EXCEPTION
> -}
> -
> -JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setLongNative(
> -#ifdef NATIVE_JNI
> -JNIEnv *env,
> -jclass clazz,
> -#endif
> -JavaObjectField* Field, JavaObject* obj, jlong val) {
> -
> - llvm_gcroot(Field, 0);
> - llvm_gcroot(obj, 0);
> - BEGIN_NATIVE_EXCEPTION(0)
> -
> - verifyNull(obj);
> - JavaField* field = JavaObjectField::getInternalField(Field);
> - field->setInstanceLongField(obj, (sint64)val);
> -
> - END_NATIVE_EXCEPTION
> -}
> -
> -JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setFloatNative(
> -#ifdef NATIVE_JNI
> -JNIEnv *env,
> -jclass clazz,
> -#endif
> -JavaObjectField* Field, JavaObject* obj, jfloat val) {
> -
> - llvm_gcroot(Field, 0);
> - llvm_gcroot(obj, 0);
> - BEGIN_NATIVE_EXCEPTION(0)
> -
> - verifyNull(obj);
> - JavaField* field = JavaObjectField::getInternalField(Field);
> - field->setInstanceFloatField(obj, (float)val);
> -
> - END_NATIVE_EXCEPTION
> -}
> -
> -JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setDoubleNative(
> -#ifdef NATIVE_JNI
> -JNIEnv *env,
> -jclass clazz,
> -#endif
> -JavaObjectField* Field, JavaObject* obj, jdouble val) {
> -
> - llvm_gcroot(Field, 0);
> - llvm_gcroot(obj, 0);
> - BEGIN_NATIVE_EXCEPTION(0)
> -
> - verifyNull(obj);
> - JavaField* field = JavaObjectField::getInternalField(Field);
> - field->setInstanceDoubleField(obj, (double)val);
> -
> - END_NATIVE_EXCEPTION
> -}
> -
> -JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setObjectNative(
> -#ifdef NATIVE_JNI
> -JNIEnv *env,
> -jclass clazz,
> -#endif
> -JavaObjectField* Field, JavaObject* obj, JavaObject* val) {
> -
> - llvm_gcroot(Field, 0);
> - llvm_gcroot(obj, 0);
> - llvm_gcroot(val, 0);
> - BEGIN_NATIVE_EXCEPTION(0)
> -
> - verifyNull(obj);
> - JavaField* field = JavaObjectField::getInternalField(Field);
> - field->setInstanceObjectField(obj, val);
> -
> - END_NATIVE_EXCEPTION
> -}
> -
> -JNIEXPORT JavaObject* JNICALL
> Java_java_io_VMObjectInputStream_allocateObject(
> -#ifdef NATIVE_JNI
> -JNIEnv *env,
> -jclass clazz,
> -#endif
> -JavaObject* target, JavaObject* constr, JavaObjectConstructor* cons) {
> -
> - JavaObject* res = 0;
> - llvm_gcroot(res, 0);
> - llvm_gcroot(target, 0);
> - llvm_gcroot(constr, 0);
> - llvm_gcroot(cons, 0);
> -
> - BEGIN_NATIVE_EXCEPTION(0)
> -
> - Jnjvm* vm = JavaThread::get()->getJVM();
> - UserClass* cl =
> - (UserClass*)UserCommonClass::resolvedImplClass(vm, target, true);
> - res = cl->doNew(vm);
> - JavaMethod* meth = JavaObjectConstructor::getInternalMethod(cons);
> - meth->invokeIntSpecial(vm, cl, res);
> -
> - END_NATIVE_EXCEPTION
> -
> - return res;
> -}
> -
> -JNIEXPORT JavaObject* JNICALL
> Java_java_lang_reflect_VMArray_createObjectArray(
> -#ifdef NATIVE_JNI
> -JNIEnv * env,
> -jclass thisClass,
> -#endif
> -JavaObject* arrayType, jint arrayLength) {
> -
> - JavaObject* res = 0;
> - llvm_gcroot(arrayType, 0);
> - llvm_gcroot(res, 0);
> -
> - BEGIN_NATIVE_EXCEPTION(0)
> -
> - Jnjvm* vm = JavaThread::get()->getJVM();
> - UserCommonClass* base =
> - UserCommonClass::resolvedImplClass(vm, arrayType, true);
> - JnjvmClassLoader* loader = base->classLoader;
> - const UTF8* name = base->getName();
> - // -1 because we're adding a new dimension in this method.
> - const int kLimit = 255 - 1;
> - const uint16* elements = name->elements;
> - if (name->size > kLimit && elements[kLimit] == '[') {
> - vm->illegalArgumentException("Too many dimensions for array");
> - }
> - const UTF8* arrayName = loader->constructArrayName(1, name);
> - UserClassArray* array = loader->constructArray(arrayName, base);
> - res = array->doNew(arrayLength, vm);
> -
> - END_NATIVE_EXCEPTION
> -
> - return res;
> -}
> -
> -
> -// Never throws.
> -JNIEXPORT
> -bool JNICALL Java_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8(
> -#ifdef NATIVE_JNI
> -JNIEnv *env,
> -jclass clazz,
> -#endif
> -) {
> - return false;
> -}
> -
> -// Never throws.
> -JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapLong(
> -#ifdef NATIVE_JNI
> -JNIEnv *env,
> -#endif
> -JavaObject* unsafe, JavaObject* obj, jlong offset, jlong expect,
> jlong update) {
> -
> - llvm_gcroot(unsafe, 0);
> - llvm_gcroot(obj, 0);
> - jlong *ptr;
> - jlong value;
> -
> - ptr = (jlong *) (((uint8 *) obj) + offset);
> -
> - value = *ptr;
> -
> - if (value == expect) {
> - *ptr = update;
> - return true;
> - } else {
> - return false;
> - }
> -
> -}
> -
> -// Never throws.
> -JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapInt(
> -#ifdef NATIVE_JNI
> -JNIEnv *env,
> -#endif
> -JavaObject* unsafe, JavaObject* obj, jlong offset, jint expect, jint
> update) {
> -
> - llvm_gcroot(unsafe, 0);
> - llvm_gcroot(obj, 0);
> - jint *ptr;
> -
> - ptr = (jint *) (((uint8 *) obj) + offset);
> -
> - return __sync_bool_compare_and_swap(ptr, expect, update);
> -}
> -
> -// Never throws.
> -JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapObject(
> -#ifdef NATIVE_JNI
> -JNIEnv *env,
> -#endif
> -JavaObject* unsafe, JavaObject* obj, jlong offset, JavaObject* expect,
> -JavaObject* update) {
> - llvm_gcroot(unsafe, 0);
> - llvm_gcroot(obj, 0);
> - llvm_gcroot(expect, 0);
> - llvm_gcroot(update, 0);
> -
> - JavaObject** ptr = (JavaObject**) (((uint8 *) obj) + offset);
> -
> - return mvm::Collector::objectReferenceTryCASBarrier((gc*)obj,
> (gc**)ptr, (gc*)expect, (gc*)update);
> -}
> -
> -// Never throws.
> -JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObjectVolatile(
> -#ifdef NATIVE_JNI
> -JNIEnv *env,
> -#endif
> -JavaObject* unsafe, JavaObject* obj, jlong offset, JavaObject* value) {
> - llvm_gcroot(unsafe, 0);
> - llvm_gcroot(obj, 0);
> - llvm_gcroot(value, 0);
> -
> - JavaObject** ptr = (JavaObject**) (((uint8 *) obj) + offset);
> - mvm::Collector::objectReferenceWriteBarrier((gc*)obj, (gc**)ptr,
> (gc*)value);
> -}
> -
> -JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_allocateMemory(
> -JavaObject* unsafe, jlong size) {
> - // TODO: Invalid size/OOM/etc handling!
> - jlong res = 0;
> - BEGIN_NATIVE_EXCEPTION(0)
> - res = (jlong)malloc(size);
> - END_NATIVE_EXCEPTION
> - return res;
> -}
> -
> -JNIEXPORT void JNICALL Java_sun_misc_Unsafe_freeMemory(
> -JavaObject* unsafe, jlong ptr) {
> - // TODO: Exception handling...
> - BEGIN_NATIVE_EXCEPTION(0)
> - free((void*)ptr);
> - END_NATIVE_EXCEPTION
> -}
> -
> -JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong__JJ(
> -JavaObject* unsafe, jlong ptr, jlong value) {
> - BEGIN_NATIVE_EXCEPTION(0)
> - *(jlong*)ptr = value;
> - END_NATIVE_EXCEPTION
> -}
> -
> -JNIEXPORT jbyte JNICALL Java_sun_misc_Unsafe_getByte__J(
> -JavaObject* unsafe, jlong ptr) {
> - jbyte res = 0;
> - BEGIN_NATIVE_EXCEPTION(0)
> - res = *(jbyte*)ptr;
> - END_NATIVE_EXCEPTION
> -
> - return res;
> -}
> -
> -JNIEXPORT void JNICALL Java_sun_misc_Unsafe_ensureClassInitialized(
> -JavaObject* unsafe, JavaObject* clazz) {
> - llvm_gcroot(unsafe, 0);
> - llvm_gcroot(clazz, 0);
> - BEGIN_NATIVE_EXCEPTION(0)
> -
> - Jnjvm* vm = JavaThread::get()->getJVM();
> -
> - CommonClass * cl = JavaObject::getClass(clazz);
> - assert(cl && cl->isClass());
> - cl->asClass()->resolveClass();
> - cl->asClass()->initialiseClass(vm);
> -
> - END_NATIVE_EXCEPTION;
> -}
> -
> -JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_staticFieldOffset(
> -JavaObject* unsafe, JavaObjectField* _field) {
> - llvm_gcroot(unsafe, 0);
> - llvm_gcroot(_field, 0);
> -
> - jlong res = 0;
> - BEGIN_NATIVE_EXCEPTION(0)
> -
> - JavaField * field = JavaObjectField::getInternalField(_field);
> - assert(field);
> -
> - res = field->ptrOffset;
> -
> - END_NATIVE_EXCEPTION;
> -
> - return res;
> -}
> -
> -JNIEXPORT JavaObject* JNICALL Java_sun_misc_Unsafe_staticFieldBase(
> -JavaObject* unsafe, JavaObjectField* _field) {
> - JavaObject* res = 0;
> - llvm_gcroot(unsafe, 0);
> - llvm_gcroot(_field, 0);
> - llvm_gcroot(res, 0);
> - BEGIN_NATIVE_EXCEPTION(0)
> -
> - JavaField * field = JavaObjectField::getInternalField(_field);
> - assert(field);
> - field->classDef->initialiseClass(JavaThread::get()->getJVM());
> -
> - res = VMStaticInstance::allocate(field->classDef);
> -
> - END_NATIVE_EXCEPTION;
> -
> - return res;
> -}
> -
> -JNIEXPORT JavaObject* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(
> -JavaObject* unsafe, JavaObject* base, jlong offset) {
> - JavaObject * res = 0;
> - llvm_gcroot(unsafe, 0);
> - llvm_gcroot(base, 0);
> - llvm_gcroot(res, 0);
> -
> - BEGIN_NATIVE_EXCEPTION(0)
> - JavaObject** ptr = (JavaObject**) (baseToPtr(base) + offset);
> - res = *ptr;
> - END_NATIVE_EXCEPTION;
> -
> - return res;
> -}
> -
> -JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_arrayBaseOffset(
> -JavaObject* unsafe, JavaObject* clazz) {
> - // Array starts at beginning of object
> - return 0;
> -}
> -
> -JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_arrayIndexScale(
> -#ifdef NATIVE_JNI
> -JNIEnv *env,
> -#endif
> -JavaObject* unsafe, JavaObject* clazz) {
> - // Return '0' if we don't support indexing this way.
> - // (We might pack fields specially, etc)
> - // TODO: Implement this for the array types we support this way
> - return 0;
> -}
> -
> -JNIEXPORT JavaObject* JNICALL
>
> Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2(
> -JavaObject* unsafe, JavaString *name, ArrayObject * bytesArr, jint
> off, jint len, JavaObject * loader, JavaObject * pd) {
> - JavaObject* res = 0;
> - llvm_gcroot(res, 0);
> - llvm_gcroot(unsafe, 0);
> - llvm_gcroot(name, 0);
> - llvm_gcroot(bytesArr, 0);
> - llvm_gcroot(loader, 0);
> - llvm_gcroot(pd, 0);
> - BEGIN_NATIVE_EXCEPTION(0)
> -
> - Jnjvm* vm = JavaThread::get()->getJVM();
> - JnjvmClassLoader* JCL = NULL;
> - JCL = JnjvmClassLoader::getJnjvmLoaderFromJavaObject(loader, vm);
> -
> - jint last = off + len;
> - if (last < bytesArr->size) {
> - assert(0 && "What exception to throw here?");
> - }
> - ClassBytes * bytes = new (JCL->allocator, len) ClassBytes(len);
> - memcpy(bytes->elements, JavaArray::getElements(bytesArr)+off, len);
> - const UTF8* utfName = JavaString::javaToInternal(name, JCL->hashUTF8);
> - UserClass *cl = JCL->constructClass(utfName, bytes);
> -
> - if (cl) res = (JavaObject*)cl->getClassDelegatee(vm);
> -
> - END_NATIVE_EXCEPTION;
> -
> - return res;
> -}
> -
> -JNIEXPORT JavaObject* JNICALL
> Java_sun_misc_Unsafe_allocateInstance__Ljava_lang_Class_2(
> -JavaObject* unsafe, JavaObjectClass * clazz) {
> - JavaObject* res = 0;
> - llvm_gcroot(unsafe, 0);
> - llvm_gcroot(clazz, 0);
> - llvm_gcroot(res, 0);
> -
> - BEGIN_NATIVE_EXCEPTION(0)
> -
> - JavaThread* th = JavaThread::get();
> - Jnjvm* vm = th->getJVM();
> -
> - UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz,
> true);
> - if (cl->isClass())
> - res = cl->asClass()->doNew(vm);
> -
> - END_NATIVE_EXCEPTION;
> -
> - return res;
> -}
> -
> -
> -JNIEXPORT void JNICALL Java_sun_misc_Unsafe_throwException(
> -JavaObject* unsafe, JavaObject * obj) {
> - llvm_gcroot(unsafe, 0);
> - llvm_gcroot(obj, 0);
> -
> - JavaThread::get()->throwException(obj);
> -}
> -
> -JNIEXPORT void JNICALL Java_sun_misc_Unsafe_registerNatives(JavaObject*) {
> - // Nothing
> -}
> -
> -// TODO: Add the Volatile variants
> -#define GET_PUT_OFFSET(Type,jtype,shorttype) \
> -JNIEXPORT jtype JNICALL Java_sun_misc_Unsafe_get ## Type ##
> __Ljava_lang_Object_2J( \
> -JavaObject* unsafe, JavaObject* base, jlong offset) { \
> - jtype res = 0; \
> - BEGIN_NATIVE_EXCEPTION(0) \
> - jtype* ptr = (jtype*) (baseToPtr(base) + offset); \
> - res = *ptr; \
> - END_NATIVE_EXCEPTION \
> - \
> - return res; \
> -} \
> - \
> -JNIEXPORT void JNICALL Java_sun_misc_Unsafe_put ## Type ##
> __Ljava_lang_Object_2J ## shorttype( \
> -JavaObject* unsafe, JavaObject* base, jlong offset, jtype val) { \
> - BEGIN_NATIVE_EXCEPTION(0) \
> - jtype* ptr = (jtype*) (baseToPtr(base) + offset); \
> - *ptr = val; \
> - END_NATIVE_EXCEPTION \
> -}
> -
> -GET_PUT_OFFSET(Boolean,jboolean,Z)
> -GET_PUT_OFFSET(Byte,jbyte,B)
> -GET_PUT_OFFSET(Char,jchar,C)
> -GET_PUT_OFFSET(Short,jshort,S)
> -GET_PUT_OFFSET(Int,jint,I)
> -GET_PUT_OFFSET(Long,jlong,J)
> -GET_PUT_OFFSET(Float,jfloat,F)
> -GET_PUT_OFFSET(Double,jdouble,D)
> -
> -}
> diff --git a/lib/J3/ClassLib/ClasspathField.inc
> b/lib/J3/ClassLib/ClasspathField.inc
> index e56c82f..010c54b 100644
> --- a/lib/J3/ClassLib/ClasspathField.inc
> +++ b/lib/J3/ClassLib/ClasspathField.inc
> @@ -1154,18 +1154,4 @@ JavaObjectField* Field, JavaObject* obj, jdouble
> val) {
> END_NATIVE_EXCEPTION
> }
>
> -// Never throws.
> -JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_objectFieldOffset(
> -#ifdef NATIVE_JNI
> -JNIEnv *env,
> -#endif
> -JavaObject* Unsafe, JavaObjectField* Field) {
> -
> - llvm_gcroot(Field, 0);
> - llvm_gcroot(Unsafe, 0);
> -
> - JavaField* field = JavaObjectField::getInternalField(Field);
> - return (jlong)field->ptrOffset;
> -}
> -
> }
> diff --git a/lib/J3/ClassLib/GNUClasspath/Classpath.inc
> b/lib/J3/ClassLib/GNUClasspath/Classpath.inc
> new file mode 100644
> index 0000000..3354774
> --- /dev/null
> +++ b/lib/J3/ClassLib/GNUClasspath/Classpath.inc
> @@ -0,0 +1,289 @@
> +//===-------- Classpath.cpp - Configuration for classpath
> -------------------===//
> +//
> +// The VMKit project
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +
> +
> +#include "Classpath.h"
> +#include "ClasspathReflect.h"
> +#include "JavaClass.h"
> +#include "JavaThread.h"
> +#include "JavaUpcalls.h"
> +#include "Jnjvm.h"
> +#include "Reader.h"
> +
> +using namespace j3;
> +
> +extern "C" {
> +
> +// Define hasClassInitializer because of a buggy implementation in
> Classpath.
> +JNIEXPORT bool JNICALL
> Java_java_io_VMObjectStreamClass_hasClassInitializer(
> +#ifdef NATIVE_JNI
> +JNIEnv *env,
> +jclass clazz,
> +#endif
> +JavaObject* Cl) {
> +
> + llvm_gcroot(Cl, 0);
> + bool res = false;
> + BEGIN_NATIVE_EXCEPTION(0)
> +
> + verifyNull(Cl);
> + Jnjvm* vm = JavaThread::get()->getJVM();
> + UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, true);
> +
> + if (cl->isClass() &&
> +
> cl->asClass()->lookupMethodDontThrow(vm->bootstrapLoader->clinitName,
> +
> vm->bootstrapLoader->clinitType,
> + true, false, 0))
> + res = true;
> +
> + END_NATIVE_EXCEPTION
> +
> + return res;
> +}
> +
> +
> +// Redefine some VMObjectStreamClass functions because of a slow
> implementation
> +// in Classpath.
> +
> +JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setBooleanNative(
> +#ifdef NATIVE_JNI
> +JNIEnv *env,
> +jclass clazz,
> +#endif
> +JavaObjectField* Field, JavaObject* obj, jboolean val) {
> +
> + llvm_gcroot(Field, 0);
> + llvm_gcroot(obj, 0);
> + BEGIN_NATIVE_EXCEPTION(0)
> +
> + verifyNull(obj);
> + JavaField* field = JavaObjectField::getInternalField(Field);
> + field->setInstanceInt8Field(obj, (uint8)val);
> +
> + END_NATIVE_EXCEPTION
> +}
> +
> +JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setByteNative(
> +#ifdef NATIVE_JNI
> +JNIEnv *env,
> +jclass clazz,
> +#endif
> +JavaObjectField* Field, JavaObject* obj, jbyte val) {
> +
> + llvm_gcroot(Field, 0);
> + llvm_gcroot(obj, 0);
> + BEGIN_NATIVE_EXCEPTION(0)
> +
> + verifyNull(obj);
> + JavaField* field = JavaObjectField::getInternalField(Field);
> + field->setInstanceInt8Field(obj, (uint8)val);
> +
> + END_NATIVE_EXCEPTION
> +}
> +
> +JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setCharNative(
> +#ifdef NATIVE_JNI
> +JNIEnv *env,
> +jclass clazz,
> +#endif
> +JavaObjectField* Field, JavaObject* obj, jchar val) {
> +
> + llvm_gcroot(Field, 0);
> + llvm_gcroot(obj, 0);
> + BEGIN_NATIVE_EXCEPTION(0)
> +
> + verifyNull(obj);
> + JavaField* field = JavaObjectField::getInternalField(Field);
> + field->setInstanceInt16Field((JavaObject*)obj, (uint16)val);
> +
> + END_NATIVE_EXCEPTION
> +}
> +
> +JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setShortNative(
> +#ifdef NATIVE_JNI
> +JNIEnv *env,
> +jclass clazz,
> +#endif
> +JavaObjectField* Field, JavaObject* obj, jshort val) {
> +
> + llvm_gcroot(Field, 0);
> + llvm_gcroot(obj, 0);
> + BEGIN_NATIVE_EXCEPTION(0)
> +
> + verifyNull(obj);
> + JavaField* field = JavaObjectField::getInternalField(Field);
> + field->setInstanceInt16Field(obj, (sint16)val);
> +
> + END_NATIVE_EXCEPTION
> +}
> +
> +JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setIntNative(
> +#ifdef NATIVE_JNI
> +JNIEnv *env,
> +jclass clazz,
> +#endif
> +JavaObjectField* Field, JavaObject* obj, jint val) {
> +
> + llvm_gcroot(Field, 0);
> + llvm_gcroot(obj, 0);
> + BEGIN_NATIVE_EXCEPTION(0)
> +
> + verifyNull(obj);
> + JavaField* field = JavaObjectField::getInternalField(Field);
> + field->setInstanceInt32Field(obj, (sint32)val);
> +
> + END_NATIVE_EXCEPTION
> +}
> +
> +JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setLongNative(
> +#ifdef NATIVE_JNI
> +JNIEnv *env,
> +jclass clazz,
> +#endif
> +JavaObjectField* Field, JavaObject* obj, jlong val) {
> +
> + llvm_gcroot(Field, 0);
> + llvm_gcroot(obj, 0);
> + BEGIN_NATIVE_EXCEPTION(0)
> +
> + verifyNull(obj);
> + JavaField* field = JavaObjectField::getInternalField(Field);
> + field->setInstanceLongField(obj, (sint64)val);
> +
> + END_NATIVE_EXCEPTION
> +}
> +
> +JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setFloatNative(
> +#ifdef NATIVE_JNI
> +JNIEnv *env,
> +jclass clazz,
> +#endif
> +JavaObjectField* Field, JavaObject* obj, jfloat val) {
> +
> + llvm_gcroot(Field, 0);
> + llvm_gcroot(obj, 0);
> + BEGIN_NATIVE_EXCEPTION(0)
> +
> + verifyNull(obj);
> + JavaField* field = JavaObjectField::getInternalField(Field);
> + field->setInstanceFloatField(obj, (float)val);
> +
> + END_NATIVE_EXCEPTION
> +}
> +
> +JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setDoubleNative(
> +#ifdef NATIVE_JNI
> +JNIEnv *env,
> +jclass clazz,
> +#endif
> +JavaObjectField* Field, JavaObject* obj, jdouble val) {
> +
> + llvm_gcroot(Field, 0);
> + llvm_gcroot(obj, 0);
> + BEGIN_NATIVE_EXCEPTION(0)
> +
> + verifyNull(obj);
> + JavaField* field = JavaObjectField::getInternalField(Field);
> + field->setInstanceDoubleField(obj, (double)val);
> +
> + END_NATIVE_EXCEPTION
> +}
> +
> +JNIEXPORT void JNICALL Java_java_io_VMObjectStreamClass_setObjectNative(
> +#ifdef NATIVE_JNI
> +JNIEnv *env,
> +jclass clazz,
> +#endif
> +JavaObjectField* Field, JavaObject* obj, JavaObject* val) {
> +
> + llvm_gcroot(Field, 0);
> + llvm_gcroot(obj, 0);
> + llvm_gcroot(val, 0);
> + BEGIN_NATIVE_EXCEPTION(0)
> +
> + verifyNull(obj);
> + JavaField* field = JavaObjectField::getInternalField(Field);
> + field->setInstanceObjectField(obj, val);
> +
> + END_NATIVE_EXCEPTION
> +}
> +
> +JNIEXPORT JavaObject* JNICALL
> Java_java_io_VMObjectInputStream_allocateObject(
> +#ifdef NATIVE_JNI
> +JNIEnv *env,
> +jclass clazz,
> +#endif
> +JavaObject* target, JavaObject* constr, JavaObjectConstructor* cons) {
> +
> + JavaObject* res = 0;
> + llvm_gcroot(res, 0);
> + llvm_gcroot(target, 0);
> + llvm_gcroot(constr, 0);
> + llvm_gcroot(cons, 0);
> +
> + BEGIN_NATIVE_EXCEPTION(0)
> +
> + Jnjvm* vm = JavaThread::get()->getJVM();
> + UserClass* cl =
> + (UserClass*)UserCommonClass::resolvedImplClass(vm, target, true);
> + res = cl->doNew(vm);
> + JavaMethod* meth = JavaObjectConstructor::getInternalMethod(cons);
> + meth->invokeIntSpecial(vm, cl, res);
> +
> + END_NATIVE_EXCEPTION
> +
> + return res;
> +}
> +
> +JNIEXPORT JavaObject* JNICALL
> Java_java_lang_reflect_VMArray_createObjectArray(
> +#ifdef NATIVE_JNI
> +JNIEnv * env,
> +jclass thisClass,
> +#endif
> +JavaObject* arrayType, jint arrayLength) {
> +
> + JavaObject* res = 0;
> + llvm_gcroot(arrayType, 0);
> + llvm_gcroot(res, 0);
> +
> + BEGIN_NATIVE_EXCEPTION(0)
> +
> + Jnjvm* vm = JavaThread::get()->getJVM();
> + UserCommonClass* base =
> + UserCommonClass::resolvedImplClass(vm, arrayType, true);
> + JnjvmClassLoader* loader = base->classLoader;
> + const UTF8* name = base->getName();
> + // -1 because we're adding a new dimension in this method.
> + const int kLimit = 255 - 1;
> + const uint16* elements = name->elements;
> + if (name->size > kLimit && elements[kLimit] == '[') {
> + vm->illegalArgumentException("Too many dimensions for array");
> + }
> + const UTF8* arrayName = loader->constructArrayName(1, name);
> + UserClassArray* array = loader->constructArray(arrayName, base);
> + res = array->doNew(arrayLength, vm);
> +
> + END_NATIVE_EXCEPTION
> +
> + return res;
> +}
> +
> +// Never throws.
> +JNIEXPORT
> +bool JNICALL Java_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8(
> +#ifdef NATIVE_JNI
> +JNIEnv *env,
> +jclass clazz,
> +#endif
> +) {
> + return false;
> +}
> +
> +}
> diff --git a/lib/J3/ClassLib/GNUClasspath/JavaUpcalls.cpp
> b/lib/J3/ClassLib/GNUClasspath/JavaUpcalls.cpp
> index bc797d1..57197c4 100644
> --- a/lib/J3/ClassLib/GNUClasspath/JavaUpcalls.cpp
> +++ b/lib/J3/ClassLib/GNUClasspath/JavaUpcalls.cpp
> @@ -1071,8 +1071,8 @@ void Classpath::InitializeSystem(Jnjvm * jvm) {
>
> }
>
> -#include "ClasspathConstructor.inc"
> #include "Classpath.inc"
> +#include "ClasspathConstructor.inc"
> #include "ClasspathField.inc"
> #include "ClasspathMethod.inc"
> #include "ClasspathVMClass.inc"
> @@ -1084,3 +1084,4 @@ void Classpath::InitializeSystem(Jnjvm * jvm) {
> #include "ClasspathVMSystemProperties.inc"
> #include "ClasspathVMThread.inc"
> #include "ClasspathVMThrowable.inc"
> +#include "Unsafe.inc"
> diff --git a/lib/J3/ClassLib/GNUClasspath/Makefile
> b/lib/J3/ClassLib/GNUClasspath/Makefile
> index be80b9e..f5939c9 100644
> --- a/lib/J3/ClassLib/GNUClasspath/Makefile
> +++ b/lib/J3/ClassLib/GNUClasspath/Makefile
> @@ -9,9 +9,11 @@
> LEVEL = ../../../..
>
>
> -EXTRA_DIST = ClasspathVMClass.inc ClasspathVMClassLoader.inc
> ClasspathVMObject.inc \
> - ClasspathVMRuntime.inc ClasspathVMStackWalker.inc
> ClasspathVMSystem.inc \
> - ClasspathVMSystemProperties.inc ClasspathVMThread.inc
> ClasspathVMThrowable.inc
> +EXTRA_DIST = Classpath.inc ClasspathVMClass.inc
> ClasspathVMClassLoader.inc \
> + ClasspathVMObject.inc ClasspathVMRuntime.inc \
> + ClasspathVMStackWalker.inc ClasspathVMSystem.inc \
> + ClasspathVMSystemProperties.inc ClasspathVMThread.inc \
> + ClasspathVMThrowable.inc
>
> include $(LEVEL)/Makefile.config
>
> diff --git a/lib/J3/ClassLib/Makefile b/lib/J3/ClassLib/Makefile
> index 8252b92..8fd7e2a 100644
> --- a/lib/J3/ClassLib/Makefile
> +++ b/lib/J3/ClassLib/Makefile
> @@ -12,9 +12,9 @@ EXTRA_DIST = ArrayCopy.inc \
> ClassContext.inc \
> ClasspathConstructor.inc \
> ClasspathField.inc \
> - Classpath.inc \
> ClasspathMethod.inc \
> - SetProperties.inc
> + SetProperties.inc \
> + Unsafe.inc
>
> include $(LEVEL)/Makefile.config
>
> diff --git a/lib/J3/ClassLib/OpenJDK/JavaUpcalls.cpp
> b/lib/J3/ClassLib/OpenJDK/JavaUpcalls.cpp
> index 22db276..3fa6390 100644
> --- a/lib/J3/ClassLib/OpenJDK/JavaUpcalls.cpp
> +++ b/lib/J3/ClassLib/OpenJDK/JavaUpcalls.cpp
> @@ -897,7 +897,7 @@ void Classpath::InitializeSystem(Jnjvm * jvm) {
>
>
> #include "ClasspathConstructor.inc"
> -#include "Classpath.inc"
> #include "ClasspathField.inc"
> #include "ClasspathMethod.inc"
> #include "OpenJDK.inc"
> +#include "Unsafe.inc"
> diff --git a/lib/J3/ClassLib/Unsafe.inc b/lib/J3/ClassLib/Unsafe.inc
> new file mode 100644
> index 0000000..44ffe73
> --- /dev/null
> +++ b/lib/J3/ClassLib/Unsafe.inc
> @@ -0,0 +1,565 @@
> +//===-------- Unsafe.inc - sun.misc.Unsafe implementation
> -----------------===//
> +//
> +// The VMKit project
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "VMStaticInstance.h"
> +#include <stdlib.h>
> +
> +/// fieldPtr - Compute the address of the field specified by the given
> +/// base/offset pair. Non-trivial due to our handling of static
> instances,
> +/// and this also handles null-checking as required.
> +///
> +static inline uint8 *fieldPtr(JavaObject *base, long long offset,
> + bool throwOnNull = true) {
> +
> + // For most uses, a 'null' base should throw an exception.
> + if (throwOnNull) verifyNull(base);
> +
> + if (base && VMStaticInstance::isVMStaticInstance(base))
> + return (uint8*)((VMStaticInstance*)base)->getStaticInstance() +
> offset;
> + else
> + return (uint8*)base + offset;
> +}
> +
> +extern "C" {
> +
> +//===--- Base/Offset methods
> ----------------------------------------------===//
> +
> +/// staticFieldOffset - Return the offset of a particular static field
> +/// Only valid to be used with the corresponding staticFieldBase
> +///
> +JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_staticFieldOffset(
> +JavaObject* unsafe, JavaObjectField* _field) {
> + llvm_gcroot(unsafe, 0);
> + llvm_gcroot(_field, 0);
> +
> + jlong res = 0;
> + BEGIN_NATIVE_EXCEPTION(0)
> +
> + JavaField * field = JavaObjectField::getInternalField(_field);
> + assert(field);
> +
> + res = field->ptrOffset;
> +
> + END_NATIVE_EXCEPTION;
> +
> + return res;
> +}
> +
> +/// staticFieldBase - Return a JavaObject* representing the static
> instance.
> +/// Note that our static instances aren't actually java objects, so we use
> +/// a placeholder object "VMStaticInstance" that also ensures that
> +/// the corresponding class doesn't get GC'd underneath it.
> +///
> +JNIEXPORT JavaObject* JNICALL Java_sun_misc_Unsafe_staticFieldBase(
> +JavaObject* unsafe, JavaObjectField* _field) {
> + JavaObject* res = 0;
> + llvm_gcroot(unsafe, 0);
> + llvm_gcroot(_field, 0);
> + llvm_gcroot(res, 0);
> + BEGIN_NATIVE_EXCEPTION(0)
> +
> + JavaField * field = JavaObjectField::getInternalField(_field);
> + assert(field);
> + field->classDef->initialiseClass(JavaThread::get()->getJVM());
> +
> + res = VMStaticInstance::allocate(field->classDef);
> +
> + END_NATIVE_EXCEPTION;
> +
> + return res;
> +}
> +
> +/// arrayBaseOffset - Offset from the array object where the actual
> +/// element data begins.
> +///
> +JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_arrayBaseOffset(
> +JavaObject* unsafe, JavaObject* clazz) {
> + // Array starts at beginning of object
> + return 0;
> +}
> +
> +/// arrayIndexScale - Indexing scale for the element type in
> +/// the specified array. For use with arrayBaseOffset,
> +/// NthElementPtr = ArrayObject + BaseOffset + N*IndexScale
> +/// Return '0' if our JVM stores the elements in a way that
> +/// makes this type of access impossible or unsupported.
> +///
> +JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_arrayIndexScale(
> +#ifdef NATIVE_JNI
> +JNIEnv *env,
> +#endif
> +JavaObject* unsafe, JavaObject* clazz) {
> + // For now, just return '0', indicating we don't support this indexing.
> + // TODO: Implement this for the array types we /do/ support this way.
> + return 0;
> +}
> +
> +
> +
> +/// objectFieldOffset - Pointer offset of the specified field
> +///
> +JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_objectFieldOffset(
> +#ifdef NATIVE_JNI
> +JNIEnv *env,
> +#endif
> +JavaObject* Unsafe, JavaObjectField* Field) {
> +
> + llvm_gcroot(Field, 0);
> + llvm_gcroot(Unsafe, 0);
> +
> + JavaField* field = JavaObjectField::getInternalField(Field);
> + return (jlong)field->ptrOffset;
> +}
> +
> +//===--- Double-register addressing field accessors
> -----------------------===//
> +// See objectFieldOffset, staticFieldOffset, staticFieldBase
> +// Can also be an array, if/when we support
> arrayIndexScale/arrayBaseOffset
> +#define GET_PUT_OFFSET(Type,jtype,shorttype) \
> +JNIEXPORT jtype JNICALL Java_sun_misc_Unsafe_get ## Type ##
> __Ljava_lang_Object_2J( \
> +JavaObject* unsafe, JavaObject* base, jlong offset) { \
> + jtype res = 0; \
> + BEGIN_NATIVE_EXCEPTION(0) \
> + jtype* ptr = (jtype*)fieldPtr(base,offset); \
> + res = *ptr; \
> + END_NATIVE_EXCEPTION \
> + return res; \
> +} \
> + \
> +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_put ## Type ##
> __Ljava_lang_Object_2J ## shorttype( \
> +JavaObject* unsafe, JavaObject* base, jlong offset, jtype val) { \
> + BEGIN_NATIVE_EXCEPTION(0) \
> + jtype* ptr = (jtype*)fieldPtr(base, offset); \
> + *ptr = val; \
> + END_NATIVE_EXCEPTION \
> +}
> +
> +//===--- Direct address read/write acccessors
> -----------------------------===//
> +#define GET_PUT_DIRECT(Type,jtype,shorttype) \
> +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_put ## Type ## __J ##
> shorttype( \
> +JavaObject* unsafe, jlong ptr, jtype val) { \
> + BEGIN_NATIVE_EXCEPTION(0) \
> + *(jtype*)ptr = val; \
> + END_NATIVE_EXCEPTION \
> +} \
> + \
> +JNIEXPORT jtype JNICALL Java_sun_misc_Unsafe_get ## Type ## __J( \
> +JavaObject* unsafe, jlong ptr) { \
> + jtype res = 0; \
> + BEGIN_NATIVE_EXCEPTION(0) \
> + res = *(jtype*)ptr; \
> + END_NATIVE_EXCEPTION \
> + return res; \
> +}
> +
> +//===--- Volatile variant of field accessors
> ------------------------------===//
> +// Memory barriers after writes to ensure new value is seen elsewhere
> +#define GET_PUT_OFFSET_VOLATILE(Type,jtype,shorttype) \
> +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_put ## Type ##
> Volatile__J ## shorttype( \
> +JavaObject* unsafe, jlong ptr, jtype val) { \
> + BEGIN_NATIVE_EXCEPTION(0) \
> + *(volatile jtype*)ptr = val; \
> + __sync_synchronize(); \
> + END_NATIVE_EXCEPTION \
> +} \
> + \
> +JNIEXPORT jtype JNICALL Java_sun_misc_Unsafe_get ## Type ## Volatile__J( \
> +JavaObject* unsafe, jlong ptr) { \
> + jtype res = 0; \
> + BEGIN_NATIVE_EXCEPTION(0) \
> + res = *(volatile jtype*)ptr; \
> + END_NATIVE_EXCEPTION \
> + return res; \
> +}
> +
> +//===--- Volatile variant of direct address accessors
> ---------------------===//
> +#define GET_PUT_DIRECT_VOLATILE(Type,jtype,shorttype) \
> +JNIEXPORT jtype JNICALL Java_sun_misc_Unsafe_get ## Type ##
> Volatile__Ljava_lang_Object_2J( \
> +JavaObject* unsafe, JavaObject* base, jlong offset) { \
> + jtype res = 0; \
> + BEGIN_NATIVE_EXCEPTION(0) \
> + volatile jtype* ptr = (volatile jtype*)fieldPtr(base,offset); \
> + res = *ptr; \
> + END_NATIVE_EXCEPTION \
> + \
> + return res; \
> +} \
> + \
> +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_put ## Type ##
> Volatile__Ljava_lang_Object_2J ## shorttype( \
> +JavaObject* unsafe, JavaObject* base, jlong offset, jtype val) { \
> + BEGIN_NATIVE_EXCEPTION(0) \
> + volatile jtype* ptr = (volatile jtype*)fieldPtr(base,offset); \
> + *ptr = val; \
> + __sync_synchronize(); \
> + END_NATIVE_EXCEPTION \
> +}
> +
> +//===--- Ordered variant of field accessors
> -------------------------------===//
> +#define GET_PUT_FIELD_ORDERED(Type,jtype,shorttype) \
> +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrdered ## Type( \
> +JavaObject* unsafe, JavaObject* base, jlong offset, jtype val) { \
> + BEGIN_NATIVE_EXCEPTION(0) \
> + volatile jtype* ptr = (volatile jtype*)fieldPtr(base,offset); \
> + *ptr = val; \
> + /* No memory barrier */ \
> + END_NATIVE_EXCEPTION \
> +}
> +
> +#define GET_PUT_ALL(Type,jtype,shorttype) \
> + GET_PUT_OFFSET(Type,jtype,shorttype) \
> + GET_PUT_DIRECT(Type,jtype,shorttype) \
> + GET_PUT_OFFSET_VOLATILE(Type,jtype,shorttype) \
> + GET_PUT_DIRECT_VOLATILE(Type,jtype,shorttype)
> +
> +GET_PUT_ALL(Boolean,jboolean,Z)
> +GET_PUT_ALL(Byte,jbyte,B)
> +GET_PUT_ALL(Char,jchar,C)
> +GET_PUT_ALL(Short,jshort,S)
> +GET_PUT_ALL(Int,jint,I)
> +GET_PUT_ALL(Long,jlong,J) // TODO: Long needs special handling!
> +GET_PUT_ALL(Float,jfloat,F)
> +GET_PUT_ALL(Double,jdouble,D)
> +
> +// Ordered:
> +GET_PUT_FIELD_ORDERED(Int,jint,I)
> +GET_PUT_FIELD_ORDERED(Long,jlong,J)
> +
> +//===--- Get/Put of Objects, due to GC needs special handling
> -------------===//
> +// JavaObject field accessors:
> +JNIEXPORT void JNICALL
> Java_sun_misc_Unsafe_putObject__Ljava_lang_Object_2JLjava_lang_Object_2(
> +#ifdef NATIVE_JNI
> +JNIEnv *env,
> +#endif
> +JavaObject* unsafe, JavaObject* base, jlong offset, JavaObject* value) {
> + llvm_gcroot(unsafe, 0);
> + llvm_gcroot(base, 0);
> + llvm_gcroot(value, 0);
> +
> + JavaObject** ptr = (JavaObject**)fieldPtr(base, offset);
> + mvm::Collector::objectReferenceWriteBarrier((gc*)base, (gc**)ptr,
> (gc*)value);
> +}
> +
> +
> +JNIEXPORT JavaObject* JNICALL
> Java_sun_misc_Unsafe_getObject__Ljava_lang_Object_2J(
> +JavaObject* unsafe, JavaObject* base, jlong offset) {
> + JavaObject * res = 0;
> + llvm_gcroot(unsafe, 0);
> + llvm_gcroot(base, 0);
> + llvm_gcroot(res, 0);
> +
> + BEGIN_NATIVE_EXCEPTION(0)
> + JavaObject** ptr = (JavaObject**)fieldPtr(base, offset);
> + res = *ptr;
> + END_NATIVE_EXCEPTION;
> +
> + return res;
> +}
> +
> +// Volatile JavaObject field accessors:
> +// Never throws.
> +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObjectVolatile(
> +#ifdef NATIVE_JNI
> +JNIEnv *env,
> +#endif
> +JavaObject* unsafe, JavaObject* base, jlong offset, JavaObject* value) {
> + llvm_gcroot(unsafe, 0);
> + llvm_gcroot(base, 0);
> + llvm_gcroot(value, 0);
> +
> + JavaObject** ptr = (JavaObject**)fieldPtr(base, offset);
> + mvm::Collector::objectReferenceWriteBarrier((gc*)base, (gc**)ptr,
> (gc*)value);
> + // Ensure this value is seen.
> + __sync_synchronize();
> +}
> +
> +JNIEXPORT JavaObject* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(
> +JavaObject* unsafe, JavaObject* base, jlong offset) {
> + JavaObject * res = 0;
> + llvm_gcroot(unsafe, 0);
> + llvm_gcroot(base, 0);
> + llvm_gcroot(res, 0);
> +
> + BEGIN_NATIVE_EXCEPTION(0)
> + JavaObject* volatile* ptr = (JavaObject* volatile*)fieldPtr(base,
> offset);
> + res = *ptr;
> + END_NATIVE_EXCEPTION;
> +
> + return res;
> +}
> +
> +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrderedObject(
> +JavaObject* unsafe, JavaObject* base, jlong offset, JavaObject* value) {
> + llvm_gcroot(unsafe, 0);
> + llvm_gcroot(base, 0);
> + llvm_gcroot(value, 0);
> +
> + JavaObject** ptr = (JavaObject**)fieldPtr(base, offset);
> + mvm::Collector::objectReferenceWriteBarrier((gc*)base, (gc**)ptr,
> (gc*)value);
> + // No barrier (difference between volatile and ordered)
> +}
> +
> +
> +//===--- CompareAndSwap field accessors
> -----------------------------------===//
> +// Never throws.
> +JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapLong(
> +#ifdef NATIVE_JNI
> +JNIEnv *env,
> +#endif
> +JavaObject* unsafe, JavaObject* base, jlong offset, jlong expect,
> jlong update) {
> +
> + llvm_gcroot(unsafe, 0);
> + llvm_gcroot(base, 0);
> + jlong *ptr;
> + jlong value;
> +
> + // TODO: Why isn't this atomic?
> + ptr = (jlong*)fieldPtr(base, offset);
> +
> + value = *ptr;
> +
> + if (value == expect) {
> + *ptr = update;
> + return true;
> + } else {
> + return false;
> + }
> +
> +}
> +
> +// Never throws.
> +JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapInt(
> +#ifdef NATIVE_JNI
> +JNIEnv *env,
> +#endif
> +JavaObject* unsafe, JavaObject* base, jlong offset, jint expect, jint
> update) {
> +
> + llvm_gcroot(unsafe, 0);
> + llvm_gcroot(base, 0);
> + jint *ptr;
> +
> + ptr = (jint *)fieldPtr(base, offset);
> +
> + return __sync_bool_compare_and_swap(ptr, expect, update);
> +}
> +
> +// Never throws.
> +JNIEXPORT bool JNICALL Java_sun_misc_Unsafe_compareAndSwapObject(
> +#ifdef NATIVE_JNI
> +JNIEnv *env,
> +#endif
> +JavaObject* unsafe, JavaObject* base, jlong offset, JavaObject* expect,
> +JavaObject* update) {
> + llvm_gcroot(unsafe, 0);
> + llvm_gcroot(base, 0);
> + llvm_gcroot(expect, 0);
> + llvm_gcroot(update, 0);
> +
> + JavaObject** ptr = (JavaObject**)fieldPtr(base, offset);
> + return mvm::Collector::objectReferenceTryCASBarrier((gc*)base,
> (gc**)ptr, (gc*)expect, (gc*)update);
> +}
> +
> +
> +//===--- Class-related functions
> ------------------------------------------===//
> +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_ensureClassInitialized(
> +JavaObject* unsafe, JavaObject* clazz) {
> + llvm_gcroot(unsafe, 0);
> + llvm_gcroot(clazz, 0);
> + BEGIN_NATIVE_EXCEPTION(0)
> +
> + Jnjvm* vm = JavaThread::get()->getJVM();
> +
> + CommonClass * cl = JavaObject::getClass(clazz);
> + assert(cl && cl->isClass());
> + cl->asClass()->resolveClass();
> + cl->asClass()->initialiseClass(vm);
> +
> + END_NATIVE_EXCEPTION;
> +}
> +
> +JNIEXPORT JavaObject* JNICALL
> Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BII(
> +JavaObject* unsafe, JavaString *name, ArrayObject * bytesArr, jint
> off, jint len) {
> + UNIMPLEMENTED();
> +}
> +
> +JNIEXPORT JavaObject* JNICALL
>
> Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2(
> +JavaObject* unsafe, JavaString *name, ArrayObject * bytesArr, jint
> off, jint len, JavaObject * loader, JavaObject * pd) {
> + JavaObject* res = 0;
> + llvm_gcroot(res, 0);
> + llvm_gcroot(unsafe, 0);
> + llvm_gcroot(name, 0);
> + llvm_gcroot(bytesArr, 0);
> + llvm_gcroot(loader, 0);
> + llvm_gcroot(pd, 0);
> + BEGIN_NATIVE_EXCEPTION(0)
> +
> + Jnjvm* vm = JavaThread::get()->getJVM();
> + JnjvmClassLoader* JCL = NULL;
> + JCL = JnjvmClassLoader::getJnjvmLoaderFromJavaObject(loader, vm);
> +
> + jint last = off + len;
> + if (last < bytesArr->size) {
> + assert(0 && "What exception to throw here?");
> + }
> + ClassBytes * bytes = new (JCL->allocator, len) ClassBytes(len);
> + memcpy(bytes->elements, JavaArray::getElements(bytesArr)+off, len);
> + const UTF8* utfName = JavaString::javaToInternal(name, JCL->hashUTF8);
> + UserClass *cl = JCL->constructClass(utfName, bytes);
> +
> + if (cl) res = (JavaObject*)cl->getClassDelegatee(vm);
> +
> + END_NATIVE_EXCEPTION;
> +
> + return res;
> +}
> +
> +JNIEXPORT JavaObject* JNICALL
> Java_sun_misc_Unsafe_allocateInstance__Ljava_lang_Class_2(
> +JavaObject* unsafe, JavaObjectClass * clazz) {
> + JavaObject* res = 0;
> + llvm_gcroot(unsafe, 0);
> + llvm_gcroot(clazz, 0);
> + llvm_gcroot(res, 0);
> +
> + BEGIN_NATIVE_EXCEPTION(0)
> +
> + JavaThread* th = JavaThread::get();
> + Jnjvm* vm = th->getJVM();
> +
> + UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz,
> true);
> + if (cl->isClass())
> + res = cl->asClass()->doNew(vm);
> +
> + END_NATIVE_EXCEPTION;
> +
> + return res;
> +}
> +
> +JNIEXPORT JavaObject* JNICALL Java_sun_Unsafe_defineAnonymousClass(
> +JavaObject* unsafe, ...) {
> + UNIMPLEMENTED();
> +}
> +
> +//===--- Memory functions
> -------------------------------------------------===//
> +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_setMemory__JJB(
> +JavaObject* unsafe, long address, long bytes, jbyte value) {
> + memset((void*)address, value, bytes);
> +}
> +
> +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_copyMemory__JJJ(
> +JavaObject* unsafe, jlong src, jlong dst, jlong size) {
> + memcpy((void*)dst, (void*)src, size);
> +}
> +
> +JNIEXPORT void JNICALL
> Java_sun_misc_Unsafe_copyMemory__Ljava_lang_Object_2JLjava_lang_Object_2JJ(
> +JavaObject* unsafe,
> +JavaObject* srcBase, jlong srcOffset,
> +JavaObject* dstBase, jlong dstOffset,
> +jlong size) {
> + BEGIN_NATIVE_EXCEPTION(0)
> + uint8_t* src = fieldPtr(srcBase, srcOffset, false /* Don't throw on
> null base*/ );
> + uint8_t* dst = fieldPtr(dstBase, dstOffset, false /* Don't throw on
> null base*/ );
> + memcpy(dst, src, size);
> + END_NATIVE_EXCEPTION
> +}
> +
> +JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_allocateMemory(
> +JavaObject* unsafe, jlong size) {
> + // TODO: Invalid size/OOM/etc handling!
> + jlong res = 0;
> + BEGIN_NATIVE_EXCEPTION(0)
> + res = (jlong)malloc(size);
> + END_NATIVE_EXCEPTION
> + return res;
> +}
> +
> +JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_reallocateMemory(
> +JavaObject* unsafe, jlong ptr, jlong newsize) {
> + // TODO: Invalid size/OOM/etc handling!
> + jlong res = 0;
> + BEGIN_NATIVE_EXCEPTION(0)
> + res = (jlong)realloc((void*)ptr, newsize);
> + END_NATIVE_EXCEPTION
> + return res;
> +}
> +
> +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_freeMemory(
> +JavaObject* unsafe, jlong ptr) {
> + // TODO: Exception handling...
> + BEGIN_NATIVE_EXCEPTION(0)
> + free((void*)ptr);
> + END_NATIVE_EXCEPTION
> +}
> +
> +JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_getAddress(
> +JavaObject* unsafe, jlong ptr) {
> + return (jlong)*(void**)ptr;
> +}
> +
> +JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_putAddress(
> +JavaObject* unsafe, jlong ptr, jlong val) {
> + *(void**)ptr = (void*)val;
> +}
> +
> +//===--- Park/Unpark thread support
> ---------------------------------------===//
> +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_park(
> +JavaObject* unsafe, jboolean isAbsolute, jlong time) {
> + // Nothing, for now.
> +}
> +
> +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_unpark(
> +JavaObject* unsafe, JavaObject* thread) {
> + // Nothing, for now.
> +}
> +
> +//===--- Monitor support
> --------------------------------------------------===//
> +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_tryMonitorEnter(
> +JavaObject* unsafe, JavaObject * obj) {
> + //TODO: Implement me!
> + UNIMPLEMENTED();
> +}
> +
> +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_monitorEnter(
> +JavaObject* unsafe, JavaObject * obj) {
> + //TODO: Implement me!
> + UNIMPLEMENTED();
> +}
> +
> +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_monitorExit(
> +JavaObject* unsafe, JavaObject * obj) {
> + //TODO: Implement me!
> + UNIMPLEMENTED();
> +}
> +
> +//===--- Misc support functions
> -------------------------------------------===//
> +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_registerNatives(JavaObject*) {
> + // Nothing, we define the Unsafe methods with the expected signatures.
> +}
> +
> +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_throwException(
> +JavaObject* unsafe, JavaObject * obj) {
> + llvm_gcroot(unsafe, 0);
> + llvm_gcroot(obj, 0);
> +
> + JavaThread::get()->throwException(obj);
> +}
> +
> +JNIEXPORT jint JNICALL Java_sun_misc_Unsafe_pageSize(
> +JavaObject* unsafe) {
> + return mvm::System::GetPageSize();
> +}
> +
> +JNIEXPORT jint JNICALL Java_sun_misc_Unsafe_addressSize(
> +JavaObject* unsafe) {
> + return mvm::kWordSize;
> +}
> +
> +JNIEXPORT jint JNICALL Java_sun_misc_Unsafe_getLoadAverage(
> +JavaObject* unsafe, ...) {
> + UNIMPLEMENTED();
> +}
> +
> +}
> --
> 1.7.5.1
>
> _______________________________________________
> vmkit-commits mailing list
> vmkit-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/vmkit-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/vmkit-commits/attachments/20111115/9f1e4872/attachment.html>
More information about the vmkit-commits
mailing list