From e19bdda13e3e80df5fde6b381848187979580ca7 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 2 Jan 2014 17:44:33 -0700 Subject: [PATCH 1/4] fix uninitialized value warning in compile.cpp Clang was complaining that newIp might be used uninitialized at the bottom of our giant, unstructured compile loop, so I initialized it with a bogus value, which means it will at least fail consistently if Clang is right and there really is a path by which that code is reached without otherwise initializing newIp. --- src/compile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compile.cpp b/src/compile.cpp index cfa1aef6c4..7028f69cca 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -4007,7 +4007,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, unsigned stackSize = codeMaxStack(t, methodCode(t, context->method)); Stack stack(t); unsigned ip = initialIp; - unsigned newIp; + unsigned newIp = -1; stack.pushValue(Return); start: From ab4adef373471403d3b12d41c2596c72ebe7195f Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 2 Jan 2014 17:47:42 -0700 Subject: [PATCH 2/4] remove obsolete idle statement from Unsafe.getLongVolatile Now that Josh has fixed the busy block bug (see commit 10d15d2), we don't need this anymore. --- src/builtin.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/builtin.cpp b/src/builtin.cpp index 1a7d283231..6c069746d2 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -765,10 +765,6 @@ Avian_sun_misc_Unsafe_getLongVolatile object o = reinterpret_cast(arguments[1]); int64_t offset; memcpy(&offset, arguments + 2, 8); - // avoid blocking the VM if this is being called in a busy loop - PROTECT(t, o); - { ENTER(t, Thread::IdleState); } - object field; if (BytesPerWord < 8) { field = fieldForOffset(t, o, offset); From cc5b58725a273c4cd208d92dbde94fd5818b9df0 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 2 Jan 2014 17:49:56 -0700 Subject: [PATCH 3/4] 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) From 789c36a4599727e5ac4f99f9f9cc51297ac6f286 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 2 Jan 2014 18:00:53 -0700 Subject: [PATCH 4/4] move Unsafe.putObjectVolatile and putOrderedObject implementations This makes them available to all class libraries, not just OpenJDK. --- classpath/sun/misc/Unsafe.java | 4 ++++ src/builtin.cpp | 20 ++++++++++++++++++++ src/classpath-openjdk.cpp | 20 -------------------- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/classpath/sun/misc/Unsafe.java b/classpath/sun/misc/Unsafe.java index a03bf3db71..21c7c43d62 100644 --- a/classpath/sun/misc/Unsafe.java +++ b/classpath/sun/misc/Unsafe.java @@ -60,6 +60,10 @@ public final class Unsafe { public native void putObject(Object o, long offset, Object x); + public native void putObjectVolatile(Object o, long offset, Object x); + + public native void putOrderedObject(Object o, long offset, Object x); + public native long getAddress(long address); public native void putAddress(long address, long x); diff --git a/src/builtin.cpp b/src/builtin.cpp index 9940b53c7b..f5733f6ec3 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -703,6 +703,26 @@ Avian_sun_misc_Unsafe_putObject set(t, o, offset, reinterpret_cast(value)); } +extern "C" AVIAN_EXPORT void JNICALL +Avian_sun_misc_Unsafe_putObjectVolatile +(Thread* t, object, uintptr_t* arguments) +{ + object o = reinterpret_cast(arguments[1]); + int64_t offset; memcpy(&offset, arguments + 2, 8); + object value = reinterpret_cast(arguments[4]); + + storeStoreMemoryBarrier(); + set(t, o, offset, reinterpret_cast(value)); + storeLoadMemoryBarrier(); +} + +extern "C" AVIAN_EXPORT void JNICALL +Avian_sun_misc_Unsafe_putOrderedObject +(Thread* t, object method, uintptr_t* arguments) +{ + Avian_sun_misc_Unsafe_putObjectVolatile(t, method, arguments); +} + extern "C" AVIAN_EXPORT int64_t JNICALL Avian_sun_misc_Unsafe_compareAndSwapObject (Thread* t, object, uintptr_t* arguments) diff --git a/src/classpath-openjdk.cpp b/src/classpath-openjdk.cpp index ac406b3adb..f802abd347 100644 --- a/src/classpath-openjdk.cpp +++ b/src/classpath-openjdk.cpp @@ -2794,26 +2794,6 @@ Avian_sun_misc_Unsafe_getObjectVolatile return value; } -extern "C" AVIAN_EXPORT void JNICALL -Avian_sun_misc_Unsafe_putObjectVolatile -(Thread* t, object, uintptr_t* arguments) -{ - object o = reinterpret_cast(arguments[1]); - int64_t offset; memcpy(&offset, arguments + 2, 8); - object value = reinterpret_cast(arguments[4]); - - storeStoreMemoryBarrier(); - set(t, o, offset, reinterpret_cast(value)); - storeLoadMemoryBarrier(); -} - -extern "C" AVIAN_EXPORT void JNICALL -Avian_sun_misc_Unsafe_putOrderedObject -(Thread* t, object method, uintptr_t* arguments) -{ - Avian_sun_misc_Unsafe_putObjectVolatile(t, method, arguments); -} - extern "C" AVIAN_EXPORT int64_t JNICALL Avian_sun_misc_Unsafe_pageSize (Thread*, object, uintptr_t*)