8158039: VarHandle float/double field/array access should support CAS/set/add atomics
authorpsandoz
Mon, 20 Jun 2016 17:57:19 +0200
changeset 39471 6622892a347a
parent 39470 d6f8b4a85fb0
child 39472 6df82f4c63ac
8158039: VarHandle float/double field/array access should support CAS/set/add atomics Reviewed-by: shade, vlivanov, darcy
jdk/make/gensrc/GensrcVarHandles.gmk
jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java
jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java
jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java
jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java
jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java
jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeDouble.java
jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeFloat.java
jdk/test/java/lang/invoke/VarHandles/generate-vh-tests.sh
--- a/jdk/make/gensrc/GensrcVarHandles.gmk	Wed Jun 15 11:20:15 2016 +0300
+++ b/jdk/make/gensrc/GensrcVarHandles.gmk	Mon Jun 20 17:57:19 2016 +0200
@@ -38,11 +38,9 @@
 
   $1_FILENAME := $(VARHANDLES_GENSRC_DIR)/VarHandle$$($1_Type)s.java
 
-  ifneq ($$(findstring $$($1_Type), Object Boolean Byte Short Char Int Long), )
-    $1_ARGS += -KCAS
-  endif
+  $1_ARGS += -KCAS
 
-  ifneq ($$(findstring $$($1_Type), Byte Short Char Int Long), )
+  ifneq ($$(findstring $$($1_Type), Byte Short Char Int Long Float Double), )
     $1_ARGS += -KAtomicAdd
   endif
 
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Wed Jun 15 11:20:15 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Mon Jun 20 17:57:19 2016 +0200
@@ -1208,21 +1208,43 @@
          * <ul>
          * <li>if the field is declared {@code final}, then the write, atomic
          *     update, and numeric atomic update access modes are unsupported.
-         * <li>if the field type is anything other than {@code boolean},
-         *     {@code byte}, {@code short}, {@code char}, {@code int},
-         *     {@code long} or a reference type, then atomic update access modes
-         *     are unsupported.  (Future major platform releases of the JDK may
-         *     support additional types for certain currently unsupported access
-         *     modes.)
          * <li>if the field type is anything other than {@code byte},
-         *     {@code short}, {@code char}, {@code int} or {@code long}, then
-         *     numeric atomic update access modes are unsupported.
+         *     {@code short}, {@code char}, {@code int} or {@code long},
+         *     {@code float}, or {@code double} then numeric atomic update
+         *     access modes are unsupported.
          * </ul>
          * <p>
          * If the field is declared {@code volatile} then the returned VarHandle
          * will override access to the field (effectively ignore the
          * {@code volatile} declaration) in accordance to it's specified
          * access modes.
+         * <p>
+         * If the field type is {@code float} or {@code double} then numeric
+         * and atomic update access modes compare values using their bitwise
+         * representation (see {@link Float#floatToRawIntBits} and
+         * {@link Double#doubleToRawLongBits}, respectively).
+         * @apiNote
+         * Bitwise comparison of {@code float} values or {@code double} values,
+         * as performed by the numeric and atomic update access modes, differ
+         * from the primitive {@code ==} operator and the {@link Float#equals}
+         * and {@link Double#equals} methods, specifically with respect to
+         * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
+         * Care should be taken when performing a compare and set or a compare
+         * and exchange operation with such values since the operation may
+         * unexpectedly fail.
+         * There are many possible NaN values that are considered to be
+         * {@code NaN} in Java, although no IEEE 754 floating-point operation
+         * provided by Java can distinguish between them.  Operation failure can
+         * occur if the expected or witness value is a NaN value and it is
+         * transformed (perhaps in a platform specific manner) into another NaN
+         * value, and thus has a different bitwise representation (see
+         * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
+         * details).
+         * The values {@code -0.0} and {@code +0.0} have different bitwise
+         * representations but are considered equal when using the primitive
+         * {@code ==} operator.  Operation failure can occur if, for example, a
+         * numeric algorithm computes an expected value to be say {@code -0.0}
+         * and previously computed the witness value to be say {@code +0.0}.
          * @param recv the receiver class, of type {@code R}, that declares the
          * non-static field
          * @param name the field's name
@@ -1305,21 +1327,43 @@
          * <ul>
          * <li>if the field is declared {@code final}, then the write, atomic
          *     update, and numeric atomic update access modes are unsupported.
-         * <li>if the field type is anything other than {@code boolean},
-         *     {@code byte}, {@code short}, {@code char}, {@code int},
-         *     {@code long} or a reference type, then atomic update access modes
-         *     are unsupported.  (Future major platform releases of the JDK may
-         *     support additional types for certain currently unsupported access
-         *     modes.)
          * <li>if the field type is anything other than {@code byte},
-         *     {@code short}, {@code char}, {@code int} or {@code long}, then
-         *     numeric atomic update access modes are unsupported.
+         *     {@code short}, {@code char}, {@code int} or {@code long},
+         *     {@code float}, or {@code double}, then numeric atomic update
+         *     access modes are unsupported.
          * </ul>
          * <p>
          * If the field is declared {@code volatile} then the returned VarHandle
          * will override access to the field (effectively ignore the
          * {@code volatile} declaration) in accordance to it's specified
          * access modes.
+         * <p>
+         * If the field type is {@code float} or {@code double} then numeric
+         * and atomic update access modes compare values using their bitwise
+         * representation (see {@link Float#floatToRawIntBits} and
+         * {@link Double#doubleToRawLongBits}, respectively).
+         * @apiNote
+         * Bitwise comparison of {@code float} values or {@code double} values,
+         * as performed by the numeric and atomic update access modes, differ
+         * from the primitive {@code ==} operator and the {@link Float#equals}
+         * and {@link Double#equals} methods, specifically with respect to
+         * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
+         * Care should be taken when performing a compare and set or a compare
+         * and exchange operation with such values since the operation may
+         * unexpectedly fail.
+         * There are many possible NaN values that are considered to be
+         * {@code NaN} in Java, although no IEEE 754 floating-point operation
+         * provided by Java can distinguish between them.  Operation failure can
+         * occur if the expected or witness value is a NaN value and it is
+         * transformed (perhaps in a platform specific manner) into another NaN
+         * value, and thus has a different bitwise representation (see
+         * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
+         * details).
+         * The values {@code -0.0} and {@code +0.0} have different bitwise
+         * representations but are considered equal when using the primitive
+         * {@code ==} operator.  Operation failure can occur if, for example, a
+         * numeric algorithm computes an expected value to be say {@code -0.0}
+         * and previously computed the witness value to be say {@code +0.0}.
          * @param decl the class that declares the static field
          * @param name the field's name
          * @param type the field's type, of type {@code T}
@@ -1588,21 +1632,43 @@
          * <ul>
          * <li>if the field is declared {@code final}, then the write, atomic
          *     update, and numeric atomic update access modes are unsupported.
-         * <li>if the field type is anything other than {@code boolean},
-         *     {@code byte}, {@code short}, {@code char}, {@code int},
-         *     {@code long} or a reference type, then atomic update access modes
-         *     are unsupported.  (Future major platform releases of the JDK may
-         *     support additional types for certain currently unsupported access
-         *     modes.)
          * <li>if the field type is anything other than {@code byte},
-         *     {@code short}, {@code char}, {@code int} or {@code long}, then
-         *     numeric atomic update access modes are unsupported.
+         *     {@code short}, {@code char}, {@code int} or {@code long},
+         *     {@code float}, or {@code double} then numeric atomic update
+         *     access modes are unsupported.
          * </ul>
          * <p>
          * If the field is declared {@code volatile} then the returned VarHandle
          * will override access to the field (effectively ignore the
          * {@code volatile} declaration) in accordance to it's specified
          * access modes.
+         * <p>
+         * If the field type is {@code float} or {@code double} then numeric
+         * and atomic update access modes compare values using their bitwise
+         * representation (see {@link Float#floatToRawIntBits} and
+         * {@link Double#doubleToRawLongBits}, respectively).
+         * @apiNote
+         * Bitwise comparison of {@code float} values or {@code double} values,
+         * as performed by the numeric and atomic update access modes, differ
+         * from the primitive {@code ==} operator and the {@link Float#equals}
+         * and {@link Double#equals} methods, specifically with respect to
+         * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
+         * Care should be taken when performing a compare and set or a compare
+         * and exchange operation with such values since the operation may
+         * unexpectedly fail.
+         * There are many possible NaN values that are considered to be
+         * {@code NaN} in Java, although no IEEE 754 floating-point operation
+         * provided by Java can distinguish between them.  Operation failure can
+         * occur if the expected or witness value is a NaN value and it is
+         * transformed (perhaps in a platform specific manner) into another NaN
+         * value, and thus has a different bitwise representation (see
+         * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
+         * details).
+         * The values {@code -0.0} and {@code +0.0} have different bitwise
+         * representations but are considered equal when using the primitive
+         * {@code ==} operator.  Operation failure can occur if, for example, a
+         * numeric algorithm computes an expected value to be say {@code -0.0}
+         * and previously computed the witness value to be say {@code +0.0}.
          * @param f the reflected field, with a field of type {@code T}, and
          * a declaring class of type {@code R}
          * @return a VarHandle giving access to non-static fields or a static
@@ -2294,16 +2360,38 @@
      * Certain access modes of the returned VarHandle are unsupported under
      * the following conditions:
      * <ul>
-     * <li>if the field type is anything other than {@code boolean},
-     *     {@code byte}, {@code short}, {@code char}, {@code int},
-     *     {@code long} or a reference type, then atomic update access modes
-     *     are unsupported.  (Future major platform releases of the JDK may
-     *     support additional types for certain currently unsupported access
-     *     modes.)
      * <li>if the component type is anything other than {@code byte},
-     *     {@code short}, {@code char}, {@code int} or {@code long}, then
-     *     numeric atomic update access modes are unsupported.
+     *     {@code short}, {@code char}, {@code int} or {@code long},
+     *     {@code float}, or {@code double} then numeric atomic update access
+     *     modes are unsupported.
      * </ul>
+     * <p>
+     * If the component type is {@code float} or {@code double} then numeric
+     * and atomic update access modes compare values using their bitwise
+     * representation (see {@link Float#floatToRawIntBits} and
+     * {@link Double#doubleToRawLongBits}, respectively).
+     * @apiNote
+     * Bitwise comparison of {@code float} values or {@code double} values,
+     * as performed by the numeric and atomic update access modes, differ
+     * from the primitive {@code ==} operator and the {@link Float#equals}
+     * and {@link Double#equals} methods, specifically with respect to
+     * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
+     * Care should be taken when performing a compare and set or a compare
+     * and exchange operation with such values since the operation may
+     * unexpectedly fail.
+     * There are many possible NaN values that are considered to be
+     * {@code NaN} in Java, although no IEEE 754 floating-point operation
+     * provided by Java can distinguish between them.  Operation failure can
+     * occur if the expected or witness value is a NaN value and it is
+     * transformed (perhaps in a platform specific manner) into another NaN
+     * value, and thus has a different bitwise representation (see
+     * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
+     * details).
+     * The values {@code -0.0} and {@code +0.0} have different bitwise
+     * representations but are considered equal when using the primitive
+     * {@code ==} operator.  Operation failure can occur if, for example, a
+     * numeric algorithm computes an expected value to be say {@code -0.0}
+     * and previously computed the witness value to be say {@code +0.0}.
      * @param arrayClass the class of an array, of type {@code T[]}
      * @return a VarHandle giving access to elements of an array
      * @throws NullPointerException if the arrayClass is null
@@ -2367,16 +2455,11 @@
      * int misalignedAtIndex = (misalignedAtZeroIndex + index) % sizeOfT;
      * boolean isMisaligned = misalignedAtIndex != 0;
      * }</pre>
-     *
-     * @implNote
-     * The variable types {@code float} and {@code double} are supported as if
-     * by transformation to and access with the variable types {@code int} and
-     * {@code long} respectively.  For example, the transformation of a
-     * {@code double} value to a long value is performed as if using
-     * {@link Double#doubleToRawLongBits(double)}, and the reverse
-     * transformation is performed as if using
-     * {@link Double#longBitsToDouble(long)}.
-     *
+     * <p>
+     * If the variable type is {@code float} or {@code double} then atomic
+     * update access modes compare values using their bitwise representation
+     * (see {@link Float#floatToRawIntBits} and
+     * {@link Double#doubleToRawLongBits}, respectively).
      * @param viewArrayClass the view array class, with a component type of
      * type {@code T}
      * @param byteOrder the endianness of the view array elements, as
@@ -2453,16 +2536,11 @@
      * int misalignedAtIndex = bb.alignmentOffset(index, sizeOfT);
      * boolean isMisaligned = misalignedAtIndex != 0;
      * }</pre>
-     *
-     * @implNote
-     * The variable types {@code float} and {@code double} are supported as if
-     * by transformation to and access with the variable types {@code int} and
-     * {@code long} respectively.  For example, the transformation of a
-     * {@code double} value to a long value is performed as if using
-     * {@link Double#doubleToRawLongBits(double)}, and the reverse
-     * transformation is performed as if using
-     * {@link Double#longBitsToDouble(long)}.
-     *
+     * <p>
+     * If the variable type is {@code float} or {@code double} then atomic
+     * update access modes compare values using their bitwise representation
+     * (see {@link Float#floatToRawIntBits} and
+     * {@link Double#doubleToRawLongBits}, respectively).
      * @param viewArrayClass the view array class, with a component type of
      * type {@code T}
      * @param byteOrder the endianness of the view array elements, as
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java	Wed Jun 15 11:20:15 2016 +0300
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java	Mon Jun 20 17:57:19 2016 +0200
@@ -25,15 +25,13 @@
 
 package jdk.internal.misc;
 
-import java.lang.reflect.Field;
-import java.security.ProtectionDomain;
-
+import jdk.internal.HotSpotIntrinsicCandidate;
 import jdk.internal.reflect.CallerSensitive;
 import jdk.internal.reflect.Reflection;
-import jdk.internal.misc.VM;
+import jdk.internal.vm.annotation.ForceInline;
 
-import jdk.internal.HotSpotIntrinsicCandidate;
-import jdk.internal.vm.annotation.ForceInline;
+import java.lang.reflect.Field;
+import java.security.ProtectionDomain;
 
 
 /**
@@ -1688,6 +1686,174 @@
      *
      * @return {@code true} if successful
      */
+    @ForceInline
+    public final boolean compareAndSwapFloat(Object o, long offset,
+                                             float expected,
+                                             float x) {
+        return compareAndSwapInt(o, offset,
+                                 Float.floatToRawIntBits(expected),
+                                 Float.floatToRawIntBits(x));
+    }
+
+    @ForceInline
+    public final float compareAndExchangeFloatVolatile(Object o, long offset,
+                                                       float expected,
+                                                       float x) {
+        int w = compareAndExchangeIntVolatile(o, offset,
+                                              Float.floatToRawIntBits(expected),
+                                              Float.floatToRawIntBits(x));
+        return Float.intBitsToFloat(w);
+    }
+
+    @ForceInline
+    public final float compareAndExchangeFloatAcquire(Object o, long offset,
+                                                  float expected,
+                                                  float x) {
+        int w = compareAndExchangeIntVolatile(o, offset,
+                                              Float.floatToRawIntBits(expected),
+                                              Float.floatToRawIntBits(x));
+        return Float.intBitsToFloat(w);
+    }
+
+    @ForceInline
+    public final float compareAndExchangeFloatRelease(Object o, long offset,
+                                                  float expected,
+                                                  float x) {
+        int w = compareAndExchangeIntRelease(o, offset,
+                                             Float.floatToRawIntBits(expected),
+                                             Float.floatToRawIntBits(x));
+        return Float.intBitsToFloat(w);
+    }
+
+    @ForceInline
+    public final boolean weakCompareAndSwapFloat(Object o, long offset,
+                                               float expected,
+                                               float x) {
+        return weakCompareAndSwapInt(o, offset,
+                                     Float.floatToRawIntBits(expected),
+                                     Float.floatToRawIntBits(x));
+    }
+
+    @ForceInline
+    public final boolean weakCompareAndSwapFloatAcquire(Object o, long offset,
+                                                      float expected,
+                                                      float x) {
+        return weakCompareAndSwapIntAcquire(o, offset,
+                                            Float.floatToRawIntBits(expected),
+                                            Float.floatToRawIntBits(x));
+    }
+
+    @ForceInline
+    public final boolean weakCompareAndSwapFloatRelease(Object o, long offset,
+                                                      float expected,
+                                                      float x) {
+        return weakCompareAndSwapIntRelease(o, offset,
+                                            Float.floatToRawIntBits(expected),
+                                            Float.floatToRawIntBits(x));
+    }
+
+    @ForceInline
+    public final boolean weakCompareAndSwapFloatVolatile(Object o, long offset,
+                                                       float expected,
+                                                       float x) {
+        return weakCompareAndSwapIntVolatile(o, offset,
+                                             Float.floatToRawIntBits(expected),
+                                             Float.floatToRawIntBits(x));
+    }
+
+    /**
+     * Atomically updates Java variable to {@code x} if it is currently
+     * holding {@code expected}.
+     *
+     * <p>This operation has memory semantics of a {@code volatile} read
+     * and write.  Corresponds to C11 atomic_compare_exchange_strong.
+     *
+     * @return {@code true} if successful
+     */
+    @ForceInline
+    public final boolean compareAndSwapDouble(Object o, long offset,
+                                              double expected,
+                                              double x) {
+        return compareAndSwapLong(o, offset,
+                                  Double.doubleToRawLongBits(expected),
+                                  Double.doubleToRawLongBits(x));
+    }
+
+    @ForceInline
+    public final double compareAndExchangeDoubleVolatile(Object o, long offset,
+                                                         double expected,
+                                                         double x) {
+        long w = compareAndExchangeLongVolatile(o, offset,
+                                                Double.doubleToRawLongBits(expected),
+                                                Double.doubleToRawLongBits(x));
+        return Double.longBitsToDouble(w);
+    }
+
+    @ForceInline
+    public final double compareAndExchangeDoubleAcquire(Object o, long offset,
+                                                        double expected,
+                                                        double x) {
+        long w = compareAndExchangeLongVolatile(o, offset,
+                                                Double.doubleToRawLongBits(expected),
+                                                Double.doubleToRawLongBits(x));
+        return Double.longBitsToDouble(w);
+    }
+
+    @ForceInline
+    public final double compareAndExchangeDoubleRelease(Object o, long offset,
+                                                        double expected,
+                                                        double x) {
+        long w = compareAndExchangeLongRelease(o, offset,
+                                               Double.doubleToRawLongBits(expected),
+                                               Double.doubleToRawLongBits(x));
+        return Double.longBitsToDouble(w);
+    }
+
+    @ForceInline
+    public final boolean weakCompareAndSwapDouble(Object o, long offset,
+                                                  double expected,
+                                                  double x) {
+        return weakCompareAndSwapLong(o, offset,
+                                     Double.doubleToRawLongBits(expected),
+                                     Double.doubleToRawLongBits(x));
+    }
+
+    @ForceInline
+    public final boolean weakCompareAndSwapDoubleAcquire(Object o, long offset,
+                                                         double expected,
+                                                         double x) {
+        return weakCompareAndSwapLongAcquire(o, offset,
+                                             Double.doubleToRawLongBits(expected),
+                                             Double.doubleToRawLongBits(x));
+    }
+
+    @ForceInline
+    public final boolean weakCompareAndSwapDoubleRelease(Object o, long offset,
+                                                         double expected,
+                                                         double x) {
+        return weakCompareAndSwapLongRelease(o, offset,
+                                             Double.doubleToRawLongBits(expected),
+                                             Double.doubleToRawLongBits(x));
+    }
+
+    @ForceInline
+    public final boolean weakCompareAndSwapDoubleVolatile(Object o, long offset,
+                                                          double expected,
+                                                          double x) {
+        return weakCompareAndSwapLongVolatile(o, offset,
+                                              Double.doubleToRawLongBits(expected),
+                                              Double.doubleToRawLongBits(x));
+    }
+
+    /**
+     * Atomically updates Java variable to {@code x} if it is currently
+     * holding {@code expected}.
+     *
+     * <p>This operation has memory semantics of a {@code volatile} read
+     * and write.  Corresponds to C11 atomic_compare_exchange_strong.
+     *
+     * @return {@code true} if successful
+     */
     @HotSpotIntrinsicCandidate
     public final native boolean compareAndSwapLong(Object o, long offset,
                                                    long expected,
@@ -2161,10 +2327,41 @@
         return v;
     }
 
+    @ForceInline
     public final char getAndAddChar(Object o, long offset, char delta) {
         return (char) getAndAddShort(o, offset, (short) delta);
     }
 
+    @ForceInline
+    public final float getAndAddFloat(Object o, long offset, float delta) {
+        int expectedBits;
+        float v;
+        do {
+            // Load and CAS with the raw bits to avoid issues with NaNs and
+            // possible bit conversion from signaling NaNs to quiet NaNs that
+            // may result in the loop not terminating.
+            expectedBits = getIntVolatile(o, offset);
+            v = Float.intBitsToFloat(expectedBits);
+        } while (!weakCompareAndSwapIntVolatile(o, offset,
+                                                expectedBits, Float.floatToRawIntBits(v + delta)));
+        return v;
+    }
+
+    @ForceInline
+    public final double getAndAddDouble(Object o, long offset, double delta) {
+        long expectedBits;
+        double v;
+        do {
+            // Load and CAS with the raw bits to avoid issues with NaNs and
+            // possible bit conversion from signaling NaNs to quiet NaNs that
+            // may result in the loop not terminating.
+            expectedBits = getLongVolatile(o, offset);
+            v = Double.longBitsToDouble(expectedBits);
+        } while (!weakCompareAndSwapLongVolatile(o, offset,
+                                                 expectedBits, Double.doubleToRawLongBits(v + delta)));
+        return v;
+    }
+
     /**
      * Atomically exchanges the given value with the current value of
      * a field or array element within the given object {@code o}
@@ -2234,6 +2431,7 @@
         return v;
     }
 
+    @ForceInline
     public final boolean getAndSetBoolean(Object o, long offset, boolean newValue) {
         return byte2bool(getAndSetByte(o, offset, bool2byte(newValue)));
     }
@@ -2247,10 +2445,23 @@
         return v;
     }
 
+    @ForceInline
     public final char getAndSetChar(Object o, long offset, char newValue) {
         return s2c(getAndSetShort(o, offset, c2s(newValue)));
     }
 
+    @ForceInline
+    public final float getAndSetFloat(Object o, long offset, float newValue) {
+        int v = getAndSetInt(o, offset, Float.floatToRawIntBits(newValue));
+        return Float.intBitsToFloat(v);
+    }
+
+    @ForceInline
+    public final double getAndSetDouble(Object o, long offset, double newValue) {
+        long v = getAndSetLong(o, offset, Double.doubleToRawLongBits(newValue));
+        return Double.longBitsToDouble(v);
+    }
+
     /**
      * Ensures that loads before the fence will not be reordered with loads and
      * stores after the fence; a "LoadLoad plus LoadStore barrier".
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java	Wed Jun 15 11:20:15 2016 +0300
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java	Mon Jun 20 17:57:19 2016 +0200
@@ -99,18 +99,18 @@
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
 
-        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
-        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE));
-        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));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE));
+        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));
 
-        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
-        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET));
     }
 
 
@@ -260,49 +260,7 @@
             vh.setOpaque(recv, 2.0d);
         });
 
-        checkUOE(() -> {
-            boolean r = vh.compareAndSet(recv, 1.0d, 2.0d);
-        });
 
-        checkUOE(() -> {
-            double r = (double) vh.compareAndExchangeVolatile(recv, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            double r = (double) vh.compareAndExchangeAcquire(recv, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            double r = (double) vh.compareAndExchangeRelease(recv, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSet(recv, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetVolatile(recv, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetAcquire(recv, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetRelease(recv, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            double r = (double) vh.getAndSet(recv, 1.0d);
-        });
-
-        checkUOE(() -> {
-            double o = (double) vh.getAndAdd(recv, 1.0d);
-        });
-
-        checkUOE(() -> {
-            double o = (double) vh.addAndGet(recv, 1.0d);
-        });
     }
 
 
@@ -350,49 +308,7 @@
             vh.setOpaque(2.0d);
         });
 
-        checkUOE(() -> {
-            boolean r = vh.compareAndSet(1.0d, 2.0d);
-        });
 
-        checkUOE(() -> {
-            double r = (double) vh.compareAndExchangeVolatile(1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            double r = (double) vh.compareAndExchangeAcquire(1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            double r = (double) vh.compareAndExchangeRelease(1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSet(1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetVolatile(1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetAcquire(1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetRelease(1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            double r = (double) vh.getAndSet(1.0d);
-        });
-
-        checkUOE(() -> {
-            double o = (double) vh.getAndAdd(1.0d);
-        });
-
-        checkUOE(() -> {
-            double o = (double) vh.addAndGet(1.0d);
-        });
     }
 
 
@@ -426,53 +342,126 @@
             assertEquals(x, 2.0d, "setOpaque double value");
         }
 
+        vh.set(recv, 1.0d);
 
+        // Compare
+        {
+            boolean r = vh.compareAndSet(recv, 1.0d, 2.0d);
+            assertEquals(r, true, "success compareAndSet double");
+            double x = (double) vh.get(recv);
+            assertEquals(x, 2.0d, "success compareAndSet double value");
+        }
+
+        {
+            boolean r = vh.compareAndSet(recv, 1.0d, 3.0d);
+            assertEquals(r, false, "failing compareAndSet double");
+            double x = (double) vh.get(recv);
+            assertEquals(x, 2.0d, "failing compareAndSet double value");
+        }
+
+        {
+            double r = (double) vh.compareAndExchangeVolatile(recv, 2.0d, 1.0d);
+            assertEquals(r, 2.0d, "success compareAndExchangeVolatile double");
+            double x = (double) vh.get(recv);
+            assertEquals(x, 1.0d, "success compareAndExchangeVolatile double value");
+        }
+
+        {
+            double r = (double) vh.compareAndExchangeVolatile(recv, 2.0d, 3.0d);
+            assertEquals(r, 1.0d, "failing compareAndExchangeVolatile double");
+            double x = (double) vh.get(recv);
+            assertEquals(x, 1.0d, "failing compareAndExchangeVolatile double value");
+        }
+
+        {
+            double r = (double) vh.compareAndExchangeAcquire(recv, 1.0d, 2.0d);
+            assertEquals(r, 1.0d, "success compareAndExchangeAcquire double");
+            double x = (double) vh.get(recv);
+            assertEquals(x, 2.0d, "success compareAndExchangeAcquire double value");
+        }
+
+        {
+            double r = (double) vh.compareAndExchangeAcquire(recv, 1.0d, 3.0d);
+            assertEquals(r, 2.0d, "failing compareAndExchangeAcquire double");
+            double x = (double) vh.get(recv);
+            assertEquals(x, 2.0d, "failing compareAndExchangeAcquire double value");
+        }
+
+        {
+            double r = (double) vh.compareAndExchangeRelease(recv, 2.0d, 1.0d);
+            assertEquals(r, 2.0d, "success compareAndExchangeRelease double");
+            double x = (double) vh.get(recv);
+            assertEquals(x, 1.0d, "success compareAndExchangeRelease double value");
+        }
+
+        {
+            double r = (double) vh.compareAndExchangeRelease(recv, 2.0d, 3.0d);
+            assertEquals(r, 1.0d, "failing compareAndExchangeRelease double");
+            double x = (double) vh.get(recv);
+            assertEquals(x, 1.0d, "failing compareAndExchangeRelease double value");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = vh.weakCompareAndSet(recv, 1.0d, 2.0d);
+            }
+            assertEquals(success, true, "weakCompareAndSet double");
+            double x = (double) vh.get(recv);
+            assertEquals(x, 2.0d, "weakCompareAndSet double value");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = vh.weakCompareAndSetAcquire(recv, 2.0d, 1.0d);
+            }
+            assertEquals(success, true, "weakCompareAndSetAcquire double");
+            double x = (double) vh.get(recv);
+            assertEquals(x, 1.0d, "weakCompareAndSetAcquire double");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = vh.weakCompareAndSetRelease(recv, 1.0d, 2.0d);
+            }
+            assertEquals(success, true, "weakCompareAndSetRelease double");
+            double x = (double) vh.get(recv);
+            assertEquals(x, 2.0d, "weakCompareAndSetRelease double");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = vh.weakCompareAndSetVolatile(recv, 2.0d, 1.0d);
+            }
+            assertEquals(success, true, "weakCompareAndSetVolatile double");
+            double x = (double) vh.get(recv);
+            assertEquals(x, 1.0d, "weakCompareAndSetVolatile double value");
+        }
+
+        // Compare set and get
+        {
+            double o = (double) vh.getAndSet(recv, 2.0d);
+            assertEquals(o, 1.0d, "getAndSet double");
+            double x = (double) vh.get(recv);
+            assertEquals(x, 2.0d, "getAndSet double value");
+        }
+
+        vh.set(recv, 1.0d);
+
+        // get and add, add and get
+        {
+            double o = (double) vh.getAndAdd(recv, 3.0d);
+            assertEquals(o, 1.0d, "getAndAdd double");
+            double c = (double) vh.addAndGet(recv, 3.0d);
+            assertEquals(c, (double)(1.0d + 3.0d + 3.0d), "getAndAdd double value");
+        }
     }
 
     static void testInstanceFieldUnsupported(VarHandleTestAccessDouble recv, VarHandle vh) {
-        checkUOE(() -> {
-            boolean r = vh.compareAndSet(recv, 1.0d, 2.0d);
-        });
 
-        checkUOE(() -> {
-            double r = (double) vh.compareAndExchangeVolatile(recv, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            double r = (double) vh.compareAndExchangeAcquire(recv, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            double r = (double) vh.compareAndExchangeRelease(recv, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSet(recv, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetVolatile(recv, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetAcquire(recv, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetRelease(recv, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            double r = (double) vh.getAndSet(recv, 1.0d);
-        });
-
-        checkUOE(() -> {
-            double o = (double) vh.getAndAdd(recv, 1.0d);
-        });
-
-        checkUOE(() -> {
-            double o = (double) vh.addAndGet(recv, 1.0d);
-        });
     }
 
 
@@ -506,53 +495,126 @@
             assertEquals(x, 2.0d, "setOpaque double value");
         }
 
+        vh.set(1.0d);
 
+        // Compare
+        {
+            boolean r = vh.compareAndSet(1.0d, 2.0d);
+            assertEquals(r, true, "success compareAndSet double");
+            double x = (double) vh.get();
+            assertEquals(x, 2.0d, "success compareAndSet double value");
+        }
+
+        {
+            boolean r = vh.compareAndSet(1.0d, 3.0d);
+            assertEquals(r, false, "failing compareAndSet double");
+            double x = (double) vh.get();
+            assertEquals(x, 2.0d, "failing compareAndSet double value");
+        }
+
+        {
+            double r = (double) vh.compareAndExchangeVolatile(2.0d, 1.0d);
+            assertEquals(r, 2.0d, "success compareAndExchangeVolatile double");
+            double x = (double) vh.get();
+            assertEquals(x, 1.0d, "success compareAndExchangeVolatile double value");
+        }
+
+        {
+            double r = (double) vh.compareAndExchangeVolatile(2.0d, 3.0d);
+            assertEquals(r, 1.0d, "failing compareAndExchangeVolatile double");
+            double x = (double) vh.get();
+            assertEquals(x, 1.0d, "failing compareAndExchangeVolatile double value");
+        }
+
+        {
+            double r = (double) vh.compareAndExchangeAcquire(1.0d, 2.0d);
+            assertEquals(r, 1.0d, "success compareAndExchangeAcquire double");
+            double x = (double) vh.get();
+            assertEquals(x, 2.0d, "success compareAndExchangeAcquire double value");
+        }
+
+        {
+            double r = (double) vh.compareAndExchangeAcquire(1.0d, 3.0d);
+            assertEquals(r, 2.0d, "failing compareAndExchangeAcquire double");
+            double x = (double) vh.get();
+            assertEquals(x, 2.0d, "failing compareAndExchangeAcquire double value");
+        }
+
+        {
+            double r = (double) vh.compareAndExchangeRelease(2.0d, 1.0d);
+            assertEquals(r, 2.0d, "success compareAndExchangeRelease double");
+            double x = (double) vh.get();
+            assertEquals(x, 1.0d, "success compareAndExchangeRelease double value");
+        }
+
+        {
+            double r = (double) vh.compareAndExchangeRelease(2.0d, 3.0d);
+            assertEquals(r, 1.0d, "failing compareAndExchangeRelease double");
+            double x = (double) vh.get();
+            assertEquals(x, 1.0d, "failing compareAndExchangeRelease double value");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = vh.weakCompareAndSet(1.0d, 2.0d);
+            }
+            assertEquals(success, true, "weakCompareAndSet double");
+            double x = (double) vh.get();
+            assertEquals(x, 2.0d, "weakCompareAndSet double value");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = vh.weakCompareAndSetAcquire(2.0d, 1.0d);
+            }
+            assertEquals(success, true, "weakCompareAndSetAcquire double");
+            double x = (double) vh.get();
+            assertEquals(x, 1.0d, "weakCompareAndSetAcquire double");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = vh.weakCompareAndSetRelease(1.0d, 2.0d);
+            }
+            assertEquals(success, true, "weakCompareAndSetRelease double");
+            double x = (double) vh.get();
+            assertEquals(x, 2.0d, "weakCompareAndSetRelease double");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = vh.weakCompareAndSetRelease(2.0d, 1.0d);
+            }
+            assertEquals(success, true, "weakCompareAndSetVolatile double");
+            double x = (double) vh.get();
+            assertEquals(x, 1.0d, "weakCompareAndSetVolatile double");
+        }
+
+        // Compare set and get
+        {
+            double o = (double) vh.getAndSet(2.0d);
+            assertEquals(o, 1.0d, "getAndSet double");
+            double x = (double) vh.get();
+            assertEquals(x, 2.0d, "getAndSet double value");
+        }
+
+        vh.set(1.0d);
+
+        // get and add, add and get
+        {
+            double o = (double) vh.getAndAdd( 3.0d);
+            assertEquals(o, 1.0d, "getAndAdd double");
+            double c = (double) vh.addAndGet(3.0d);
+            assertEquals(c, (double)(1.0d + 3.0d + 3.0d), "getAndAdd double value");
+        }
     }
 
     static void testStaticFieldUnsupported(VarHandle vh) {
-        checkUOE(() -> {
-            boolean r = vh.compareAndSet(1.0d, 2.0d);
-        });
 
-        checkUOE(() -> {
-            double r = (double) vh.compareAndExchangeVolatile(1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            double r = (double) vh.compareAndExchangeAcquire(1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            double r = (double) vh.compareAndExchangeRelease(1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSet(1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetVolatile(1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetAcquire(1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetRelease(1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            double r = (double) vh.getAndSet(1.0d);
-        });
-
-        checkUOE(() -> {
-            double o = (double) vh.getAndAdd(1.0d);
-        });
-
-        checkUOE(() -> {
-            double o = (double) vh.addAndGet(1.0d);
-        });
     }
 
 
@@ -589,7 +651,122 @@
                 assertEquals(x, 2.0d, "setOpaque double value");
             }
 
+            vh.set(array, i, 1.0d);
 
+            // Compare
+            {
+                boolean r = vh.compareAndSet(array, i, 1.0d, 2.0d);
+                assertEquals(r, true, "success compareAndSet double");
+                double x = (double) vh.get(array, i);
+                assertEquals(x, 2.0d, "success compareAndSet double value");
+            }
+
+            {
+                boolean r = vh.compareAndSet(array, i, 1.0d, 3.0d);
+                assertEquals(r, false, "failing compareAndSet double");
+                double x = (double) vh.get(array, i);
+                assertEquals(x, 2.0d, "failing compareAndSet double value");
+            }
+
+            {
+                double r = (double) vh.compareAndExchangeVolatile(array, i, 2.0d, 1.0d);
+                assertEquals(r, 2.0d, "success compareAndExchangeVolatile double");
+                double x = (double) vh.get(array, i);
+                assertEquals(x, 1.0d, "success compareAndExchangeVolatile double value");
+            }
+
+            {
+                double r = (double) vh.compareAndExchangeVolatile(array, i, 2.0d, 3.0d);
+                assertEquals(r, 1.0d, "failing compareAndExchangeVolatile double");
+                double x = (double) vh.get(array, i);
+                assertEquals(x, 1.0d, "failing compareAndExchangeVolatile double value");
+            }
+
+            {
+                double r = (double) vh.compareAndExchangeAcquire(array, i, 1.0d, 2.0d);
+                assertEquals(r, 1.0d, "success compareAndExchangeAcquire double");
+                double x = (double) vh.get(array, i);
+                assertEquals(x, 2.0d, "success compareAndExchangeAcquire double value");
+            }
+
+            {
+                double r = (double) vh.compareAndExchangeAcquire(array, i, 1.0d, 3.0d);
+                assertEquals(r, 2.0d, "failing compareAndExchangeAcquire double");
+                double x = (double) vh.get(array, i);
+                assertEquals(x, 2.0d, "failing compareAndExchangeAcquire double value");
+            }
+
+            {
+                double r = (double) vh.compareAndExchangeRelease(array, i, 2.0d, 1.0d);
+                assertEquals(r, 2.0d, "success compareAndExchangeRelease double");
+                double x = (double) vh.get(array, i);
+                assertEquals(x, 1.0d, "success compareAndExchangeRelease double value");
+            }
+
+            {
+                double r = (double) vh.compareAndExchangeRelease(array, i, 2.0d, 3.0d);
+                assertEquals(r, 1.0d, "failing compareAndExchangeRelease double");
+                double x = (double) vh.get(array, i);
+                assertEquals(x, 1.0d, "failing compareAndExchangeRelease double value");
+            }
+
+            {
+                boolean success = false;
+                for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                    success = vh.weakCompareAndSet(array, i, 1.0d, 2.0d);
+                }
+                assertEquals(success, true, "weakCompareAndSet double");
+                double x = (double) vh.get(array, i);
+                assertEquals(x, 2.0d, "weakCompareAndSet double value");
+            }
+
+            {
+                boolean success = false;
+                for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                    success = vh.weakCompareAndSetAcquire(array, i, 2.0d, 1.0d);
+                }
+                assertEquals(success, true, "weakCompareAndSetAcquire double");
+                double x = (double) vh.get(array, i);
+                assertEquals(x, 1.0d, "weakCompareAndSetAcquire double");
+            }
+
+            {
+                boolean success = false;
+                for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                    success = vh.weakCompareAndSetRelease(array, i, 1.0d, 2.0d);
+                }
+                assertEquals(success, true, "weakCompareAndSetRelease double");
+                double x = (double) vh.get(array, i);
+                assertEquals(x, 2.0d, "weakCompareAndSetRelease double");
+            }
+
+            {
+                boolean success = false;
+                for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                    success = vh.weakCompareAndSetVolatile(array, i, 2.0d, 1.0d);
+                }
+                assertEquals(success, true, "weakCompareAndSetVolatile double");
+                double x = (double) vh.get(array, i);
+                assertEquals(x, 1.0d, "weakCompareAndSetVolatile double");
+            }
+
+            // Compare set and get
+            {
+                double o = (double) vh.getAndSet(array, i, 2.0d);
+                assertEquals(o, 1.0d, "getAndSet double");
+                double x = (double) vh.get(array, i);
+                assertEquals(x, 2.0d, "getAndSet double value");
+            }
+
+            vh.set(array, i, 1.0d);
+
+            // get and add, add and get
+            {
+                double o = (double) vh.getAndAdd(array, i, 3.0d);
+                assertEquals(o, 1.0d, "getAndAdd double");
+                double c = (double) vh.addAndGet(array, i, 3.0d);
+                assertEquals(c, (double)(1.0d + 3.0d + 3.0d), "getAndAdd double value");
+            }
         }
     }
 
@@ -597,49 +774,7 @@
         double[] array = new double[10];
 
         int i = 0;
-        checkUOE(() -> {
-            boolean r = vh.compareAndSet(array, i, 1.0d, 2.0d);
-        });
 
-        checkUOE(() -> {
-            double r = (double) vh.compareAndExchangeVolatile(array, i, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            double r = (double) vh.compareAndExchangeAcquire(array, i, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            double r = (double) vh.compareAndExchangeRelease(array, i, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSet(array, i, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetVolatile(array, i, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetAcquire(array, i, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetRelease(array, i, 1.0d, 2.0d);
-        });
-
-        checkUOE(() -> {
-            double r = (double) vh.getAndSet(array, i, 1.0d);
-        });
-
-        checkUOE(() -> {
-            double o = (double) vh.getAndAdd(array, i, 1.0d);
-        });
-
-        checkUOE(() -> {
-            double o = (double) vh.addAndGet(array, i, 1.0d);
-        });
     }
 
     static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
@@ -680,7 +815,49 @@
                 vh.setOpaque(array, ci, 1.0d);
             });
 
+            checkIOOBE(() -> {
+                boolean r = vh.compareAndSet(array, ci, 1.0d, 2.0d);
+            });
 
+            checkIOOBE(() -> {
+                double r = (double) vh.compareAndExchangeVolatile(array, ci, 2.0d, 1.0d);
+            });
+
+            checkIOOBE(() -> {
+                double r = (double) vh.compareAndExchangeAcquire(array, ci, 2.0d, 1.0d);
+            });
+
+            checkIOOBE(() -> {
+                double r = (double) vh.compareAndExchangeRelease(array, ci, 2.0d, 1.0d);
+            });
+
+            checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSet(array, ci, 1.0d, 2.0d);
+            });
+
+            checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, 1.0d, 2.0d);
+            });
+
+            checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetAcquire(array, ci, 1.0d, 2.0d);
+            });
+
+            checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetRelease(array, ci, 1.0d, 2.0d);
+            });
+
+            checkIOOBE(() -> {
+                double o = (double) vh.getAndSet(array, ci, 1.0d);
+            });
+
+            checkIOOBE(() -> {
+                double o = (double) vh.getAndAdd(array, ci, 3.0d);
+            });
+
+            checkIOOBE(() -> {
+                double o = (double) vh.addAndGet(array, ci, 3.0d);
+            });
         }
     }
 }
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java	Wed Jun 15 11:20:15 2016 +0300
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java	Mon Jun 20 17:57:19 2016 +0200
@@ -99,18 +99,18 @@
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
 
-        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
-        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE));
-        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));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE));
+        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));
 
-        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
-        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET));
     }
 
 
@@ -260,49 +260,7 @@
             vh.setOpaque(recv, 2.0f);
         });
 
-        checkUOE(() -> {
-            boolean r = vh.compareAndSet(recv, 1.0f, 2.0f);
-        });
 
-        checkUOE(() -> {
-            float r = (float) vh.compareAndExchangeVolatile(recv, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            float r = (float) vh.compareAndExchangeAcquire(recv, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            float r = (float) vh.compareAndExchangeRelease(recv, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSet(recv, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetVolatile(recv, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetAcquire(recv, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetRelease(recv, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            float r = (float) vh.getAndSet(recv, 1.0f);
-        });
-
-        checkUOE(() -> {
-            float o = (float) vh.getAndAdd(recv, 1.0f);
-        });
-
-        checkUOE(() -> {
-            float o = (float) vh.addAndGet(recv, 1.0f);
-        });
     }
 
 
@@ -350,49 +308,7 @@
             vh.setOpaque(2.0f);
         });
 
-        checkUOE(() -> {
-            boolean r = vh.compareAndSet(1.0f, 2.0f);
-        });
 
-        checkUOE(() -> {
-            float r = (float) vh.compareAndExchangeVolatile(1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            float r = (float) vh.compareAndExchangeAcquire(1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            float r = (float) vh.compareAndExchangeRelease(1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSet(1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetVolatile(1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetAcquire(1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetRelease(1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            float r = (float) vh.getAndSet(1.0f);
-        });
-
-        checkUOE(() -> {
-            float o = (float) vh.getAndAdd(1.0f);
-        });
-
-        checkUOE(() -> {
-            float o = (float) vh.addAndGet(1.0f);
-        });
     }
 
 
@@ -426,53 +342,126 @@
             assertEquals(x, 2.0f, "setOpaque float value");
         }
 
+        vh.set(recv, 1.0f);
 
+        // Compare
+        {
+            boolean r = vh.compareAndSet(recv, 1.0f, 2.0f);
+            assertEquals(r, true, "success compareAndSet float");
+            float x = (float) vh.get(recv);
+            assertEquals(x, 2.0f, "success compareAndSet float value");
+        }
+
+        {
+            boolean r = vh.compareAndSet(recv, 1.0f, 3.0f);
+            assertEquals(r, false, "failing compareAndSet float");
+            float x = (float) vh.get(recv);
+            assertEquals(x, 2.0f, "failing compareAndSet float value");
+        }
+
+        {
+            float r = (float) vh.compareAndExchangeVolatile(recv, 2.0f, 1.0f);
+            assertEquals(r, 2.0f, "success compareAndExchangeVolatile float");
+            float x = (float) vh.get(recv);
+            assertEquals(x, 1.0f, "success compareAndExchangeVolatile float value");
+        }
+
+        {
+            float r = (float) vh.compareAndExchangeVolatile(recv, 2.0f, 3.0f);
+            assertEquals(r, 1.0f, "failing compareAndExchangeVolatile float");
+            float x = (float) vh.get(recv);
+            assertEquals(x, 1.0f, "failing compareAndExchangeVolatile float value");
+        }
+
+        {
+            float r = (float) vh.compareAndExchangeAcquire(recv, 1.0f, 2.0f);
+            assertEquals(r, 1.0f, "success compareAndExchangeAcquire float");
+            float x = (float) vh.get(recv);
+            assertEquals(x, 2.0f, "success compareAndExchangeAcquire float value");
+        }
+
+        {
+            float r = (float) vh.compareAndExchangeAcquire(recv, 1.0f, 3.0f);
+            assertEquals(r, 2.0f, "failing compareAndExchangeAcquire float");
+            float x = (float) vh.get(recv);
+            assertEquals(x, 2.0f, "failing compareAndExchangeAcquire float value");
+        }
+
+        {
+            float r = (float) vh.compareAndExchangeRelease(recv, 2.0f, 1.0f);
+            assertEquals(r, 2.0f, "success compareAndExchangeRelease float");
+            float x = (float) vh.get(recv);
+            assertEquals(x, 1.0f, "success compareAndExchangeRelease float value");
+        }
+
+        {
+            float r = (float) vh.compareAndExchangeRelease(recv, 2.0f, 3.0f);
+            assertEquals(r, 1.0f, "failing compareAndExchangeRelease float");
+            float x = (float) vh.get(recv);
+            assertEquals(x, 1.0f, "failing compareAndExchangeRelease float value");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = vh.weakCompareAndSet(recv, 1.0f, 2.0f);
+            }
+            assertEquals(success, true, "weakCompareAndSet float");
+            float x = (float) vh.get(recv);
+            assertEquals(x, 2.0f, "weakCompareAndSet float value");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = vh.weakCompareAndSetAcquire(recv, 2.0f, 1.0f);
+            }
+            assertEquals(success, true, "weakCompareAndSetAcquire float");
+            float x = (float) vh.get(recv);
+            assertEquals(x, 1.0f, "weakCompareAndSetAcquire float");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = vh.weakCompareAndSetRelease(recv, 1.0f, 2.0f);
+            }
+            assertEquals(success, true, "weakCompareAndSetRelease float");
+            float x = (float) vh.get(recv);
+            assertEquals(x, 2.0f, "weakCompareAndSetRelease float");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = vh.weakCompareAndSetVolatile(recv, 2.0f, 1.0f);
+            }
+            assertEquals(success, true, "weakCompareAndSetVolatile float");
+            float x = (float) vh.get(recv);
+            assertEquals(x, 1.0f, "weakCompareAndSetVolatile float value");
+        }
+
+        // Compare set and get
+        {
+            float o = (float) vh.getAndSet(recv, 2.0f);
+            assertEquals(o, 1.0f, "getAndSet float");
+            float x = (float) vh.get(recv);
+            assertEquals(x, 2.0f, "getAndSet float value");
+        }
+
+        vh.set(recv, 1.0f);
+
+        // get and add, add and get
+        {
+            float o = (float) vh.getAndAdd(recv, 3.0f);
+            assertEquals(o, 1.0f, "getAndAdd float");
+            float c = (float) vh.addAndGet(recv, 3.0f);
+            assertEquals(c, (float)(1.0f + 3.0f + 3.0f), "getAndAdd float value");
+        }
     }
 
     static void testInstanceFieldUnsupported(VarHandleTestAccessFloat recv, VarHandle vh) {
-        checkUOE(() -> {
-            boolean r = vh.compareAndSet(recv, 1.0f, 2.0f);
-        });
 
-        checkUOE(() -> {
-            float r = (float) vh.compareAndExchangeVolatile(recv, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            float r = (float) vh.compareAndExchangeAcquire(recv, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            float r = (float) vh.compareAndExchangeRelease(recv, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSet(recv, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetVolatile(recv, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetAcquire(recv, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetRelease(recv, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            float r = (float) vh.getAndSet(recv, 1.0f);
-        });
-
-        checkUOE(() -> {
-            float o = (float) vh.getAndAdd(recv, 1.0f);
-        });
-
-        checkUOE(() -> {
-            float o = (float) vh.addAndGet(recv, 1.0f);
-        });
     }
 
 
@@ -506,53 +495,126 @@
             assertEquals(x, 2.0f, "setOpaque float value");
         }
 
+        vh.set(1.0f);
 
+        // Compare
+        {
+            boolean r = vh.compareAndSet(1.0f, 2.0f);
+            assertEquals(r, true, "success compareAndSet float");
+            float x = (float) vh.get();
+            assertEquals(x, 2.0f, "success compareAndSet float value");
+        }
+
+        {
+            boolean r = vh.compareAndSet(1.0f, 3.0f);
+            assertEquals(r, false, "failing compareAndSet float");
+            float x = (float) vh.get();
+            assertEquals(x, 2.0f, "failing compareAndSet float value");
+        }
+
+        {
+            float r = (float) vh.compareAndExchangeVolatile(2.0f, 1.0f);
+            assertEquals(r, 2.0f, "success compareAndExchangeVolatile float");
+            float x = (float) vh.get();
+            assertEquals(x, 1.0f, "success compareAndExchangeVolatile float value");
+        }
+
+        {
+            float r = (float) vh.compareAndExchangeVolatile(2.0f, 3.0f);
+            assertEquals(r, 1.0f, "failing compareAndExchangeVolatile float");
+            float x = (float) vh.get();
+            assertEquals(x, 1.0f, "failing compareAndExchangeVolatile float value");
+        }
+
+        {
+            float r = (float) vh.compareAndExchangeAcquire(1.0f, 2.0f);
+            assertEquals(r, 1.0f, "success compareAndExchangeAcquire float");
+            float x = (float) vh.get();
+            assertEquals(x, 2.0f, "success compareAndExchangeAcquire float value");
+        }
+
+        {
+            float r = (float) vh.compareAndExchangeAcquire(1.0f, 3.0f);
+            assertEquals(r, 2.0f, "failing compareAndExchangeAcquire float");
+            float x = (float) vh.get();
+            assertEquals(x, 2.0f, "failing compareAndExchangeAcquire float value");
+        }
+
+        {
+            float r = (float) vh.compareAndExchangeRelease(2.0f, 1.0f);
+            assertEquals(r, 2.0f, "success compareAndExchangeRelease float");
+            float x = (float) vh.get();
+            assertEquals(x, 1.0f, "success compareAndExchangeRelease float value");
+        }
+
+        {
+            float r = (float) vh.compareAndExchangeRelease(2.0f, 3.0f);
+            assertEquals(r, 1.0f, "failing compareAndExchangeRelease float");
+            float x = (float) vh.get();
+            assertEquals(x, 1.0f, "failing compareAndExchangeRelease float value");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = vh.weakCompareAndSet(1.0f, 2.0f);
+            }
+            assertEquals(success, true, "weakCompareAndSet float");
+            float x = (float) vh.get();
+            assertEquals(x, 2.0f, "weakCompareAndSet float value");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = vh.weakCompareAndSetAcquire(2.0f, 1.0f);
+            }
+            assertEquals(success, true, "weakCompareAndSetAcquire float");
+            float x = (float) vh.get();
+            assertEquals(x, 1.0f, "weakCompareAndSetAcquire float");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = vh.weakCompareAndSetRelease(1.0f, 2.0f);
+            }
+            assertEquals(success, true, "weakCompareAndSetRelease float");
+            float x = (float) vh.get();
+            assertEquals(x, 2.0f, "weakCompareAndSetRelease float");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = vh.weakCompareAndSetRelease(2.0f, 1.0f);
+            }
+            assertEquals(success, true, "weakCompareAndSetVolatile float");
+            float x = (float) vh.get();
+            assertEquals(x, 1.0f, "weakCompareAndSetVolatile float");
+        }
+
+        // Compare set and get
+        {
+            float o = (float) vh.getAndSet(2.0f);
+            assertEquals(o, 1.0f, "getAndSet float");
+            float x = (float) vh.get();
+            assertEquals(x, 2.0f, "getAndSet float value");
+        }
+
+        vh.set(1.0f);
+
+        // get and add, add and get
+        {
+            float o = (float) vh.getAndAdd( 3.0f);
+            assertEquals(o, 1.0f, "getAndAdd float");
+            float c = (float) vh.addAndGet(3.0f);
+            assertEquals(c, (float)(1.0f + 3.0f + 3.0f), "getAndAdd float value");
+        }
     }
 
     static void testStaticFieldUnsupported(VarHandle vh) {
-        checkUOE(() -> {
-            boolean r = vh.compareAndSet(1.0f, 2.0f);
-        });
 
-        checkUOE(() -> {
-            float r = (float) vh.compareAndExchangeVolatile(1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            float r = (float) vh.compareAndExchangeAcquire(1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            float r = (float) vh.compareAndExchangeRelease(1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSet(1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetVolatile(1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetAcquire(1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetRelease(1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            float r = (float) vh.getAndSet(1.0f);
-        });
-
-        checkUOE(() -> {
-            float o = (float) vh.getAndAdd(1.0f);
-        });
-
-        checkUOE(() -> {
-            float o = (float) vh.addAndGet(1.0f);
-        });
     }
 
 
@@ -589,7 +651,122 @@
                 assertEquals(x, 2.0f, "setOpaque float value");
             }
 
+            vh.set(array, i, 1.0f);
 
+            // Compare
+            {
+                boolean r = vh.compareAndSet(array, i, 1.0f, 2.0f);
+                assertEquals(r, true, "success compareAndSet float");
+                float x = (float) vh.get(array, i);
+                assertEquals(x, 2.0f, "success compareAndSet float value");
+            }
+
+            {
+                boolean r = vh.compareAndSet(array, i, 1.0f, 3.0f);
+                assertEquals(r, false, "failing compareAndSet float");
+                float x = (float) vh.get(array, i);
+                assertEquals(x, 2.0f, "failing compareAndSet float value");
+            }
+
+            {
+                float r = (float) vh.compareAndExchangeVolatile(array, i, 2.0f, 1.0f);
+                assertEquals(r, 2.0f, "success compareAndExchangeVolatile float");
+                float x = (float) vh.get(array, i);
+                assertEquals(x, 1.0f, "success compareAndExchangeVolatile float value");
+            }
+
+            {
+                float r = (float) vh.compareAndExchangeVolatile(array, i, 2.0f, 3.0f);
+                assertEquals(r, 1.0f, "failing compareAndExchangeVolatile float");
+                float x = (float) vh.get(array, i);
+                assertEquals(x, 1.0f, "failing compareAndExchangeVolatile float value");
+            }
+
+            {
+                float r = (float) vh.compareAndExchangeAcquire(array, i, 1.0f, 2.0f);
+                assertEquals(r, 1.0f, "success compareAndExchangeAcquire float");
+                float x = (float) vh.get(array, i);
+                assertEquals(x, 2.0f, "success compareAndExchangeAcquire float value");
+            }
+
+            {
+                float r = (float) vh.compareAndExchangeAcquire(array, i, 1.0f, 3.0f);
+                assertEquals(r, 2.0f, "failing compareAndExchangeAcquire float");
+                float x = (float) vh.get(array, i);
+                assertEquals(x, 2.0f, "failing compareAndExchangeAcquire float value");
+            }
+
+            {
+                float r = (float) vh.compareAndExchangeRelease(array, i, 2.0f, 1.0f);
+                assertEquals(r, 2.0f, "success compareAndExchangeRelease float");
+                float x = (float) vh.get(array, i);
+                assertEquals(x, 1.0f, "success compareAndExchangeRelease float value");
+            }
+
+            {
+                float r = (float) vh.compareAndExchangeRelease(array, i, 2.0f, 3.0f);
+                assertEquals(r, 1.0f, "failing compareAndExchangeRelease float");
+                float x = (float) vh.get(array, i);
+                assertEquals(x, 1.0f, "failing compareAndExchangeRelease float value");
+            }
+
+            {
+                boolean success = false;
+                for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                    success = vh.weakCompareAndSet(array, i, 1.0f, 2.0f);
+                }
+                assertEquals(success, true, "weakCompareAndSet float");
+                float x = (float) vh.get(array, i);
+                assertEquals(x, 2.0f, "weakCompareAndSet float value");
+            }
+
+            {
+                boolean success = false;
+                for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                    success = vh.weakCompareAndSetAcquire(array, i, 2.0f, 1.0f);
+                }
+                assertEquals(success, true, "weakCompareAndSetAcquire float");
+                float x = (float) vh.get(array, i);
+                assertEquals(x, 1.0f, "weakCompareAndSetAcquire float");
+            }
+
+            {
+                boolean success = false;
+                for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                    success = vh.weakCompareAndSetRelease(array, i, 1.0f, 2.0f);
+                }
+                assertEquals(success, true, "weakCompareAndSetRelease float");
+                float x = (float) vh.get(array, i);
+                assertEquals(x, 2.0f, "weakCompareAndSetRelease float");
+            }
+
+            {
+                boolean success = false;
+                for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                    success = vh.weakCompareAndSetVolatile(array, i, 2.0f, 1.0f);
+                }
+                assertEquals(success, true, "weakCompareAndSetVolatile float");
+                float x = (float) vh.get(array, i);
+                assertEquals(x, 1.0f, "weakCompareAndSetVolatile float");
+            }
+
+            // Compare set and get
+            {
+                float o = (float) vh.getAndSet(array, i, 2.0f);
+                assertEquals(o, 1.0f, "getAndSet float");
+                float x = (float) vh.get(array, i);
+                assertEquals(x, 2.0f, "getAndSet float value");
+            }
+
+            vh.set(array, i, 1.0f);
+
+            // get and add, add and get
+            {
+                float o = (float) vh.getAndAdd(array, i, 3.0f);
+                assertEquals(o, 1.0f, "getAndAdd float");
+                float c = (float) vh.addAndGet(array, i, 3.0f);
+                assertEquals(c, (float)(1.0f + 3.0f + 3.0f), "getAndAdd float value");
+            }
         }
     }
 
@@ -597,49 +774,7 @@
         float[] array = new float[10];
 
         int i = 0;
-        checkUOE(() -> {
-            boolean r = vh.compareAndSet(array, i, 1.0f, 2.0f);
-        });
 
-        checkUOE(() -> {
-            float r = (float) vh.compareAndExchangeVolatile(array, i, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            float r = (float) vh.compareAndExchangeAcquire(array, i, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            float r = (float) vh.compareAndExchangeRelease(array, i, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSet(array, i, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetVolatile(array, i, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetAcquire(array, i, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            boolean r = vh.weakCompareAndSetRelease(array, i, 1.0f, 2.0f);
-        });
-
-        checkUOE(() -> {
-            float r = (float) vh.getAndSet(array, i, 1.0f);
-        });
-
-        checkUOE(() -> {
-            float o = (float) vh.getAndAdd(array, i, 1.0f);
-        });
-
-        checkUOE(() -> {
-            float o = (float) vh.addAndGet(array, i, 1.0f);
-        });
     }
 
     static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
@@ -680,7 +815,49 @@
                 vh.setOpaque(array, ci, 1.0f);
             });
 
+            checkIOOBE(() -> {
+                boolean r = vh.compareAndSet(array, ci, 1.0f, 2.0f);
+            });
 
+            checkIOOBE(() -> {
+                float r = (float) vh.compareAndExchangeVolatile(array, ci, 2.0f, 1.0f);
+            });
+
+            checkIOOBE(() -> {
+                float r = (float) vh.compareAndExchangeAcquire(array, ci, 2.0f, 1.0f);
+            });
+
+            checkIOOBE(() -> {
+                float r = (float) vh.compareAndExchangeRelease(array, ci, 2.0f, 1.0f);
+            });
+
+            checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSet(array, ci, 1.0f, 2.0f);
+            });
+
+            checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, 1.0f, 2.0f);
+            });
+
+            checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetAcquire(array, ci, 1.0f, 2.0f);
+            });
+
+            checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetRelease(array, ci, 1.0f, 2.0f);
+            });
+
+            checkIOOBE(() -> {
+                float o = (float) vh.getAndSet(array, ci, 1.0f);
+            });
+
+            checkIOOBE(() -> {
+                float o = (float) vh.getAndAdd(array, ci, 3.0f);
+            });
+
+            checkIOOBE(() -> {
+                float o = (float) vh.addAndGet(array, ci, 3.0f);
+            });
         }
     }
 }
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java	Wed Jun 15 11:20:15 2016 +0300
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java	Mon Jun 20 17:57:19 2016 +0200
@@ -148,33 +148,126 @@
             assertEquals(x, 2.0d, "setOpaque double value");
         }
 
+        hs.get(TestAccessMode.SET).invokeExact(recv, 1.0d);
 
+        // Compare
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, 1.0d, 2.0d);
+            assertEquals(r, true, "success compareAndSet double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 2.0d, "success compareAndSet double value");
+        }
+
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, 1.0d, 3.0d);
+            assertEquals(r, false, "failing compareAndSet double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 2.0d, "failing compareAndSet double value");
+        }
+
+        {
+            double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact(recv, 2.0d, 1.0d);
+            assertEquals(r, 2.0d, "success compareAndExchangeVolatile double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 1.0d, "success compareAndExchangeVolatile double value");
+        }
+
+        {
+            double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact(recv, 2.0d, 3.0d);
+            assertEquals(r, 1.0d, "failing compareAndExchangeVolatile double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 1.0d, "failing compareAndExchangeVolatile double value");
+        }
+
+        {
+            double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, 1.0d, 2.0d);
+            assertEquals(r, 1.0d, "success compareAndExchangeAcquire double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 2.0d, "success compareAndExchangeAcquire double value");
+        }
+
+        {
+            double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, 1.0d, 3.0d);
+            assertEquals(r, 2.0d, "failing compareAndExchangeAcquire double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 2.0d, "failing compareAndExchangeAcquire double value");
+        }
+
+        {
+            double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, 2.0d, 1.0d);
+            assertEquals(r, 2.0d, "success compareAndExchangeRelease double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 1.0d, "success compareAndExchangeRelease double value");
+        }
+
+        {
+            double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, 2.0d, 3.0d);
+            assertEquals(r, 1.0d, "failing compareAndExchangeRelease double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 1.0d, "failing compareAndExchangeRelease double value");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 1.0d, 2.0d);
+            }
+            assertEquals(success, true, "weakCompareAndSet double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 2.0d, "weakCompareAndSet double value");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 2.0d, 1.0d);
+            }
+            assertEquals(success, true, "weakCompareAndSetAcquire double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 1.0d, "weakCompareAndSetAcquire double");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 1.0d, 2.0d);
+            }
+            assertEquals(success, true, "weakCompareAndSetRelease double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 2.0d, "weakCompareAndSetRelease double");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(recv, 2.0d, 1.0d);
+            }
+            assertEquals(success, true, "weakCompareAndSetVolatile double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 1.0d, "weakCompareAndSetVolatile double");
+        }
+
+        // Compare set and get
+        {
+            double o = (double) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, 2.0d);
+            assertEquals(o, 1.0d, "getAndSet double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 2.0d, "getAndSet double value");
+        }
+
+        hs.get(TestAccessMode.SET).invokeExact(recv, 1.0d);
+
+        // get and add, add and get
+        {
+            double o = (double) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(recv, 3.0d);
+            assertEquals(o, 1.0d, "getAndAdd double");
+            double c = (double) hs.get(TestAccessMode.ADD_AND_GET).invokeExact(recv, 3.0d);
+            assertEquals(c, (double)(1.0d + 3.0d + 3.0d), "getAndAdd double value");
+        }
     }
 
     static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessDouble recv, Handles hs) throws Throwable {
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
-            checkUOE(am, () -> {
-                boolean r = (boolean) hs.get(am).invokeExact(recv, 1.0d, 2.0d);
-            });
-        }
 
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
-            checkUOE(am, () -> {
-                double r = (double) hs.get(am).invokeExact(recv, 1.0d, 2.0d);
-            });
-        }
-
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
-            checkUOE(am, () -> {
-                double r = (double) hs.get(am).invokeExact(recv, 1.0d);
-            });
-        }
-
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
-            checkUOE(am, () -> {
-                double r = (double) hs.get(am).invokeExact(recv, 1.0d);
-            });
-        }
     }
 
 
@@ -208,33 +301,126 @@
             assertEquals(x, 2.0d, "setOpaque double value");
         }
 
+        hs.get(TestAccessMode.SET).invokeExact(1.0d);
 
+        // Compare
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(1.0d, 2.0d);
+            assertEquals(r, true, "success compareAndSet double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 2.0d, "success compareAndSet double value");
+        }
+
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(1.0d, 3.0d);
+            assertEquals(r, false, "failing compareAndSet double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 2.0d, "failing compareAndSet double value");
+        }
+
+        {
+            double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact(2.0d, 1.0d);
+            assertEquals(r, 2.0d, "success compareAndExchangeVolatile double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 1.0d, "success compareAndExchangeVolatile double value");
+        }
+
+        {
+            double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact(2.0d, 3.0d);
+            assertEquals(r, 1.0d, "failing compareAndExchangeVolatile double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 1.0d, "failing compareAndExchangeVolatile double value");
+        }
+
+        {
+            double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(1.0d, 2.0d);
+            assertEquals(r, 1.0d, "success compareAndExchangeAcquire double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 2.0d, "success compareAndExchangeAcquire double value");
+        }
+
+        {
+            double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(1.0d, 3.0d);
+            assertEquals(r, 2.0d, "failing compareAndExchangeAcquire double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 2.0d, "failing compareAndExchangeAcquire double value");
+        }
+
+        {
+            double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(2.0d, 1.0d);
+            assertEquals(r, 2.0d, "success compareAndExchangeRelease double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 1.0d, "success compareAndExchangeRelease double value");
+        }
+
+        {
+            double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(2.0d, 3.0d);
+            assertEquals(r, 1.0d, "failing compareAndExchangeRelease double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 1.0d, "failing compareAndExchangeRelease double value");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(1.0d, 2.0d);
+            }
+            assertEquals(success, true, "weakCompareAndSet double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 2.0d, "weakCompareAndSet double value");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(2.0d, 1.0d);
+            }
+            assertEquals(success, true, "weakCompareAndSetAcquire double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 1.0d, "weakCompareAndSetAcquire double");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(1.0d, 2.0d);
+            }
+            assertEquals(success, true, "weakCompareAndSetRelease double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 2.0d, "weakCompareAndSetRelease double");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(2.0d, 1.0d);
+            }
+            assertEquals(success, true, "weakCompareAndSetVolatile double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 1.0d, "weakCompareAndSetVolatile double");
+        }
+
+        // Compare set and get
+        {
+            double o = (double) hs.get(TestAccessMode.GET_AND_SET).invokeExact( 2.0d);
+            assertEquals(o, 1.0d, "getAndSet double");
+            double x = (double) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 2.0d, "getAndSet double value");
+        }
+
+        hs.get(TestAccessMode.SET).invokeExact(1.0d);
+
+        // get and add, add and get
+        {
+            double o = (double) hs.get(TestAccessMode.GET_AND_ADD).invokeExact( 3.0d);
+            assertEquals(o, 1.0d, "getAndAdd double");
+            double c = (double) hs.get(TestAccessMode.ADD_AND_GET).invokeExact(3.0d);
+            assertEquals(c, (double)(1.0d + 3.0d + 3.0d), "getAndAdd double value");
+        }
     }
 
     static void testStaticFieldUnsupported(Handles hs) throws Throwable {
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
-            checkUOE(am, () -> {
-                boolean r = (boolean) hs.get(am).invokeExact(1.0d, 2.0d);
-            });
-        }
 
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
-            checkUOE(am, () -> {
-                double r = (double) hs.get(am).invokeExact(1.0d, 2.0d);
-            });
-        }
-
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
-            checkUOE(am, () -> {
-                double r = (double) hs.get(am).invokeExact(1.0d);
-            });
-        }
-
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
-            checkUOE(am, () -> {
-                double r = (double) hs.get(am).invokeExact(1.0d);
-            });
-        }
     }
 
 
@@ -271,7 +457,122 @@
                 assertEquals(x, 2.0d, "setOpaque double value");
             }
 
+            hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0d);
 
+            // Compare
+            {
+                boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, 1.0d, 2.0d);
+                assertEquals(r, true, "success compareAndSet double");
+                double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 2.0d, "success compareAndSet double value");
+            }
+
+            {
+                boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, 1.0d, 3.0d);
+                assertEquals(r, false, "failing compareAndSet double");
+                double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 2.0d, "failing compareAndSet double value");
+            }
+
+            {
+                double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact(array, i, 2.0d, 1.0d);
+                assertEquals(r, 2.0d, "success compareAndExchangeVolatile double");
+                double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 1.0d, "success compareAndExchangeVolatile double value");
+            }
+
+            {
+                double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact(array, i, 2.0d, 3.0d);
+                assertEquals(r, 1.0d, "failing compareAndExchangeVolatile double");
+                double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 1.0d, "failing compareAndExchangeVolatile double value");
+            }
+
+            {
+                double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, 1.0d, 2.0d);
+                assertEquals(r, 1.0d, "success compareAndExchangeAcquire double");
+                double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 2.0d, "success compareAndExchangeAcquire double value");
+            }
+
+            {
+                double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, 1.0d, 3.0d);
+                assertEquals(r, 2.0d, "failing compareAndExchangeAcquire double");
+                double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 2.0d, "failing compareAndExchangeAcquire double value");
+            }
+
+            {
+                double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, 2.0d, 1.0d);
+                assertEquals(r, 2.0d, "success compareAndExchangeRelease double");
+                double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 1.0d, "success compareAndExchangeRelease double value");
+            }
+
+            {
+                double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, 2.0d, 3.0d);
+                assertEquals(r, 1.0d, "failing compareAndExchangeRelease double");
+                double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 1.0d, "failing compareAndExchangeRelease double value");
+            }
+
+            {
+                boolean success = false;
+                for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                    success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 1.0d, 2.0d);
+                }
+                assertEquals(success, true, "weakCompareAndSet double");
+                double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 2.0d, "weakCompareAndSet double value");
+            }
+
+            {
+                boolean success = false;
+                for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                    success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 2.0d, 1.0d);
+                }
+                assertEquals(success, true, "weakCompareAndSetAcquire double");
+                double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 1.0d, "weakCompareAndSetAcquire double");
+            }
+
+            {
+                boolean success = false;
+                for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                    success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, 1.0d, 2.0d);
+                }
+                assertEquals(success, true, "weakCompareAndSetRelease double");
+                double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 2.0d, "weakCompareAndSetRelease double");
+            }
+
+            {
+                boolean success = false;
+                for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                    success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(array, i, 2.0d, 1.0d);
+                }
+                assertEquals(success, true, "weakCompareAndSetVolatile double");
+                double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 1.0d, "weakCompareAndSetVolatile double");
+            }
+
+            // Compare set and get
+            {
+                double o = (double) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, 2.0d);
+                assertEquals(o, 1.0d, "getAndSet double");
+                double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 2.0d, "getAndSet double value");
+            }
+
+            hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0d);
+
+            // get and add, add and get
+            {
+                double o = (double) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(array, i, 3.0d);
+                assertEquals(o, 1.0d, "getAndAdd double");
+                double c = (double) hs.get(TestAccessMode.ADD_AND_GET).invokeExact(array, i, 3.0d);
+                assertEquals(c, (double)(1.0d + 3.0d + 3.0d), "getAndAdd double value");
+            }
         }
     }
 
@@ -279,29 +580,7 @@
         double[] array = new double[10];
 
         final int i = 0;
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
-            checkUOE(am, () -> {
-                boolean r = (boolean) hs.get(am).invokeExact(array, i, 1.0d, 2.0d);
-            });
-        }
 
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
-            checkUOE(am, () -> {
-                double r = (double) hs.get(am).invokeExact(array, i, 1.0d, 2.0d);
-            });
-        }
-
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
-            checkUOE(am, () -> {
-                double r = (double) hs.get(am).invokeExact(array, i, 1.0d);
-            });
-        }
-
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
-            checkUOE(am, () -> {
-                double o = (double) hs.get(am).invokeExact(array, i, 1.0d);
-            });
-        }
     }
 
     static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
@@ -322,7 +601,29 @@
                 });
             }
 
+            for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
+                checkIOOBE(am, () -> {
+                    boolean r = (boolean) hs.get(am).invokeExact(array, ci, 1.0d, 2.0d);
+                });
+            }
 
+            for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
+                checkIOOBE(am, () -> {
+                    double r = (double) hs.get(am).invokeExact(array, ci, 2.0d, 1.0d);
+                });
+            }
+
+            for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
+                checkIOOBE(am, () -> {
+                    double o = (double) hs.get(am).invokeExact(array, ci, 1.0d);
+                });
+            }
+
+            for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
+                checkIOOBE(am, () -> {
+                    double o = (double) hs.get(am).invokeExact(array, ci, 3.0d);
+                });
+            }
         }
     }
 }
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java	Wed Jun 15 11:20:15 2016 +0300
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java	Mon Jun 20 17:57:19 2016 +0200
@@ -148,33 +148,126 @@
             assertEquals(x, 2.0f, "setOpaque float value");
         }
 
+        hs.get(TestAccessMode.SET).invokeExact(recv, 1.0f);
 
+        // Compare
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, 1.0f, 2.0f);
+            assertEquals(r, true, "success compareAndSet float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 2.0f, "success compareAndSet float value");
+        }
+
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, 1.0f, 3.0f);
+            assertEquals(r, false, "failing compareAndSet float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 2.0f, "failing compareAndSet float value");
+        }
+
+        {
+            float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact(recv, 2.0f, 1.0f);
+            assertEquals(r, 2.0f, "success compareAndExchangeVolatile float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 1.0f, "success compareAndExchangeVolatile float value");
+        }
+
+        {
+            float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact(recv, 2.0f, 3.0f);
+            assertEquals(r, 1.0f, "failing compareAndExchangeVolatile float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 1.0f, "failing compareAndExchangeVolatile float value");
+        }
+
+        {
+            float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, 1.0f, 2.0f);
+            assertEquals(r, 1.0f, "success compareAndExchangeAcquire float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 2.0f, "success compareAndExchangeAcquire float value");
+        }
+
+        {
+            float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, 1.0f, 3.0f);
+            assertEquals(r, 2.0f, "failing compareAndExchangeAcquire float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 2.0f, "failing compareAndExchangeAcquire float value");
+        }
+
+        {
+            float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, 2.0f, 1.0f);
+            assertEquals(r, 2.0f, "success compareAndExchangeRelease float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 1.0f, "success compareAndExchangeRelease float value");
+        }
+
+        {
+            float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, 2.0f, 3.0f);
+            assertEquals(r, 1.0f, "failing compareAndExchangeRelease float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 1.0f, "failing compareAndExchangeRelease float value");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 1.0f, 2.0f);
+            }
+            assertEquals(success, true, "weakCompareAndSet float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 2.0f, "weakCompareAndSet float value");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 2.0f, 1.0f);
+            }
+            assertEquals(success, true, "weakCompareAndSetAcquire float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 1.0f, "weakCompareAndSetAcquire float");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 1.0f, 2.0f);
+            }
+            assertEquals(success, true, "weakCompareAndSetRelease float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 2.0f, "weakCompareAndSetRelease float");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(recv, 2.0f, 1.0f);
+            }
+            assertEquals(success, true, "weakCompareAndSetVolatile float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 1.0f, "weakCompareAndSetVolatile float");
+        }
+
+        // Compare set and get
+        {
+            float o = (float) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, 2.0f);
+            assertEquals(o, 1.0f, "getAndSet float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 2.0f, "getAndSet float value");
+        }
+
+        hs.get(TestAccessMode.SET).invokeExact(recv, 1.0f);
+
+        // get and add, add and get
+        {
+            float o = (float) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(recv, 3.0f);
+            assertEquals(o, 1.0f, "getAndAdd float");
+            float c = (float) hs.get(TestAccessMode.ADD_AND_GET).invokeExact(recv, 3.0f);
+            assertEquals(c, (float)(1.0f + 3.0f + 3.0f), "getAndAdd float value");
+        }
     }
 
     static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessFloat recv, Handles hs) throws Throwable {
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
-            checkUOE(am, () -> {
-                boolean r = (boolean) hs.get(am).invokeExact(recv, 1.0f, 2.0f);
-            });
-        }
 
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
-            checkUOE(am, () -> {
-                float r = (float) hs.get(am).invokeExact(recv, 1.0f, 2.0f);
-            });
-        }
-
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
-            checkUOE(am, () -> {
-                float r = (float) hs.get(am).invokeExact(recv, 1.0f);
-            });
-        }
-
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
-            checkUOE(am, () -> {
-                float r = (float) hs.get(am).invokeExact(recv, 1.0f);
-            });
-        }
     }
 
 
@@ -208,33 +301,126 @@
             assertEquals(x, 2.0f, "setOpaque float value");
         }
 
+        hs.get(TestAccessMode.SET).invokeExact(1.0f);
 
+        // Compare
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(1.0f, 2.0f);
+            assertEquals(r, true, "success compareAndSet float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 2.0f, "success compareAndSet float value");
+        }
+
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(1.0f, 3.0f);
+            assertEquals(r, false, "failing compareAndSet float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 2.0f, "failing compareAndSet float value");
+        }
+
+        {
+            float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact(2.0f, 1.0f);
+            assertEquals(r, 2.0f, "success compareAndExchangeVolatile float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 1.0f, "success compareAndExchangeVolatile float value");
+        }
+
+        {
+            float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact(2.0f, 3.0f);
+            assertEquals(r, 1.0f, "failing compareAndExchangeVolatile float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 1.0f, "failing compareAndExchangeVolatile float value");
+        }
+
+        {
+            float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(1.0f, 2.0f);
+            assertEquals(r, 1.0f, "success compareAndExchangeAcquire float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 2.0f, "success compareAndExchangeAcquire float value");
+        }
+
+        {
+            float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(1.0f, 3.0f);
+            assertEquals(r, 2.0f, "failing compareAndExchangeAcquire float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 2.0f, "failing compareAndExchangeAcquire float value");
+        }
+
+        {
+            float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(2.0f, 1.0f);
+            assertEquals(r, 2.0f, "success compareAndExchangeRelease float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 1.0f, "success compareAndExchangeRelease float value");
+        }
+
+        {
+            float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(2.0f, 3.0f);
+            assertEquals(r, 1.0f, "failing compareAndExchangeRelease float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 1.0f, "failing compareAndExchangeRelease float value");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(1.0f, 2.0f);
+            }
+            assertEquals(success, true, "weakCompareAndSet float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 2.0f, "weakCompareAndSet float value");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(2.0f, 1.0f);
+            }
+            assertEquals(success, true, "weakCompareAndSetAcquire float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 1.0f, "weakCompareAndSetAcquire float");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(1.0f, 2.0f);
+            }
+            assertEquals(success, true, "weakCompareAndSetRelease float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 2.0f, "weakCompareAndSetRelease float");
+        }
+
+        {
+            boolean success = false;
+            for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(2.0f, 1.0f);
+            }
+            assertEquals(success, true, "weakCompareAndSetVolatile float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 1.0f, "weakCompareAndSetVolatile float");
+        }
+
+        // Compare set and get
+        {
+            float o = (float) hs.get(TestAccessMode.GET_AND_SET).invokeExact( 2.0f);
+            assertEquals(o, 1.0f, "getAndSet float");
+            float x = (float) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 2.0f, "getAndSet float value");
+        }
+
+        hs.get(TestAccessMode.SET).invokeExact(1.0f);
+
+        // get and add, add and get
+        {
+            float o = (float) hs.get(TestAccessMode.GET_AND_ADD).invokeExact( 3.0f);
+            assertEquals(o, 1.0f, "getAndAdd float");
+            float c = (float) hs.get(TestAccessMode.ADD_AND_GET).invokeExact(3.0f);
+            assertEquals(c, (float)(1.0f + 3.0f + 3.0f), "getAndAdd float value");
+        }
     }
 
     static void testStaticFieldUnsupported(Handles hs) throws Throwable {
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
-            checkUOE(am, () -> {
-                boolean r = (boolean) hs.get(am).invokeExact(1.0f, 2.0f);
-            });
-        }
 
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
-            checkUOE(am, () -> {
-                float r = (float) hs.get(am).invokeExact(1.0f, 2.0f);
-            });
-        }
-
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
-            checkUOE(am, () -> {
-                float r = (float) hs.get(am).invokeExact(1.0f);
-            });
-        }
-
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
-            checkUOE(am, () -> {
-                float r = (float) hs.get(am).invokeExact(1.0f);
-            });
-        }
     }
 
 
@@ -271,7 +457,122 @@
                 assertEquals(x, 2.0f, "setOpaque float value");
             }
 
+            hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0f);
 
+            // Compare
+            {
+                boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, 1.0f, 2.0f);
+                assertEquals(r, true, "success compareAndSet float");
+                float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 2.0f, "success compareAndSet float value");
+            }
+
+            {
+                boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, 1.0f, 3.0f);
+                assertEquals(r, false, "failing compareAndSet float");
+                float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 2.0f, "failing compareAndSet float value");
+            }
+
+            {
+                float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact(array, i, 2.0f, 1.0f);
+                assertEquals(r, 2.0f, "success compareAndExchangeVolatile float");
+                float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 1.0f, "success compareAndExchangeVolatile float value");
+            }
+
+            {
+                float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact(array, i, 2.0f, 3.0f);
+                assertEquals(r, 1.0f, "failing compareAndExchangeVolatile float");
+                float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 1.0f, "failing compareAndExchangeVolatile float value");
+            }
+
+            {
+                float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, 1.0f, 2.0f);
+                assertEquals(r, 1.0f, "success compareAndExchangeAcquire float");
+                float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 2.0f, "success compareAndExchangeAcquire float value");
+            }
+
+            {
+                float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, 1.0f, 3.0f);
+                assertEquals(r, 2.0f, "failing compareAndExchangeAcquire float");
+                float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 2.0f, "failing compareAndExchangeAcquire float value");
+            }
+
+            {
+                float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, 2.0f, 1.0f);
+                assertEquals(r, 2.0f, "success compareAndExchangeRelease float");
+                float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 1.0f, "success compareAndExchangeRelease float value");
+            }
+
+            {
+                float r = (float) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, 2.0f, 3.0f);
+                assertEquals(r, 1.0f, "failing compareAndExchangeRelease float");
+                float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 1.0f, "failing compareAndExchangeRelease float value");
+            }
+
+            {
+                boolean success = false;
+                for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                    success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 1.0f, 2.0f);
+                }
+                assertEquals(success, true, "weakCompareAndSet float");
+                float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 2.0f, "weakCompareAndSet float value");
+            }
+
+            {
+                boolean success = false;
+                for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                    success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 2.0f, 1.0f);
+                }
+                assertEquals(success, true, "weakCompareAndSetAcquire float");
+                float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 1.0f, "weakCompareAndSetAcquire float");
+            }
+
+            {
+                boolean success = false;
+                for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                    success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, 1.0f, 2.0f);
+                }
+                assertEquals(success, true, "weakCompareAndSetRelease float");
+                float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 2.0f, "weakCompareAndSetRelease float");
+            }
+
+            {
+                boolean success = false;
+                for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                    success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(array, i, 2.0f, 1.0f);
+                }
+                assertEquals(success, true, "weakCompareAndSetVolatile float");
+                float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 1.0f, "weakCompareAndSetVolatile float");
+            }
+
+            // Compare set and get
+            {
+                float o = (float) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, 2.0f);
+                assertEquals(o, 1.0f, "getAndSet float");
+                float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 2.0f, "getAndSet float value");
+            }
+
+            hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0f);
+
+            // get and add, add and get
+            {
+                float o = (float) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(array, i, 3.0f);
+                assertEquals(o, 1.0f, "getAndAdd float");
+                float c = (float) hs.get(TestAccessMode.ADD_AND_GET).invokeExact(array, i, 3.0f);
+                assertEquals(c, (float)(1.0f + 3.0f + 3.0f), "getAndAdd float value");
+            }
         }
     }
 
@@ -279,29 +580,7 @@
         float[] array = new float[10];
 
         final int i = 0;
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
-            checkUOE(am, () -> {
-                boolean r = (boolean) hs.get(am).invokeExact(array, i, 1.0f, 2.0f);
-            });
-        }
 
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
-            checkUOE(am, () -> {
-                float r = (float) hs.get(am).invokeExact(array, i, 1.0f, 2.0f);
-            });
-        }
-
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
-            checkUOE(am, () -> {
-                float r = (float) hs.get(am).invokeExact(array, i, 1.0f);
-            });
-        }
-
-        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
-            checkUOE(am, () -> {
-                float o = (float) hs.get(am).invokeExact(array, i, 1.0f);
-            });
-        }
     }
 
     static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
@@ -322,7 +601,29 @@
                 });
             }
 
+            for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
+                checkIOOBE(am, () -> {
+                    boolean r = (boolean) hs.get(am).invokeExact(array, ci, 1.0f, 2.0f);
+                });
+            }
 
+            for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
+                checkIOOBE(am, () -> {
+                    float r = (float) hs.get(am).invokeExact(array, ci, 2.0f, 1.0f);
+                });
+            }
+
+            for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
+                checkIOOBE(am, () -> {
+                    float o = (float) hs.get(am).invokeExact(array, ci, 1.0f);
+                });
+            }
+
+            for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
+                checkIOOBE(am, () -> {
+                    float o = (float) hs.get(am).invokeExact(array, ci, 3.0f);
+                });
+            }
         }
     }
 }
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeDouble.java	Wed Jun 15 11:20:15 2016 +0300
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeDouble.java	Mon Jun 20 17:57:19 2016 +0200
@@ -324,7 +324,322 @@
         });
 
 
+        // CompareAndSet
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.compareAndSet(null, 1.0d, 1.0d);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.compareAndSet(Void.class, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.compareAndSet(recv, Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.compareAndSet(recv, 1.0d, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.compareAndSet(0, 1.0d, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.compareAndSet();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.compareAndSet(recv, 1.0d, 1.0d, Void.class);
+        });
 
+
+        // WeakCompareAndSet
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSet(null, 1.0d, 1.0d);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSet(Void.class, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSet(recv, Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSet(recv, 1.0d, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSet(0, 1.0d, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSet();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSet(recv, 1.0d, 1.0d, Void.class);
+        });
+
+
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetVolatile(null, 1.0d, 1.0d);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(recv, Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(recv, 1.0d, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetVolatile(0, 1.0d, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(recv, 1.0d, 1.0d, Void.class);
+        });
+
+
+        // WeakCompareAndSetAcquire
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetAcquire(null, 1.0d, 1.0d);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetAcquire(Void.class, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetAcquire(recv, Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetAcquire(recv, 1.0d, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetAcquire(0, 1.0d, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetAcquire();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetAcquire(recv, 1.0d, 1.0d, Void.class);
+        });
+
+
+        // WeakCompareAndSetRelease
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetRelease(null, 1.0d, 1.0d);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetRelease(Void.class, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetRelease(recv, Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetRelease(recv, 1.0d, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetRelease(0, 1.0d, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetRelease();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetRelease(recv, 1.0d, 1.0d, Void.class);
+        });
+
+
+        // CompareAndExchangeVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            double x = (double) vh.compareAndExchangeVolatile(null, 1.0d, 1.0d);
+        });
+        checkCCE(() -> { // receiver reference class
+            double x = (double) vh.compareAndExchangeVolatile(Void.class, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // expected reference class
+            double x = (double) vh.compareAndExchangeVolatile(recv, Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            double x = (double) vh.compareAndExchangeVolatile(recv, 1.0d, Void.class);
+        });
+        checkWMTE(() -> { // reciever primitive class
+            double x = (double) vh.compareAndExchangeVolatile(0, 1.0d, 1.0d);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.compareAndExchangeVolatile(recv, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.compareAndExchangeVolatile(recv, 1.0d, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            double x = (double) vh.compareAndExchangeVolatile();
+        });
+        checkWMTE(() -> { // >
+            double x = (double) vh.compareAndExchangeVolatile(recv, 1.0d, 1.0d, Void.class);
+        });
+
+
+        // CompareAndExchangeVolatileAcquire
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            double x = (double) vh.compareAndExchangeAcquire(null, 1.0d, 1.0d);
+        });
+        checkCCE(() -> { // receiver reference class
+            double x = (double) vh.compareAndExchangeAcquire(Void.class, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // expected reference class
+            double x = (double) vh.compareAndExchangeAcquire(recv, Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            double x = (double) vh.compareAndExchangeAcquire(recv, 1.0d, Void.class);
+        });
+        checkWMTE(() -> { // reciever primitive class
+            double x = (double) vh.compareAndExchangeAcquire(0, 1.0d, 1.0d);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.compareAndExchangeAcquire(recv, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.compareAndExchangeAcquire(recv, 1.0d, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            double x = (double) vh.compareAndExchangeAcquire();
+        });
+        checkWMTE(() -> { // >
+            double x = (double) vh.compareAndExchangeAcquire(recv, 1.0d, 1.0d, Void.class);
+        });
+
+
+        // CompareAndExchangeRelease
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            double x = (double) vh.compareAndExchangeRelease(null, 1.0d, 1.0d);
+        });
+        checkCCE(() -> { // receiver reference class
+            double x = (double) vh.compareAndExchangeRelease(Void.class, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // expected reference class
+            double x = (double) vh.compareAndExchangeRelease(recv, Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            double x = (double) vh.compareAndExchangeRelease(recv, 1.0d, Void.class);
+        });
+        checkWMTE(() -> { // reciever primitive class
+            double x = (double) vh.compareAndExchangeRelease(0, 1.0d, 1.0d);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.compareAndExchangeRelease(recv, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.compareAndExchangeRelease(recv, 1.0d, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            double x = (double) vh.compareAndExchangeRelease();
+        });
+        checkWMTE(() -> { // >
+            double x = (double) vh.compareAndExchangeRelease(recv, 1.0d, 1.0d, Void.class);
+        });
+
+
+        // GetAndSet
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            double x = (double) vh.getAndSet(null, 1.0d);
+        });
+        checkCCE(() -> { // receiver reference class
+            double x = (double) vh.getAndSet(Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // value reference class
+            double x = (double) vh.getAndSet(recv, Void.class);
+        });
+        checkWMTE(() -> { // reciever primitive class
+            double x = (double) vh.getAndSet(0, 1.0d);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.getAndSet(recv, 1.0d);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.getAndSet(recv, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            double x = (double) vh.getAndSet();
+        });
+        checkWMTE(() -> { // >
+            double x = (double) vh.getAndSet(recv, 1.0d, Void.class);
+        });
+
+        // GetAndAdd
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            double x = (double) vh.getAndAdd(null, 1.0d);
+        });
+        checkCCE(() -> { // receiver reference class
+            double x = (double) vh.getAndAdd(Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // value reference class
+            double x = (double) vh.getAndAdd(recv, Void.class);
+        });
+        checkWMTE(() -> { // reciever primitive class
+            double x = (double) vh.getAndAdd(0, 1.0d);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.getAndAdd(recv, 1.0d);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.getAndAdd(recv, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            double x = (double) vh.getAndAdd();
+        });
+        checkWMTE(() -> { // >
+            double x = (double) vh.getAndAdd(recv, 1.0d, Void.class);
+        });
+
+
+        // AddAndGet
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            double x = (double) vh.addAndGet(null, 1.0d);
+        });
+        checkCCE(() -> { // receiver reference class
+            double x = (double) vh.addAndGet(Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // value reference class
+            double x = (double) vh.addAndGet(recv, Void.class);
+        });
+        checkWMTE(() -> { // reciever primitive class
+            double x = (double) vh.addAndGet(0, 1.0d);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.addAndGet(recv, 1.0d);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.addAndGet(recv, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            double x = (double) vh.addAndGet();
+        });
+        checkWMTE(() -> { // >
+            double x = (double) vh.addAndGet(recv, 1.0d, Void.class);
+        });
     }
 
     static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeDouble recv, Handles hs) throws Throwable {
@@ -391,7 +706,153 @@
             });
         }
 
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
+            // Incorrect argument types
+            checkNPE(() -> { // null receiver
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeDouble.class, double.class, double.class)).
+                    invokeExact((VarHandleTestMethodTypeDouble) null, 1.0d, 1.0d);
+            });
+            hs.checkWMTEOrCCE(() -> { // receiver reference class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, double.class, double.class)).
+                    invokeExact(Void.class, 1.0d, 1.0d);
+            });
+            checkWMTE(() -> { // expected reference class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeDouble.class, Class.class, double.class)).
+                    invokeExact(recv, Void.class, 1.0d);
+            });
+            checkWMTE(() -> { // actual reference class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeDouble.class, double.class, Class.class)).
+                    invokeExact(recv, 1.0d, Void.class);
+            });
+            checkWMTE(() -> { // receiver primitive class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class , double.class, double.class)).
+                    invokeExact(0, 1.0d, 1.0d);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeDouble.class, double.class, double.class, Class.class)).
+                    invokeExact(recv, 1.0d, 1.0d, Void.class);
+            });
+        }
 
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
+            checkNPE(() -> { // null receiver
+                double x = (double) hs.get(am, methodType(double.class, VarHandleTestMethodTypeDouble.class, double.class, double.class)).
+                    invokeExact((VarHandleTestMethodTypeDouble) null, 1.0d, 1.0d);
+            });
+            hs.checkWMTEOrCCE(() -> { // receiver reference class
+                double x = (double) hs.get(am, methodType(double.class, Class.class, double.class, double.class)).
+                    invokeExact(Void.class, 1.0d, 1.0d);
+            });
+            checkWMTE(() -> { // expected reference class
+                double x = (double) hs.get(am, methodType(double.class, VarHandleTestMethodTypeDouble.class, Class.class, double.class)).
+                    invokeExact(recv, Void.class, 1.0d);
+            });
+            checkWMTE(() -> { // actual reference class
+                double x = (double) hs.get(am, methodType(double.class, VarHandleTestMethodTypeDouble.class, double.class, Class.class)).
+                    invokeExact(recv, 1.0d, Void.class);
+            });
+            checkWMTE(() -> { // reciever primitive class
+                double x = (double) hs.get(am, methodType(double.class, int.class , double.class, double.class)).
+                    invokeExact(0, 1.0d, 1.0d);
+            });
+            // Incorrect return type
+            checkWMTE(() -> { // reference class
+                Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeDouble.class , double.class, double.class)).
+                    invokeExact(recv, 1.0d, 1.0d);
+            });
+            checkWMTE(() -> { // primitive class
+                boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeDouble.class , double.class, double.class)).
+                    invokeExact(recv, 1.0d, 1.0d);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                double x = (double) hs.get(am, methodType(double.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                double x = (double) hs.get(am, methodType(double.class, VarHandleTestMethodTypeDouble.class, double.class, double.class, Class.class)).
+                    invokeExact(recv, 1.0d, 1.0d, Void.class);
+            });
+        }
+
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
+            checkNPE(() -> { // null receiver
+                double x = (double) hs.get(am, methodType(double.class, VarHandleTestMethodTypeDouble.class, double.class)).
+                    invokeExact((VarHandleTestMethodTypeDouble) null, 1.0d);
+            });
+            hs.checkWMTEOrCCE(() -> { // receiver reference class
+                double x = (double) hs.get(am, methodType(double.class, Class.class, double.class)).
+                    invokeExact(Void.class, 1.0d);
+            });
+            checkWMTE(() -> { // value reference class
+                double x = (double) hs.get(am, methodType(double.class, VarHandleTestMethodTypeDouble.class, Class.class)).
+                    invokeExact(recv, Void.class);
+            });
+            checkWMTE(() -> { // reciever primitive class
+                double x = (double) hs.get(am, methodType(double.class, int.class, double.class)).
+                    invokeExact(0, 1.0d);
+            });
+            // Incorrect return type
+            checkWMTE(() -> { // reference class
+                Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeDouble.class, double.class)).
+                    invokeExact(recv, 1.0d);
+            });
+            checkWMTE(() -> { // primitive class
+                boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeDouble.class, double.class)).
+                    invokeExact(recv, 1.0d);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                double x = (double) hs.get(am, methodType(double.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                double x = (double) hs.get(am, methodType(double.class, VarHandleTestMethodTypeDouble.class, double.class)).
+                    invokeExact(recv, 1.0d, Void.class);
+            });
+        }
+
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
+            checkNPE(() -> { // null receiver
+                double x = (double) hs.get(am, methodType(double.class, VarHandleTestMethodTypeDouble.class, double.class)).
+                    invokeExact((VarHandleTestMethodTypeDouble) null, 1.0d);
+            });
+            hs.checkWMTEOrCCE(() -> { // receiver reference class
+                double x = (double) hs.get(am, methodType(double.class, Class.class, double.class)).
+                    invokeExact(Void.class, 1.0d);
+            });
+            checkWMTE(() -> { // value reference class
+                double x = (double) hs.get(am, methodType(double.class, VarHandleTestMethodTypeDouble.class, Class.class)).
+                    invokeExact(recv, Void.class);
+            });
+            checkWMTE(() -> { // reciever primitive class
+                double x = (double) hs.get(am, methodType(double.class, int.class, double.class)).
+                    invokeExact(0, 1.0d);
+            });
+            // Incorrect return type
+            checkWMTE(() -> { // reference class
+                Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeDouble.class, double.class)).
+                    invokeExact(recv, 1.0d);
+            });
+            checkWMTE(() -> { // primitive class
+                boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeDouble.class, double.class)).
+                    invokeExact(recv, 1.0d);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                double x = (double) hs.get(am, methodType(double.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                double x = (double) hs.get(am, methodType(double.class, VarHandleTestMethodTypeDouble.class, double.class)).
+                    invokeExact(recv, 1.0d, Void.class);
+            });
+        }
     }
 
 
@@ -505,7 +966,223 @@
         });
 
 
+        // CompareAndSet
+        // Incorrect argument types
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.compareAndSet(Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.compareAndSet(1.0d, Void.class);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.compareAndSet();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.compareAndSet(1.0d, 1.0d, Void.class);
+        });
 
+
+        // WeakCompareAndSet
+        // Incorrect argument types
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSet(Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSet(1.0d, Void.class);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSet();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSet(1.0d, 1.0d, Void.class);
+        });
+
+
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(1.0d, Void.class);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(1.0d, 1.0d, Void.class);
+        });
+
+
+        // WeakCompareAndSetAcquire
+        // Incorrect argument types
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetAcquire(Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetAcquire(1.0d, Void.class);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetAcquire();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetAcquire(1.0d, 1.0d, Void.class);
+        });
+
+
+        // WeakCompareAndSetRelease
+        // Incorrect argument types
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetRelease(Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetRelease(1.0d, Void.class);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetRelease();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetRelease(1.0d, 1.0d, Void.class);
+        });
+
+
+        // CompareAndExchangeVolatile
+        // Incorrect argument types
+        checkWMTE(() -> { // expected reference class
+            double x = (double) vh.compareAndExchangeVolatile(Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            double x = (double) vh.compareAndExchangeVolatile(1.0d, Void.class);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.compareAndExchangeVolatile(1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.compareAndExchangeVolatile(1.0d, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            double x = (double) vh.compareAndExchangeVolatile();
+        });
+        checkWMTE(() -> { // >
+            double x = (double) vh.compareAndExchangeVolatile(1.0d, 1.0d, Void.class);
+        });
+
+
+        // CompareAndExchangeAcquire
+        // Incorrect argument types
+        checkWMTE(() -> { // expected reference class
+            double x = (double) vh.compareAndExchangeAcquire(Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            double x = (double) vh.compareAndExchangeAcquire(1.0d, Void.class);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.compareAndExchangeAcquire(1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.compareAndExchangeAcquire(1.0d, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            double x = (double) vh.compareAndExchangeAcquire();
+        });
+        checkWMTE(() -> { // >
+            double x = (double) vh.compareAndExchangeAcquire(1.0d, 1.0d, Void.class);
+        });
+
+
+        // CompareAndExchangeRelease
+        // Incorrect argument types
+        checkWMTE(() -> { // expected reference class
+            double x = (double) vh.compareAndExchangeRelease(Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            double x = (double) vh.compareAndExchangeRelease(1.0d, Void.class);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.compareAndExchangeRelease(1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.compareAndExchangeRelease(1.0d, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            double x = (double) vh.compareAndExchangeRelease();
+        });
+        checkWMTE(() -> { // >
+            double x = (double) vh.compareAndExchangeRelease(1.0d, 1.0d, Void.class);
+        });
+
+
+        // GetAndSet
+        // Incorrect argument types
+        checkWMTE(() -> { // value reference class
+            double x = (double) vh.getAndSet(Void.class);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.getAndSet(1.0d);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.getAndSet(1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            double x = (double) vh.getAndSet();
+        });
+        checkWMTE(() -> { // >
+            double x = (double) vh.getAndSet(1.0d, Void.class);
+        });
+
+        // GetAndAdd
+        // Incorrect argument types
+        checkWMTE(() -> { // value reference class
+            double x = (double) vh.getAndAdd(Void.class);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.getAndAdd(1.0d);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.getAndAdd(1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            double x = (double) vh.getAndAdd();
+        });
+        checkWMTE(() -> { // >
+            double x = (double) vh.getAndAdd(1.0d, Void.class);
+        });
+
+
+        // AddAndGet
+        // Incorrect argument types
+        checkWMTE(() -> { // value reference class
+            double x = (double) vh.addAndGet(Void.class);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.addAndGet(1.0d);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.addAndGet(1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            double x = (double) vh.addAndGet();
+        });
+        checkWMTE(() -> { // >
+            double x = (double) vh.addAndGet(1.0d, Void.class);
+        });
     }
 
     static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
@@ -543,7 +1220,108 @@
                     invokeExact(1.0d, Void.class);
             });
         }
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
+            // Incorrect argument types
+            checkWMTE(() -> { // expected reference class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, double.class)).
+                    invokeExact(Void.class, 1.0d);
+            });
+            checkWMTE(() -> { // actual reference class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, double.class, Class.class)).
+                    invokeExact(1.0d, Void.class);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, double.class, double.class, Class.class)).
+                    invokeExact(1.0d, 1.0d, Void.class);
+            });
+        }
 
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
+            // Incorrect argument types
+            checkWMTE(() -> { // expected reference class
+                double x = (double) hs.get(am, methodType(double.class, Class.class, double.class)).
+                    invokeExact(Void.class, 1.0d);
+            });
+            checkWMTE(() -> { // actual reference class
+                double x = (double) hs.get(am, methodType(double.class, double.class, Class.class)).
+                    invokeExact(1.0d, Void.class);
+            });
+            // Incorrect return type
+            checkWMTE(() -> { // reference class
+                Void r = (Void) hs.get(am, methodType(Void.class, double.class, double.class)).
+                    invokeExact(1.0d, 1.0d);
+            });
+            checkWMTE(() -> { // primitive class
+                boolean x = (boolean) hs.get(am, methodType(boolean.class, double.class, double.class)).
+                    invokeExact(1.0d, 1.0d);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                double x = (double) hs.get(am, methodType(double.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                double x = (double) hs.get(am, methodType(double.class, double.class, double.class, Class.class)).
+                    invokeExact(1.0d, 1.0d, Void.class);
+            });
+        }
+
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
+            // Incorrect argument types
+            checkWMTE(() -> { // value reference class
+                double x = (double) hs.get(am, methodType(double.class, Class.class)).
+                    invokeExact(Void.class);
+            });
+            // Incorrect return type
+            checkWMTE(() -> { // reference class
+                Void r = (Void) hs.get(am, methodType(Void.class, double.class)).
+                    invokeExact(1.0d);
+            });
+            checkWMTE(() -> { // primitive class
+                boolean x = (boolean) hs.get(am, methodType(boolean.class, double.class)).
+                    invokeExact(1.0d);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                double x = (double) hs.get(am, methodType(double.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                double x = (double) hs.get(am, methodType(double.class, double.class, Class.class)).
+                    invokeExact(1.0d, Void.class);
+            });
+        }
+
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
+            // Incorrect argument types
+            checkWMTE(() -> { // value reference class
+                double x = (double) hs.get(am, methodType(double.class, Class.class)).
+                    invokeExact(Void.class);
+            });
+            // Incorrect return type
+            checkWMTE(() -> { // reference class
+                Void r = (Void) hs.get(am, methodType(Void.class, double.class)).
+                    invokeExact(1.0d);
+            });
+            checkWMTE(() -> { // primitive class
+                boolean x = (boolean) hs.get(am, methodType(boolean.class, double.class)).
+                    invokeExact(1.0d);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                double x = (double) hs.get(am, methodType(double.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                double x = (double) hs.get(am, methodType(double.class, double.class, Class.class)).
+                    invokeExact(1.0d, Void.class);
+            });
+        }
     }
 
 
@@ -775,7 +1553,355 @@
         });
 
 
+        // CompareAndSet
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.compareAndSet(null, 0, 1.0d, 1.0d);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.compareAndSet(Void.class, 0, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.compareAndSet(array, 0, Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.compareAndSet(array, 0, 1.0d, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.compareAndSet(0, 0, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // index reference class
+            boolean r = vh.compareAndSet(array, Void.class, 1.0d, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.compareAndSet();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.compareAndSet(array, 0, 1.0d, 1.0d, Void.class);
+        });
 
+
+        // WeakCompareAndSet
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSet(null, 0, 1.0d, 1.0d);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSet(Void.class, 0, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSet(array, 0, Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSet(array, 0, 1.0d, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSet(0, 0, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // index reference class
+            boolean r = vh.weakCompareAndSet(array, Void.class, 1.0d, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSet();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSet(array, 0, 1.0d, 1.0d, Void.class);
+        });
+
+
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetVolatile(null, 0, 1.0d, 1.0d);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 0, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, 1.0d, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetVolatile(0, 0, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // index reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, Void.class, 1.0d, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, 1.0d, 1.0d, Void.class);
+        });
+
+
+        // WeakCompareAndSetAcquire
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetAcquire(null, 0, 1.0d, 1.0d);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetAcquire(Void.class, 0, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetAcquire(array, 0, Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetAcquire(array, 0, 1.0d, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetAcquire(0, 0, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // index reference class
+            boolean r = vh.weakCompareAndSetAcquire(array, Void.class, 1.0d, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetAcquire();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetAcquire(array, 0, 1.0d, 1.0d, Void.class);
+        });
+
+
+        // WeakCompareAndSetRelease
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetRelease(null, 0, 1.0d, 1.0d);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetRelease(Void.class, 0, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetRelease(array, 0, Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetRelease(array, 0, 1.0d, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetRelease(0, 0, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // index reference class
+            boolean r = vh.weakCompareAndSetRelease(array, Void.class, 1.0d, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetRelease();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetRelease(array, 0, 1.0d, 1.0d, Void.class);
+        });
+
+
+        // CompareAndExchangeVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            double x = (double) vh.compareAndExchangeVolatile(null, 0, 1.0d, 1.0d);
+        });
+        checkCCE(() -> { // array reference class
+            double x = (double) vh.compareAndExchangeVolatile(Void.class, 0, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // expected reference class
+            double x = (double) vh.compareAndExchangeVolatile(array, 0, Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            double x = (double) vh.compareAndExchangeVolatile(array, 0, 1.0d, Void.class);
+        });
+        checkWMTE(() -> { // array primitive class
+            double x = (double) vh.compareAndExchangeVolatile(0, 0, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // index reference class
+            double x = (double) vh.compareAndExchangeVolatile(array, Void.class, 1.0d, 1.0d);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.compareAndExchangeVolatile(array, 0, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.compareAndExchangeVolatile(array, 0, 1.0d, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            double x = (double) vh.compareAndExchangeVolatile();
+        });
+        checkWMTE(() -> { // >
+            double x = (double) vh.compareAndExchangeVolatile(array, 0, 1.0d, 1.0d, Void.class);
+        });
+
+
+        // CompareAndExchangeAcquire
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            double x = (double) vh.compareAndExchangeAcquire(null, 0, 1.0d, 1.0d);
+        });
+        checkCCE(() -> { // array reference class
+            double x = (double) vh.compareAndExchangeAcquire(Void.class, 0, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // expected reference class
+            double x = (double) vh.compareAndExchangeAcquire(array, 0, Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            double x = (double) vh.compareAndExchangeAcquire(array, 0, 1.0d, Void.class);
+        });
+        checkWMTE(() -> { // array primitive class
+            double x = (double) vh.compareAndExchangeAcquire(0, 0, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // index reference class
+            double x = (double) vh.compareAndExchangeAcquire(array, Void.class, 1.0d, 1.0d);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.compareAndExchangeAcquire(array, 0, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.compareAndExchangeAcquire(array, 0, 1.0d, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            double x = (double) vh.compareAndExchangeAcquire();
+        });
+        checkWMTE(() -> { // >
+            double x = (double) vh.compareAndExchangeAcquire(array, 0, 1.0d, 1.0d, Void.class);
+        });
+
+
+        // CompareAndExchangeRelease
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            double x = (double) vh.compareAndExchangeRelease(null, 0, 1.0d, 1.0d);
+        });
+        checkCCE(() -> { // array reference class
+            double x = (double) vh.compareAndExchangeRelease(Void.class, 0, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // expected reference class
+            double x = (double) vh.compareAndExchangeRelease(array, 0, Void.class, 1.0d);
+        });
+        checkWMTE(() -> { // actual reference class
+            double x = (double) vh.compareAndExchangeRelease(array, 0, 1.0d, Void.class);
+        });
+        checkWMTE(() -> { // array primitive class
+            double x = (double) vh.compareAndExchangeRelease(0, 0, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // index reference class
+            double x = (double) vh.compareAndExchangeRelease(array, Void.class, 1.0d, 1.0d);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.compareAndExchangeRelease(array, 0, 1.0d, 1.0d);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.compareAndExchangeRelease(array, 0, 1.0d, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            double x = (double) vh.compareAndExchangeRelease();
+        });
+        checkWMTE(() -> { // >
+            double x = (double) vh.compareAndExchangeRelease(array, 0, 1.0d, 1.0d, Void.class);
+        });
+
+
+        // GetAndSet
+        // Incorrect argument types
+        checkNPE(() -> { // null array
+            double x = (double) vh.getAndSet(null, 0, 1.0d);
+        });
+        checkCCE(() -> { // array reference class
+            double x = (double) vh.getAndSet(Void.class, 0, 1.0d);
+        });
+        checkWMTE(() -> { // value reference class
+            double x = (double) vh.getAndSet(array, 0, Void.class);
+        });
+        checkWMTE(() -> { // reciarrayever primitive class
+            double x = (double) vh.getAndSet(0, 0, 1.0d);
+        });
+        checkWMTE(() -> { // index reference class
+            double x = (double) vh.getAndSet(array, Void.class, 1.0d);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.getAndSet(array, 0, 1.0d);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.getAndSet(array, 0, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            double x = (double) vh.getAndSet();
+        });
+        checkWMTE(() -> { // >
+            double x = (double) vh.getAndSet(array, 0, 1.0d, Void.class);
+        });
+
+        // GetAndAdd
+        // Incorrect argument types
+        checkNPE(() -> { // null array
+            double x = (double) vh.getAndAdd(null, 0, 1.0d);
+        });
+        checkCCE(() -> { // array reference class
+            double x = (double) vh.getAndAdd(Void.class, 0, 1.0d);
+        });
+        checkWMTE(() -> { // value reference class
+            double x = (double) vh.getAndAdd(array, 0, Void.class);
+        });
+        checkWMTE(() -> { // array primitive class
+            double x = (double) vh.getAndAdd(0, 0, 1.0d);
+        });
+        checkWMTE(() -> { // index reference class
+            double x = (double) vh.getAndAdd(array, Void.class, 1.0d);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.getAndAdd(array, 0, 1.0d);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.getAndAdd(array, 0, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            double x = (double) vh.getAndAdd();
+        });
+        checkWMTE(() -> { // >
+            double x = (double) vh.getAndAdd(array, 0, 1.0d, Void.class);
+        });
+
+
+        // AddAndGet
+        // Incorrect argument types
+        checkNPE(() -> { // null array
+            double x = (double) vh.addAndGet(null, 0, 1.0d);
+        });
+        checkCCE(() -> { // array reference class
+            double x = (double) vh.addAndGet(Void.class, 0, 1.0d);
+        });
+        checkWMTE(() -> { // value reference class
+            double x = (double) vh.addAndGet(array, 0, Void.class);
+        });
+        checkWMTE(() -> { // array primitive class
+            double x = (double) vh.addAndGet(0, 0, 1.0d);
+        });
+        checkWMTE(() -> { // index reference class
+            double x = (double) vh.addAndGet(array, Void.class, 1.0d);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.addAndGet(array, 0, 1.0d);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.addAndGet(array, 0, 1.0d);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            double x = (double) vh.addAndGet();
+        });
+        checkWMTE(() -> { // >
+            double x = (double) vh.addAndGet(array, 0, 1.0d, Void.class);
+        });
     }
 
     static void testArrayWrongMethodType(Handles hs) throws Throwable {
@@ -852,7 +1978,172 @@
                     invokeExact(array, 0, 1.0d, Void.class);
             });
         }
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
+            // Incorrect argument types
+            checkNPE(() -> { // null receiver
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, double[].class, int.class, double.class, double.class)).
+                    invokeExact((double[]) null, 0, 1.0d, 1.0d);
+            });
+            hs.checkWMTEOrCCE(() -> { // receiver reference class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, double.class, double.class)).
+                    invokeExact(Void.class, 0, 1.0d, 1.0d);
+            });
+            checkWMTE(() -> { // expected reference class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, double[].class, int.class, Class.class, double.class)).
+                    invokeExact(array, 0, Void.class, 1.0d);
+            });
+            checkWMTE(() -> { // actual reference class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, double[].class, int.class, double.class, Class.class)).
+                    invokeExact(array, 0, 1.0d, Void.class);
+            });
+            checkWMTE(() -> { // receiver primitive class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, double.class, double.class)).
+                    invokeExact(0, 0, 1.0d, 1.0d);
+            });
+            checkWMTE(() -> { // index reference class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, double[].class, Class.class, double.class, double.class)).
+                    invokeExact(array, Void.class, 1.0d, 1.0d);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, double[].class, int.class, double.class, double.class, Class.class)).
+                    invokeExact(array, 0, 1.0d, 1.0d, Void.class);
+            });
+        }
 
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
+            // Incorrect argument types
+            checkNPE(() -> { // null receiver
+                double x = (double) hs.get(am, methodType(double.class, double[].class, int.class, double.class, double.class)).
+                    invokeExact((double[]) null, 0, 1.0d, 1.0d);
+            });
+            hs.checkWMTEOrCCE(() -> { // array reference class
+                double x = (double) hs.get(am, methodType(double.class, Class.class, int.class, double.class, double.class)).
+                    invokeExact(Void.class, 0, 1.0d, 1.0d);
+            });
+            checkWMTE(() -> { // expected reference class
+                double x = (double) hs.get(am, methodType(double.class, double[].class, int.class, Class.class, double.class)).
+                    invokeExact(array, 0, Void.class, 1.0d);
+            });
+            checkWMTE(() -> { // actual reference class
+                double x = (double) hs.get(am, methodType(double.class, double[].class, int.class, double.class, Class.class)).
+                    invokeExact(array, 0, 1.0d, Void.class);
+            });
+            checkWMTE(() -> { // array primitive class
+                double x = (double) hs.get(am, methodType(double.class, int.class, int.class, double.class, double.class)).
+                    invokeExact(0, 0, 1.0d, 1.0d);
+            });
+            checkWMTE(() -> { // index reference class
+                double x = (double) hs.get(am, methodType(double.class, double[].class, Class.class, double.class, double.class)).
+                    invokeExact(array, Void.class, 1.0d, 1.0d);
+            });
+            // Incorrect return type
+            checkWMTE(() -> { // reference class
+                Void r = (Void) hs.get(am, methodType(Void.class, double[].class, int.class, double.class, double.class)).
+                    invokeExact(array, 0, 1.0d, 1.0d);
+            });
+            checkWMTE(() -> { // primitive class
+                boolean x = (boolean) hs.get(am, methodType(boolean.class, double[].class, int.class, double.class, double.class)).
+                    invokeExact(array, 0, 1.0d, 1.0d);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                double x = (double) hs.get(am, methodType(double.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                double x = (double) hs.get(am, methodType(double.class, double[].class, int.class, double.class, double.class, Class.class)).
+                    invokeExact(array, 0, 1.0d, 1.0d, Void.class);
+            });
+        }
+
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
+            // Incorrect argument types
+            checkNPE(() -> { // null array
+                double x = (double) hs.get(am, methodType(double.class, double[].class, int.class, double.class)).
+                    invokeExact((double[]) null, 0, 1.0d);
+            });
+            hs.checkWMTEOrCCE(() -> { // array reference class
+                double x = (double) hs.get(am, methodType(double.class, Class.class, int.class, double.class)).
+                    invokeExact(Void.class, 0, 1.0d);
+            });
+            checkWMTE(() -> { // value reference class
+                double x = (double) hs.get(am, methodType(double.class, double[].class, int.class, Class.class)).
+                    invokeExact(array, 0, Void.class);
+            });
+            checkWMTE(() -> { // array primitive class
+                double x = (double) hs.get(am, methodType(double.class, int.class, int.class, double.class)).
+                    invokeExact(0, 0, 1.0d);
+            });
+            checkWMTE(() -> { // index reference class
+                double x = (double) hs.get(am, methodType(double.class, double[].class, Class.class, double.class)).
+                    invokeExact(array, Void.class, 1.0d);
+            });
+            // Incorrect return type
+            checkWMTE(() -> { // reference class
+                Void r = (Void) hs.get(am, methodType(Void.class, double[].class, int.class, double.class)).
+                    invokeExact(array, 0, 1.0d);
+            });
+            checkWMTE(() -> { // primitive class
+                boolean x = (boolean) hs.get(am, methodType(boolean.class, double[].class, int.class, double.class)).
+                    invokeExact(array, 0, 1.0d);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                double x = (double) hs.get(am, methodType(double.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                double x = (double) hs.get(am, methodType(double.class, double[].class, int.class, double.class, Class.class)).
+                    invokeExact(array, 0, 1.0d, Void.class);
+            });
+        }
+
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
+            // Incorrect argument types
+            checkNPE(() -> { // null array
+                double x = (double) hs.get(am, methodType(double.class, double[].class, int.class, double.class)).
+                    invokeExact((double[]) null, 0, 1.0d);
+            });
+            hs.checkWMTEOrCCE(() -> { // array reference class
+                double x = (double) hs.get(am, methodType(double.class, Class.class, int.class, double.class)).
+                    invokeExact(Void.class, 0, 1.0d);
+            });
+            checkWMTE(() -> { // value reference class
+                double x = (double) hs.get(am, methodType(double.class, double[].class, int.class, Class.class)).
+                    invokeExact(array, 0, Void.class);
+            });
+            checkWMTE(() -> { // array primitive class
+                double x = (double) hs.get(am, methodType(double.class, int.class, int.class, double.class)).
+                    invokeExact(0, 0, 1.0d);
+            });
+            checkWMTE(() -> { // index reference class
+                double x = (double) hs.get(am, methodType(double.class, double[].class, Class.class, double.class)).
+                    invokeExact(array, Void.class, 1.0d);
+            });
+            // Incorrect return type
+            checkWMTE(() -> { // reference class
+                Void r = (Void) hs.get(am, methodType(Void.class, double[].class, int.class, double.class)).
+                    invokeExact(array, 0, 1.0d);
+            });
+            checkWMTE(() -> { // primitive class
+                boolean x = (boolean) hs.get(am, methodType(boolean.class, double[].class, int.class, double.class)).
+                    invokeExact(array, 0, 1.0d);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                double x = (double) hs.get(am, methodType(double.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                double x = (double) hs.get(am, methodType(double.class, double[].class, int.class, double.class, Class.class)).
+                    invokeExact(array, 0, 1.0d, Void.class);
+            });
+        }
     }
 }
 
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeFloat.java	Wed Jun 15 11:20:15 2016 +0300
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeFloat.java	Mon Jun 20 17:57:19 2016 +0200
@@ -324,7 +324,322 @@
         });
 
 
+        // CompareAndSet
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.compareAndSet(null, 1.0f, 1.0f);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.compareAndSet(Void.class, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.compareAndSet(recv, Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.compareAndSet(recv, 1.0f, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.compareAndSet(0, 1.0f, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.compareAndSet();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.compareAndSet(recv, 1.0f, 1.0f, Void.class);
+        });
 
+
+        // WeakCompareAndSet
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSet(null, 1.0f, 1.0f);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSet(Void.class, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSet(recv, Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSet(recv, 1.0f, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSet(0, 1.0f, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSet();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSet(recv, 1.0f, 1.0f, Void.class);
+        });
+
+
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetVolatile(null, 1.0f, 1.0f);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(recv, Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(recv, 1.0f, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetVolatile(0, 1.0f, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(recv, 1.0f, 1.0f, Void.class);
+        });
+
+
+        // WeakCompareAndSetAcquire
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetAcquire(null, 1.0f, 1.0f);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetAcquire(Void.class, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetAcquire(recv, Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetAcquire(recv, 1.0f, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetAcquire(0, 1.0f, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetAcquire();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetAcquire(recv, 1.0f, 1.0f, Void.class);
+        });
+
+
+        // WeakCompareAndSetRelease
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetRelease(null, 1.0f, 1.0f);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetRelease(Void.class, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetRelease(recv, Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetRelease(recv, 1.0f, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetRelease(0, 1.0f, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetRelease();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetRelease(recv, 1.0f, 1.0f, Void.class);
+        });
+
+
+        // CompareAndExchangeVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            float x = (float) vh.compareAndExchangeVolatile(null, 1.0f, 1.0f);
+        });
+        checkCCE(() -> { // receiver reference class
+            float x = (float) vh.compareAndExchangeVolatile(Void.class, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // expected reference class
+            float x = (float) vh.compareAndExchangeVolatile(recv, Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            float x = (float) vh.compareAndExchangeVolatile(recv, 1.0f, Void.class);
+        });
+        checkWMTE(() -> { // reciever primitive class
+            float x = (float) vh.compareAndExchangeVolatile(0, 1.0f, 1.0f);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.compareAndExchangeVolatile(recv, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.compareAndExchangeVolatile(recv, 1.0f, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            float x = (float) vh.compareAndExchangeVolatile();
+        });
+        checkWMTE(() -> { // >
+            float x = (float) vh.compareAndExchangeVolatile(recv, 1.0f, 1.0f, Void.class);
+        });
+
+
+        // CompareAndExchangeVolatileAcquire
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            float x = (float) vh.compareAndExchangeAcquire(null, 1.0f, 1.0f);
+        });
+        checkCCE(() -> { // receiver reference class
+            float x = (float) vh.compareAndExchangeAcquire(Void.class, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // expected reference class
+            float x = (float) vh.compareAndExchangeAcquire(recv, Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            float x = (float) vh.compareAndExchangeAcquire(recv, 1.0f, Void.class);
+        });
+        checkWMTE(() -> { // reciever primitive class
+            float x = (float) vh.compareAndExchangeAcquire(0, 1.0f, 1.0f);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.compareAndExchangeAcquire(recv, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.compareAndExchangeAcquire(recv, 1.0f, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            float x = (float) vh.compareAndExchangeAcquire();
+        });
+        checkWMTE(() -> { // >
+            float x = (float) vh.compareAndExchangeAcquire(recv, 1.0f, 1.0f, Void.class);
+        });
+
+
+        // CompareAndExchangeRelease
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            float x = (float) vh.compareAndExchangeRelease(null, 1.0f, 1.0f);
+        });
+        checkCCE(() -> { // receiver reference class
+            float x = (float) vh.compareAndExchangeRelease(Void.class, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // expected reference class
+            float x = (float) vh.compareAndExchangeRelease(recv, Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            float x = (float) vh.compareAndExchangeRelease(recv, 1.0f, Void.class);
+        });
+        checkWMTE(() -> { // reciever primitive class
+            float x = (float) vh.compareAndExchangeRelease(0, 1.0f, 1.0f);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.compareAndExchangeRelease(recv, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.compareAndExchangeRelease(recv, 1.0f, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            float x = (float) vh.compareAndExchangeRelease();
+        });
+        checkWMTE(() -> { // >
+            float x = (float) vh.compareAndExchangeRelease(recv, 1.0f, 1.0f, Void.class);
+        });
+
+
+        // GetAndSet
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            float x = (float) vh.getAndSet(null, 1.0f);
+        });
+        checkCCE(() -> { // receiver reference class
+            float x = (float) vh.getAndSet(Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // value reference class
+            float x = (float) vh.getAndSet(recv, Void.class);
+        });
+        checkWMTE(() -> { // reciever primitive class
+            float x = (float) vh.getAndSet(0, 1.0f);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.getAndSet(recv, 1.0f);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.getAndSet(recv, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            float x = (float) vh.getAndSet();
+        });
+        checkWMTE(() -> { // >
+            float x = (float) vh.getAndSet(recv, 1.0f, Void.class);
+        });
+
+        // GetAndAdd
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            float x = (float) vh.getAndAdd(null, 1.0f);
+        });
+        checkCCE(() -> { // receiver reference class
+            float x = (float) vh.getAndAdd(Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // value reference class
+            float x = (float) vh.getAndAdd(recv, Void.class);
+        });
+        checkWMTE(() -> { // reciever primitive class
+            float x = (float) vh.getAndAdd(0, 1.0f);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.getAndAdd(recv, 1.0f);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.getAndAdd(recv, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            float x = (float) vh.getAndAdd();
+        });
+        checkWMTE(() -> { // >
+            float x = (float) vh.getAndAdd(recv, 1.0f, Void.class);
+        });
+
+
+        // AddAndGet
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            float x = (float) vh.addAndGet(null, 1.0f);
+        });
+        checkCCE(() -> { // receiver reference class
+            float x = (float) vh.addAndGet(Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // value reference class
+            float x = (float) vh.addAndGet(recv, Void.class);
+        });
+        checkWMTE(() -> { // reciever primitive class
+            float x = (float) vh.addAndGet(0, 1.0f);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.addAndGet(recv, 1.0f);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.addAndGet(recv, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            float x = (float) vh.addAndGet();
+        });
+        checkWMTE(() -> { // >
+            float x = (float) vh.addAndGet(recv, 1.0f, Void.class);
+        });
     }
 
     static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeFloat recv, Handles hs) throws Throwable {
@@ -391,7 +706,153 @@
             });
         }
 
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
+            // Incorrect argument types
+            checkNPE(() -> { // null receiver
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeFloat.class, float.class, float.class)).
+                    invokeExact((VarHandleTestMethodTypeFloat) null, 1.0f, 1.0f);
+            });
+            hs.checkWMTEOrCCE(() -> { // receiver reference class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, float.class, float.class)).
+                    invokeExact(Void.class, 1.0f, 1.0f);
+            });
+            checkWMTE(() -> { // expected reference class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeFloat.class, Class.class, float.class)).
+                    invokeExact(recv, Void.class, 1.0f);
+            });
+            checkWMTE(() -> { // actual reference class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeFloat.class, float.class, Class.class)).
+                    invokeExact(recv, 1.0f, Void.class);
+            });
+            checkWMTE(() -> { // receiver primitive class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class , float.class, float.class)).
+                    invokeExact(0, 1.0f, 1.0f);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeFloat.class, float.class, float.class, Class.class)).
+                    invokeExact(recv, 1.0f, 1.0f, Void.class);
+            });
+        }
 
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
+            checkNPE(() -> { // null receiver
+                float x = (float) hs.get(am, methodType(float.class, VarHandleTestMethodTypeFloat.class, float.class, float.class)).
+                    invokeExact((VarHandleTestMethodTypeFloat) null, 1.0f, 1.0f);
+            });
+            hs.checkWMTEOrCCE(() -> { // receiver reference class
+                float x = (float) hs.get(am, methodType(float.class, Class.class, float.class, float.class)).
+                    invokeExact(Void.class, 1.0f, 1.0f);
+            });
+            checkWMTE(() -> { // expected reference class
+                float x = (float) hs.get(am, methodType(float.class, VarHandleTestMethodTypeFloat.class, Class.class, float.class)).
+                    invokeExact(recv, Void.class, 1.0f);
+            });
+            checkWMTE(() -> { // actual reference class
+                float x = (float) hs.get(am, methodType(float.class, VarHandleTestMethodTypeFloat.class, float.class, Class.class)).
+                    invokeExact(recv, 1.0f, Void.class);
+            });
+            checkWMTE(() -> { // reciever primitive class
+                float x = (float) hs.get(am, methodType(float.class, int.class , float.class, float.class)).
+                    invokeExact(0, 1.0f, 1.0f);
+            });
+            // Incorrect return type
+            checkWMTE(() -> { // reference class
+                Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeFloat.class , float.class, float.class)).
+                    invokeExact(recv, 1.0f, 1.0f);
+            });
+            checkWMTE(() -> { // primitive class
+                boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeFloat.class , float.class, float.class)).
+                    invokeExact(recv, 1.0f, 1.0f);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                float x = (float) hs.get(am, methodType(float.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                float x = (float) hs.get(am, methodType(float.class, VarHandleTestMethodTypeFloat.class, float.class, float.class, Class.class)).
+                    invokeExact(recv, 1.0f, 1.0f, Void.class);
+            });
+        }
+
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
+            checkNPE(() -> { // null receiver
+                float x = (float) hs.get(am, methodType(float.class, VarHandleTestMethodTypeFloat.class, float.class)).
+                    invokeExact((VarHandleTestMethodTypeFloat) null, 1.0f);
+            });
+            hs.checkWMTEOrCCE(() -> { // receiver reference class
+                float x = (float) hs.get(am, methodType(float.class, Class.class, float.class)).
+                    invokeExact(Void.class, 1.0f);
+            });
+            checkWMTE(() -> { // value reference class
+                float x = (float) hs.get(am, methodType(float.class, VarHandleTestMethodTypeFloat.class, Class.class)).
+                    invokeExact(recv, Void.class);
+            });
+            checkWMTE(() -> { // reciever primitive class
+                float x = (float) hs.get(am, methodType(float.class, int.class, float.class)).
+                    invokeExact(0, 1.0f);
+            });
+            // Incorrect return type
+            checkWMTE(() -> { // reference class
+                Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeFloat.class, float.class)).
+                    invokeExact(recv, 1.0f);
+            });
+            checkWMTE(() -> { // primitive class
+                boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeFloat.class, float.class)).
+                    invokeExact(recv, 1.0f);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                float x = (float) hs.get(am, methodType(float.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                float x = (float) hs.get(am, methodType(float.class, VarHandleTestMethodTypeFloat.class, float.class)).
+                    invokeExact(recv, 1.0f, Void.class);
+            });
+        }
+
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
+            checkNPE(() -> { // null receiver
+                float x = (float) hs.get(am, methodType(float.class, VarHandleTestMethodTypeFloat.class, float.class)).
+                    invokeExact((VarHandleTestMethodTypeFloat) null, 1.0f);
+            });
+            hs.checkWMTEOrCCE(() -> { // receiver reference class
+                float x = (float) hs.get(am, methodType(float.class, Class.class, float.class)).
+                    invokeExact(Void.class, 1.0f);
+            });
+            checkWMTE(() -> { // value reference class
+                float x = (float) hs.get(am, methodType(float.class, VarHandleTestMethodTypeFloat.class, Class.class)).
+                    invokeExact(recv, Void.class);
+            });
+            checkWMTE(() -> { // reciever primitive class
+                float x = (float) hs.get(am, methodType(float.class, int.class, float.class)).
+                    invokeExact(0, 1.0f);
+            });
+            // Incorrect return type
+            checkWMTE(() -> { // reference class
+                Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeFloat.class, float.class)).
+                    invokeExact(recv, 1.0f);
+            });
+            checkWMTE(() -> { // primitive class
+                boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeFloat.class, float.class)).
+                    invokeExact(recv, 1.0f);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                float x = (float) hs.get(am, methodType(float.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                float x = (float) hs.get(am, methodType(float.class, VarHandleTestMethodTypeFloat.class, float.class)).
+                    invokeExact(recv, 1.0f, Void.class);
+            });
+        }
     }
 
 
@@ -505,7 +966,223 @@
         });
 
 
+        // CompareAndSet
+        // Incorrect argument types
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.compareAndSet(Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.compareAndSet(1.0f, Void.class);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.compareAndSet();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.compareAndSet(1.0f, 1.0f, Void.class);
+        });
 
+
+        // WeakCompareAndSet
+        // Incorrect argument types
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSet(Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSet(1.0f, Void.class);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSet();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSet(1.0f, 1.0f, Void.class);
+        });
+
+
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(1.0f, Void.class);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(1.0f, 1.0f, Void.class);
+        });
+
+
+        // WeakCompareAndSetAcquire
+        // Incorrect argument types
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetAcquire(Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetAcquire(1.0f, Void.class);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetAcquire();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetAcquire(1.0f, 1.0f, Void.class);
+        });
+
+
+        // WeakCompareAndSetRelease
+        // Incorrect argument types
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetRelease(Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetRelease(1.0f, Void.class);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetRelease();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetRelease(1.0f, 1.0f, Void.class);
+        });
+
+
+        // CompareAndExchangeVolatile
+        // Incorrect argument types
+        checkWMTE(() -> { // expected reference class
+            float x = (float) vh.compareAndExchangeVolatile(Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            float x = (float) vh.compareAndExchangeVolatile(1.0f, Void.class);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.compareAndExchangeVolatile(1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.compareAndExchangeVolatile(1.0f, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            float x = (float) vh.compareAndExchangeVolatile();
+        });
+        checkWMTE(() -> { // >
+            float x = (float) vh.compareAndExchangeVolatile(1.0f, 1.0f, Void.class);
+        });
+
+
+        // CompareAndExchangeAcquire
+        // Incorrect argument types
+        checkWMTE(() -> { // expected reference class
+            float x = (float) vh.compareAndExchangeAcquire(Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            float x = (float) vh.compareAndExchangeAcquire(1.0f, Void.class);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.compareAndExchangeAcquire(1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.compareAndExchangeAcquire(1.0f, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            float x = (float) vh.compareAndExchangeAcquire();
+        });
+        checkWMTE(() -> { // >
+            float x = (float) vh.compareAndExchangeAcquire(1.0f, 1.0f, Void.class);
+        });
+
+
+        // CompareAndExchangeRelease
+        // Incorrect argument types
+        checkWMTE(() -> { // expected reference class
+            float x = (float) vh.compareAndExchangeRelease(Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            float x = (float) vh.compareAndExchangeRelease(1.0f, Void.class);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.compareAndExchangeRelease(1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.compareAndExchangeRelease(1.0f, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            float x = (float) vh.compareAndExchangeRelease();
+        });
+        checkWMTE(() -> { // >
+            float x = (float) vh.compareAndExchangeRelease(1.0f, 1.0f, Void.class);
+        });
+
+
+        // GetAndSet
+        // Incorrect argument types
+        checkWMTE(() -> { // value reference class
+            float x = (float) vh.getAndSet(Void.class);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.getAndSet(1.0f);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.getAndSet(1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            float x = (float) vh.getAndSet();
+        });
+        checkWMTE(() -> { // >
+            float x = (float) vh.getAndSet(1.0f, Void.class);
+        });
+
+        // GetAndAdd
+        // Incorrect argument types
+        checkWMTE(() -> { // value reference class
+            float x = (float) vh.getAndAdd(Void.class);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.getAndAdd(1.0f);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.getAndAdd(1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            float x = (float) vh.getAndAdd();
+        });
+        checkWMTE(() -> { // >
+            float x = (float) vh.getAndAdd(1.0f, Void.class);
+        });
+
+
+        // AddAndGet
+        // Incorrect argument types
+        checkWMTE(() -> { // value reference class
+            float x = (float) vh.addAndGet(Void.class);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.addAndGet(1.0f);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.addAndGet(1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            float x = (float) vh.addAndGet();
+        });
+        checkWMTE(() -> { // >
+            float x = (float) vh.addAndGet(1.0f, Void.class);
+        });
     }
 
     static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
@@ -543,7 +1220,108 @@
                     invokeExact(1.0f, Void.class);
             });
         }
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
+            // Incorrect argument types
+            checkWMTE(() -> { // expected reference class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, float.class)).
+                    invokeExact(Void.class, 1.0f);
+            });
+            checkWMTE(() -> { // actual reference class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, float.class, Class.class)).
+                    invokeExact(1.0f, Void.class);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, float.class, float.class, Class.class)).
+                    invokeExact(1.0f, 1.0f, Void.class);
+            });
+        }
 
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
+            // Incorrect argument types
+            checkWMTE(() -> { // expected reference class
+                float x = (float) hs.get(am, methodType(float.class, Class.class, float.class)).
+                    invokeExact(Void.class, 1.0f);
+            });
+            checkWMTE(() -> { // actual reference class
+                float x = (float) hs.get(am, methodType(float.class, float.class, Class.class)).
+                    invokeExact(1.0f, Void.class);
+            });
+            // Incorrect return type
+            checkWMTE(() -> { // reference class
+                Void r = (Void) hs.get(am, methodType(Void.class, float.class, float.class)).
+                    invokeExact(1.0f, 1.0f);
+            });
+            checkWMTE(() -> { // primitive class
+                boolean x = (boolean) hs.get(am, methodType(boolean.class, float.class, float.class)).
+                    invokeExact(1.0f, 1.0f);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                float x = (float) hs.get(am, methodType(float.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                float x = (float) hs.get(am, methodType(float.class, float.class, float.class, Class.class)).
+                    invokeExact(1.0f, 1.0f, Void.class);
+            });
+        }
+
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
+            // Incorrect argument types
+            checkWMTE(() -> { // value reference class
+                float x = (float) hs.get(am, methodType(float.class, Class.class)).
+                    invokeExact(Void.class);
+            });
+            // Incorrect return type
+            checkWMTE(() -> { // reference class
+                Void r = (Void) hs.get(am, methodType(Void.class, float.class)).
+                    invokeExact(1.0f);
+            });
+            checkWMTE(() -> { // primitive class
+                boolean x = (boolean) hs.get(am, methodType(boolean.class, float.class)).
+                    invokeExact(1.0f);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                float x = (float) hs.get(am, methodType(float.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                float x = (float) hs.get(am, methodType(float.class, float.class, Class.class)).
+                    invokeExact(1.0f, Void.class);
+            });
+        }
+
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
+            // Incorrect argument types
+            checkWMTE(() -> { // value reference class
+                float x = (float) hs.get(am, methodType(float.class, Class.class)).
+                    invokeExact(Void.class);
+            });
+            // Incorrect return type
+            checkWMTE(() -> { // reference class
+                Void r = (Void) hs.get(am, methodType(Void.class, float.class)).
+                    invokeExact(1.0f);
+            });
+            checkWMTE(() -> { // primitive class
+                boolean x = (boolean) hs.get(am, methodType(boolean.class, float.class)).
+                    invokeExact(1.0f);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                float x = (float) hs.get(am, methodType(float.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                float x = (float) hs.get(am, methodType(float.class, float.class, Class.class)).
+                    invokeExact(1.0f, Void.class);
+            });
+        }
     }
 
 
@@ -775,7 +1553,355 @@
         });
 
 
+        // CompareAndSet
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.compareAndSet(null, 0, 1.0f, 1.0f);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.compareAndSet(Void.class, 0, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.compareAndSet(array, 0, Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.compareAndSet(array, 0, 1.0f, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.compareAndSet(0, 0, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // index reference class
+            boolean r = vh.compareAndSet(array, Void.class, 1.0f, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.compareAndSet();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.compareAndSet(array, 0, 1.0f, 1.0f, Void.class);
+        });
 
+
+        // WeakCompareAndSet
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSet(null, 0, 1.0f, 1.0f);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSet(Void.class, 0, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSet(array, 0, Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSet(array, 0, 1.0f, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSet(0, 0, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // index reference class
+            boolean r = vh.weakCompareAndSet(array, Void.class, 1.0f, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSet();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSet(array, 0, 1.0f, 1.0f, Void.class);
+        });
+
+
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetVolatile(null, 0, 1.0f, 1.0f);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 0, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, 1.0f, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetVolatile(0, 0, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // index reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, Void.class, 1.0f, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, 1.0f, 1.0f, Void.class);
+        });
+
+
+        // WeakCompareAndSetAcquire
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetAcquire(null, 0, 1.0f, 1.0f);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetAcquire(Void.class, 0, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetAcquire(array, 0, Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetAcquire(array, 0, 1.0f, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetAcquire(0, 0, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // index reference class
+            boolean r = vh.weakCompareAndSetAcquire(array, Void.class, 1.0f, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetAcquire();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetAcquire(array, 0, 1.0f, 1.0f, Void.class);
+        });
+
+
+        // WeakCompareAndSetRelease
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetRelease(null, 0, 1.0f, 1.0f);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetRelease(Void.class, 0, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetRelease(array, 0, Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetRelease(array, 0, 1.0f, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetRelease(0, 0, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // index reference class
+            boolean r = vh.weakCompareAndSetRelease(array, Void.class, 1.0f, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetRelease();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetRelease(array, 0, 1.0f, 1.0f, Void.class);
+        });
+
+
+        // CompareAndExchangeVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            float x = (float) vh.compareAndExchangeVolatile(null, 0, 1.0f, 1.0f);
+        });
+        checkCCE(() -> { // array reference class
+            float x = (float) vh.compareAndExchangeVolatile(Void.class, 0, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // expected reference class
+            float x = (float) vh.compareAndExchangeVolatile(array, 0, Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            float x = (float) vh.compareAndExchangeVolatile(array, 0, 1.0f, Void.class);
+        });
+        checkWMTE(() -> { // array primitive class
+            float x = (float) vh.compareAndExchangeVolatile(0, 0, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // index reference class
+            float x = (float) vh.compareAndExchangeVolatile(array, Void.class, 1.0f, 1.0f);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.compareAndExchangeVolatile(array, 0, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.compareAndExchangeVolatile(array, 0, 1.0f, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            float x = (float) vh.compareAndExchangeVolatile();
+        });
+        checkWMTE(() -> { // >
+            float x = (float) vh.compareAndExchangeVolatile(array, 0, 1.0f, 1.0f, Void.class);
+        });
+
+
+        // CompareAndExchangeAcquire
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            float x = (float) vh.compareAndExchangeAcquire(null, 0, 1.0f, 1.0f);
+        });
+        checkCCE(() -> { // array reference class
+            float x = (float) vh.compareAndExchangeAcquire(Void.class, 0, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // expected reference class
+            float x = (float) vh.compareAndExchangeAcquire(array, 0, Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            float x = (float) vh.compareAndExchangeAcquire(array, 0, 1.0f, Void.class);
+        });
+        checkWMTE(() -> { // array primitive class
+            float x = (float) vh.compareAndExchangeAcquire(0, 0, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // index reference class
+            float x = (float) vh.compareAndExchangeAcquire(array, Void.class, 1.0f, 1.0f);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.compareAndExchangeAcquire(array, 0, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.compareAndExchangeAcquire(array, 0, 1.0f, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            float x = (float) vh.compareAndExchangeAcquire();
+        });
+        checkWMTE(() -> { // >
+            float x = (float) vh.compareAndExchangeAcquire(array, 0, 1.0f, 1.0f, Void.class);
+        });
+
+
+        // CompareAndExchangeRelease
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            float x = (float) vh.compareAndExchangeRelease(null, 0, 1.0f, 1.0f);
+        });
+        checkCCE(() -> { // array reference class
+            float x = (float) vh.compareAndExchangeRelease(Void.class, 0, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // expected reference class
+            float x = (float) vh.compareAndExchangeRelease(array, 0, Void.class, 1.0f);
+        });
+        checkWMTE(() -> { // actual reference class
+            float x = (float) vh.compareAndExchangeRelease(array, 0, 1.0f, Void.class);
+        });
+        checkWMTE(() -> { // array primitive class
+            float x = (float) vh.compareAndExchangeRelease(0, 0, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // index reference class
+            float x = (float) vh.compareAndExchangeRelease(array, Void.class, 1.0f, 1.0f);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.compareAndExchangeRelease(array, 0, 1.0f, 1.0f);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.compareAndExchangeRelease(array, 0, 1.0f, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            float x = (float) vh.compareAndExchangeRelease();
+        });
+        checkWMTE(() -> { // >
+            float x = (float) vh.compareAndExchangeRelease(array, 0, 1.0f, 1.0f, Void.class);
+        });
+
+
+        // GetAndSet
+        // Incorrect argument types
+        checkNPE(() -> { // null array
+            float x = (float) vh.getAndSet(null, 0, 1.0f);
+        });
+        checkCCE(() -> { // array reference class
+            float x = (float) vh.getAndSet(Void.class, 0, 1.0f);
+        });
+        checkWMTE(() -> { // value reference class
+            float x = (float) vh.getAndSet(array, 0, Void.class);
+        });
+        checkWMTE(() -> { // reciarrayever primitive class
+            float x = (float) vh.getAndSet(0, 0, 1.0f);
+        });
+        checkWMTE(() -> { // index reference class
+            float x = (float) vh.getAndSet(array, Void.class, 1.0f);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.getAndSet(array, 0, 1.0f);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.getAndSet(array, 0, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            float x = (float) vh.getAndSet();
+        });
+        checkWMTE(() -> { // >
+            float x = (float) vh.getAndSet(array, 0, 1.0f, Void.class);
+        });
+
+        // GetAndAdd
+        // Incorrect argument types
+        checkNPE(() -> { // null array
+            float x = (float) vh.getAndAdd(null, 0, 1.0f);
+        });
+        checkCCE(() -> { // array reference class
+            float x = (float) vh.getAndAdd(Void.class, 0, 1.0f);
+        });
+        checkWMTE(() -> { // value reference class
+            float x = (float) vh.getAndAdd(array, 0, Void.class);
+        });
+        checkWMTE(() -> { // array primitive class
+            float x = (float) vh.getAndAdd(0, 0, 1.0f);
+        });
+        checkWMTE(() -> { // index reference class
+            float x = (float) vh.getAndAdd(array, Void.class, 1.0f);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.getAndAdd(array, 0, 1.0f);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.getAndAdd(array, 0, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            float x = (float) vh.getAndAdd();
+        });
+        checkWMTE(() -> { // >
+            float x = (float) vh.getAndAdd(array, 0, 1.0f, Void.class);
+        });
+
+
+        // AddAndGet
+        // Incorrect argument types
+        checkNPE(() -> { // null array
+            float x = (float) vh.addAndGet(null, 0, 1.0f);
+        });
+        checkCCE(() -> { // array reference class
+            float x = (float) vh.addAndGet(Void.class, 0, 1.0f);
+        });
+        checkWMTE(() -> { // value reference class
+            float x = (float) vh.addAndGet(array, 0, Void.class);
+        });
+        checkWMTE(() -> { // array primitive class
+            float x = (float) vh.addAndGet(0, 0, 1.0f);
+        });
+        checkWMTE(() -> { // index reference class
+            float x = (float) vh.addAndGet(array, Void.class, 1.0f);
+        });
+        // Incorrect return type
+        checkWMTE(() -> { // reference class
+            Void r = (Void) vh.addAndGet(array, 0, 1.0f);
+        });
+        checkWMTE(() -> { // primitive class
+            boolean x = (boolean) vh.addAndGet(array, 0, 1.0f);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            float x = (float) vh.addAndGet();
+        });
+        checkWMTE(() -> { // >
+            float x = (float) vh.addAndGet(array, 0, 1.0f, Void.class);
+        });
     }
 
     static void testArrayWrongMethodType(Handles hs) throws Throwable {
@@ -852,7 +1978,172 @@
                     invokeExact(array, 0, 1.0f, Void.class);
             });
         }
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
+            // Incorrect argument types
+            checkNPE(() -> { // null receiver
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, float[].class, int.class, float.class, float.class)).
+                    invokeExact((float[]) null, 0, 1.0f, 1.0f);
+            });
+            hs.checkWMTEOrCCE(() -> { // receiver reference class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, float.class, float.class)).
+                    invokeExact(Void.class, 0, 1.0f, 1.0f);
+            });
+            checkWMTE(() -> { // expected reference class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, float[].class, int.class, Class.class, float.class)).
+                    invokeExact(array, 0, Void.class, 1.0f);
+            });
+            checkWMTE(() -> { // actual reference class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, float[].class, int.class, float.class, Class.class)).
+                    invokeExact(array, 0, 1.0f, Void.class);
+            });
+            checkWMTE(() -> { // receiver primitive class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, float.class, float.class)).
+                    invokeExact(0, 0, 1.0f, 1.0f);
+            });
+            checkWMTE(() -> { // index reference class
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, float[].class, Class.class, float.class, float.class)).
+                    invokeExact(array, Void.class, 1.0f, 1.0f);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                boolean r = (boolean) hs.get(am, methodType(boolean.class, float[].class, int.class, float.class, float.class, Class.class)).
+                    invokeExact(array, 0, 1.0f, 1.0f, Void.class);
+            });
+        }
 
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
+            // Incorrect argument types
+            checkNPE(() -> { // null receiver
+                float x = (float) hs.get(am, methodType(float.class, float[].class, int.class, float.class, float.class)).
+                    invokeExact((float[]) null, 0, 1.0f, 1.0f);
+            });
+            hs.checkWMTEOrCCE(() -> { // array reference class
+                float x = (float) hs.get(am, methodType(float.class, Class.class, int.class, float.class, float.class)).
+                    invokeExact(Void.class, 0, 1.0f, 1.0f);
+            });
+            checkWMTE(() -> { // expected reference class
+                float x = (float) hs.get(am, methodType(float.class, float[].class, int.class, Class.class, float.class)).
+                    invokeExact(array, 0, Void.class, 1.0f);
+            });
+            checkWMTE(() -> { // actual reference class
+                float x = (float) hs.get(am, methodType(float.class, float[].class, int.class, float.class, Class.class)).
+                    invokeExact(array, 0, 1.0f, Void.class);
+            });
+            checkWMTE(() -> { // array primitive class
+                float x = (float) hs.get(am, methodType(float.class, int.class, int.class, float.class, float.class)).
+                    invokeExact(0, 0, 1.0f, 1.0f);
+            });
+            checkWMTE(() -> { // index reference class
+                float x = (float) hs.get(am, methodType(float.class, float[].class, Class.class, float.class, float.class)).
+                    invokeExact(array, Void.class, 1.0f, 1.0f);
+            });
+            // Incorrect return type
+            checkWMTE(() -> { // reference class
+                Void r = (Void) hs.get(am, methodType(Void.class, float[].class, int.class, float.class, float.class)).
+                    invokeExact(array, 0, 1.0f, 1.0f);
+            });
+            checkWMTE(() -> { // primitive class
+                boolean x = (boolean) hs.get(am, methodType(boolean.class, float[].class, int.class, float.class, float.class)).
+                    invokeExact(array, 0, 1.0f, 1.0f);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                float x = (float) hs.get(am, methodType(float.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                float x = (float) hs.get(am, methodType(float.class, float[].class, int.class, float.class, float.class, Class.class)).
+                    invokeExact(array, 0, 1.0f, 1.0f, Void.class);
+            });
+        }
+
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
+            // Incorrect argument types
+            checkNPE(() -> { // null array
+                float x = (float) hs.get(am, methodType(float.class, float[].class, int.class, float.class)).
+                    invokeExact((float[]) null, 0, 1.0f);
+            });
+            hs.checkWMTEOrCCE(() -> { // array reference class
+                float x = (float) hs.get(am, methodType(float.class, Class.class, int.class, float.class)).
+                    invokeExact(Void.class, 0, 1.0f);
+            });
+            checkWMTE(() -> { // value reference class
+                float x = (float) hs.get(am, methodType(float.class, float[].class, int.class, Class.class)).
+                    invokeExact(array, 0, Void.class);
+            });
+            checkWMTE(() -> { // array primitive class
+                float x = (float) hs.get(am, methodType(float.class, int.class, int.class, float.class)).
+                    invokeExact(0, 0, 1.0f);
+            });
+            checkWMTE(() -> { // index reference class
+                float x = (float) hs.get(am, methodType(float.class, float[].class, Class.class, float.class)).
+                    invokeExact(array, Void.class, 1.0f);
+            });
+            // Incorrect return type
+            checkWMTE(() -> { // reference class
+                Void r = (Void) hs.get(am, methodType(Void.class, float[].class, int.class, float.class)).
+                    invokeExact(array, 0, 1.0f);
+            });
+            checkWMTE(() -> { // primitive class
+                boolean x = (boolean) hs.get(am, methodType(boolean.class, float[].class, int.class, float.class)).
+                    invokeExact(array, 0, 1.0f);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                float x = (float) hs.get(am, methodType(float.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                float x = (float) hs.get(am, methodType(float.class, float[].class, int.class, float.class, Class.class)).
+                    invokeExact(array, 0, 1.0f, Void.class);
+            });
+        }
+
+        for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
+            // Incorrect argument types
+            checkNPE(() -> { // null array
+                float x = (float) hs.get(am, methodType(float.class, float[].class, int.class, float.class)).
+                    invokeExact((float[]) null, 0, 1.0f);
+            });
+            hs.checkWMTEOrCCE(() -> { // array reference class
+                float x = (float) hs.get(am, methodType(float.class, Class.class, int.class, float.class)).
+                    invokeExact(Void.class, 0, 1.0f);
+            });
+            checkWMTE(() -> { // value reference class
+                float x = (float) hs.get(am, methodType(float.class, float[].class, int.class, Class.class)).
+                    invokeExact(array, 0, Void.class);
+            });
+            checkWMTE(() -> { // array primitive class
+                float x = (float) hs.get(am, methodType(float.class, int.class, int.class, float.class)).
+                    invokeExact(0, 0, 1.0f);
+            });
+            checkWMTE(() -> { // index reference class
+                float x = (float) hs.get(am, methodType(float.class, float[].class, Class.class, float.class)).
+                    invokeExact(array, Void.class, 1.0f);
+            });
+            // Incorrect return type
+            checkWMTE(() -> { // reference class
+                Void r = (Void) hs.get(am, methodType(Void.class, float[].class, int.class, float.class)).
+                    invokeExact(array, 0, 1.0f);
+            });
+            checkWMTE(() -> { // primitive class
+                boolean x = (boolean) hs.get(am, methodType(boolean.class, float[].class, int.class, float.class)).
+                    invokeExact(array, 0, 1.0f);
+            });
+            // Incorrect arity
+            checkWMTE(() -> { // 0
+                float x = (float) hs.get(am, methodType(float.class)).
+                    invokeExact();
+            });
+            checkWMTE(() -> { // >
+                float x = (float) hs.get(am, methodType(float.class, float[].class, int.class, float.class, Class.class)).
+                    invokeExact(array, 0, 1.0f, Void.class);
+            });
+        }
     }
 }
 
--- a/jdk/test/java/lang/invoke/VarHandles/generate-vh-tests.sh	Wed Jun 15 11:20:15 2016 +0300
+++ b/jdk/test/java/lang/invoke/VarHandles/generate-vh-tests.sh	Mon Jun 20 17:57:19 2016 +0200
@@ -14,14 +14,10 @@
   Type="$(tr '[:lower:]' '[:upper:]' <<< ${type:0:1})${type:1}"
   args="-K$type -Dtype=$type -DType=$Type"
 
-  case $type in
-    String|boolean|byte|short|char|int|long)
-      args="$args -KCAS"
-      ;;
-  esac
+  args="$args -KCAS"
 
   case $type in
-    byte|short|char|int|long)
+    byte|short|char|int|long|float|double)
       args="$args -KAtomicAdd"
       ;;
   esac