changeset 13334:d5c1bee59e2a JEP-193-VarHandles-branch

Add VarHandle.compareAndExchange{Volatile, Acquire, Release}. The corresponding Unsafe methods need to be made intrinsic and the current implementations while functional are incorrect with respect to the witness on failure.
author psandoz
date Thu, 10 Sep 2015 14:44:32 +0200
parents e2eb50447723
children 08559d472428
files src/java.base/share/classes/java/lang/invoke/VarForm.java src/java.base/share/classes/java/lang/invoke/VarHandle.java src/java.base/share/classes/java/lang/invoke/VarHandleBooleans.java src/java.base/share/classes/java/lang/invoke/VarHandleByteArrayViews.java src/java.base/share/classes/java/lang/invoke/VarHandleBytes.java src/java.base/share/classes/java/lang/invoke/VarHandleChars.java src/java.base/share/classes/java/lang/invoke/VarHandleDoubles.java src/java.base/share/classes/java/lang/invoke/VarHandleFloats.java src/java.base/share/classes/java/lang/invoke/VarHandleGuards.java src/java.base/share/classes/java/lang/invoke/VarHandleIntArrayViews.java src/java.base/share/classes/java/lang/invoke/VarHandleInts.java src/java.base/share/classes/java/lang/invoke/VarHandleLongs.java src/java.base/share/classes/java/lang/invoke/VarHandleObjects.java src/java.base/share/classes/java/lang/invoke/VarHandleShorts.java src/java.base/share/classes/java/lang/invoke/VarHandles.java src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template src/java.base/share/classes/sun/misc/Unsafe.java test/java/lang/invoke/X-VarHandleTest.java.template
diffstat 18 files changed, 779 insertions(+), 268 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/invoke/VarForm.java	Fri Sep 04 17:29:49 2015 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/VarForm.java	Thu Sep 10 14:44:32 2015 +0200
@@ -57,8 +57,9 @@
     final MemberName mbGetAcquire;
     final MemberName mbSetRelease;
     final MemberName mbCompareAndSet;
-    final MemberName mbCompareAndSetAcquire;
-    final MemberName mbCompareAndSetRelease;
+    final MemberName mbCompareAndExchangeVolatile;
+    final MemberName mbCompareAndExchangeAcquire;
+    final MemberName mbCompareAndExchangeRelease;
     final MemberName mbWeakCompareAndSet;
     final MemberName mbWeakCompareAndSetAcquire;
     final MemberName mbWeakCompareAndSetRelease;
@@ -78,8 +79,9 @@
         mbGetAcquire = linkMap.get(AccessKind.getAcquire);
         mbSetRelease = linkMap.get(AccessKind.setRelease);
         mbCompareAndSet = linkMap.get(AccessKind.compareAndSet);
-        mbCompareAndSetAcquire = linkMap.get(AccessKind.compareAndSetAcquire);
-        mbCompareAndSetRelease = linkMap.get(AccessKind.compareAndSetRelease);
+        mbCompareAndExchangeVolatile = linkMap.get(AccessKind.compareAndExchangeVolatile);
+        mbCompareAndExchangeAcquire = linkMap.get(AccessKind.compareAndExchangeAcquire);
+        mbCompareAndExchangeRelease = linkMap.get(AccessKind.compareAndExchangeRelease);
         mbWeakCompareAndSet = linkMap.get(AccessKind.weakCompareAndSet);
         mbWeakCompareAndSetAcquire = linkMap.get(AccessKind.weakCompareAndSetAcquire);
         mbWeakCompareAndSetRelease = linkMap.get(AccessKind.weakCompareAndSetRelease);
--- a/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Fri Sep 04 17:29:49 2015 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Thu Sep 10 14:44:32 2015 +0200
@@ -156,7 +156,8 @@
     // e.g. by 24 bytes on 64 bit architectures
     final MethodType typeGet;
     final MethodType typeSet;
-    final MethodType typeCompare;
+    final MethodType typeCompareSwap;
+    final MethodType typeCompareExchange;
     final MethodType typeGetAndUpdate;
 
     final VarForm vform;
@@ -182,7 +183,10 @@
 
         // (Receiver, <Intermediates>, Value, Value)boolean
         l.add(value);
-        this.typeCompare = MethodType.methodType(boolean.class, l);
+        this.typeCompareSwap = MethodType.methodType(boolean.class, l);
+
+        // (Receiver, <Intermediates>, Value, Value)Value
+        this.typeCompareExchange = MethodType.methodType(value, l);
     }
 
     RuntimeException unsupported(MemberName mn) {
@@ -353,9 +357,28 @@
      * An operation to atomically set the value of a variable to the an updated
      * value if the variable's current value {@code ==} an expected value.
      *
-     * This method differs from {@link #compareAndSet(Object...)}, in the way
-     * it only provides the <i>acquire</i> semantics, not the full ordering
-     * semantics of {@code compareAndSet}.
+     * The parameters of this method consist of those referencing the
+     * variable, followed by two values or instances of the variable type.  The
+     * first value is the expected value, the second value is the updated
+     * value.
+     *
+     * @param args the signature-polymorphic parameter list, statically
+     * represented using varargs
+     * @return the signature-polymorphic result, statically represented using
+     * {@code Object}
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    @HotSpotIntrinsicCandidate
+    Object compareAndExchangeVolatile(Object... args);
+
+    /**
+     * An operation to atomically set the value of a variable to the an updated
+     * value if the variable's current value {@code ==} an expected value.
+     *
+     * This method differs from {@link #compareAndExchangeVolatile(Object...)},
+     * in the way it only provides the <i>acquire</i> semantics, not the full
+     * ordering semantics of {@code compareAndExchangeVolatile}.
      *
      * The parameters of this method consist of those referencing the
      * variable, followed by two values or instances of the variable type.  The
@@ -364,21 +387,21 @@
      *
      * @param args the signature-polymorphic parameter list, statically
      * represented using varargs
-     * @return {@code true} if successful. False return indicates that
-     * the actual value was not equal to the expected value.
+     * @return the signature-polymorphic result, statically represented using
+     * {@code Object}
      */
     public final native
     @MethodHandle.PolymorphicSignature
     @HotSpotIntrinsicCandidate
-    boolean compareAndSetAcquire(Object... args);
+    Object compareAndExchangeAcquire(Object... args);
 
     /**
      * An operation to atomically set the value of a variable to the an updated
      * value if the variable's current value {@code ==} an expected value.
      *
-     * This method differs from {@link #compareAndSet(Object...)}, in the way
-     * it only provides the <i>release</i> semantics, not the full ordering
-     * semantics of {@code compareAndSet}.
+     * This method differs from {@link #compareAndExchangeRelease(Object...)},
+     * in the way it only provides the <i>release</i> semantics, not the full
+     * ordering semantics of {@code compareAndExchangeVolatile}.
      *
      * The parameters of this method consist of those referencing the
      * variable, followed by two values or instances of the variable type.  The
@@ -387,13 +410,15 @@
      *
      * @param args the signature-polymorphic parameter list, statically
      * represented using varargs
-     * @return {@code true} if successful. False return indicates that
-     * the actual value was not equal to the expected value.
+     * @return the signature-polymorphic result, statically represented using
+     * {@code Object}
      */
     public final native
     @MethodHandle.PolymorphicSignature
     @HotSpotIntrinsicCandidate
-    boolean compareAndSetRelease(Object... args);
+    Object compareAndExchangeRelease(Object... args);
+
+    // Weak (spurious failures allowed)
 
     /**
      * An operation to atomically set the value of a variable to the an updated
@@ -445,7 +470,6 @@
     @HotSpotIntrinsicCandidate
     boolean weakCompareAndSetAcquire(Object... args);
 
-
     /**
      * An operation to atomically set the value of a variable to the an updated
      * value if the variable's current value {@code ==} an expected value.
@@ -529,10 +553,11 @@
     Object addAndGet(Object... args);
 
     enum AccessType {
-        get,
-        set,
-        compare,
-        getAndUpdate;
+        get,                  // 0
+        set,                  // 1
+        compareAndSwap,       // 2
+        compareAndExchange,   // 3
+        getAndUpdate;         // 4
 
         MethodType getMethodType(VarHandle vh) {
             return getMethodType(this.ordinal(), vh);
@@ -547,9 +572,12 @@
                 return vh.typeSet;
             }
             else if (ordinal == 2) {
-                return vh.typeCompare;
+                return vh.typeCompareSwap;
             }
             else if (ordinal == 3) {
+                return vh.typeCompareExchange;
+            }
+            else if (ordinal == 4) {
                 return vh.typeGetAndUpdate;
             }
             else {
@@ -559,23 +587,25 @@
     }
 
     enum AccessKind {
-        getRelaxed(AccessType.get),
-        setRelaxed(AccessType.set),
-        getVolatile(AccessType.get),
-        setVolatile(AccessType.set),
-        getAcquire(AccessType.get),
-        setRelease(AccessType.set),
-        compareAndSet(AccessType.compare),
-        compareAndSetAcquire(AccessType.compare),
-        compareAndSetRelease(AccessType.compare),
-        weakCompareAndSet(AccessType.compare),
-        weakCompareAndSetAcquire(AccessType.compare),
-        weakCompareAndSetRelease(AccessType.compare),
-        getAndSet(AccessType.getAndUpdate),
-        getAndAdd(AccessType.getAndUpdate),
-        addAndGet(AccessType.getAndUpdate),
-        getOpaque(AccessType.get),
-        setOpaque(AccessType.set);
+        getRelaxed(AccessType.get),                             // 0
+        setRelaxed(AccessType.set),                             // 1
+        getVolatile(AccessType.get),                            // 2
+        setVolatile(AccessType.set),                            // 3
+        getAcquire(AccessType.get),                             // 4
+        setRelease(AccessType.set),                             // 5
+        getOpaque(AccessType.get),                              // 6
+        setOpaque(AccessType.set),                              // 7
+        compareAndSet(AccessType.compareAndSwap),                  // 8
+        compareAndExchangeVolatile(AccessType.compareAndExchange), // 9
+        compareAndExchangeAcquire(AccessType.compareAndExchange),  // 10
+        compareAndExchangeRelease(AccessType.compareAndExchange),  // 11
+        weakCompareAndSet(AccessType.compareAndSwap),              // 12
+        weakCompareAndSetAcquire(AccessType.compareAndSwap),       // 13
+        weakCompareAndSetRelease(AccessType.compareAndSwap),       // 14
+        getAndSet(AccessType.getAndUpdate),                     // 15
+        getAndAdd(AccessType.getAndUpdate),                     // 16
+        addAndGet(AccessType.getAndUpdate),                     // 17
+        ;
 
         final AccessType at;
         final boolean isPolyMorphicInReturnType;
@@ -609,27 +639,29 @@
             } else if (kind == 5) {
                 return vform.mbSetRelease;
             } else if (kind == 6) {
+                return vform.mbGetOpaque;
+            } else if (kind == 7) {
+                return vform.mbSetOpaque;
+            } else if (kind == 8) {
                 return vform.mbCompareAndSet;
-            } else if (kind == 7) {
-                return vform.mbCompareAndSetAcquire;
-            } else if (kind == 8) {
-                return vform.mbCompareAndSetRelease;
             } else if (kind == 9) {
+                return vform.mbCompareAndExchangeVolatile;
+            } else if (kind == 10) {
+                return vform.mbCompareAndExchangeAcquire;
+            } else if (kind == 11) {
+                return vform.mbCompareAndExchangeRelease;
+            } else if (kind == 12) {
                 return vform.mbWeakCompareAndSet;
-            } else if (kind == 10) {
+            } else if (kind == 13) {
                 return vform.mbWeakCompareAndSetAcquire;
-            } else if (kind == 11) {
+            } else if (kind == 14) {
                 return vform.mbWeakCompareAndSetRelease;
-            } else if (kind == 12) {
+            } else if (kind == 15) {
                 return vform.mbGetAndSet;
-            } else if (kind == 13) {
+            } else if (kind == 16) {
                 return vform.mbGetAndAdd;
-            } else if (kind == 14) {
+            } else if (kind == 17) {
                 return vform.mbAddAndGet;
-            } else if (kind == 15) {
-                return vform.mbGetOpaque;
-            } else if (kind == 16) {
-                return vform.mbSetOpaque;
             } else {
                 throw new IllegalStateException("Illegal kind: " + kind);
             }
--- a/src/java.base/share/classes/java/lang/invoke/VarHandleBooleans.java	Fri Sep 04 17:29:49 2015 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandleBooleans.java	Thu Sep 10 14:44:32 2015 +0200
@@ -203,6 +203,14 @@
 
 
 
+
+
+
+
+
+
+
+
     }
 
 
@@ -378,6 +386,15 @@
 
 
 
+
+
+
+
+
+
+
+
+
     }
 
 
@@ -586,6 +603,17 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
     }
 
 }
--- a/src/java.base/share/classes/java/lang/invoke/VarHandleByteArrayViews.java	Fri Sep 04 17:29:49 2015 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandleByteArrayViews.java	Thu Sep 10 14:44:32 2015 +0200
@@ -76,6 +76,7 @@
             UNSAFE.putLongUnaligned(ba, (long) index + Unsafe.ARRAY_BYTE_BASE_OFFSET, value);
         }
 
+        // @@@ Opaque accessors
     }
 
     static final class ArrayAsAlignedLongArray extends VarHandle {
@@ -104,6 +105,8 @@
             UNSAFE.putLong(ba, (((long) index) << SCALE) + Unsafe.ARRAY_BYTE_BASE_OFFSET, value);
         }
 
+        // @@@ Opaque accessors
+
         // TODO other operations
     }
 
@@ -145,6 +148,7 @@
             UNSAFE.putLongUnaligned(base, (long) index + address, value);
         }
 
+        // @@@ Opaque accessors
     }
 
     // Aligned
@@ -204,6 +208,8 @@
             UNSAFE.putLongVolatile(base, (((long) index) << SCALE) + address, value);
         }
 
+        // @@@ Opaque accessors
+
         @ForceInline
         static long getAcquire(ByteBufferAsAlignedLongArray handle, ByteBuffer bb, int index) {
             long length = bb.limit();
@@ -237,6 +243,8 @@
             return UNSAFE.compareAndSwapLong(base, (((long) index) << SCALE) + address, expected, value);
         }
 
+        // @@@ Compare set/exchange methods accessors
+
         @ForceInline
         static long getAndSet(ByteBufferAsAlignedLongArray handle, ByteBuffer bb, int index, long value) {
             long length = bb.limit();
--- a/src/java.base/share/classes/java/lang/invoke/VarHandleBytes.java	Fri Sep 04 17:29:49 2015 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandleBytes.java	Thu Sep 10 14:44:32 2015 +0200
@@ -203,6 +203,14 @@
 
 
 
+
+
+
+
+
+
+
+
     }
 
 
@@ -378,6 +386,15 @@
 
 
 
+
+
+
+
+
+
+
+
+
     }
 
 
@@ -586,6 +603,17 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
     }
 
 }
--- a/src/java.base/share/classes/java/lang/invoke/VarHandleChars.java	Fri Sep 04 17:29:49 2015 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandleChars.java	Thu Sep 10 14:44:32 2015 +0200
@@ -203,6 +203,14 @@
 
 
 
+
+
+
+
+
+
+
+
     }
 
 
@@ -378,6 +386,15 @@
 
 
 
+
+
+
+
+
+
+
+
+
     }
 
 
@@ -586,6 +603,17 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
     }
 
 }
--- a/src/java.base/share/classes/java/lang/invoke/VarHandleDoubles.java	Fri Sep 04 17:29:49 2015 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandleDoubles.java	Thu Sep 10 14:44:32 2015 +0200
@@ -203,6 +203,14 @@
 
 
 
+
+
+
+
+
+
+
+
     }
 
 
@@ -378,6 +386,15 @@
 
 
 
+
+
+
+
+
+
+
+
+
     }
 
 
@@ -586,6 +603,17 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
     }
 
 }
--- a/src/java.base/share/classes/java/lang/invoke/VarHandleFloats.java	Fri Sep 04 17:29:49 2015 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandleFloats.java	Thu Sep 10 14:44:32 2015 +0200
@@ -203,6 +203,14 @@
 
 
 
+
+
+
+
+
+
+
+
     }
 
 
@@ -378,6 +386,15 @@
 
 
 
+
+
+
+
+
+
+
+
+
     }
 
 
@@ -586,6 +603,17 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
     }
 
 }
--- a/src/java.base/share/classes/java/lang/invoke/VarHandleGuards.java	Fri Sep 04 17:29:49 2015 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandleGuards.java	Thu Sep 10 14:44:32 2015 +0200
@@ -29,6 +29,15 @@
 final class VarHandleGuards {
 
     @ForceInline
+    final static void checkExactType(VarHandle handle, VarHandle.AccessDescriptor ad) {
+        MethodType expected = VarHandle.AccessType.getMethodType(ad.type, handle);
+        if (expected != ad.symbolicMethodType) {
+            throw Invokers.newWrongMethodTypeException(expected,
+                                                       ad.symbolicMethodType);
+        }
+    }
+
+    @ForceInline
     final static MemberName getMemberName(VarHandle handle, VarHandle.AccessDescriptor ad) {
         MemberName mn = VarHandle.AccessKind.getMemberName(ad.kind, handle.vform);
         if (mn == null) {
@@ -38,15 +47,6 @@
     }
 
     @ForceInline
-    final static void checkExactType(VarHandle handle, VarHandle.AccessDescriptor ad) {
-        MethodType expected = VarHandle.AccessType.getMethodType(ad.type, handle);
-        if (expected != ad.symbolicMethodType) {
-            throw Invokers.newWrongMethodTypeException(expected,
-                    ad.symbolicMethodType);
-        }
-    }
-
-    @ForceInline
     final static Object guard_L_L(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
         return MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
@@ -59,15 +59,21 @@
     }
 
     @ForceInline
+    final static Object guard_LL_L(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+        checkExactType(handle, ad);
+        return MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+    }
+
+    @ForceInline
     final static boolean guard_LLL_Z(VarHandle handle, Object arg0, Object arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
         return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
     }
 
     @ForceInline
-    final static Object guard_LL_L(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+    final static Object guard_LLL_L(VarHandle handle, Object arg0, Object arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
-        return MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
     }
 
     @ForceInline
@@ -83,15 +89,21 @@
     }
 
     @ForceInline
+    final static int guard_LI_I(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+        checkExactType(handle, ad);
+        return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+    }
+
+    @ForceInline
     final static boolean guard_LII_Z(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
         return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
     }
 
     @ForceInline
-    final static int guard_LI_I(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+    final static int guard_LII_I(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
-        return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
     }
 
     @ForceInline
@@ -107,15 +119,21 @@
     }
 
     @ForceInline
+    final static long guard_LJ_J(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+        checkExactType(handle, ad);
+        return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+    }
+
+    @ForceInline
     final static boolean guard_LJJ_Z(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
         return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
     }
 
     @ForceInline
-    final static long guard_LJ_J(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+    final static long guard_LJJ_J(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
-        return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
     }
 
     @ForceInline
@@ -131,15 +149,21 @@
     }
 
     @ForceInline
+    final static float guard_LF_F(VarHandle handle, Object arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+        checkExactType(handle, ad);
+        return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+    }
+
+    @ForceInline
     final static boolean guard_LFF_Z(VarHandle handle, Object arg0, float arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
         return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
     }
 
     @ForceInline
-    final static float guard_LF_F(VarHandle handle, Object arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+    final static float guard_LFF_F(VarHandle handle, Object arg0, float arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
-        return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
     }
 
     @ForceInline
@@ -155,15 +179,21 @@
     }
 
     @ForceInline
+    final static double guard_LD_D(VarHandle handle, Object arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+        checkExactType(handle, ad);
+        return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+    }
+
+    @ForceInline
     final static boolean guard_LDD_Z(VarHandle handle, Object arg0, double arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
         return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
     }
 
     @ForceInline
-    final static double guard_LD_D(VarHandle handle, Object arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+    final static double guard_LDD_D(VarHandle handle, Object arg0, double arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
-        return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
     }
 
     @ForceInline
@@ -197,15 +227,21 @@
     }
 
     @ForceInline
+    final static int guard_I_I(VarHandle handle, int arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+        checkExactType(handle, ad);
+        return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+    }
+
+    @ForceInline
     final static boolean guard_II_Z(VarHandle handle, int arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
         return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
     }
 
     @ForceInline
-    final static int guard_I_I(VarHandle handle, int arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+    final static int guard_II_I(VarHandle handle, int arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
-        return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
     }
 
     @ForceInline
@@ -221,15 +257,21 @@
     }
 
     @ForceInline
+    final static long guard_J_J(VarHandle handle, long arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+        checkExactType(handle, ad);
+        return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+    }
+
+    @ForceInline
     final static boolean guard_JJ_Z(VarHandle handle, long arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
         return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
     }
 
     @ForceInline
-    final static long guard_J_J(VarHandle handle, long arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+    final static long guard_JJ_J(VarHandle handle, long arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
-        return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
     }
 
     @ForceInline
@@ -245,15 +287,21 @@
     }
 
     @ForceInline
+    final static float guard_F_F(VarHandle handle, float arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+        checkExactType(handle, ad);
+        return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+    }
+
+    @ForceInline
     final static boolean guard_FF_Z(VarHandle handle, float arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
         return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
     }
 
     @ForceInline
-    final static float guard_F_F(VarHandle handle, float arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+    final static float guard_FF_F(VarHandle handle, float arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
-        return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
     }
 
     @ForceInline
@@ -269,15 +317,21 @@
     }
 
     @ForceInline
+    final static double guard_D_D(VarHandle handle, double arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+        checkExactType(handle, ad);
+        return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+    }
+
+    @ForceInline
     final static boolean guard_DD_Z(VarHandle handle, double arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
         return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
     }
 
     @ForceInline
-    final static double guard_D_D(VarHandle handle, double arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+    final static double guard_DD_D(VarHandle handle, double arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
-        return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
     }
 
     @ForceInline
@@ -293,15 +347,21 @@
     }
 
     @ForceInline
+    final static Object guard_LIL_L(VarHandle handle, Object arg0, int arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+        checkExactType(handle, ad);
+        return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+    }
+
+    @ForceInline
     final static boolean guard_LILL_Z(VarHandle handle, Object arg0, int arg1, Object arg2, Object arg3, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
         return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
     }
 
     @ForceInline
-    final static Object guard_LIL_L(VarHandle handle, Object arg0, int arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+    final static Object guard_LILL_L(VarHandle handle, Object arg0, int arg1, Object arg2, Object arg3, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
-        return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
     }
 
     @ForceInline
@@ -317,9 +377,9 @@
     }
 
     @ForceInline
-    final static int guard_LII_I(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+    final static int guard_LIII_I(VarHandle handle, Object arg0, int arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
-        return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
     }
 
     @ForceInline
@@ -335,15 +395,21 @@
     }
 
     @ForceInline
+    final static long guard_LIJ_J(VarHandle handle, Object arg0, int arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+        checkExactType(handle, ad);
+        return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+    }
+
+    @ForceInline
     final static boolean guard_LIJJ_Z(VarHandle handle, Object arg0, int arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
         return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
     }
 
     @ForceInline
-    final static long guard_LIJ_J(VarHandle handle, Object arg0, int arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+    final static long guard_LIJJ_J(VarHandle handle, Object arg0, int arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
-        return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
     }
 
     @ForceInline
@@ -359,15 +425,21 @@
     }
 
     @ForceInline
+    final static float guard_LIF_F(VarHandle handle, Object arg0, int arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+        checkExactType(handle, ad);
+        return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+    }
+
+    @ForceInline
     final static boolean guard_LIFF_Z(VarHandle handle, Object arg0, int arg1, float arg2, float arg3, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
         return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
     }
 
     @ForceInline
-    final static float guard_LIF_F(VarHandle handle, Object arg0, int arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+    final static float guard_LIFF_F(VarHandle handle, Object arg0, int arg1, float arg2, float arg3, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
-        return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
     }
 
     @ForceInline
@@ -383,15 +455,21 @@
     }
 
     @ForceInline
+    final static double guard_LID_D(VarHandle handle, Object arg0, int arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+        checkExactType(handle, ad);
+        return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+    }
+
+    @ForceInline
     final static boolean guard_LIDD_Z(VarHandle handle, Object arg0, int arg1, double arg2, double arg3, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
         return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
     }
 
     @ForceInline
-    final static double guard_LID_D(VarHandle handle, Object arg0, int arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+    final static double guard_LIDD_D(VarHandle handle, Object arg0, int arg1, double arg2, double arg3, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
-        return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
     }
 
     @ForceInline
@@ -407,15 +485,21 @@
     }
 
     @ForceInline
+    final static int guard_LJI_I(VarHandle handle, Object arg0, long arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+        checkExactType(handle, ad);
+        return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+    }
+
+    @ForceInline
     final static boolean guard_LJII_Z(VarHandle handle, Object arg0, long arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
         return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
     }
 
     @ForceInline
-    final static int guard_LJI_I(VarHandle handle, Object arg0, long arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+    final static int guard_LJII_I(VarHandle handle, Object arg0, long arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
-        return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
     }
 
     @ForceInline
@@ -431,8 +515,9 @@
     }
 
     @ForceInline
-    final static long guard_LJJ_J(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+    final static long guard_LJJJ_J(VarHandle handle, Object arg0, long arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
         checkExactType(handle, ad);
-        return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
     }
+
 }
--- a/src/java.base/share/classes/java/lang/invoke/VarHandleIntArrayViews.java	Fri Sep 04 17:29:49 2015 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandleIntArrayViews.java	Thu Sep 10 14:44:32 2015 +0200
@@ -67,6 +67,8 @@
             UNSAFE.putIntVolatile(Objects.requireNonNull(holder), handle.fieldOffsets[index], value);
         }
 
+        // @@@ Opaque accessors
+
         @ForceInline
         static int getAcquire(ArrayViewField handle, Object holder, int index) {
             if (index < 0 || index >= handle.fieldOffsets.length)
@@ -88,19 +90,7 @@
             return UNSAFE.compareAndSwapInt(Objects.requireNonNull(holder), handle.fieldOffsets[index], expected, value);
         }
 
-        @ForceInline
-        static boolean compareAndSetAcquire(ArrayViewField handle, Object holder, int index, int expected, int value) {
-            if (index < 0 || index >= handle.fieldOffsets.length)
-                throw new ArrayIndexOutOfBoundsException();
-            return UNSAFE.compareAndSwapIntAcquire(Objects.requireNonNull(holder), handle.fieldOffsets[index], expected, value);
-        }
-
-        @ForceInline
-        static boolean compareAndSetRelease(ArrayViewField handle, Object holder, int index, int expected, int value) {
-            if (index < 0 || index >= handle.fieldOffsets.length)
-                throw new ArrayIndexOutOfBoundsException();
-            return UNSAFE.compareAndSwapIntRelease(Objects.requireNonNull(holder), handle.fieldOffsets[index], expected, value);
-        }
+        // @@@ Compare exchange accessors
 
         @ForceInline
         static boolean weakCompareAndSet(ArrayViewField handle, Object holder, int index, int expected, int value) {
--- a/src/java.base/share/classes/java/lang/invoke/VarHandleInts.java	Fri Sep 04 17:29:49 2015 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandleInts.java	Thu Sep 10 14:44:32 2015 +0200
@@ -140,16 +140,24 @@
         }
 
         @ForceInline
-        static boolean compareAndSetAcquire(FieldInstanceReadWrite handle, Object holder, int expected, int value) {
-            return UNSAFE.compareAndSwapIntAcquire(Objects.requireNonNull(holder),
+        static int compareAndExchangeVolatile(FieldInstanceReadWrite handle, Object holder, int expected, int value) {
+            return UNSAFE.compareAndExchangeIntVolatile(Objects.requireNonNull(holder),
                                                handle.fieldOffset,
                                                expected,
                                                value);
         }
 
         @ForceInline
-        static boolean compareAndSetRelease(FieldInstanceReadWrite handle, Object holder, int expected, int value) {
-            return UNSAFE.compareAndSwapIntRelease(Objects.requireNonNull(holder),
+        static int compareAndExchangeAcquire(FieldInstanceReadWrite handle, Object holder, int expected, int value) {
+            return UNSAFE.compareAndExchangeIntAcquire(Objects.requireNonNull(holder),
+                                               handle.fieldOffset,
+                                               expected,
+                                               value);
+        }
+
+        @ForceInline
+        static int compareAndExchangeRelease(FieldInstanceReadWrite handle, Object holder, int expected, int value) {
+            return UNSAFE.compareAndExchangeIntRelease(Objects.requireNonNull(holder),
                                                handle.fieldOffset,
                                                expected,
                                                value);
@@ -315,17 +323,26 @@
                                                value);
         }
 
+
         @ForceInline
-        static boolean compareAndSetAcquire(FieldStaticReadWrite handle, int expected, int value) {
-            return UNSAFE.compareAndSwapIntAcquire(handle.base,
+        static int compareAndExchangeVolatile(FieldStaticReadWrite handle, int expected, int value) {
+            return UNSAFE.compareAndExchangeIntVolatile(handle.base,
                                                handle.fieldOffset,
                                                expected,
                                                value);
         }
 
         @ForceInline
-        static boolean compareAndSetRelease(FieldStaticReadWrite handle, int expected, int value) {
-            return UNSAFE.compareAndSwapIntRelease(handle.base,
+        static int compareAndExchangeAcquire(FieldStaticReadWrite handle, int expected, int value) {
+            return UNSAFE.compareAndExchangeIntAcquire(handle.base,
+                                               handle.fieldOffset,
+                                               expected,
+                                               value);
+        }
+
+        @ForceInline
+        static int compareAndExchangeRelease(FieldStaticReadWrite handle, int expected, int value) {
+            return UNSAFE.compareAndExchangeIntRelease(handle.base,
                                                handle.fieldOffset,
                                                expected,
                                                value);
@@ -500,22 +517,33 @@
         }
 
         @ForceInline
-        static boolean compareAndSetAcquire(Array handle, int[] array, int index, int expected, int value) {
+        static int compareAndExchangeVolatile(Array handle, int[] array, int index, int expected, int value) {
             if (index < 0 || index >= array.length) // bounds and null check
                 throw new ArrayIndexOutOfBoundsException();
 
-            return UNSAFE.compareAndSwapIntAcquire(array,
+            return UNSAFE.compareAndExchangeIntVolatile(array,
                                                (((long) index) << handle.ashift) + handle.abase,
                                                expected,
                                                value);
         }
 
         @ForceInline
-        static boolean compareAndSetRelease(Array handle, Object[] array, int index, int expected, int value) {
+        static int compareAndExchangeAcquire(Array handle, int[] array, int index, int expected, int value) {
             if (index < 0 || index >= array.length) // bounds and null check
                 throw new ArrayIndexOutOfBoundsException();
 
-            return UNSAFE.compareAndSwapIntRelease(array,
+            return UNSAFE.compareAndExchangeIntAcquire(array,
+                                               (((long) index) << handle.ashift) + handle.abase,
+                                               expected,
+                                               value);
+        }
+
+        @ForceInline
+        static int compareAndExchangeRelease(Array handle, int[] array, int index, int expected, int value) {
+            if (index < 0 || index >= array.length) // bounds and null check
+                throw new ArrayIndexOutOfBoundsException();
+
+            return UNSAFE.compareAndExchangeIntRelease(array,
                                                (((long) index) << handle.ashift) + handle.abase,
                                                expected,
                                                value);
--- a/src/java.base/share/classes/java/lang/invoke/VarHandleLongs.java	Fri Sep 04 17:29:49 2015 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandleLongs.java	Thu Sep 10 14:44:32 2015 +0200
@@ -140,16 +140,24 @@
         }
 
         @ForceInline
-        static boolean compareAndSetAcquire(FieldInstanceReadWrite handle, Object holder, long expected, long value) {
-            return UNSAFE.compareAndSwapLongAcquire(Objects.requireNonNull(holder),
+        static long compareAndExchangeVolatile(FieldInstanceReadWrite handle, Object holder, long expected, long value) {
+            return UNSAFE.compareAndExchangeLongVolatile(Objects.requireNonNull(holder),
                                                handle.fieldOffset,
                                                expected,
                                                value);
         }
 
         @ForceInline
-        static boolean compareAndSetRelease(FieldInstanceReadWrite handle, Object holder, long expected, long value) {
-            return UNSAFE.compareAndSwapLongRelease(Objects.requireNonNull(holder),
+        static long compareAndExchangeAcquire(FieldInstanceReadWrite handle, Object holder, long expected, long value) {
+            return UNSAFE.compareAndExchangeLongAcquire(Objects.requireNonNull(holder),
+                                               handle.fieldOffset,
+                                               expected,
+                                               value);
+        }
+
+        @ForceInline
+        static long compareAndExchangeRelease(FieldInstanceReadWrite handle, Object holder, long expected, long value) {
+            return UNSAFE.compareAndExchangeLongRelease(Objects.requireNonNull(holder),
                                                handle.fieldOffset,
                                                expected,
                                                value);
@@ -315,17 +323,26 @@
                                                value);
         }
 
+
         @ForceInline
-        static boolean compareAndSetAcquire(FieldStaticReadWrite handle, long expected, long value) {
-            return UNSAFE.compareAndSwapLongAcquire(handle.base,
+        static long compareAndExchangeVolatile(FieldStaticReadWrite handle, long expected, long value) {
+            return UNSAFE.compareAndExchangeLongVolatile(handle.base,
                                                handle.fieldOffset,
                                                expected,
                                                value);
         }
 
         @ForceInline
-        static boolean compareAndSetRelease(FieldStaticReadWrite handle, long expected, long value) {
-            return UNSAFE.compareAndSwapLongRelease(handle.base,
+        static long compareAndExchangeAcquire(FieldStaticReadWrite handle, long expected, long value) {
+            return UNSAFE.compareAndExchangeLongAcquire(handle.base,
+                                               handle.fieldOffset,
+                                               expected,
+                                               value);
+        }
+
+        @ForceInline
+        static long compareAndExchangeRelease(FieldStaticReadWrite handle, long expected, long value) {
+            return UNSAFE.compareAndExchangeLongRelease(handle.base,
                                                handle.fieldOffset,
                                                expected,
                                                value);
@@ -500,22 +517,33 @@
         }
 
         @ForceInline
-        static boolean compareAndSetAcquire(Array handle, long[] array, int index, long expected, long value) {
+        static long compareAndExchangeVolatile(Array handle, long[] array, int index, long expected, long value) {
             if (index < 0 || index >= array.length) // bounds and null check
                 throw new ArrayIndexOutOfBoundsException();
 
-            return UNSAFE.compareAndSwapLongAcquire(array,
+            return UNSAFE.compareAndExchangeLongVolatile(array,
                                                (((long) index) << handle.ashift) + handle.abase,
                                                expected,
                                                value);
         }
 
         @ForceInline
-        static boolean compareAndSetRelease(Array handle, Object[] array, int index, long expected, long value) {
+        static long compareAndExchangeAcquire(Array handle, long[] array, int index, long expected, long value) {
             if (index < 0 || index >= array.length) // bounds and null check
                 throw new ArrayIndexOutOfBoundsException();
 
-            return UNSAFE.compareAndSwapLongRelease(array,
+            return UNSAFE.compareAndExchangeLongAcquire(array,
+                                               (((long) index) << handle.ashift) + handle.abase,
+                                               expected,
+                                               value);
+        }
+
+        @ForceInline
+        static long compareAndExchangeRelease(Array handle, long[] array, int index, long expected, long value) {
+            if (index < 0 || index >= array.length) // bounds and null check
+                throw new ArrayIndexOutOfBoundsException();
+
+            return UNSAFE.compareAndExchangeLongRelease(array,
                                                (((long) index) << handle.ashift) + handle.abase,
                                                expected,
                                                value);
--- a/src/java.base/share/classes/java/lang/invoke/VarHandleObjects.java	Fri Sep 04 17:29:49 2015 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandleObjects.java	Thu Sep 10 14:44:32 2015 +0200
@@ -140,16 +140,24 @@
         }
 
         @ForceInline
-        static boolean compareAndSetAcquire(FieldInstanceReadWrite handle, Object holder, Object expected, Object value) {
-            return UNSAFE.compareAndSwapObjectAcquire(Objects.requireNonNull(holder),
+        static Object compareAndExchangeVolatile(FieldInstanceReadWrite handle, Object holder, Object expected, Object value) {
+            return UNSAFE.compareAndExchangeObjectVolatile(Objects.requireNonNull(holder),
                                                handle.fieldOffset,
                                                expected,
                                                handle.fieldType.cast(value));
         }
 
         @ForceInline
-        static boolean compareAndSetRelease(FieldInstanceReadWrite handle, Object holder, Object expected, Object value) {
-            return UNSAFE.compareAndSwapObjectRelease(Objects.requireNonNull(holder),
+        static Object compareAndExchangeAcquire(FieldInstanceReadWrite handle, Object holder, Object expected, Object value) {
+            return UNSAFE.compareAndExchangeObjectAcquire(Objects.requireNonNull(holder),
+                                               handle.fieldOffset,
+                                               expected,
+                                               handle.fieldType.cast(value));
+        }
+
+        @ForceInline
+        static Object compareAndExchangeRelease(FieldInstanceReadWrite handle, Object holder, Object expected, Object value) {
+            return UNSAFE.compareAndExchangeObjectRelease(Objects.requireNonNull(holder),
                                                handle.fieldOffset,
                                                expected,
                                                handle.fieldType.cast(value));
@@ -315,17 +323,26 @@
                                                handle.fieldType.cast(value));
         }
 
+
         @ForceInline
-        static boolean compareAndSetAcquire(FieldStaticReadWrite handle, Object expected, Object value) {
-            return UNSAFE.compareAndSwapObjectAcquire(handle.base,
+        static Object compareAndExchangeVolatile(FieldStaticReadWrite handle, Object expected, Object value) {
+            return UNSAFE.compareAndExchangeObjectVolatile(handle.base,
                                                handle.fieldOffset,
                                                expected,
                                                handle.fieldType.cast(value));
         }
 
         @ForceInline
-        static boolean compareAndSetRelease(FieldStaticReadWrite handle, Object expected, Object value) {
-            return UNSAFE.compareAndSwapObjectRelease(handle.base,
+        static Object compareAndExchangeAcquire(FieldStaticReadWrite handle, Object expected, Object value) {
+            return UNSAFE.compareAndExchangeObjectAcquire(handle.base,
+                                               handle.fieldOffset,
+                                               expected,
+                                               handle.fieldType.cast(value));
+        }
+
+        @ForceInline
+        static Object compareAndExchangeRelease(FieldStaticReadWrite handle, Object expected, Object value) {
+            return UNSAFE.compareAndExchangeObjectRelease(handle.base,
                                                handle.fieldOffset,
                                                expected,
                                                handle.fieldType.cast(value));
@@ -500,22 +517,33 @@
         }
 
         @ForceInline
-        static boolean compareAndSetAcquire(Array handle, Object[] array, int index, Object expected, Object value) {
+        static Object compareAndExchangeVolatile(Array handle, Object[] array, int index, Object expected, Object value) {
             if (index < 0 || index >= array.length) // bounds and null check
                 throw new ArrayIndexOutOfBoundsException();
 
-            return UNSAFE.compareAndSwapObjectAcquire(array,
+            return UNSAFE.compareAndExchangeObjectVolatile(array,
                                                (((long) index) << handle.ashift) + handle.abase,
                                                expected,
                                                handle.componentType.cast(value));
         }
 
         @ForceInline
-        static boolean compareAndSetRelease(Array handle, Object[] array, int index, Object expected, Object value) {
+        static Object compareAndExchangeAcquire(Array handle, Object[] array, int index, Object expected, Object value) {
             if (index < 0 || index >= array.length) // bounds and null check
                 throw new ArrayIndexOutOfBoundsException();
 
-            return UNSAFE.compareAndSwapObjectRelease(array,
+            return UNSAFE.compareAndExchangeObjectAcquire(array,
+                                               (((long) index) << handle.ashift) + handle.abase,
+                                               expected,
+                                               handle.componentType.cast(value));
+        }
+
+        @ForceInline
+        static Object compareAndExchangeRelease(Array handle, Object[] array, int index, Object expected, Object value) {
+            if (index < 0 || index >= array.length) // bounds and null check
+                throw new ArrayIndexOutOfBoundsException();
+
+            return UNSAFE.compareAndExchangeObjectRelease(array,
                                                (((long) index) << handle.ashift) + handle.abase,
                                                expected,
                                                handle.componentType.cast(value));
--- a/src/java.base/share/classes/java/lang/invoke/VarHandleShorts.java	Fri Sep 04 17:29:49 2015 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandleShorts.java	Thu Sep 10 14:44:32 2015 +0200
@@ -203,6 +203,14 @@
 
 
 
+
+
+
+
+
+
+
+
     }
 
 
@@ -378,6 +386,15 @@
 
 
 
+
+
+
+
+
+
+
+
+
     }
 
 
@@ -586,6 +603,17 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
     }
 
 }
--- a/src/java.base/share/classes/java/lang/invoke/VarHandles.java	Fri Sep 04 17:29:49 2015 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandles.java	Thu Sep 10 14:44:32 2015 +0200
@@ -25,6 +25,10 @@
 
 package java.lang.invoke;
 
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.lang.reflect.Parameter;
@@ -321,7 +325,9 @@
 
             void set(Object value);
 
-            boolean compareAndSet(Object actualValue, Object expectedValue);
+            boolean compareAndSwap(Object actualValue, Object expectedValue);
+
+            Object compareAndExchange(Object actualValue, Object expectedValue);
 
             Object getAndUpdate(Object value);
         }
--- a/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template	Fri Sep 04 17:29:49 2015 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template	Thu Sep 10 14:44:32 2015 +0200
@@ -140,16 +140,24 @@
         }
 
         @ForceInline
-        static boolean compareAndSetAcquire(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
-            return UNSAFE.compareAndSwap$Type$Acquire(Objects.requireNonNull(holder),
+        static $type$ compareAndExchangeVolatile(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
+            return UNSAFE.compareAndExchange$Type$Volatile(Objects.requireNonNull(holder),
                                                handle.fieldOffset,
                                                expected,
                                                {#if[Object]?handle.fieldType.cast(value):value});
         }
 
         @ForceInline
-        static boolean compareAndSetRelease(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
-            return UNSAFE.compareAndSwap$Type$Release(Objects.requireNonNull(holder),
+        static $type$ compareAndExchangeAcquire(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
+            return UNSAFE.compareAndExchange$Type$Acquire(Objects.requireNonNull(holder),
+                                               handle.fieldOffset,
+                                               expected,
+                                               {#if[Object]?handle.fieldType.cast(value):value});
+        }
+
+        @ForceInline
+        static $type$ compareAndExchangeRelease(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
+            return UNSAFE.compareAndExchange$Type$Release(Objects.requireNonNull(holder),
                                                handle.fieldOffset,
                                                expected,
                                                {#if[Object]?handle.fieldType.cast(value):value});
@@ -315,17 +323,26 @@
                                                {#if[Object]?handle.fieldType.cast(value):value});
         }
 
+
         @ForceInline
-        static boolean compareAndSetAcquire(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
-            return UNSAFE.compareAndSwap$Type$Acquire(handle.base,
+        static $type$ compareAndExchangeVolatile(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
+            return UNSAFE.compareAndExchange$Type$Volatile(handle.base,
                                                handle.fieldOffset,
                                                expected,
                                                {#if[Object]?handle.fieldType.cast(value):value});
         }
 
         @ForceInline
-        static boolean compareAndSetRelease(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
-            return UNSAFE.compareAndSwap$Type$Release(handle.base,
+        static $type$ compareAndExchangeAcquire(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
+            return UNSAFE.compareAndExchange$Type$Acquire(handle.base,
+                                               handle.fieldOffset,
+                                               expected,
+                                               {#if[Object]?handle.fieldType.cast(value):value});
+        }
+
+        @ForceInline
+        static $type$ compareAndExchangeRelease(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
+            return UNSAFE.compareAndExchange$Type$Release(handle.base,
                                                handle.fieldOffset,
                                                expected,
                                                {#if[Object]?handle.fieldType.cast(value):value});
@@ -500,22 +517,33 @@
         }
 
         @ForceInline
-        static boolean compareAndSetAcquire(Array handle, $type$[] array, int index, $type$ expected, $type$ value) {
+        static $type$ compareAndExchangeVolatile(Array handle, $type$[] array, int index, $type$ expected, $type$ value) {
             if (index < 0 || index >= array.length) // bounds and null check
                 throw new ArrayIndexOutOfBoundsException();
 
-            return UNSAFE.compareAndSwap$Type$Acquire(array,
+            return UNSAFE.compareAndExchange$Type$Volatile(array,
                                                (((long) index) << handle.ashift) + handle.abase,
                                                expected,
                                                {#if[Object]?handle.componentType.cast(value):value});
         }
 
         @ForceInline
-        static boolean compareAndSetRelease(Array handle, Object[] array, int index, $type$ expected, $type$ value) {
+        static $type$ compareAndExchangeAcquire(Array handle, $type$[] array, int index, $type$ expected, $type$ value) {
             if (index < 0 || index >= array.length) // bounds and null check
                 throw new ArrayIndexOutOfBoundsException();
 
-            return UNSAFE.compareAndSwap$Type$Release(array,
+            return UNSAFE.compareAndExchange$Type$Acquire(array,
+                                               (((long) index) << handle.ashift) + handle.abase,
+                                               expected,
+                                               {#if[Object]?handle.componentType.cast(value):value});
+        }
+
+        @ForceInline
+        static $type$ compareAndExchangeRelease(Array handle, $type$[] array, int index, $type$ expected, $type$ value) {
+            if (index < 0 || index >= array.length) // bounds and null check
+                throw new ArrayIndexOutOfBoundsException();
+
+            return UNSAFE.compareAndExchange$Type$Release(array,
                                                (((long) index) << handle.ashift) + handle.abase,
                                                expected,
                                                {#if[Object]?handle.componentType.cast(value):value});
--- a/src/java.base/share/classes/sun/misc/Unsafe.java	Fri Sep 04 17:29:49 2015 +0300
+++ b/src/java.base/share/classes/sun/misc/Unsafe.java	Thu Sep 10 14:44:32 2015 +0200
@@ -709,6 +709,27 @@
                                                      Object expected,
                                                      Object x);
 
+    public final Object compareAndExchangeObjectVolatile(Object o, long offset,
+                                                         Object expected,
+                                                         Object x) {
+        boolean r = compareAndSwapObject(o, offset, expected, x);
+        // @@@ This is incorrect, but sufficient for now until this method is
+        //     made intrinsic and returns the actual witness on failure
+        return r ? x : getObjectVolatile(o, offset);
+    }
+
+    public final Object compareAndExchangeObjectAcquire(Object o, long offset,
+                                                        Object expected,
+                                                        Object x) {
+        return compareAndExchangeObjectVolatile(o, offset, expected, x);
+    }
+
+    public final Object compareAndExchangeObjectRelease(Object o, long offset,
+                                                        Object expected,
+                                                        Object x) {
+        return compareAndExchangeObjectVolatile(o, offset, expected, x);
+    }
+
     @HotSpotIntrinsicCandidate
     public final native boolean compareAndSwapObjectAcquire(Object o, long offset,
                                                      Object expected,
@@ -748,6 +769,27 @@
                                                   int expected,
                                                   int x);
 
+    public final int compareAndExchangeIntVolatile(Object o, long offset,
+                                                   int expected,
+                                                   int x) {
+        boolean r = compareAndSwapInt(o, offset, expected, x);
+        // @@@ This is incorrect, but sufficient for now until this method is
+        //     made intrinsic and returns the actual witness on failure
+        return r ? x : getIntVolatile(o, offset);
+    }
+
+    public final int compareAndExchangeIntAcquire(Object o, long offset,
+                                                  int expected,
+                                                  int x) {
+        return compareAndExchangeIntVolatile(o, offset, expected, x);
+    }
+
+    public final int compareAndExchangeIntRelease(Object o, long offset,
+                                                  int expected,
+                                                  int x) {
+        return compareAndExchangeIntVolatile(o, offset, expected, x);
+    }
+
     @HotSpotIntrinsicCandidate
     public final native boolean compareAndSwapIntAcquire(Object o, long offset,
                                                   int expected,
@@ -787,6 +829,27 @@
                                                    long expected,
                                                    long x);
 
+    public final long compareAndExchangeLongVolatile(Object o, long offset,
+                                                     long expected,
+                                                     long x) {
+        boolean r = compareAndSwapLong(o, offset, expected, x);
+        // @@@ This is incorrect, but sufficient for now until this method is
+        //     made intrinsic and returns the actual witness on failure
+        return r ? x : getLongVolatile(o, offset);
+    }
+
+    public final long compareAndExchangeLongAcquire(Object o, long offset,
+                                                    long expected,
+                                                    long x) {
+        return compareAndExchangeLongVolatile(o, offset, expected, x);
+    }
+
+    public final long compareAndExchangeLongRelease(Object o, long offset,
+                                                    long expected,
+                                                    long x) {
+        return compareAndExchangeLongVolatile(o, offset, expected, x);
+    }
+
     @HotSpotIntrinsicCandidate
     public final native boolean compareAndSwapLongAcquire(Object o, long offset,
                                                    long expected,
--- a/test/java/lang/invoke/X-VarHandleTest.java.template	Fri Sep 04 17:29:49 2015 +0300
+++ b/test/java/lang/invoke/X-VarHandleTest.java.template	Thu Sep 10 14:44:32 2015 +0200
@@ -88,9 +88,9 @@
                 throw new RuntimeException();
         }
 
+#if[CAS]
         vh.setRelaxed(this, $value1$);
 
-#if[CAS]
         // Compare
         {
             boolean r = vh.compareAndSet(this, $value1$, $value2$);
@@ -102,7 +102,43 @@
         }
 
         {
-            boolean r = vh.compareAndSetAcquire(this, $value2$, $value1$);
+            $type$ r = ($type$) vh.compareAndExchangeVolatile(this, $value2$, $value1$);
+            if (!Objects.equals(r, $value1$))
+                throw new RuntimeException();
+            $type$ x = ($type$) vh.getRelaxed(this);
+            if (!Objects.equals(x, $value1$))
+                throw new RuntimeException();
+        }
+
+        {
+            $type$ r = ($type$) vh.compareAndExchangeAcquire(this, $value1$, $value2$);
+            if (!Objects.equals(r, $value2$))
+                throw new RuntimeException();
+            $type$ x = ($type$) vh.getRelaxed(this);
+            if (!Objects.equals(x, $value2$))
+                throw new RuntimeException();
+        }
+
+        {
+            $type$ r = ($type$) vh.compareAndExchangeRelease(this, $value2$, $value1$);
+            if (!Objects.equals(r, $value1$))
+                throw new RuntimeException();
+            $type$ x = ($type$) vh.getRelaxed(this);
+            if (!Objects.equals(x, $value1$))
+                throw new RuntimeException();
+        }
+
+        {
+            boolean r = vh.weakCompareAndSet(this, $value1$, $value2$);
+            if (!r)
+                throw new RuntimeException();
+            $type$ x = ($type$) vh.getRelaxed(this);
+            if (!Objects.equals(x, $value2$))
+                throw new RuntimeException();
+        }
+
+        {
+            boolean r = vh.weakCompareAndSetAcquire(this, $value2$, $value1$);
             if (!r)
                 throw new RuntimeException();
             $type$ x = ($type$) vh.getRelaxed(this);
@@ -111,7 +147,7 @@
         }
 
         {
-            boolean r = vh.compareAndSetRelease(this, $value1$, $value2$);
+            boolean r = vh.weakCompareAndSetRelease(this, $value1$, $value2$);
             if (!r)
                 throw new RuntimeException();
             $type$ x = ($type$) vh.getRelaxed(this);
@@ -119,53 +155,30 @@
                 throw new RuntimeException();
         }
 
+        // Compare set and get
         {
-            boolean r = vh.weakCompareAndSet(this, $value2$, $value1$);
-            if (!r)
+            $type$ o = ($type$) vh.getAndSet(this, $value1$);
+            if (!Objects.equals(o, $value2$))
                 throw new RuntimeException();
             $type$ x = ($type$) vh.getRelaxed(this);
             if (!Objects.equals(x, $value1$))
                 throw new RuntimeException();
         }
-
-        {
-            boolean r = vh.weakCompareAndSetAcquire(this, $value1$, $value2$);
-            if (!r)
-                throw new RuntimeException();
-            $type$ x = ($type$) vh.getRelaxed(this);
-            if (!Objects.equals(x, $value2$))
-                throw new RuntimeException();
-        }
-
-        {
-            boolean r = vh.weakCompareAndSetRelease(this, $value2$, $value1$);
-            if (!r)
-                throw new RuntimeException();
-            $type$ x = ($type$) vh.getRelaxed(this);
-            if (!Objects.equals(x, $value1$))
-                throw new RuntimeException();
-        }
-
-        // Compare set and get
-        {
-            $type$ o = ($type$) vh.getAndSet(this, $value2$);
-            if (!Objects.equals(o, $value1$))
-                throw new RuntimeException();
-            $type$ x = ($type$) vh.getRelaxed(this);
-            if (!Objects.equals(x, $value2$))
-                throw new RuntimeException();
-        }
 #else[CAS]
         checkUOE(() -> {
             boolean r = vh.compareAndSet(this, $value1$, $value2$);
         });
 
         checkUOE(() -> {
-            boolean r = vh.compareAndSetAcquire(this, $value1$, $value2$);
+            $type$ r = ($type$) vh.compareAndExchangeVolatile(this, $value1$, $value2$);
         });
 
         checkUOE(() -> {
-            boolean r = vh.compareAndSetRelease(this, $value1$, $value2$);
+            $type$ r = ($type$) vh.compareAndExchangeAcquire(this, $value1$, $value2$);
+        });
+
+        checkUOE(() -> {
+            $type$ r = ($type$) vh.compareAndExchangeRelease(this, $value1$, $value2$);
         });
 
         checkUOE(() -> {
@@ -182,14 +195,16 @@
 #end[CAS]
 
 #if[AtomicAdd]
+        vh.setRelaxed(this, $value1$);
+
         // get and add, add and get
         {
             $type$ o = ($type$) vh.getAndAdd(this, $value3$);
-            if (o != $value2$)
+            if (o != $value1$)
                 throw new RuntimeException();
 
             $type$ c = ($type$) vh.addAndGet(this, $value3$);
-            if (c != $value2$ + $value3$ + $value3$)
+            if (c != $value1$ + $value3$ + $value3$)
                 throw new RuntimeException();
         }
 #else[AtomicAdd]
@@ -241,9 +256,9 @@
                 throw new RuntimeException();
         }
 
+#if[CAS]
         vh.setRelaxed($value1$);
 
-#if[CAS]
         // Compare
         {
             boolean r = vh.compareAndSet($value1$, $value2$);
@@ -255,7 +270,43 @@
         }
 
         {
-            boolean r = vh.compareAndSetAcquire($value2$, $value1$);
+            $type$ r = ($type$) vh.compareAndExchangeVolatile($value2$, $value1$);
+            if (!Objects.equals(r, $value1$))
+                throw new RuntimeException();
+            $type$ x = ($type$) vh.getRelaxed();
+            if (!Objects.equals(x, $value1$))
+                throw new RuntimeException();
+        }
+
+        {
+            $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value2$);
+            if (!Objects.equals(r, $value2$))
+                throw new RuntimeException();
+            $type$ x = ($type$) vh.getRelaxed();
+            if (!Objects.equals(x, $value2$))
+                throw new RuntimeException();
+        }
+
+        {
+            $type$ r = ($type$) vh.compareAndExchangeRelease($value2$, $value1$);
+            if (!Objects.equals(r, $value1$))
+                throw new RuntimeException();
+            $type$ x = ($type$) vh.getRelaxed();
+            if (!Objects.equals(x, $value1$))
+                throw new RuntimeException();
+        }
+
+        {
+            boolean r = vh.weakCompareAndSet($value1$, $value2$);
+            if (!r)
+                throw new RuntimeException();
+            $type$ x = ($type$) vh.getRelaxed();
+            if (!Objects.equals(x, $value2$))
+                throw new RuntimeException();
+        }
+
+        {
+            boolean r = vh.weakCompareAndSetAcquire($value2$, $value1$);
             if (!r)
                 throw new RuntimeException();
             $type$ x = ($type$) vh.getRelaxed();
@@ -264,7 +315,7 @@
         }
 
         {
-            boolean r = vh.compareAndSetRelease($value1$, $value2$);
+            boolean r = vh.weakCompareAndSetRelease($value1$, $value2$);
             if (!r)
                 throw new RuntimeException();
             $type$ x = ($type$) vh.getRelaxed();
@@ -272,53 +323,30 @@
                 throw new RuntimeException();
         }
 
+        // Compare set and get
         {
-            boolean r = vh.weakCompareAndSet($value2$, $value1$);
-            if (!r)
+            $type$ o = ($type$) vh.getAndSet($value1$);
+            if (!Objects.equals(o, $value2$))
                 throw new RuntimeException();
             $type$ x = ($type$) vh.getRelaxed();
             if (!Objects.equals(x, $value1$))
                 throw new RuntimeException();
         }
-
-        {
-            boolean r = vh.weakCompareAndSetAcquire($value1$, $value2$);
-            if (!r)
-                throw new RuntimeException();
-            $type$ x = ($type$) vh.getRelaxed();
-            if (!Objects.equals(x, $value2$))
-                throw new RuntimeException();
-        }
-
-        {
-            boolean r = vh.weakCompareAndSetRelease($value2$, $value1$);
-            if (!r)
-                throw new RuntimeException();
-            $type$ x = ($type$) vh.getRelaxed();
-            if (!Objects.equals(x, $value1$))
-                throw new RuntimeException();
-        }
-
-        // Compare set and get
-        {
-            $type$ o = ($type$) vh.getAndSet($value2$);
-            if (!Objects.equals(o, $value1$))
-                throw new RuntimeException();
-            $type$ x = ($type$) vh.getRelaxed();
-            if (!Objects.equals(x, $value2$))
-                throw new RuntimeException();
-        }
 #else[CAS]
         checkUOE(() -> {
             boolean r = vh.compareAndSet($value1$, $value2$);
         });
 
         checkUOE(() -> {
-            boolean r = vh.compareAndSetAcquire($value1$, $value2$);
+            $type$ r = ($type$) vh.compareAndExchangeVolatile($value1$, $value2$);
         });
 
         checkUOE(() -> {
-            boolean r = vh.compareAndSetRelease($value1$, $value2$);
+            $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value2$);
+        });
+
+        checkUOE(() -> {
+            $type$ r = ($type$) vh.compareAndExchangeRelease($value1$, $value2$);
         });
 
         checkUOE(() -> {
@@ -335,14 +363,16 @@
 #end[CAS]
 
 #if[AtomicAdd]
+        vh.setRelaxed($value1$);
+
         // get and add, add and get
         {
             $type$ o = ($type$) vh.getAndAdd($value3$);
-            if (o != $value2$)
+            if (o != $value1$)
                 throw new RuntimeException();
 
             $type$ c = ($type$) vh.addAndGet($value3$);
-            if (c != $value2$ + $value3$ + $value3$)
+            if (c != $value1$ + $value3$ + $value3$)
                 throw new RuntimeException();
         }
 #else[AtomicAdd]
@@ -397,9 +427,9 @@
                     throw new RuntimeException();
             }
 
+#if[CAS]
             vh.setRelaxed(array, i, $value1$);
 
-#if[CAS]
             // Compare
             {
                 boolean r = vh.compareAndSet(array, i, $value1$, $value2$);
@@ -411,7 +441,43 @@
             }
     
             {
-                boolean r = vh.compareAndSetAcquire(array, i, $value2$, $value1$);
+                $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, $value2$, $value1$);
+                if (!Objects.equals(r, $value1$))
+                    throw new RuntimeException();
+                $type$ x = ($type$) vh.getRelaxed(array, i);
+                if (!Objects.equals(x, $value1$))
+                    throw new RuntimeException();
+            }
+    
+            {
+                $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, $value1$, $value2$);
+                if (!Objects.equals(r, $value2$))
+                    throw new RuntimeException();
+                $type$ x = ($type$) vh.getRelaxed(array, i);
+                if (!Objects.equals(x, $value2$))
+                    throw new RuntimeException();
+            }
+
+            {
+                $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, $value2$, $value1$);
+                if (!Objects.equals(r, $value1$))
+                    throw new RuntimeException();
+                $type$ x = ($type$) vh.getRelaxed(array, i);
+                if (!Objects.equals(x, $value1$))
+                    throw new RuntimeException();
+            }
+
+            {
+                boolean r = vh.weakCompareAndSet(array, i, $value1$, $value2$);
+                if (!r)
+                    throw new RuntimeException();
+                $type$ x = ($type$) vh.getRelaxed(array, i);
+                if (!Objects.equals(x, $value2$))
+                    throw new RuntimeException();
+            }
+    
+            {
+                boolean r = vh.weakCompareAndSetAcquire(array, i, $value2$, $value1$);
                 if (!r)
                     throw new RuntimeException();
                 $type$ x = ($type$) vh.getRelaxed(array, i);
@@ -420,7 +486,7 @@
             }
     
             {
-                boolean r = vh.compareAndSetRelease(array, i, $value1$, $value2$);
+                boolean r = vh.weakCompareAndSetRelease(array, i, $value1$, $value2$);
                 if (!r)
                     throw new RuntimeException();
                 $type$ x = ($type$) vh.getRelaxed(array, i);
@@ -428,53 +494,30 @@
                     throw new RuntimeException();
             }
     
+            // Compare set and get
             {
-                boolean r = vh.weakCompareAndSet(array, i, $value2$, $value1$);
-                if (!r)
+                $type$ o = ($type$) vh.getAndSet(array, i, $value1$);
+                if (!Objects.equals(o, $value2$))
                     throw new RuntimeException();
                 $type$ x = ($type$) vh.getRelaxed(array, i);
                 if (!Objects.equals(x, $value1$))
                     throw new RuntimeException();
             }
-    
-            {
-                boolean r = vh.weakCompareAndSetAcquire(array, i, $value1$, $value2$);
-                if (!r)
-                    throw new RuntimeException();
-                $type$ x = ($type$) vh.getRelaxed(array, i);
-                if (!Objects.equals(x, $value2$))
-                    throw new RuntimeException();
-            }
-    
-            {
-                boolean r = vh.weakCompareAndSetRelease(array, i, $value2$, $value1$);
-                if (!r)
-                    throw new RuntimeException();
-                $type$ x = ($type$) vh.getRelaxed(array, i);
-                if (!Objects.equals(x, $value1$))
-                    throw new RuntimeException();
-            }
-    
-            // Compare set and get
-            {
-                $type$ o = ($type$) vh.getAndSet(array, i, $value2$);
-                if (!Objects.equals(o, $value1$))
-                    throw new RuntimeException();
-                $type$ x = ($type$) vh.getRelaxed(array, i);
-                if (!Objects.equals(x, $value2$))
-                    throw new RuntimeException();
-            }
 #else[CAS]
             checkUOE(() -> {
                 boolean r = vh.compareAndSet(array, ci, $value1$, $value2$);
             });
 
             checkUOE(() -> {
-                boolean r = vh.compareAndSetAcquire(array, ci, $value1$, $value2$);
+                $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, $value1$, $value2$);
             });
 
             checkUOE(() -> {
-                boolean r = vh.compareAndSetRelease(array, ci, $value1$, $value2$);
+                $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, $value1$, $value2$);
+            });
+
+            checkUOE(() -> {
+                $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, $value1$, $value2$);
             });
 
             checkUOE(() -> {
@@ -491,14 +534,16 @@
 #end[CAS]
 
 #if[AtomicAdd]
+            vh.setRelaxed(array, i, $value1$);
+
             // get and add, add and get
             {
                 $type$ o = ($type$) vh.getAndAdd(array, i, $value3$);
-                if (o != $value2$)
+                if (o != $value1$)
                     throw new RuntimeException();
     
                 $type$ c = ($type$) vh.addAndGet(array, i, $value3$);
-                if (c != $value2$ + $value3$ + $value3$)
+                if (c != $value1$ + $value3$ + $value3$)
                     throw new RuntimeException();
             }
 #else[AtomicAdd]