diff --git a/classpath/sun/misc/Unsafe.java b/classpath/sun/misc/Unsafe.java index 5cb571ee9c..a03bf3db71 100644 --- a/classpath/sun/misc/Unsafe.java +++ b/classpath/sun/misc/Unsafe.java @@ -50,6 +50,10 @@ public final class Unsafe { public native long getLongVolatile(Object o, long offset); + public native long putLongVolatile(Object o, long offset, long x); + + public native long putOrderedLong(Object o, long offset, long x); + public native void putOrderedInt(Object o, long offset, int x); public native Object getObject(Object o, long offset); diff --git a/src/builtin.cpp b/src/builtin.cpp index 6c069746d2..9940b53c7b 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -784,6 +784,42 @@ Avian_sun_misc_Unsafe_getLongVolatile return result; } +extern "C" AVIAN_EXPORT void JNICALL +Avian_sun_misc_Unsafe_putLongVolatile +(Thread* t, object, uintptr_t* arguments) +{ + object o = reinterpret_cast(arguments[1]); + int64_t offset; memcpy(&offset, arguments + 2, 8); + int64_t value; memcpy(&value, arguments + 4, 8); + + object field; + if (BytesPerWord < 8) { + field = fieldForOffset(t, o, offset); + + PROTECT(t, field); + acquire(t, field); + } else { + storeStoreMemoryBarrier(); + } + + fieldAtOffset(o, offset) = value; + + if (BytesPerWord < 8) { + release(t, field); + } else { + storeLoadMemoryBarrier(); + } +} + +extern "C" AVIAN_EXPORT void JNICALL +Avian_sun_misc_Unsafe_putOrderedLong +(Thread* t, object method, uintptr_t* arguments) +{ + // todo: we might be able to use weaker barriers here than + // putLongVolatile does + Avian_sun_misc_Unsafe_putLongVolatile(t, method, arguments); +} + extern "C" AVIAN_EXPORT void JNICALL Avian_sun_misc_Unsafe_unpark (Thread* t, object, uintptr_t* arguments)