From cc5b58725a273c4cd208d92dbde94fd5818b9df0 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 2 Jan 2014 17:49:56 -0700 Subject: [PATCH] implement Unsafe.putOrderedLong and putVolatileLong The former just defers to the latter for now, since it provides strictly weaker guarantees. Thus it's correct to use full volatile-style barriers, though not as efficient as it could be on some architectures. --- classpath/sun/misc/Unsafe.java | 4 ++++ src/builtin.cpp | 36 ++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) 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)