[vmkit-commits] [PATCH 3/3] Define all methods in sun.misc.Unsafe, fixes to existing.
Nicolas Geoffray
nicolas.geoffray at gmail.com
Wed Nov 16 12:24:38 PST 2011
Looks good with a few comments.
On Wed, Nov 16, 2011 at 12:17 AM, Will Dietz <wdietz2 at illinois.edu> wrote:
> Inlined below.
>
> Thanks! :)
>
> ~Will
>
> >From 3ace0392fcfffe9398c876e5921e79b9f349c53a Mon Sep 17 00:00:00 2001
> From: Will Dietz <w at wdtz.org>
> Date: Tue, 15 Nov 2011 17:01:39 -0600
> Subject: [PATCH 3/3] Define all methods in sun.misc.Unsafe, fixes to
> existing.
>
> * Add full set of get/put, including volatile and ordered. Update existing
> volatile to use memory barrier on writes.
> * Fix all get/put to make use of fieldPtr, thereby correctly handling both
> staticInstances as well as throwing null pointer exceptions.
> * Add memory methods: memcpy, memset, realloc
> * Add empty park/unpark methods. (Very) inefficient, but these methods are
> allowed to return arbitrarily, so this is allowed and gets code going.
> * Add misc query functions (pageSize/addressSize/etc)
> * Drop NATIVE_JNI in this file, while we're at it.
>
> The functions that I've never seen called still have UNIMPLEMENTED,
> the rest have been used in 'real' code and seem to work fine.
> Only exception to this is the putOrdered variants.
> ---
> lib/J3/ClassLib/Unsafe.inc | 273
> ++++++++++++++++++++++++++++++++++++-------
> 1 files changed, 228 insertions(+), 45 deletions(-)
>
> diff --git a/lib/J3/ClassLib/Unsafe.inc b/lib/J3/ClassLib/Unsafe.inc
> index 5fe64db..240d0ec 100644
> --- a/lib/J3/ClassLib/Unsafe.inc
> +++ b/lib/J3/ClassLib/Unsafe.inc
> @@ -102,9 +102,6 @@ JavaObject* unsafe, JavaObject* clazz) {
> /// 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);
> @@ -136,19 +133,110 @@ JavaObject* unsafe, JavaObject* base, jlong
> offset, jtype 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)
> +//===--- 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:
> -// Never throws.
> -JNIEXPORT JavaObject* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(
> +JNIEXPORT void JNICALL
> Java_sun_misc_Unsafe_putObject__Ljava_lang_Object_2JLjava_lang_Object_2(
> +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);
> @@ -166,9 +254,6 @@ JavaObject* unsafe, JavaObject* base, jlong offset) {
> // 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);
> @@ -176,38 +261,49 @@ JavaObject* unsafe, JavaObject* base, jlong
> offset, JavaObject* value) {
>
> JavaObject** ptr = (JavaObject**)fieldPtr(base, offset);
> mvm::Collector::objectReferenceWriteBarrier((gc*)base, (gc**)ptr,
> (gc*)value);
> + // Ensure this value is seen.
> + __sync_synchronize();
> }
>
> -//===--- Misc get/put defined, TODO: generalize!
> --------------------------===//
> -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 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);
>
> -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
> + 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(
> -JavaObject* unsafe, JavaObject* obj, jlong offset, jlong expect,
> jlong update) {
> +JavaObject* unsafe, JavaObject* base, jlong offset, jlong expect,
> jlong update) {
>
> llvm_gcroot(unsafe, 0);
> - llvm_gcroot(obj, 0);
> + llvm_gcroot(base, 0);
> jlong *ptr;
> jlong value;
>
> - ptr = (jlong *) (((uint8 *) obj) + offset);
> + // TODO: Why isn't this atomic?
>
Why would it be on a 32 bit system?
> + ptr = (jlong*)fieldPtr(base, offset);
>
> value = *ptr;
>
> @@ -222,37 +318,31 @@ JavaObject* unsafe, JavaObject* obj, jlong
> offset, jlong expect, jlong update) {
>
> // 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) {
> +JavaObject* unsafe, JavaObject* base, jlong offset, jint expect, jint
> update) {
>
> llvm_gcroot(unsafe, 0);
> - llvm_gcroot(obj, 0);
> + llvm_gcroot(base, 0);
> jint *ptr;
>
> - ptr = (jint *) (((uint8 *) obj) + offset);
> + 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* obj, jlong offset, JavaObject* expect,
> +JavaObject* unsafe, JavaObject* base, jlong offset, JavaObject* expect,
> JavaObject* update) {
> llvm_gcroot(unsafe, 0);
> - llvm_gcroot(obj, 0);
> + llvm_gcroot(base, 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);
> + 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) {
> @@ -270,6 +360,11 @@ JavaObject* unsafe, JavaObject* clazz) {
> 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;
> @@ -322,8 +417,34 @@ JavaObject* unsafe, JavaObjectClass * clazz) {
> 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);
>
How does that deal with GC barriers?
> + END_NATIVE_EXCEPTION
> +}
> +
> JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_allocateMemory(
> JavaObject* unsafe, jlong size) {
> // TODO: Invalid size/OOM/etc handling!
> @@ -334,6 +455,16 @@ JavaObject* unsafe, jlong size) {
> 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...
> @@ -342,6 +473,45 @@ JavaObject* unsafe, jlong 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*) {
> @@ -356,6 +526,19 @@ JavaObject* unsafe, JavaObject * obj) {
> 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/20111116/34d0c6a8/attachment.html>
More information about the vmkit-commits
mailing list