8194233: Improve support for array handles
authorpsandoz
Mon, 22 Jan 2018 13:27:28 -0800
changeset 49788 5375d426822a
parent 49787 99b627637911
child 49789 27b359322b1e
8194233: Improve support for array handles Reviewed-by: jrose, vlivanov, ahgross, rhalade
src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template
test/jdk/java/lang/invoke/VarHandles/VarHandleBaseTest.java
test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java
test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java
test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java
test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java
test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java
test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java
test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java
test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java
test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessString.java
test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template
--- a/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template	Fri Jan 19 11:24:39 2018 -0800
+++ b/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template	Mon Jan 22 13:27:28 2018 -0800
@@ -592,6 +592,28 @@
             return accessMode.at.accessModeType({#if[Object]?arrayType:$type$[].class}, {#if[Object]?arrayType.getComponentType():$type$.class}, int.class);
         }
 
+#if[Object]
+        @ForceInline
+        static Object runtimeTypeCheck(Array handle, Object[] oarray, Object value) {
+            if (handle.arrayType == oarray.getClass()) {
+                // Fast path: static array type same as argument array type
+                return handle.componentType.cast(value);
+            } else {
+                // Slow path: check value against argument array component type
+                return reflectiveTypeCheck(oarray, value);
+            }
+        }
+
+        @ForceInline
+        static Object reflectiveTypeCheck(Object[] oarray, Object value) {
+            try {
+                return oarray.getClass().getComponentType().cast(value);
+            } catch (ClassCastException e) {
+                throw new ArrayStoreException();
+            }
+        }
+#end[Object]
+
         @ForceInline
         static $type$ get(Array handle, Object oarray, int index) {
 #if[Object]
@@ -632,7 +654,7 @@
 #end[Object]
             UNSAFE.put$Type$Volatile(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -655,7 +677,7 @@
 #end[Object]
             UNSAFE.put$Type$Opaque(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -678,7 +700,7 @@
 #end[Object]
             UNSAFE.put$Type$Release(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 #if[CAS]
 
@@ -692,7 +714,7 @@
             return UNSAFE.compareAndSet$Type$(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
                     {#if[Object]?handle.componentType.cast(expected):expected},
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -705,7 +727,7 @@
             return UNSAFE.compareAndExchange$Type$(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
                     {#if[Object]?handle.componentType.cast(expected):expected},
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -718,7 +740,7 @@
             return UNSAFE.compareAndExchange$Type$Acquire(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
                     {#if[Object]?handle.componentType.cast(expected):expected},
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -731,7 +753,7 @@
             return UNSAFE.compareAndExchange$Type$Release(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
                     {#if[Object]?handle.componentType.cast(expected):expected},
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -744,7 +766,7 @@
             return UNSAFE.weakCompareAndSet$Type$Plain(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
                     {#if[Object]?handle.componentType.cast(expected):expected},
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -757,7 +779,7 @@
             return UNSAFE.weakCompareAndSet$Type$(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
                     {#if[Object]?handle.componentType.cast(expected):expected},
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -770,7 +792,7 @@
             return UNSAFE.weakCompareAndSet$Type$Acquire(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
                     {#if[Object]?handle.componentType.cast(expected):expected},
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -783,7 +805,7 @@
             return UNSAFE.weakCompareAndSet$Type$Release(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
                     {#if[Object]?handle.componentType.cast(expected):expected},
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -795,7 +817,7 @@
 #end[Object]
             return UNSAFE.getAndSet$Type$(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -807,7 +829,7 @@
 #end[Object]
             return UNSAFE.getAndSet$Type$Acquire(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -819,7 +841,7 @@
 #end[Object]
             return UNSAFE.getAndSet$Type$Release(array,
                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
-                    {#if[Object]?handle.componentType.cast(value):value});
+                    {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 #end[CAS]
 #if[AtomicAdd]
--- a/test/jdk/java/lang/invoke/VarHandles/VarHandleBaseTest.java	Fri Jan 19 11:24:39 2018 -0800
+++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleBaseTest.java	Mon Jan 22 13:27:28 2018 -0800
@@ -70,6 +70,14 @@
         checkWithThrowable(IndexOutOfBoundsException.class, message, r);
     }
 
+    static void checkASE(ThrowingRunnable r) {
+        checkWithThrowable(ArrayStoreException.class, null, r);
+    }
+
+    static void checkASE(Object message, ThrowingRunnable r) {
+        checkWithThrowable(ArrayStoreException.class, message, r);
+    }
+
     static void checkISE(ThrowingRunnable r) {
         checkWithThrowable(IllegalStateException.class, null, r);
     }
--- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java	Fri Jan 19 11:24:39 2018 -0800
+++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java	Mon Jan 22 13:27:28 2018 -0800
@@ -60,6 +60,7 @@
 
     VarHandle vhArray;
 
+
     @BeforeClass
     public void setup() throws Exception {
         vhFinalField = MethodHandles.lookup().findVarHandle(
@@ -210,7 +211,6 @@
         cases.add(new VarHandleAccessTestCase("Array index out of bounds",
                                               vhArray, VarHandleTestAccessBoolean::testArrayIndexOutOfBounds,
                                               false));
-
         // Work around issue with jtreg summary reporting which truncates
         // the String result of Object.toString to 30 characters, hence
         // the first dummy argument
@@ -1255,5 +1255,6 @@
             });
         }
     }
+
 }
 
--- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java	Fri Jan 19 11:24:39 2018 -0800
+++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java	Mon Jan 22 13:27:28 2018 -0800
@@ -60,6 +60,7 @@
 
     VarHandle vhArray;
 
+
     @BeforeClass
     public void setup() throws Exception {
         vhFinalField = MethodHandles.lookup().findVarHandle(
@@ -210,7 +211,6 @@
         cases.add(new VarHandleAccessTestCase("Array index out of bounds",
                                               vhArray, VarHandleTestAccessByte::testArrayIndexOutOfBounds,
                                               false));
-
         // Work around issue with jtreg summary reporting which truncates
         // the String result of Object.toString to 30 characters, hence
         // the first dummy argument
@@ -1292,5 +1292,6 @@
             });
         }
     }
+
 }
 
--- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java	Fri Jan 19 11:24:39 2018 -0800
+++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java	Mon Jan 22 13:27:28 2018 -0800
@@ -60,6 +60,7 @@
 
     VarHandle vhArray;
 
+
     @BeforeClass
     public void setup() throws Exception {
         vhFinalField = MethodHandles.lookup().findVarHandle(
@@ -210,7 +211,6 @@
         cases.add(new VarHandleAccessTestCase("Array index out of bounds",
                                               vhArray, VarHandleTestAccessChar::testArrayIndexOutOfBounds,
                                               false));
-
         // Work around issue with jtreg summary reporting which truncates
         // the String result of Object.toString to 30 characters, hence
         // the first dummy argument
@@ -1292,5 +1292,6 @@
             });
         }
     }
+
 }
 
--- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java	Fri Jan 19 11:24:39 2018 -0800
+++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java	Mon Jan 22 13:27:28 2018 -0800
@@ -60,6 +60,7 @@
 
     VarHandle vhArray;
 
+
     @BeforeClass
     public void setup() throws Exception {
         vhFinalField = MethodHandles.lookup().findVarHandle(
@@ -210,7 +211,6 @@
         cases.add(new VarHandleAccessTestCase("Array index out of bounds",
                                               vhArray, VarHandleTestAccessDouble::testArrayIndexOutOfBounds,
                                               false));
-
         // Work around issue with jtreg summary reporting which truncates
         // the String result of Object.toString to 30 characters, hence
         // the first dummy argument
@@ -1183,5 +1183,6 @@
 
         }
     }
+
 }
 
--- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java	Fri Jan 19 11:24:39 2018 -0800
+++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java	Mon Jan 22 13:27:28 2018 -0800
@@ -60,6 +60,7 @@
 
     VarHandle vhArray;
 
+
     @BeforeClass
     public void setup() throws Exception {
         vhFinalField = MethodHandles.lookup().findVarHandle(
@@ -210,7 +211,6 @@
         cases.add(new VarHandleAccessTestCase("Array index out of bounds",
                                               vhArray, VarHandleTestAccessFloat::testArrayIndexOutOfBounds,
                                               false));
-
         // Work around issue with jtreg summary reporting which truncates
         // the String result of Object.toString to 30 characters, hence
         // the first dummy argument
@@ -1183,5 +1183,6 @@
 
         }
     }
+
 }
 
--- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java	Fri Jan 19 11:24:39 2018 -0800
+++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java	Mon Jan 22 13:27:28 2018 -0800
@@ -60,6 +60,7 @@
 
     VarHandle vhArray;
 
+
     @BeforeClass
     public void setup() throws Exception {
         vhFinalField = MethodHandles.lookup().findVarHandle(
@@ -210,7 +211,6 @@
         cases.add(new VarHandleAccessTestCase("Array index out of bounds",
                                               vhArray, VarHandleTestAccessInt::testArrayIndexOutOfBounds,
                                               false));
-
         // Work around issue with jtreg summary reporting which truncates
         // the String result of Object.toString to 30 characters, hence
         // the first dummy argument
@@ -1292,5 +1292,6 @@
             });
         }
     }
+
 }
 
--- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java	Fri Jan 19 11:24:39 2018 -0800
+++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java	Mon Jan 22 13:27:28 2018 -0800
@@ -60,6 +60,7 @@
 
     VarHandle vhArray;
 
+
     @BeforeClass
     public void setup() throws Exception {
         vhFinalField = MethodHandles.lookup().findVarHandle(
@@ -210,7 +211,6 @@
         cases.add(new VarHandleAccessTestCase("Array index out of bounds",
                                               vhArray, VarHandleTestAccessLong::testArrayIndexOutOfBounds,
                                               false));
-
         // Work around issue with jtreg summary reporting which truncates
         // the String result of Object.toString to 30 characters, hence
         // the first dummy argument
@@ -1292,5 +1292,6 @@
             });
         }
     }
+
 }
 
--- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java	Fri Jan 19 11:24:39 2018 -0800
+++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java	Mon Jan 22 13:27:28 2018 -0800
@@ -60,6 +60,7 @@
 
     VarHandle vhArray;
 
+
     @BeforeClass
     public void setup() throws Exception {
         vhFinalField = MethodHandles.lookup().findVarHandle(
@@ -210,7 +211,6 @@
         cases.add(new VarHandleAccessTestCase("Array index out of bounds",
                                               vhArray, VarHandleTestAccessShort::testArrayIndexOutOfBounds,
                                               false));
-
         // Work around issue with jtreg summary reporting which truncates
         // the String result of Object.toString to 30 characters, hence
         // the first dummy argument
@@ -1292,5 +1292,6 @@
             });
         }
     }
+
 }
 
--- a/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessString.java	Fri Jan 19 11:24:39 2018 -0800
+++ b/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessString.java	Mon Jan 22 13:27:28 2018 -0800
@@ -60,6 +60,8 @@
 
     VarHandle vhArray;
 
+    VarHandle vhArrayObject;
+
     @BeforeClass
     public void setup() throws Exception {
         vhFinalField = MethodHandles.lookup().findVarHandle(
@@ -75,6 +77,7 @@
             VarHandleTestAccessString.class, "static_v", String.class);
 
         vhArray = MethodHandles.arrayElementVarHandle(String[].class);
+        vhArrayObject = MethodHandles.arrayElementVarHandle(Object[].class);
     }
 
 
@@ -204,13 +207,17 @@
 
         cases.add(new VarHandleAccessTestCase("Array",
                                               vhArray, VarHandleTestAccessString::testArray));
+        cases.add(new VarHandleAccessTestCase("Array Object[]",
+                                              vhArrayObject, VarHandleTestAccessString::testArray));
         cases.add(new VarHandleAccessTestCase("Array unsupported",
                                               vhArray, VarHandleTestAccessString::testArrayUnsupported,
                                               false));
         cases.add(new VarHandleAccessTestCase("Array index out of bounds",
                                               vhArray, VarHandleTestAccessString::testArrayIndexOutOfBounds,
                                               false));
-
+        cases.add(new VarHandleAccessTestCase("Array store exception",
+                                              vhArrayObject, VarHandleTestAccessString::testArrayStoreException,
+                                              false));
         // Work around issue with jtreg summary reporting which truncates
         // the String result of Object.toString to 30 characters, hence
         // the first dummy argument
@@ -1146,5 +1153,86 @@
 
         }
     }
+
+    static void testArrayStoreException(VarHandle vh) throws Throwable {
+        Object[] array = new String[10];
+        Arrays.fill(array, "foo");
+        Object value = new Object();
+
+        // Set
+        checkASE(() -> {
+            vh.set(array, 0, value);
+        });
+
+        // SetVolatile
+        checkASE(() -> {
+            vh.setVolatile(array, 0, value);
+        });
+
+        // SetOpaque
+        checkASE(() -> {
+            vh.setOpaque(array, 0, value);
+        });
+
+        // SetRelease
+        checkASE(() -> {
+            vh.setRelease(array, 0, value);
+        });
+
+        // CompareAndSet
+        checkASE(() -> { // receiver reference class
+            boolean r = vh.compareAndSet(array, 0, "foo", value);
+        });
+
+        // WeakCompareAndSet
+        checkASE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetPlain(array, 0, "foo", value);
+        });
+
+        // WeakCompareAndSetVolatile
+        checkASE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSet(array, 0, "foo", value);
+        });
+
+        // WeakCompareAndSetAcquire
+        checkASE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetAcquire(array, 0, "foo", value);
+        });
+
+        // WeakCompareAndSetRelease
+        checkASE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetRelease(array, 0, "foo", value);
+        });
+
+        // CompareAndExchange
+        checkASE(() -> { // receiver reference class
+            String x = (String) vh.compareAndExchange(array, 0, "foo", value);
+        });
+
+        // CompareAndExchangeAcquire
+        checkASE(() -> { // receiver reference class
+            String x = (String) vh.compareAndExchangeAcquire(array, 0, "foo", value);
+        });
+
+        // CompareAndExchangeRelease
+        checkASE(() -> { // receiver reference class
+            String x = (String) vh.compareAndExchangeRelease(array, 0, "foo", value);
+        });
+
+        // GetAndSet
+        checkASE(() -> { // receiver reference class
+            String x = (String) vh.getAndSet(array, 0, value);
+        });
+
+        // GetAndSetAcquire
+        checkASE(() -> { // receiver reference class
+            String x = (String) vh.getAndSetAcquire(array, 0, value);
+        });
+
+        // GetAndSetRelease
+        checkASE(() -> { // receiver reference class
+            String x = (String) vh.getAndSetRelease(array, 0, value);
+        });
+    }
 }
 
--- a/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template	Fri Jan 19 11:24:39 2018 -0800
+++ b/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template	Mon Jan 22 13:27:28 2018 -0800
@@ -60,6 +60,10 @@
 
     VarHandle vhArray;
 
+#if[String]
+    VarHandle vhArrayObject;
+#end[String]
+
     @BeforeClass
     public void setup() throws Exception {
         vhFinalField = MethodHandles.lookup().findVarHandle(
@@ -75,6 +79,9 @@
             VarHandleTestAccess$Type$.class, "static_v", $type$.class);
 
         vhArray = MethodHandles.arrayElementVarHandle($type$[].class);
+#if[String]
+        vhArrayObject = MethodHandles.arrayElementVarHandle(Object[].class);
+#end[String]
     }
 
 
@@ -236,13 +243,21 @@
 
         cases.add(new VarHandleAccessTestCase("Array",
                                               vhArray, VarHandleTestAccess$Type$::testArray));
+#if[String]
+        cases.add(new VarHandleAccessTestCase("Array Object[]",
+                                              vhArrayObject, VarHandleTestAccess$Type$::testArray));
+#end[String]
         cases.add(new VarHandleAccessTestCase("Array unsupported",
                                               vhArray, VarHandleTestAccess$Type$::testArrayUnsupported,
                                               false));
         cases.add(new VarHandleAccessTestCase("Array index out of bounds",
                                               vhArray, VarHandleTestAccess$Type$::testArrayIndexOutOfBounds,
                                               false));
-
+#if[String]
+        cases.add(new VarHandleAccessTestCase("Array store exception",
+                                              vhArrayObject, VarHandleTestAccess$Type$::testArrayStoreException,
+                                              false));
+#end[String]
         // Work around issue with jtreg summary reporting which truncates
         // the String result of Object.toString to 30 characters, hence
         // the first dummy argument
@@ -1823,5 +1838,88 @@
 #end[Bitwise]
         }
     }
+
+#if[String]
+    static void testArrayStoreException(VarHandle vh) throws Throwable {
+        Object[] array = new $type$[10];
+        Arrays.fill(array, $value1$);
+        Object value = new Object();
+
+        // Set
+        checkASE(() -> {
+            vh.set(array, 0, value);
+        });
+
+        // SetVolatile
+        checkASE(() -> {
+            vh.setVolatile(array, 0, value);
+        });
+
+        // SetOpaque
+        checkASE(() -> {
+            vh.setOpaque(array, 0, value);
+        });
+
+        // SetRelease
+        checkASE(() -> {
+            vh.setRelease(array, 0, value);
+        });
+
+        // CompareAndSet
+        checkASE(() -> { // receiver reference class
+            boolean r = vh.compareAndSet(array, 0, $value1$, value);
+        });
+
+        // WeakCompareAndSet
+        checkASE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetPlain(array, 0, $value1$, value);
+        });
+
+        // WeakCompareAndSetVolatile
+        checkASE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSet(array, 0, $value1$, value);
+        });
+
+        // WeakCompareAndSetAcquire
+        checkASE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetAcquire(array, 0, $value1$, value);
+        });
+
+        // WeakCompareAndSetRelease
+        checkASE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetRelease(array, 0, $value1$, value);
+        });
+
+        // CompareAndExchange
+        checkASE(() -> { // receiver reference class
+            $type$ x = ($type$) vh.compareAndExchange(array, 0, $value1$, value);
+        });
+
+        // CompareAndExchangeAcquire
+        checkASE(() -> { // receiver reference class
+            $type$ x = ($type$) vh.compareAndExchangeAcquire(array, 0, $value1$, value);
+        });
+
+        // CompareAndExchangeRelease
+        checkASE(() -> { // receiver reference class
+            $type$ x = ($type$) vh.compareAndExchangeRelease(array, 0, $value1$, value);
+        });
+
+        // GetAndSet
+        checkASE(() -> { // receiver reference class
+            $type$ x = ($type$) vh.getAndSet(array, 0, value);
+        });
+
+        // GetAndSetAcquire
+        checkASE(() -> { // receiver reference class
+            $type$ x = ($type$) vh.getAndSetAcquire(array, 0, value);
+        });
+
+        // GetAndSetRelease
+        checkASE(() -> { // receiver reference class
+            $type$ x = ($type$) vh.getAndSetRelease(array, 0, value);
+        });
+    }
+#end[String]
 }