changeset 14347:6929d396c267

8154755: Add a VarHandle weakCompareAndSet with volatile semantics Reviewed-by: shade, vlivanov
author psandoz
date Fri, 29 Apr 2016 13:46:19 -0700
parents daefa1109859
children c15926d86fb1
files src/java.base/share/classes/java/lang/invoke/VarHandle.java src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template test/java/lang/invoke/VarHandles/VarHandleBaseTest.java test/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java test/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java test/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java test/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java test/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java test/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java test/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java test/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java test/java/lang/invoke/VarHandles/VarHandleTestAccessString.java test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeInt.java test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeLong.java test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeString.java test/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template test/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template test/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template test/java/lang/invoke/VarHandles/X-VarHandleTestMethodType.java.template
diffstat 29 files changed, 1098 insertions(+), 152 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Fri Apr 29 13:46:19 2016 -0700
@@ -136,6 +136,7 @@
  * consists of the methods
  * {@link #compareAndSet compareAndSet},
  * {@link #weakCompareAndSet weakCompareAndSet},
+ * {@link #weakCompareAndSetVolatile weakCompareAndSetVolatile},
  * {@link #weakCompareAndSetAcquire weakCompareAndSetAcquire},
  * {@link #weakCompareAndSetRelease weakCompareAndSetRelease},
  * {@link #compareAndExchangeAcquire compareAndExchangeAcquire},
@@ -458,7 +459,7 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code get}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.get)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.GET)} on this VarHandle.
      *
      * <p>This access mode is supported by all VarHandle instances and never
      * throws {@code UnsupportedOperationException}.
@@ -488,7 +489,7 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code set}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.set)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.SET)} on this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T newValue)}
@@ -516,7 +517,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code getVolatile}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.getVolatile)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.GET_VOLATILE)} on this
+     * VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT)}
@@ -544,7 +546,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code setVolatile}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.setVolatile)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.SET_VOLATILE)} on this
+     * VarHandle.
      *
      * @apiNote
      * Ignoring the many semantic differences from C and C++, this method has
@@ -574,7 +577,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code getOpaque}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.getOpaque)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.GET_OPAQUE)} on this
+     * VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT)}
@@ -603,7 +607,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code setOpaque}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.setOpaque)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.SET_OPAQUE)} on this
+     * VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T newValue)}
@@ -631,7 +636,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code getAcquire}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.getAcquire)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.GET_ACQUIRE)} on this
+     * VarHandle.
      *
      * @apiNote
      * Ignoring the many semantic differences from C and C++, this method has
@@ -664,7 +670,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code setRelease}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.setRelease)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.SET_RELEASE)} on this
+     * VarHandle.
      *
      * @apiNote
      * Ignoring the many semantic differences from C and C++, this method has
@@ -700,7 +707,7 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code
      * compareAndSet} must match the access mode type that is the result of
-     * calling {@code accessModeType(VarHandle.AccessMode.compareAndSet)} on
+     * calling {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_SET)} on
      * this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
@@ -734,7 +741,7 @@
      * <p>The symbolic type descriptor at the call site of {@code
      * compareAndExchangeVolatile}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.compareAndExchangeVolatile)}
+     * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE)}
      * on this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
@@ -769,7 +776,7 @@
      * <p>The symbolic type descriptor at the call site of {@code
      * compareAndExchangeAcquire}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.compareAndExchangeAcquire)} on
+     * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)} on
      * this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
@@ -804,7 +811,8 @@
      * <p>The symbolic type descriptor at the call site of {@code
      * compareAndExchangeRelease}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.compareAndExchangeRelease)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)}
+     * on this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T expectedValue, T newValue)}
@@ -836,14 +844,14 @@
      * {@link #get}.
      *
      * <p>This operation may fail spuriously (typically, due to memory
-     * contention) even if the current value does match the expected value.
+     * contention) even if the witness value does match the expected value.
      *
      * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
      *
      * <p>The symbolic type descriptor at the call site of {@code
      * weakCompareAndSet} must match the access mode type that is the result of
-     * calling {@code accessModeType(VarHandle.AccessMode.weakCompareAndSet)} on
-     * this VarHandle.
+     * calling {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)}
+     * on this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T expectedValue, T newValue)}
@@ -867,20 +875,58 @@
 
     /**
      * Possibly atomically sets the value of a variable to the {@code newValue}
+     * with the memory semantics of {@link #setVolatile} if the variable's
+     * current value, referred to as the <em>witness value</em>, {@code ==} the
+     * {@code expectedValue}, as accessed with the memory semantics of
+     * {@link #getVolatile}.
+     *
+     * <p>This operation may fail spuriously (typically, due to memory
+     * contention) even if the witness value does match the expected value.
+     *
+     * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code
+     * weakCompareAndSetVolatile} must match the access mode type that is the
+     * result of calling {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE)}
+     * on this VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT, T expectedValue, T newValue)}
+     * , statically represented using varargs.
+     * @return {@code true} if successful, otherwise {@code false} if the
+     * witness value was not the same as the {@code expectedValue} or if this
+     * operation spuriously failed.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type is not
+     * compatible with the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type is compatible with the
+     * caller's symbolic type descriptor, but a reference cast fails.
+     * @see #setVolatile(Object...)
+     * @see #getVolatile(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    @HotSpotIntrinsicCandidate
+    boolean weakCompareAndSetVolatile(Object... args);
+
+    /**
+     * Possibly atomically sets the value of a variable to the {@code newValue}
      * with the semantics of {@link #set} if the variable's current value,
      * referred to as the <em>witness value</em>, {@code ==} the
      * {@code expectedValue}, as accessed with the memory semantics of
      * {@link #getAcquire}.
      *
      * <p>This operation may fail spuriously (typically, due to memory
-     * contention) even if the current value does match the expected value.
+     * contention) even if the witness value does match the expected value.
      *
      * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
      *
      * <p>The symbolic type descriptor at the call site of {@code
      * weakCompareAndSetAcquire}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.weakCompareAndSetAcquire)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)}
+     * on this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T expectedValue, T newValue)}
@@ -910,14 +956,15 @@
      * {@link #get}.
      *
      * <p>This operation may fail spuriously (typically, due to memory
-     * contention) even if the current value does match the expected value.
+     * contention) even if the witness value does match the expected value.
      *
      * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
      *
      * <p>The symbolic type descriptor at the call site of {@code
      * weakCompareAndSetRelease}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.weakCompareAndSetRelease)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)}
+     * on this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T expectedValue, T newValue)}
@@ -949,7 +996,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code getAndSet}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.getAndSet)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_SET)} on this
+     * VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T newValue)}
@@ -985,7 +1033,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code getAndAdd}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.getAndAdd)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_ADD)} on this
+     * VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T value)}
@@ -1017,7 +1066,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code addAndGet}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.addAndGet)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.ADD_AND_GET)} on this
+     * VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T value)}
@@ -1083,109 +1133,115 @@
          * method
          * {@link VarHandle#get VarHandle.get}
          */
-        GET("get", AccessType.GET, Object.class),   // 0
+        GET("get", AccessType.GET, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#set VarHandle.set}
          */
-        SET("set", AccessType.SET, void.class),     // 1
+        SET("set", AccessType.SET, void.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getVolatile VarHandle.getVolatile}
          */
-        GET_VOLATILE("getVolatile", AccessType.GET, Object.class),  // 2
+        GET_VOLATILE("getVolatile", AccessType.GET, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#setVolatile VarHandle.setVolatile}
          */
-        SET_VOLATILE("setVolatile", AccessType.SET, void.class),    // 3
+        SET_VOLATILE("setVolatile", AccessType.SET, void.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getAcquire VarHandle.getAcquire}
          */
-        GET_ACQUIRE("getAcquire", AccessType.GET, Object.class),   // 4
+        GET_ACQUIRE("getAcquire", AccessType.GET, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#setRelease VarHandle.setRelease}
          */
-        SET_RELEASE("setRelease", AccessType.SET, void.class),     // 5
+        SET_RELEASE("setRelease", AccessType.SET, void.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getOpaque VarHandle.getOpaque}
          */
-        GET_OPAQUE("getOpaque", AccessType.GET, Object.class),    // 6
+        GET_OPAQUE("getOpaque", AccessType.GET, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#setOpaque VarHandle.setOpaque}
          */
-        SET_OPAQUE("setOpaque", AccessType.SET, void.class),      // 7
+        SET_OPAQUE("setOpaque", AccessType.SET, void.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndSet VarHandle.compareAndSet}
          */
-        COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),    // 8
+        COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndExchangeVolatile VarHandle.compareAndExchangeVolatile}
          */
-        COMPARE_AND_EXCHANGE_VOLATILE("compareAndExchangeVolatile", AccessType.COMPARE_AND_EXCHANGE, Object.class), // 9
+        COMPARE_AND_EXCHANGE_VOLATILE("compareAndExchangeVolatile", AccessType.COMPARE_AND_EXCHANGE, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndExchangeAcquire VarHandle.compareAndExchangeAcquire}
          */
-        COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE, Object.class),  // 10
+        COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndExchangeRelease VarHandle.compareAndExchangeRelease}
          */
-        COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE, Object.class),  // 11
+        COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#weakCompareAndSet VarHandle.weakCompareAndSet}
          */
-        WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),        // 12
+        WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#weakCompareAndSetVolatile VarHandle.weakCompareAndSetVolatile}
+         */
+        WEAK_COMPARE_AND_SET_VOLATILE("weakCompareAndSetVolatile", AccessType.COMPARE_AND_SWAP, boolean.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#weakCompareAndSetAcquire VarHandle.weakCompareAndSetAcquire}
          */
-        WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SWAP, boolean.class), // 13
+        WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SWAP, boolean.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#weakCompareAndSetRelease VarHandle.weakCompareAndSetRelease}
          */
-        WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SWAP, boolean.class), // 14
+        WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SWAP, boolean.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getAndSet VarHandle.getAndSet}
          */
-        GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE, Object.class),   // 15
+        GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getAndAdd VarHandle.getAndAdd}
          */
-        GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE, Object.class),   // 16
+        GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#addAndGet VarHandle.addAndGet}
          */
-        ADD_AND_GET("addAndGet", AccessType.GET_AND_UPDATE, Object.class),   // 17
+        ADD_AND_GET("addAndGet", AccessType.GET_AND_UPDATE, Object.class),
         ;
 
         static final Map<String, AccessMode> methodNameToAccessMode;
--- a/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template	Fri Apr 29 23:15:15 2016 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template	Fri Apr 29 13:46:19 2016 -0700
@@ -155,6 +155,15 @@
         }
 
         @ForceInline
+        static boolean weakCompareAndSetVolatile(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
+            // TODO defer to strong form until new Unsafe method is added
+            return UNSAFE.compareAndSwap$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
+                                               handle.fieldOffset,
+                                               {#if[Object]?handle.fieldType.cast(expected):expected},
+                                               {#if[Object]?handle.fieldType.cast(value):value});
+        }
+
+        @ForceInline
         static boolean weakCompareAndSetAcquire(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
             return UNSAFE.weakCompareAndSwap$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
                                                handle.fieldOffset,
@@ -319,6 +328,15 @@
         }
 
         @ForceInline
+        static boolean weakCompareAndSetVolatile(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
+            // TODO defer to strong form until new Unsafe method is added
+            return UNSAFE.compareAndSwap$Type$(handle.base,
+                                               handle.fieldOffset,
+                                               {#if[Object]?handle.fieldType.cast(expected):expected},
+                                               {#if[Object]?handle.fieldType.cast(value):value});
+        }
+
+        @ForceInline
         static boolean weakCompareAndSetAcquire(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
             return UNSAFE.weakCompareAndSwap$Type$Acquire(handle.base,
                                                handle.fieldOffset,
@@ -535,6 +553,20 @@
         }
 
         @ForceInline
+        static boolean weakCompareAndSetVolatile(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
+#if[Object]
+            Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+            $type$[] array = ($type$[]) oarray;
+#end[Object]
+            // TODO defer to strong form until new Unsafe method is added
+            return UNSAFE.compareAndSwap$Type$(array,
+                    (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+                    {#if[Object]?handle.componentType.cast(expected):expected},
+                    {#if[Object]?handle.componentType.cast(value):value});
+        }
+
+        @ForceInline
         static boolean weakCompareAndSetAcquire(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
--- a/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template	Fri Apr 29 23:15:15 2016 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template	Fri Apr 29 13:46:19 2016 -0700
@@ -228,6 +228,16 @@
         }
 
         @ForceInline
+        static boolean weakCompareAndSetVolatile(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
+            byte[] ba = (byte[]) oba;
+            // TODO defer to strong form until new Unsafe method is added
+            return UNSAFE.compareAndSwap$RawType$(
+                    ba,
+                    address(ba, index(ba, index)),
+                    convEndian(handle.be, expected), convEndian(handle.be, value));
+        }
+
+        @ForceInline
         static boolean weakCompareAndSetAcquire(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
             byte[] ba = (byte[]) oba;
             return UNSAFE.weakCompareAndSwap$RawType$Acquire(
@@ -444,6 +454,16 @@
         }
 
         @ForceInline
+        static boolean weakCompareAndSetVolatile(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
+            ByteBuffer bb = (ByteBuffer) obb;
+            // TODO defer to strong form until new Unsafe method is added
+            return UNSAFE.compareAndSwap$RawType$(
+                    UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+                    address(bb, indexRO(bb, index)),
+                    convEndian(handle.be, expected), convEndian(handle.be, value));
+        }
+
+        @ForceInline
         static boolean weakCompareAndSetAcquire(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
             ByteBuffer bb = (ByteBuffer) obb;
             return UNSAFE.weakCompareAndSwap$RawType$Acquire(
--- a/test/java/lang/invoke/VarHandles/VarHandleBaseTest.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleBaseTest.java	Fri Apr 29 13:46:19 2016 -0700
@@ -148,6 +148,7 @@
         COMPARE_AND_EXCHANGE_ACQUIRE(TestAccessType.COMPARE_AND_EXCHANGE),
         COMPARE_AND_EXCHANGE_RELEASE(TestAccessType.COMPARE_AND_EXCHANGE),
         WEAK_COMPARE_AND_SET(TestAccessType.COMPARE_AND_SET),
+        WEAK_COMPARE_AND_SET_VOLATILE(TestAccessType.COMPARE_AND_SET),
         WEAK_COMPARE_AND_SET_ACQUIRE(TestAccessType.COMPARE_AND_SET),
         WEAK_COMPARE_AND_SET_RELEASE(TestAccessType.COMPARE_AND_SET),
         GET_AND_SET(TestAccessType.GET_AND_SET),
--- a/test/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java	Fri Apr 29 13:46:19 2016 -0700
@@ -104,6 +104,7 @@
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -280,6 +281,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, true, false);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, true, false);
         });
 
@@ -362,6 +367,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(true, false);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(true, false);
         });
 
@@ -434,6 +443,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, true, false);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, true, false);
         });
 
@@ -506,6 +519,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(true, false);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(true, false);
         });
 
@@ -585,6 +602,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(array, i, true, false);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(array, i, true, false);
         });
 
--- a/test/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java	Fri Apr 29 13:46:19 2016 -0700
@@ -104,6 +104,7 @@
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -280,6 +281,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, (byte)1, (byte)2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, (byte)1, (byte)2);
         });
 
@@ -362,6 +367,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile((byte)1, (byte)2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire((byte)1, (byte)2);
         });
 
@@ -434,6 +443,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, (byte)1, (byte)2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, (byte)1, (byte)2);
         });
 
@@ -506,6 +519,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile((byte)1, (byte)2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire((byte)1, (byte)2);
         });
 
@@ -585,6 +602,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(array, i, (byte)1, (byte)2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(array, i, (byte)1, (byte)2);
         });
 
--- a/test/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java	Fri Apr 29 13:46:19 2016 -0700
@@ -104,6 +104,7 @@
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -280,6 +281,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, 'a', 'b');
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, 'a', 'b');
         });
 
@@ -362,6 +367,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile('a', 'b');
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire('a', 'b');
         });
 
@@ -434,6 +443,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, 'a', 'b');
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, 'a', 'b');
         });
 
@@ -506,6 +519,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile('a', 'b');
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire('a', 'b');
         });
 
@@ -585,6 +602,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(array, i, 'a', 'b');
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(array, i, 'a', 'b');
         });
 
--- a/test/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java	Fri Apr 29 13:46:19 2016 -0700
@@ -104,6 +104,7 @@
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -280,6 +281,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, 1.0d, 2.0d);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, 1.0d, 2.0d);
         });
 
@@ -362,6 +367,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(1.0d, 2.0d);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(1.0d, 2.0d);
         });
 
@@ -434,6 +443,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, 1.0d, 2.0d);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, 1.0d, 2.0d);
         });
 
@@ -506,6 +519,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(1.0d, 2.0d);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(1.0d, 2.0d);
         });
 
@@ -585,6 +602,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(array, i, 1.0d, 2.0d);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(array, i, 1.0d, 2.0d);
         });
 
--- a/test/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java	Fri Apr 29 13:46:19 2016 -0700
@@ -104,6 +104,7 @@
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -280,6 +281,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, 1.0f, 2.0f);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, 1.0f, 2.0f);
         });
 
@@ -362,6 +367,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(1.0f, 2.0f);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(1.0f, 2.0f);
         });
 
@@ -434,6 +443,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, 1.0f, 2.0f);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, 1.0f, 2.0f);
         });
 
@@ -506,6 +519,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(1.0f, 2.0f);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(1.0f, 2.0f);
         });
 
@@ -585,6 +602,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(array, i, 1.0f, 2.0f);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(array, i, 1.0f, 2.0f);
         });
 
--- a/test/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java	Fri Apr 29 13:46:19 2016 -0700
@@ -104,6 +104,7 @@
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -421,12 +422,19 @@
             assertEquals(x, 2, "weakCompareAndSetRelease int");
         }
 
+        {
+            boolean r = vh.weakCompareAndSetVolatile(recv, 2, 1);
+            assertEquals(r, true, "weakCompareAndSetVolatile int");
+            int x = (int) vh.get(recv);
+            assertEquals(x, 1, "weakCompareAndSetVolatile int value");
+        }
+
         // Compare set and get
         {
-            int o = (int) vh.getAndSet(recv, 1);
-            assertEquals(o, 2, "getAndSet int");
+            int o = (int) vh.getAndSet(recv, 2);
+            assertEquals(o, 1, "getAndSet int");
             int x = (int) vh.get(recv);
-            assertEquals(x, 1, "getAndSet int value");
+            assertEquals(x, 2, "getAndSet int value");
         }
 
         vh.set(recv, 1);
@@ -549,18 +557,25 @@
         }
 
         {
-            boolean r = (boolean) vh.weakCompareAndSetRelease( 1, 2);
+            boolean r = (boolean) vh.weakCompareAndSetRelease(1, 2);
             assertEquals(r, true, "weakCompareAndSetRelease int");
             int x = (int) vh.get();
             assertEquals(x, 2, "weakCompareAndSetRelease int");
         }
 
+        {
+            boolean r = (boolean) vh.weakCompareAndSetVolatile(2, 1);
+            assertEquals(r, true, "weakCompareAndSetVolatile int");
+            int x = (int) vh.get();
+            assertEquals(x, 1, "weakCompareAndSetVolatile int value");
+        }
+
         // Compare set and get
         {
-            int o = (int) vh.getAndSet( 1);
-            assertEquals(o, 2, "getAndSet int");
+            int o = (int) vh.getAndSet( 2);
+            assertEquals(o, 1, "getAndSet int");
             int x = (int) vh.get();
-            assertEquals(x, 1, "getAndSet int value");
+            assertEquals(x, 2, "getAndSet int value");
         }
 
         vh.set(1);
@@ -692,12 +707,19 @@
                 assertEquals(x, 2, "weakCompareAndSetRelease int");
             }
 
+            {
+                boolean r = vh.weakCompareAndSetVolatile(array, i, 2, 1);
+                assertEquals(r, true, "weakCompareAndSetVolatile int");
+                int x = (int) vh.get(array, i);
+                assertEquals(x, 1, "weakCompareAndSetVolatile int value");
+            }
+
             // Compare set and get
             {
-                int o = (int) vh.getAndSet(array, i, 1);
-                assertEquals(o, 2, "getAndSet int");
+                int o = (int) vh.getAndSet(array, i, 2);
+                assertEquals(o, 1, "getAndSet int");
                 int x = (int) vh.get(array, i);
-                assertEquals(x, 1, "getAndSet int value");
+                assertEquals(x, 2, "getAndSet int value");
             }
 
             vh.set(array, i, 1);
@@ -778,6 +800,10 @@
             });
 
             checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, 1, 2);
+            });
+
+            checkIOOBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, 1, 2);
             });
 
--- a/test/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java	Fri Apr 29 13:46:19 2016 -0700
@@ -104,6 +104,7 @@
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -421,12 +422,19 @@
             assertEquals(x, 2L, "weakCompareAndSetRelease long");
         }
 
+        {
+            boolean r = vh.weakCompareAndSetVolatile(recv, 2L, 1L);
+            assertEquals(r, true, "weakCompareAndSetVolatile long");
+            long x = (long) vh.get(recv);
+            assertEquals(x, 1L, "weakCompareAndSetVolatile long value");
+        }
+
         // Compare set and get
         {
-            long o = (long) vh.getAndSet(recv, 1L);
-            assertEquals(o, 2L, "getAndSet long");
+            long o = (long) vh.getAndSet(recv, 2L);
+            assertEquals(o, 1L, "getAndSet long");
             long x = (long) vh.get(recv);
-            assertEquals(x, 1L, "getAndSet long value");
+            assertEquals(x, 2L, "getAndSet long value");
         }
 
         vh.set(recv, 1L);
@@ -549,18 +557,25 @@
         }
 
         {
-            boolean r = (boolean) vh.weakCompareAndSetRelease( 1L, 2L);
+            boolean r = (boolean) vh.weakCompareAndSetRelease(1L, 2L);
             assertEquals(r, true, "weakCompareAndSetRelease long");
             long x = (long) vh.get();
             assertEquals(x, 2L, "weakCompareAndSetRelease long");
         }
 
+        {
+            boolean r = (boolean) vh.weakCompareAndSetVolatile(2L, 1L);
+            assertEquals(r, true, "weakCompareAndSetVolatile long");
+            long x = (long) vh.get();
+            assertEquals(x, 1L, "weakCompareAndSetVolatile long value");
+        }
+
         // Compare set and get
         {
-            long o = (long) vh.getAndSet( 1L);
-            assertEquals(o, 2L, "getAndSet long");
+            long o = (long) vh.getAndSet( 2L);
+            assertEquals(o, 1L, "getAndSet long");
             long x = (long) vh.get();
-            assertEquals(x, 1L, "getAndSet long value");
+            assertEquals(x, 2L, "getAndSet long value");
         }
 
         vh.set(1L);
@@ -692,12 +707,19 @@
                 assertEquals(x, 2L, "weakCompareAndSetRelease long");
             }
 
+            {
+                boolean r = vh.weakCompareAndSetVolatile(array, i, 2L, 1L);
+                assertEquals(r, true, "weakCompareAndSetVolatile long");
+                long x = (long) vh.get(array, i);
+                assertEquals(x, 1L, "weakCompareAndSetVolatile long value");
+            }
+
             // Compare set and get
             {
-                long o = (long) vh.getAndSet(array, i, 1L);
-                assertEquals(o, 2L, "getAndSet long");
+                long o = (long) vh.getAndSet(array, i, 2L);
+                assertEquals(o, 1L, "getAndSet long");
                 long x = (long) vh.get(array, i);
-                assertEquals(x, 1L, "getAndSet long value");
+                assertEquals(x, 2L, "getAndSet long value");
             }
 
             vh.set(array, i, 1L);
@@ -778,6 +800,10 @@
             });
 
             checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, 1L, 2L);
+            });
+
+            checkIOOBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, 1L, 2L);
             });
 
--- a/test/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java	Fri Apr 29 13:46:19 2016 -0700
@@ -104,6 +104,7 @@
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -280,6 +281,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, (short)1, (short)2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, (short)1, (short)2);
         });
 
@@ -362,6 +367,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile((short)1, (short)2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire((short)1, (short)2);
         });
 
@@ -434,6 +443,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, (short)1, (short)2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, (short)1, (short)2);
         });
 
@@ -506,6 +519,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile((short)1, (short)2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire((short)1, (short)2);
         });
 
@@ -585,6 +602,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(array, i, (short)1, (short)2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(array, i, (short)1, (short)2);
         });
 
--- a/test/java/lang/invoke/VarHandles/VarHandleTestAccessString.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestAccessString.java	Fri Apr 29 13:46:19 2016 -0700
@@ -104,6 +104,7 @@
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -435,12 +436,19 @@
             assertEquals(x, "bar", "weakCompareAndSetRelease String");
         }
 
+        {
+            boolean r = vh.weakCompareAndSetVolatile(recv, "bar", "foo");
+            assertEquals(r, true, "weakCompareAndSetVolatile String");
+            String x = (String) vh.get(recv);
+            assertEquals(x, "foo", "weakCompareAndSetVolatile String value");
+        }
+
         // Compare set and get
         {
-            String o = (String) vh.getAndSet(recv, "foo");
-            assertEquals(o, "bar", "getAndSet String");
+            String o = (String) vh.getAndSet(recv, "bar");
+            assertEquals(o, "foo", "getAndSet String");
             String x = (String) vh.get(recv);
-            assertEquals(x, "foo", "getAndSet String value");
+            assertEquals(x, "bar", "getAndSet String value");
         }
 
     }
@@ -561,18 +569,25 @@
         }
 
         {
-            boolean r = (boolean) vh.weakCompareAndSetRelease( "foo", "bar");
+            boolean r = (boolean) vh.weakCompareAndSetRelease("foo", "bar");
             assertEquals(r, true, "weakCompareAndSetRelease String");
             String x = (String) vh.get();
             assertEquals(x, "bar", "weakCompareAndSetRelease String");
         }
 
+        {
+            boolean r = (boolean) vh.weakCompareAndSetVolatile("bar", "foo");
+            assertEquals(r, true, "weakCompareAndSetVolatile String");
+            String x = (String) vh.get();
+            assertEquals(x, "foo", "weakCompareAndSetVolatile String value");
+        }
+
         // Compare set and get
         {
-            String o = (String) vh.getAndSet( "foo");
-            assertEquals(o, "bar", "getAndSet String");
+            String o = (String) vh.getAndSet( "bar");
+            assertEquals(o, "foo", "getAndSet String");
             String x = (String) vh.get();
-            assertEquals(x, "foo", "getAndSet String value");
+            assertEquals(x, "bar", "getAndSet String value");
         }
 
     }
@@ -702,12 +717,19 @@
                 assertEquals(x, "bar", "weakCompareAndSetRelease String");
             }
 
+            {
+                boolean r = vh.weakCompareAndSetVolatile(array, i, "bar", "foo");
+                assertEquals(r, true, "weakCompareAndSetVolatile String");
+                String x = (String) vh.get(array, i);
+                assertEquals(x, "foo", "weakCompareAndSetVolatile String value");
+            }
+
             // Compare set and get
             {
-                String o = (String) vh.getAndSet(array, i, "foo");
-                assertEquals(o, "bar", "getAndSet String");
+                String o = (String) vh.getAndSet(array, i, "bar");
+                assertEquals(o, "foo", "getAndSet String");
                 String x = (String) vh.get(array, i);
-                assertEquals(x, "foo", "getAndSet String value");
+                assertEquals(x, "bar", "getAndSet String value");
             }
 
         }
@@ -786,6 +808,10 @@
             });
 
             checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, "foo", "bar");
+            });
+
+            checkIOOBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, "foo", "bar");
             });
 
--- a/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java	Fri Apr 29 13:46:19 2016 -0700
@@ -93,6 +93,7 @@
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -204,6 +205,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
         });
 
@@ -265,6 +270,10 @@
             });
 
             checkUOE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkUOE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -306,6 +315,10 @@
             });
 
             checkUOE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkUOE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
--- a/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java	Fri Apr 29 13:46:19 2016 -0700
@@ -93,6 +93,7 @@
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -239,6 +240,10 @@
             });
 
             checkROBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkROBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -334,6 +339,10 @@
             });
 
             checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkIOOBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -415,6 +424,10 @@
                 });
 
                 checkIOOBE(() -> {
+                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                });
+
+                checkIOOBE(() -> {
                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                 });
 
@@ -487,6 +500,10 @@
                 });
 
                 checkISE(() -> {
+                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                });
+
+                checkISE(() -> {
                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                 });
 
@@ -562,6 +579,10 @@
                     });
 
                     checkISE(() -> {
+                        boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                    });
+
+                    checkISE(() -> {
                         boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                     });
 
@@ -699,12 +720,19 @@
                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease double");
                 }
 
+                {
+                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
+                    assertEquals(r, true, "weakCompareAndSetVolatile double");
+                    double x = (double) vh.get(array, i);
+                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile double value");
+                }
+
                 // Compare set and get
                 {
-                    double o = (double) vh.getAndSet(array, i, VALUE_1);
-                    assertEquals(o, VALUE_2, "getAndSet double");
+                    double o = (double) vh.getAndSet(array, i, VALUE_2);
+                    assertEquals(o, VALUE_1, "getAndSet double");
                     double x = (double) vh.get(array, i);
-                    assertEquals(x, VALUE_1, "getAndSet double value");
+                    assertEquals(x, VALUE_2, "getAndSet double value");
                 }
 
             }
@@ -832,12 +860,19 @@
                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease double");
                 }
 
+                {
+                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
+                    assertEquals(r, true, "weakCompareAndSetVolatile double");
+                    double x = (double) vh.get(array, i);
+                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile double value");
+                }
+
                 // Compare set and get
                 {
-                    double o = (double) vh.getAndSet(array, i, VALUE_1);
-                    assertEquals(o, VALUE_2, "getAndSet double");
+                    double o = (double) vh.getAndSet(array, i, VALUE_2);
+                    assertEquals(o, VALUE_1, "getAndSet double");
                     double x = (double) vh.get(array, i);
-                    assertEquals(x, VALUE_1, "getAndSet double value");
+                    assertEquals(x, VALUE_2, "getAndSet double value");
                 }
 
             }
--- a/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java	Fri Apr 29 13:46:19 2016 -0700
@@ -93,6 +93,7 @@
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -239,6 +240,10 @@
             });
 
             checkROBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkROBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -334,6 +339,10 @@
             });
 
             checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkIOOBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -415,6 +424,10 @@
                 });
 
                 checkIOOBE(() -> {
+                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                });
+
+                checkIOOBE(() -> {
                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                 });
 
@@ -487,6 +500,10 @@
                 });
 
                 checkISE(() -> {
+                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                });
+
+                checkISE(() -> {
                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                 });
 
@@ -562,6 +579,10 @@
                     });
 
                     checkISE(() -> {
+                        boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                    });
+
+                    checkISE(() -> {
                         boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                     });
 
@@ -699,12 +720,19 @@
                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease float");
                 }
 
+                {
+                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
+                    assertEquals(r, true, "weakCompareAndSetVolatile float");
+                    float x = (float) vh.get(array, i);
+                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile float value");
+                }
+
                 // Compare set and get
                 {
-                    float o = (float) vh.getAndSet(array, i, VALUE_1);
-                    assertEquals(o, VALUE_2, "getAndSet float");
+                    float o = (float) vh.getAndSet(array, i, VALUE_2);
+                    assertEquals(o, VALUE_1, "getAndSet float");
                     float x = (float) vh.get(array, i);
-                    assertEquals(x, VALUE_1, "getAndSet float value");
+                    assertEquals(x, VALUE_2, "getAndSet float value");
                 }
 
             }
@@ -832,12 +860,19 @@
                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease float");
                 }
 
+                {
+                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
+                    assertEquals(r, true, "weakCompareAndSetVolatile float");
+                    float x = (float) vh.get(array, i);
+                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile float value");
+                }
+
                 // Compare set and get
                 {
-                    float o = (float) vh.getAndSet(array, i, VALUE_1);
-                    assertEquals(o, VALUE_2, "getAndSet float");
+                    float o = (float) vh.getAndSet(array, i, VALUE_2);
+                    assertEquals(o, VALUE_1, "getAndSet float");
                     float x = (float) vh.get(array, i);
-                    assertEquals(x, VALUE_1, "getAndSet float value");
+                    assertEquals(x, VALUE_2, "getAndSet float value");
                 }
 
             }
--- a/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java	Fri Apr 29 13:46:19 2016 -0700
@@ -38,10 +38,10 @@
 import java.nio.ByteOrder;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.EnumSet;
 import java.util.List;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.*;
 
 public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest {
     static final int SIZE = Integer.BYTES;
@@ -93,6 +93,7 @@
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -232,6 +233,10 @@
             });
 
             checkROBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkROBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -320,6 +325,10 @@
             });
 
             checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkIOOBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -408,6 +417,10 @@
                 });
 
                 checkIOOBE(() -> {
+                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                });
+
+                checkIOOBE(() -> {
                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                 });
 
@@ -487,6 +500,10 @@
                 });
 
                 checkISE(() -> {
+                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                });
+
+                checkISE(() -> {
                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                 });
 
@@ -569,6 +586,10 @@
                     });
 
                     checkISE(() -> {
+                        boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                    });
+
+                    checkISE(() -> {
                         boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                     });
 
@@ -713,12 +734,19 @@
                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease int");
                 }
 
+                {
+                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
+                    assertEquals(r, true, "weakCompareAndSetVolatile int");
+                    int x = (int) vh.get(array, i);
+                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile int value");
+                }
+
                 // Compare set and get
                 {
-                    int o = (int) vh.getAndSet(array, i, VALUE_1);
-                    assertEquals(o, VALUE_2, "getAndSet int");
+                    int o = (int) vh.getAndSet(array, i, VALUE_2);
+                    assertEquals(o, VALUE_1, "getAndSet int");
                     int x = (int) vh.get(array, i);
-                    assertEquals(x, VALUE_1, "getAndSet int value");
+                    assertEquals(x, VALUE_2, "getAndSet int value");
                 }
 
                 vh.set(array, i, VALUE_1);
@@ -855,12 +883,19 @@
                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease int");
                 }
 
+                {
+                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
+                    assertEquals(r, true, "weakCompareAndSetVolatile int");
+                    int x = (int) vh.get(array, i);
+                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile int value");
+                }
+
                 // Compare set and get
                 {
-                    int o = (int) vh.getAndSet(array, i, VALUE_1);
-                    assertEquals(o, VALUE_2, "getAndSet int");
+                    int o = (int) vh.getAndSet(array, i, VALUE_2);
+                    assertEquals(o, VALUE_1, "getAndSet int");
                     int x = (int) vh.get(array, i);
-                    assertEquals(x, VALUE_1, "getAndSet int value");
+                    assertEquals(x, VALUE_2, "getAndSet int value");
                 }
 
                 vh.set(array, i, VALUE_1);
--- a/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java	Fri Apr 29 13:46:19 2016 -0700
@@ -93,6 +93,7 @@
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -232,6 +233,10 @@
             });
 
             checkROBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkROBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -320,6 +325,10 @@
             });
 
             checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkIOOBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -408,6 +417,10 @@
                 });
 
                 checkIOOBE(() -> {
+                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                });
+
+                checkIOOBE(() -> {
                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                 });
 
@@ -487,6 +500,10 @@
                 });
 
                 checkISE(() -> {
+                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                });
+
+                checkISE(() -> {
                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                 });
 
@@ -569,6 +586,10 @@
                     });
 
                     checkISE(() -> {
+                        boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                    });
+
+                    checkISE(() -> {
                         boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                     });
 
@@ -713,12 +734,19 @@
                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease long");
                 }
 
+                {
+                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
+                    assertEquals(r, true, "weakCompareAndSetVolatile long");
+                    long x = (long) vh.get(array, i);
+                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile long value");
+                }
+
                 // Compare set and get
                 {
-                    long o = (long) vh.getAndSet(array, i, VALUE_1);
-                    assertEquals(o, VALUE_2, "getAndSet long");
+                    long o = (long) vh.getAndSet(array, i, VALUE_2);
+                    assertEquals(o, VALUE_1, "getAndSet long");
                     long x = (long) vh.get(array, i);
-                    assertEquals(x, VALUE_1, "getAndSet long value");
+                    assertEquals(x, VALUE_2, "getAndSet long value");
                 }
 
                 vh.set(array, i, VALUE_1);
@@ -855,12 +883,19 @@
                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease long");
                 }
 
+                {
+                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
+                    assertEquals(r, true, "weakCompareAndSetVolatile long");
+                    long x = (long) vh.get(array, i);
+                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile long value");
+                }
+
                 // Compare set and get
                 {
-                    long o = (long) vh.getAndSet(array, i, VALUE_1);
-                    assertEquals(o, VALUE_2, "getAndSet long");
+                    long o = (long) vh.getAndSet(array, i, VALUE_2);
+                    assertEquals(o, VALUE_1, "getAndSet long");
                     long x = (long) vh.get(array, i);
-                    assertEquals(x, VALUE_1, "getAndSet long value");
+                    assertEquals(x, VALUE_2, "getAndSet long value");
                 }
 
                 vh.set(array, i, VALUE_1);
--- a/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java	Fri Apr 29 13:46:19 2016 -0700
@@ -93,6 +93,7 @@
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -204,6 +205,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
         });
 
@@ -265,6 +270,10 @@
             });
 
             checkUOE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkUOE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -306,6 +315,10 @@
             });
 
             checkUOE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkUOE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
--- a/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java	Fri Apr 29 13:46:19 2016 -0700
@@ -228,12 +228,19 @@
             assertEquals(x, 2, "weakCompareAndSetRelease int");
         }
 
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(recv, 2, 1);
+            assertEquals(r, true, "weakCompareAndSetVolatile int");
+            int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 1, "weakCompareAndSetVolatile int value");
+        }
+
         // Compare set and get
         {
-            int o = (int) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, 1);
-            assertEquals(o, 2, "getAndSet int");
+            int o = (int) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, 2);
+            assertEquals(o, 1, "getAndSet int");
             int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv);
-            assertEquals(x, 1, "getAndSet int value");
+            assertEquals(x, 2, "getAndSet int value");
         }
 
         hs.get(TestAccessMode.SET).invokeExact(recv, 1);
@@ -356,18 +363,25 @@
         }
 
         {
-            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact( 1, 2);
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(1, 2);
             assertEquals(r, true, "weakCompareAndSetRelease int");
             int x = (int) hs.get(TestAccessMode.GET).invokeExact();
             assertEquals(x, 2, "weakCompareAndSetRelease int");
         }
 
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(2, 1);
+            assertEquals(r, true, "weakCompareAndSetVolatile int");
+            int x = (int) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 1, "weakCompareAndSetVolatile int value");
+        }
+
         // Compare set and get
         {
-            int o = (int) hs.get(TestAccessMode.GET_AND_SET).invokeExact( 1);
-            assertEquals(o, 2, "getAndSet int");
+            int o = (int) hs.get(TestAccessMode.GET_AND_SET).invokeExact(2);
+            assertEquals(o, 1, "getAndSet int");
             int x = (int) hs.get(TestAccessMode.GET).invokeExact();
-            assertEquals(x, 1, "getAndSet int value");
+            assertEquals(x, 2, "getAndSet int value");
         }
 
         hs.get(TestAccessMode.SET).invokeExact(1);
@@ -499,12 +513,19 @@
                 assertEquals(x, 2, "weakCompareAndSetRelease int");
             }
 
+            {
+                boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(array, i, 2, 1);
+                assertEquals(r, true, "weakCompareAndSetVolatile int");
+                int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 1, "weakCompareAndSetVolatile int value");
+            }
+
             // Compare set and get
             {
-                int o = (int) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, 1);
-                assertEquals(o, 2, "getAndSet int");
+                int o = (int) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, 2);
+                assertEquals(o, 1, "getAndSet int");
                 int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i);
-                assertEquals(x, 1, "getAndSet int value");
+                assertEquals(x, 2, "getAndSet int value");
             }
 
             hs.get(TestAccessMode.SET).invokeExact(array, i, 1);
--- a/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java	Fri Apr 29 13:46:19 2016 -0700
@@ -228,12 +228,19 @@
             assertEquals(x, 2L, "weakCompareAndSetRelease long");
         }
 
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(recv, 2L, 1L);
+            assertEquals(r, true, "weakCompareAndSetVolatile long");
+            long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 1L, "weakCompareAndSetVolatile long value");
+        }
+
         // Compare set and get
         {
-            long o = (long) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, 1L);
-            assertEquals(o, 2L, "getAndSet long");
+            long o = (long) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, 2L);
+            assertEquals(o, 1L, "getAndSet long");
             long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv);
-            assertEquals(x, 1L, "getAndSet long value");
+            assertEquals(x, 2L, "getAndSet long value");
         }
 
         hs.get(TestAccessMode.SET).invokeExact(recv, 1L);
@@ -356,18 +363,25 @@
         }
 
         {
-            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact( 1L, 2L);
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(1L, 2L);
             assertEquals(r, true, "weakCompareAndSetRelease long");
             long x = (long) hs.get(TestAccessMode.GET).invokeExact();
             assertEquals(x, 2L, "weakCompareAndSetRelease long");
         }
 
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(2L, 1L);
+            assertEquals(r, true, "weakCompareAndSetVolatile long");
+            long x = (long) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 1L, "weakCompareAndSetVolatile long value");
+        }
+
         // Compare set and get
         {
-            long o = (long) hs.get(TestAccessMode.GET_AND_SET).invokeExact( 1L);
-            assertEquals(o, 2L, "getAndSet long");
+            long o = (long) hs.get(TestAccessMode.GET_AND_SET).invokeExact(2L);
+            assertEquals(o, 1L, "getAndSet long");
             long x = (long) hs.get(TestAccessMode.GET).invokeExact();
-            assertEquals(x, 1L, "getAndSet long value");
+            assertEquals(x, 2L, "getAndSet long value");
         }
 
         hs.get(TestAccessMode.SET).invokeExact(1L);
@@ -499,12 +513,19 @@
                 assertEquals(x, 2L, "weakCompareAndSetRelease long");
             }
 
+            {
+                boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(array, i, 2L, 1L);
+                assertEquals(r, true, "weakCompareAndSetVolatile long");
+                long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 1L, "weakCompareAndSetVolatile long value");
+            }
+
             // Compare set and get
             {
-                long o = (long) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, 1L);
-                assertEquals(o, 2L, "getAndSet long");
+                long o = (long) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, 2L);
+                assertEquals(o, 1L, "getAndSet long");
                 long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i);
-                assertEquals(x, 1L, "getAndSet long value");
+                assertEquals(x, 2L, "getAndSet long value");
             }
 
             hs.get(TestAccessMode.SET).invokeExact(array, i, 1L);
--- a/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java	Fri Apr 29 13:46:19 2016 -0700
@@ -228,12 +228,19 @@
             assertEquals(x, "bar", "weakCompareAndSetRelease String");
         }
 
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(recv, "bar", "foo");
+            assertEquals(r, true, "weakCompareAndSetVolatile String");
+            String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, "foo", "weakCompareAndSetVolatile String value");
+        }
+
         // Compare set and get
         {
-            String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, "foo");
-            assertEquals(o, "bar", "getAndSet String");
+            String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, "bar");
+            assertEquals(o, "foo", "getAndSet String");
             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
-            assertEquals(x, "foo", "getAndSet String value");
+            assertEquals(x, "bar", "getAndSet String value");
         }
 
     }
@@ -352,18 +359,25 @@
         }
 
         {
-            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact( "foo", "bar");
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact("foo", "bar");
             assertEquals(r, true, "weakCompareAndSetRelease String");
             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
             assertEquals(x, "bar", "weakCompareAndSetRelease String");
         }
 
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact("bar", "foo");
+            assertEquals(r, true, "weakCompareAndSetVolatile String");
+            String x = (String) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, "foo", "weakCompareAndSetVolatile String value");
+        }
+
         // Compare set and get
         {
-            String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact( "foo");
-            assertEquals(o, "bar", "getAndSet String");
+            String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact("bar");
+            assertEquals(o, "foo", "getAndSet String");
             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
-            assertEquals(x, "foo", "getAndSet String value");
+            assertEquals(x, "bar", "getAndSet String value");
         }
 
     }
@@ -491,12 +505,19 @@
                 assertEquals(x, "bar", "weakCompareAndSetRelease String");
             }
 
+            {
+                boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(array, i, "bar", "foo");
+                assertEquals(r, true, "weakCompareAndSetVolatile String");
+                String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, "foo", "weakCompareAndSetVolatile String value");
+            }
+
             // Compare set and get
             {
-                String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, "foo");
-                assertEquals(o, "bar", "getAndSet String");
+                String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, "bar");
+                assertEquals(o, "foo", "getAndSet String");
                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
-                assertEquals(x, "foo", "getAndSet String value");
+                assertEquals(x, "bar", "getAndSet String value");
             }
 
         }
--- a/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeInt.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeInt.java	Fri Apr 29 13:46:19 2016 -0700
@@ -374,6 +374,32 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetVolatile(null, 1, 1);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 1, 1);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(recv, Void.class, 1);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(recv, 1, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetVolatile(0, 1, 1);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(recv, 1, 1, Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkNPE(() -> { // null receiver
@@ -972,6 +998,23 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 1);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(1, Void.class);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(1, 1, Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkWMTE(() -> { // expected reference class
@@ -1566,6 +1609,35 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetVolatile(null, 0, 1, 1);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 0, 1, 1);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, Void.class, 1);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, 1, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetVolatile(0, 0, 1, 1);
+        });
+        checkWMTE(() -> { // index reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, Void.class, 1, 1);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, 1, 1, Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkNPE(() -> { // null receiver
--- a/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeLong.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeLong.java	Fri Apr 29 13:46:19 2016 -0700
@@ -374,6 +374,32 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetVolatile(null, 1L, 1L);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 1L, 1L);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(recv, Void.class, 1L);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(recv, 1L, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetVolatile(0, 1L, 1L);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(recv, 1L, 1L, Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkNPE(() -> { // null receiver
@@ -972,6 +998,23 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 1L);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(1L, Void.class);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(1L, 1L, Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkWMTE(() -> { // expected reference class
@@ -1566,6 +1609,35 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetVolatile(null, 0, 1L, 1L);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 0, 1L, 1L);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, Void.class, 1L);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, 1L, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetVolatile(0, 0, 1L, 1L);
+        });
+        checkWMTE(() -> { // index reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, Void.class, 1L, 1L);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, 1L, 1L, Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkNPE(() -> { // null receiver
--- a/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeString.java	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeString.java	Fri Apr 29 13:46:19 2016 -0700
@@ -374,6 +374,32 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetVolatile(null, "foo", "foo");
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, "foo", "foo");
+        });
+        checkCCE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(recv, Void.class, "foo");
+        });
+        checkCCE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(recv, "foo", Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetVolatile(0, "foo", "foo");
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(recv, "foo", "foo", Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkNPE(() -> { // null receiver
@@ -878,6 +904,23 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkCCE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, "foo");
+        });
+        checkCCE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile("foo", Void.class);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile("foo", "foo", Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkCCE(() -> { // expected reference class
@@ -1407,6 +1450,35 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetVolatile(null, 0, "foo", "foo");
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 0, "foo", "foo");
+        });
+        checkCCE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, Void.class, "foo");
+        });
+        checkCCE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, "foo", Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetVolatile(0, 0, "foo", "foo");
+        });
+        checkWMTE(() -> { // index reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, Void.class, "foo", "foo");
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, "foo", "foo", Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkNPE(() -> { // null receiver
--- a/test/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template	Fri Apr 29 13:46:19 2016 -0700
@@ -105,6 +105,7 @@
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -114,6 +115,7 @@
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -297,6 +299,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, $value1$, $value2$);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, $value1$, $value2$);
         });
 
@@ -383,6 +389,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile($value1$, $value2$);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire($value1$, $value2$);
         });
 
@@ -514,12 +524,19 @@
             assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
         }
 
+        {
+            boolean r = vh.weakCompareAndSetVolatile(recv, $value2$, $value1$);
+            assertEquals(r, true, "weakCompareAndSetVolatile $type$");
+            $type$ x = ($type$) vh.get(recv);
+            assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$ value");
+        }
+
         // Compare set and get
         {
-            $type$ o = ($type$) vh.getAndSet(recv, $value1$);
-            assertEquals(o, $value2$, "getAndSet $type$");
+            $type$ o = ($type$) vh.getAndSet(recv, $value2$);
+            assertEquals(o, $value1$, "getAndSet $type$");
             $type$ x = ($type$) vh.get(recv);
-            assertEquals(x, $value1$, "getAndSet $type$ value");
+            assertEquals(x, $value2$, "getAndSet $type$ value");
         }
 #end[CAS]
 
@@ -559,6 +576,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, $value1$, $value2$);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, $value1$, $value2$);
         });
 
@@ -684,18 +705,25 @@
         }
 
         {
-            boolean r = (boolean) vh.weakCompareAndSetRelease( $value1$, $value2$);
+            boolean r = (boolean) vh.weakCompareAndSetRelease($value1$, $value2$);
             assertEquals(r, true, "weakCompareAndSetRelease $type$");
             $type$ x = ($type$) vh.get();
             assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
         }
 
+        {
+            boolean r = (boolean) vh.weakCompareAndSetVolatile($value2$, $value1$);
+            assertEquals(r, true, "weakCompareAndSetVolatile $type$");
+            $type$ x = ($type$) vh.get();
+            assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$ value");
+        }
+
         // Compare set and get
         {
-            $type$ o = ($type$) vh.getAndSet( $value1$);
-            assertEquals(o, $value2$, "getAndSet $type$");
+            $type$ o = ($type$) vh.getAndSet( $value2$);
+            assertEquals(o, $value1$, "getAndSet $type$");
             $type$ x = ($type$) vh.get();
-            assertEquals(x, $value1$, "getAndSet $type$ value");
+            assertEquals(x, $value2$, "getAndSet $type$ value");
         }
 #end[CAS]
 
@@ -735,6 +763,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile($value1$, $value2$);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire($value1$, $value2$);
         });
 
@@ -869,12 +901,19 @@
                 assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
             }
 
+            {
+                boolean r = vh.weakCompareAndSetVolatile(array, i, $value2$, $value1$);
+                assertEquals(r, true, "weakCompareAndSetVolatile $type$");
+                $type$ x = ($type$) vh.get(array, i);
+                assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$ value");
+            }
+
             // Compare set and get
             {
-                $type$ o = ($type$) vh.getAndSet(array, i, $value1$);
-                assertEquals(o, $value2$, "getAndSet $type$");
+                $type$ o = ($type$) vh.getAndSet(array, i, $value2$);
+                assertEquals(o, $value1$, "getAndSet $type$");
                 $type$ x = ($type$) vh.get(array, i);
-                assertEquals(x, $value1$, "getAndSet $type$ value");
+                assertEquals(x, $value2$, "getAndSet $type$ value");
             }
 #end[CAS]
 
@@ -918,6 +957,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(array, i, $value1$, $value2$);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(array, i, $value1$, $value2$);
         });
 
@@ -997,6 +1040,10 @@
             });
 
             checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, $value1$, $value2$);
+            });
+
+            checkIOOBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, $value1$, $value2$);
             });
 
--- a/test/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template	Fri Apr 29 13:46:19 2016 -0700
@@ -94,6 +94,7 @@
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -103,6 +104,7 @@
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -221,6 +223,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
         });
 
@@ -291,6 +297,10 @@
             });
 
             checkROBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkROBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -322,6 +332,10 @@
             });
 
             checkUOE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkUOE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -375,6 +389,10 @@
             });
 
             checkUOE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkUOE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -461,6 +479,10 @@
             });
 
             checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkIOOBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -553,6 +575,10 @@
                 });
 
                 checkIOOBE(() -> {
+                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                });
+
+                checkIOOBE(() -> {
                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                 });
 
@@ -636,6 +662,10 @@
                 });
 
                 checkISE(() -> {
+                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                });
+
+                checkISE(() -> {
                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                 });
 
@@ -722,6 +752,10 @@
                     });
 
                     checkISE(() -> {
+                        boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                    });
+
+                    checkISE(() -> {
                         boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                     });
 
@@ -870,12 +904,19 @@
                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$");
                 }
 
+                {
+                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
+                    assertEquals(r, true, "weakCompareAndSetVolatile $type$");
+                    $type$ x = ($type$) vh.get(array, i);
+                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile $type$ value");
+                }
+
                 // Compare set and get
                 {
-                    $type$ o = ($type$) vh.getAndSet(array, i, VALUE_1);
-                    assertEquals(o, VALUE_2, "getAndSet $type$");
+                    $type$ o = ($type$) vh.getAndSet(array, i, VALUE_2);
+                    assertEquals(o, VALUE_1, "getAndSet $type$");
                     $type$ x = ($type$) vh.get(array, i);
-                    assertEquals(x, VALUE_1, "getAndSet $type$ value");
+                    assertEquals(x, VALUE_2, "getAndSet $type$ value");
                 }
 #end[CAS]
 
@@ -1016,12 +1057,19 @@
                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$");
                 }
 
+                {
+                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
+                    assertEquals(r, true, "weakCompareAndSetVolatile $type$");
+                    $type$ x = ($type$) vh.get(array, i);
+                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile $type$ value");
+                }
+
                 // Compare set and get
                 {
-                    $type$ o = ($type$) vh.getAndSet(array, i, VALUE_1);
-                    assertEquals(o, VALUE_2, "getAndSet $type$");
+                    $type$ o = ($type$) vh.getAndSet(array, i, VALUE_2);
+                    assertEquals(o, VALUE_1, "getAndSet $type$");
                     $type$ x = ($type$) vh.get(array, i);
-                    assertEquals(x, VALUE_1, "getAndSet $type$ value");
+                    assertEquals(x, VALUE_2, "getAndSet $type$ value");
                 }
 #end[CAS]
 
--- a/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template	Fri Apr 29 13:46:19 2016 -0700
@@ -229,12 +229,19 @@
             assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
         }
 
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(recv, $value2$, $value1$);
+            assertEquals(r, true, "weakCompareAndSetVolatile $type$");
+            $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$ value");
+        }
+
         // Compare set and get
         {
-            $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, $value1$);
-            assertEquals(o, $value2$, "getAndSet $type$");
+            $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, $value2$);
+            assertEquals(o, $value1$, "getAndSet $type$");
             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
-            assertEquals(x, $value1$, "getAndSet $type$ value");
+            assertEquals(x, $value2$, "getAndSet $type$ value");
         }
 #end[CAS]
 
@@ -387,18 +394,25 @@
         }
 
         {
-            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact( $value1$, $value2$);
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact($value1$, $value2$);
             assertEquals(r, true, "weakCompareAndSetRelease $type$");
             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
             assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
         }
 
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact($value2$, $value1$);
+            assertEquals(r, true, "weakCompareAndSetVolatile $type$");
+            $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$ value");
+        }
+
         // Compare set and get
         {
-            $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact( $value1$);
-            assertEquals(o, $value2$, "getAndSet $type$");
+            $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact($value2$);
+            assertEquals(o, $value1$, "getAndSet $type$");
             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
-            assertEquals(x, $value1$, "getAndSet $type$ value");
+            assertEquals(x, $value2$, "getAndSet $type$ value");
         }
 #end[CAS]
 
@@ -560,12 +574,19 @@
                 assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
             }
 
+            {
+                boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(array, i, $value2$, $value1$);
+                assertEquals(r, true, "weakCompareAndSetVolatile $type$");
+                $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$ value");
+            }
+
             // Compare set and get
             {
-                $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, $value1$);
-                assertEquals(o, $value2$, "getAndSet $type$");
+                $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, $value2$);
+                assertEquals(o, $value1$, "getAndSet $type$");
                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
-                assertEquals(x, $value1$, "getAndSet $type$ value");
+                assertEquals(x, $value2$, "getAndSet $type$ value");
             }
 #end[CAS]
 
--- a/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodType.java.template	Fri Apr 29 23:15:15 2016 +0300
+++ b/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodType.java.template	Fri Apr 29 13:46:19 2016 -0700
@@ -375,6 +375,32 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetVolatile(null, $value1$, $value1$);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, $value1$, $value1$);
+        });
+        check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(recv, Void.class, $value1$);
+        });
+        check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(recv, $value1$, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetVolatile(0, $value1$, $value1$);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(recv, $value1$, $value1$, Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkNPE(() -> { // null receiver
@@ -981,6 +1007,23 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, $value1$);
+        });
+        check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile($value1$, Void.class);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile($value1$, $value1$, Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         check{#if[String]?CCE:WMTE}(() -> { // expected reference class
@@ -1583,6 +1626,35 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetVolatile(null, 0, $value1$, $value1$);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 0, $value1$, $value1$);
+        });
+        check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, Void.class, $value1$);
+        });
+        check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, $value1$, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetVolatile(0, 0, $value1$, $value1$);
+        });
+        checkWMTE(() -> { // index reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, Void.class, $value1$, $value1$);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, $value1$, $value1$, Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkNPE(() -> { // null receiver