8158039: VarHandle float/double field/array access should support CAS/set/add atomics
Reviewed-by: shade, vlivanov, darcy
--- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestDouble.java Mon Jun 20 08:11:22 2016 -0400
+++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestDouble.java Mon Jun 20 13:06:33 2016 +0200
@@ -173,7 +173,125 @@
}
+ UNSAFE.putDouble(base, offset, 1.0d);
+ // Compare
+ {
+ boolean r = UNSAFE.compareAndSwapDouble(base, offset, 1.0d, 2.0d);
+ assertEquals(r, true, "success compareAndSwap double");
+ double x = UNSAFE.getDouble(base, offset);
+ assertEquals(x, 2.0d, "success compareAndSwap double value");
+ }
+
+ {
+ boolean r = UNSAFE.compareAndSwapDouble(base, offset, 1.0d, 3.0d);
+ assertEquals(r, false, "failing compareAndSwap double");
+ double x = UNSAFE.getDouble(base, offset);
+ assertEquals(x, 2.0d, "failing compareAndSwap double value");
+ }
+
+ // Advanced compare
+ {
+ double r = UNSAFE.compareAndExchangeDoubleVolatile(base, offset, 2.0d, 1.0d);
+ assertEquals(r, 2.0d, "success compareAndExchangeVolatile double");
+ double x = UNSAFE.getDouble(base, offset);
+ assertEquals(x, 1.0d, "success compareAndExchangeVolatile double value");
+ }
+
+ {
+ double r = UNSAFE.compareAndExchangeDoubleVolatile(base, offset, 2.0d, 3.0d);
+ assertEquals(r, 1.0d, "failing compareAndExchangeVolatile double");
+ double x = UNSAFE.getDouble(base, offset);
+ assertEquals(x, 1.0d, "failing compareAndExchangeVolatile double value");
+ }
+
+ {
+ double r = UNSAFE.compareAndExchangeDoubleAcquire(base, offset, 1.0d, 2.0d);
+ assertEquals(r, 1.0d, "success compareAndExchangeAcquire double");
+ double x = UNSAFE.getDouble(base, offset);
+ assertEquals(x, 2.0d, "success compareAndExchangeAcquire double value");
+ }
+
+ {
+ double r = UNSAFE.compareAndExchangeDoubleAcquire(base, offset, 1.0d, 3.0d);
+ assertEquals(r, 2.0d, "failing compareAndExchangeAcquire double");
+ double x = UNSAFE.getDouble(base, offset);
+ assertEquals(x, 2.0d, "failing compareAndExchangeAcquire double value");
+ }
+
+ {
+ double r = UNSAFE.compareAndExchangeDoubleRelease(base, offset, 2.0d, 1.0d);
+ assertEquals(r, 2.0d, "success compareAndExchangeRelease double");
+ double x = UNSAFE.getDouble(base, offset);
+ assertEquals(x, 1.0d, "success compareAndExchangeRelease double value");
+ }
+
+ {
+ double r = UNSAFE.compareAndExchangeDoubleRelease(base, offset, 2.0d, 3.0d);
+ assertEquals(r, 1.0d, "failing compareAndExchangeRelease double");
+ double x = UNSAFE.getDouble(base, offset);
+ assertEquals(x, 1.0d, "failing compareAndExchangeRelease double value");
+ }
+
+ {
+ boolean success = false;
+ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+ success = UNSAFE.weakCompareAndSwapDouble(base, offset, 1.0d, 2.0d);
+ }
+ assertEquals(success, true, "weakCompareAndSwap double");
+ double x = UNSAFE.getDouble(base, offset);
+ assertEquals(x, 2.0d, "weakCompareAndSwap double value");
+ }
+
+ {
+ boolean success = false;
+ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+ success = UNSAFE.weakCompareAndSwapDoubleAcquire(base, offset, 2.0d, 1.0d);
+ }
+ assertEquals(success, true, "weakCompareAndSwapAcquire double");
+ double x = UNSAFE.getDouble(base, offset);
+ assertEquals(x, 1.0d, "weakCompareAndSwapAcquire double");
+ }
+
+ {
+ boolean success = false;
+ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+ success = UNSAFE.weakCompareAndSwapDoubleRelease(base, offset, 1.0d, 2.0d);
+ }
+ assertEquals(success, true, "weakCompareAndSwapRelease double");
+ double x = UNSAFE.getDouble(base, offset);
+ assertEquals(x, 2.0d, "weakCompareAndSwapRelease double");
+ }
+
+ {
+ boolean success = false;
+ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+ success = UNSAFE.weakCompareAndSwapDoubleVolatile(base, offset, 2.0d, 1.0d);
+ }
+ assertEquals(success, true, "weakCompareAndSwapVolatile double");
+ double x = UNSAFE.getDouble(base, offset);
+ assertEquals(x, 1.0d, "weakCompareAndSwapVolatile double");
+ }
+
+ UNSAFE.putDouble(base, offset, 2.0d);
+
+ // Compare set and get
+ {
+ double o = UNSAFE.getAndSetDouble(base, offset, 1.0d);
+ assertEquals(o, 2.0d, "getAndSet double");
+ double x = UNSAFE.getDouble(base, offset);
+ assertEquals(x, 1.0d, "getAndSet double value");
+ }
+
+ UNSAFE.putDouble(base, offset, 1.0d);
+
+ // get and add, add and get
+ {
+ double o = UNSAFE.getAndAddDouble(base, offset, 2.0d);
+ assertEquals(o, 1.0d, "getAndAdd double");
+ double x = UNSAFE.getDouble(base, offset);
+ assertEquals(x, (double)(1.0d + 2.0d), "getAndAdd double");
+ }
}
static void testAccess(long address) {
--- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestFloat.java Mon Jun 20 08:11:22 2016 -0400
+++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestFloat.java Mon Jun 20 13:06:33 2016 +0200
@@ -173,7 +173,125 @@
}
+ UNSAFE.putFloat(base, offset, 1.0f);
+ // Compare
+ {
+ boolean r = UNSAFE.compareAndSwapFloat(base, offset, 1.0f, 2.0f);
+ assertEquals(r, true, "success compareAndSwap float");
+ float x = UNSAFE.getFloat(base, offset);
+ assertEquals(x, 2.0f, "success compareAndSwap float value");
+ }
+
+ {
+ boolean r = UNSAFE.compareAndSwapFloat(base, offset, 1.0f, 3.0f);
+ assertEquals(r, false, "failing compareAndSwap float");
+ float x = UNSAFE.getFloat(base, offset);
+ assertEquals(x, 2.0f, "failing compareAndSwap float value");
+ }
+
+ // Advanced compare
+ {
+ float r = UNSAFE.compareAndExchangeFloatVolatile(base, offset, 2.0f, 1.0f);
+ assertEquals(r, 2.0f, "success compareAndExchangeVolatile float");
+ float x = UNSAFE.getFloat(base, offset);
+ assertEquals(x, 1.0f, "success compareAndExchangeVolatile float value");
+ }
+
+ {
+ float r = UNSAFE.compareAndExchangeFloatVolatile(base, offset, 2.0f, 3.0f);
+ assertEquals(r, 1.0f, "failing compareAndExchangeVolatile float");
+ float x = UNSAFE.getFloat(base, offset);
+ assertEquals(x, 1.0f, "failing compareAndExchangeVolatile float value");
+ }
+
+ {
+ float r = UNSAFE.compareAndExchangeFloatAcquire(base, offset, 1.0f, 2.0f);
+ assertEquals(r, 1.0f, "success compareAndExchangeAcquire float");
+ float x = UNSAFE.getFloat(base, offset);
+ assertEquals(x, 2.0f, "success compareAndExchangeAcquire float value");
+ }
+
+ {
+ float r = UNSAFE.compareAndExchangeFloatAcquire(base, offset, 1.0f, 3.0f);
+ assertEquals(r, 2.0f, "failing compareAndExchangeAcquire float");
+ float x = UNSAFE.getFloat(base, offset);
+ assertEquals(x, 2.0f, "failing compareAndExchangeAcquire float value");
+ }
+
+ {
+ float r = UNSAFE.compareAndExchangeFloatRelease(base, offset, 2.0f, 1.0f);
+ assertEquals(r, 2.0f, "success compareAndExchangeRelease float");
+ float x = UNSAFE.getFloat(base, offset);
+ assertEquals(x, 1.0f, "success compareAndExchangeRelease float value");
+ }
+
+ {
+ float r = UNSAFE.compareAndExchangeFloatRelease(base, offset, 2.0f, 3.0f);
+ assertEquals(r, 1.0f, "failing compareAndExchangeRelease float");
+ float x = UNSAFE.getFloat(base, offset);
+ assertEquals(x, 1.0f, "failing compareAndExchangeRelease float value");
+ }
+
+ {
+ boolean success = false;
+ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+ success = UNSAFE.weakCompareAndSwapFloat(base, offset, 1.0f, 2.0f);
+ }
+ assertEquals(success, true, "weakCompareAndSwap float");
+ float x = UNSAFE.getFloat(base, offset);
+ assertEquals(x, 2.0f, "weakCompareAndSwap float value");
+ }
+
+ {
+ boolean success = false;
+ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+ success = UNSAFE.weakCompareAndSwapFloatAcquire(base, offset, 2.0f, 1.0f);
+ }
+ assertEquals(success, true, "weakCompareAndSwapAcquire float");
+ float x = UNSAFE.getFloat(base, offset);
+ assertEquals(x, 1.0f, "weakCompareAndSwapAcquire float");
+ }
+
+ {
+ boolean success = false;
+ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+ success = UNSAFE.weakCompareAndSwapFloatRelease(base, offset, 1.0f, 2.0f);
+ }
+ assertEquals(success, true, "weakCompareAndSwapRelease float");
+ float x = UNSAFE.getFloat(base, offset);
+ assertEquals(x, 2.0f, "weakCompareAndSwapRelease float");
+ }
+
+ {
+ boolean success = false;
+ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+ success = UNSAFE.weakCompareAndSwapFloatVolatile(base, offset, 2.0f, 1.0f);
+ }
+ assertEquals(success, true, "weakCompareAndSwapVolatile float");
+ float x = UNSAFE.getFloat(base, offset);
+ assertEquals(x, 1.0f, "weakCompareAndSwapVolatile float");
+ }
+
+ UNSAFE.putFloat(base, offset, 2.0f);
+
+ // Compare set and get
+ {
+ float o = UNSAFE.getAndSetFloat(base, offset, 1.0f);
+ assertEquals(o, 2.0f, "getAndSet float");
+ float x = UNSAFE.getFloat(base, offset);
+ assertEquals(x, 1.0f, "getAndSet float value");
+ }
+
+ UNSAFE.putFloat(base, offset, 1.0f);
+
+ // get and add, add and get
+ {
+ float o = UNSAFE.getAndAddFloat(base, offset, 2.0f);
+ assertEquals(o, 1.0f, "getAndAdd float");
+ float x = UNSAFE.getFloat(base, offset);
+ assertEquals(x, (float)(1.0f + 2.0f), "getAndAdd float");
+ }
}
static void testAccess(long address) {
--- a/hotspot/test/compiler/unsafe/generate-unsafe-access-tests.sh Mon Jun 20 08:11:22 2016 -0400
+++ b/hotspot/test/compiler/unsafe/generate-unsafe-access-tests.sh Mon Jun 20 13:06:33 2016 +0200
@@ -55,12 +55,12 @@
if [ "$package" == "jdk.internal.misc" ]; then
case $type in
- boolean|byte|char|short)
+ boolean|byte|char|short|float|double)
args="$args -KCAS"
;;
esac
case $type in
- byte|char|short)
+ byte|char|short|float|double)
args="$args -KAtomicAdd"
;;
esac