Merge pull request #213 from dicej/unsafe

implement Unsafe.{get|put}*Volatile
This commit is contained in:
Mike Jensen 2014-04-01 07:37:59 -06:00
commit f10aa1c5a9
3 changed files with 191 additions and 2 deletions

View File

@ -46,15 +46,39 @@ public final class Unsafe {
public native void putDouble(long address, double x);
public native boolean getBooleanVolatile(Object o, long offset);
public native void putBooleanVolatile(Object o, long offset, boolean x);
public native byte getByteVolatile(Object o, long offset);
public native void putByteVolatile(Object o, long offset, byte x);
public native short getShortVolatile(Object o, long offset);
public native void putShortVolatile(Object o, long offset, short x);
public native char getCharVolatile(Object o, long offset);
public native void putCharVolatile(Object o, long offset, char x);
public native int getIntVolatile(Object o, long offset);
public native void putIntVolatile(Object o, long offset, int x);
public native float getFloatVolatile(Object o, long offset);
public native void putFloatVolatile(Object o, long offset, float x);
public native double getDoubleVolatile(Object o, long offset);
public native void putDoubleVolatile(Object o, long offset, double x);
public native long getLongVolatile(Object o, long offset);
public native long putLongVolatile(Object o, long offset, long x);
public native void putLongVolatile(Object o, long offset, long x);
public native long putOrderedLong(Object o, long offset, long x);
public native void putOrderedLong(Object o, long offset, long x);
public native void putOrderedInt(Object o, long offset, int x);

View File

@ -992,6 +992,112 @@ Avian_sun_misc_Unsafe_getIntVolatile
return result;
}
extern "C" AVIAN_EXPORT void JNICALL
Avian_sun_misc_Unsafe_putByteVolatile
(Thread*, object, uintptr_t* arguments)
{
object o = reinterpret_cast<object>(arguments[1]);
int64_t offset; memcpy(&offset, arguments + 2, 8);
int8_t value = arguments[4];
storeStoreMemoryBarrier();
fieldAtOffset<int8_t>(o, offset) = value;
storeLoadMemoryBarrier();
}
extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_sun_misc_Unsafe_getByteVolatile
(Thread*, object, uintptr_t* arguments)
{
object o = reinterpret_cast<object>(arguments[1]);
int64_t offset; memcpy(&offset, arguments + 2, 8);
int8_t result = fieldAtOffset<int8_t>(o, offset);
loadMemoryBarrier();
return result;
}
extern "C" AVIAN_EXPORT void JNICALL
Avian_sun_misc_Unsafe_putBooleanVolatile
(Thread* t, object method, uintptr_t* arguments)
{
Avian_sun_misc_Unsafe_putByteVolatile(t, method, arguments);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_sun_misc_Unsafe_getBooleanVolatile
(Thread* t, object method, uintptr_t* arguments)
{
return Avian_sun_misc_Unsafe_getByteVolatile(t, method, arguments);
}
extern "C" AVIAN_EXPORT void JNICALL
Avian_sun_misc_Unsafe_putShortVolatile
(Thread*, object, uintptr_t* arguments)
{
object o = reinterpret_cast<object>(arguments[1]);
int64_t offset; memcpy(&offset, arguments + 2, 8);
int16_t value = arguments[4];
storeStoreMemoryBarrier();
fieldAtOffset<int16_t>(o, offset) = value;
storeLoadMemoryBarrier();
}
extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_sun_misc_Unsafe_getShortVolatile
(Thread*, object, uintptr_t* arguments)
{
object o = reinterpret_cast<object>(arguments[1]);
int64_t offset; memcpy(&offset, arguments + 2, 8);
int16_t result = fieldAtOffset<int16_t>(o, offset);
loadMemoryBarrier();
return result;
}
extern "C" AVIAN_EXPORT void JNICALL
Avian_sun_misc_Unsafe_putCharVolatile
(Thread* t, object method, uintptr_t* arguments)
{
Avian_sun_misc_Unsafe_putShortVolatile(t, method, arguments);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_sun_misc_Unsafe_getCharVolatile
(Thread* t, object method, uintptr_t* arguments)
{
return Avian_sun_misc_Unsafe_getShortVolatile(t, method, arguments);
}
extern "C" AVIAN_EXPORT void JNICALL
Avian_sun_misc_Unsafe_putFloatVolatile
(Thread* t, object method, uintptr_t* arguments)
{
Avian_sun_misc_Unsafe_putIntVolatile(t, method, arguments);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_sun_misc_Unsafe_getFloatVolatile
(Thread* t, object method, uintptr_t* arguments)
{
return Avian_sun_misc_Unsafe_getIntVolatile(t, method, arguments);
}
extern "C" AVIAN_EXPORT void JNICALL
Avian_sun_misc_Unsafe_putDoubleVolatile
(Thread* t, object method, uintptr_t* arguments)
{
Avian_sun_misc_Unsafe_putLongVolatile(t, method, arguments);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_sun_misc_Unsafe_getDoubleVolatile
(Thread* t, object method, uintptr_t* arguments)
{
return Avian_sun_misc_Unsafe_getLongVolatile(t, method, arguments);
}
extern "C" AVIAN_EXPORT void JNICALL
Avian_sun_misc_Unsafe_throwException
(Thread* t, object, uintptr_t* arguments)

View File

@ -76,10 +76,69 @@ public class UnsafeTest {
}
}
private static void unsafeArray(Unsafe u) {
final int offset = u.arrayBaseOffset(long[].class);
final int scale = u.arrayIndexScale(long[].class);
final int size = 64;
final long[] array = new long[size];
for (int i = 0; i < size; ++i)
u.putBooleanVolatile(array, offset + (i * scale), i % 2 == 0);
for (int i = 0; i < size; ++i)
expect(u.getBooleanVolatile(array, offset + (i * scale))
== (i % 2 == 0));
for (int i = 0; i < size; ++i)
u.putByteVolatile(array, offset + (i * scale), (byte) 42);
for (int i = 0; i < size; ++i)
expect(u.getByteVolatile(array, offset + (i * scale)) == 42);
for (int i = 0; i < size; ++i)
u.putShortVolatile(array, offset + (i * scale), (short) -12345);
for (int i = 0; i < size; ++i)
expect(u.getShortVolatile(array, offset + (i * scale)) == -12345);
for (int i = 0; i < size; ++i)
u.putCharVolatile(array, offset + (i * scale), (char) 23456);
for (int i = 0; i < size; ++i)
expect(u.getCharVolatile(array, offset + (i * scale)) == 23456);
for (int i = 0; i < size; ++i)
u.putIntVolatile(array, offset + (i * scale), 0x12345678);
for (int i = 0; i < size; ++i)
expect(u.getIntVolatile(array, offset + (i * scale)) == 0x12345678);
for (int i = 0; i < size; ++i)
u.putFloatVolatile(array, offset + (i * scale), 1.2345678F);
for (int i = 0; i < size; ++i)
expect(u.getFloatVolatile(array, offset + (i * scale)) == 1.2345678F);
for (int i = 0; i < size; ++i)
u.putLongVolatile(array, offset + (i * scale), 0x1234567890ABCDEFL);
for (int i = 0; i < size; ++i)
expect(u.getLongVolatile(array, offset + (i * scale))
== 0x1234567890ABCDEFL);
for (int i = 0; i < size; ++i)
u.putDoubleVolatile(array, offset + (i * scale), 1.23456789012345D);
for (int i = 0; i < size; ++i)
expect(u.getDoubleVolatile(array, offset + (i * scale))
== 1.23456789012345D);
}
public static void main(String[] args) {
Unsafe u = avian.Machine.getUnsafe();
unsafeCatch(u);
unsafeMemory(u);
unsafeArray(u);
}
}