| // Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| package varhandle; |
| |
| import java.lang.invoke.MethodHandles; |
| import java.lang.invoke.VarHandle; |
| |
| public class InstanceLongField { |
| |
| private long field; |
| |
| private static void checkJavaLangInvokeWrongMethodTypeException(RuntimeException e) { |
| if (e.getClass().getCanonicalName().equals("java.lang.invoke.WrongMethodTypeException") |
| || e.getMessage().equals("java.lang.invoke.WrongMethodTypeException")) { |
| return; |
| } |
| throw e; |
| } |
| |
| public static void testGet(VarHandle varHandle) { |
| System.out.println("testGet"); |
| |
| InstanceLongField instance = new InstanceLongField(); |
| varHandle.set(instance, 1L); |
| |
| System.out.println(varHandle.get(instance)); |
| System.out.println((Object) varHandle.get(instance)); |
| System.out.println((long) varHandle.get(instance)); |
| System.out.println((float) varHandle.get(instance)); |
| System.out.println((double) varHandle.get(instance)); |
| try { |
| System.out.println((boolean) varHandle.get(instance)); |
| System.out.println("Unexpected success"); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| } |
| try { |
| System.out.println((byte) varHandle.get(instance)); |
| System.out.println("Unexpected success"); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| } |
| try { |
| System.out.println((short) varHandle.get(instance)); |
| System.out.println("Unexpected success"); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| } |
| try { |
| System.out.println((char) varHandle.get(instance)); |
| System.out.println("Unexpected success"); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| } |
| try { |
| System.out.println((int) varHandle.get(instance)); |
| System.out.println("Unexpected success 5"); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| } |
| try { |
| System.out.println((String) varHandle.get(instance)); |
| System.out.println("Unexpected success"); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| } |
| } |
| |
| public static void testGetVolatile(VarHandle varHandle) { |
| System.out.println("testGetVolatile"); |
| |
| InstanceLongField instance = new InstanceLongField(); |
| varHandle.set(instance, 1); |
| |
| System.out.println(varHandle.getVolatile(instance)); |
| System.out.println((Object) varHandle.getVolatile(instance)); |
| System.out.println((long) varHandle.getVolatile(instance)); |
| System.out.println((float) varHandle.getVolatile(instance)); |
| System.out.println((double) varHandle.getVolatile(instance)); |
| try { |
| System.out.println((boolean) varHandle.getVolatile(instance)); |
| System.out.println("Unexpected success"); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| } |
| try { |
| System.out.println((byte) varHandle.getVolatile(instance)); |
| System.out.println("Unexpected success"); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| } |
| try { |
| System.out.println((short) varHandle.getVolatile(instance)); |
| System.out.println("Unexpected success"); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| } |
| try { |
| System.out.println((char) varHandle.getVolatile(instance)); |
| System.out.println("Unexpected success"); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| } |
| try { |
| System.out.println((int) varHandle.getVolatile(instance)); |
| System.out.println("Unexpected success"); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| } |
| try { |
| System.out.println((String) varHandle.getVolatile(instance)); |
| System.out.println("Unexpected success"); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| } |
| } |
| |
| public static void testSet(VarHandle varHandle) { |
| System.out.println("testSet"); |
| |
| InstanceLongField instance = new InstanceLongField(); |
| System.out.println((long) varHandle.get(instance)); |
| |
| // Long value. |
| varHandle.set(instance, (long) 1); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.set(instance, Long.valueOf(2)); |
| System.out.println(varHandle.get(instance)); |
| |
| // Long compatible values. |
| varHandle.set(instance, (byte) 3); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.set(instance, Byte.valueOf((byte) 4)); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.set(instance, '0'); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.set(instance, Character.valueOf('1')); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.set(instance, (short) 5); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.set(instance, Short.valueOf((short) 6)); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.set(instance, (int) 7); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.set(instance, Integer.valueOf(8)); |
| System.out.println((long) varHandle.get(instance)); |
| |
| // Long non-compatible values. |
| try { |
| varHandle.set(instance, true); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.set(instance, "3"); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.set(instance, 3.0f); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.set(instance, 3.0); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| } |
| |
| public static void testSetVolatile(VarHandle varHandle) { |
| System.out.println("testSetVolatile"); |
| |
| InstanceLongField instance = new InstanceLongField(); |
| System.out.println((long) varHandle.get(instance)); |
| |
| // Long value. |
| varHandle.setVolatile(instance, (long) 1); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.setVolatile(instance, Long.valueOf(2)); |
| System.out.println(varHandle.get(instance)); |
| |
| // Long compatible values. |
| varHandle.setVolatile(instance, (byte) 3); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.setVolatile(instance, Byte.valueOf((byte) 4)); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.setVolatile(instance, '0'); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.setVolatile(instance, Character.valueOf('1')); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.setVolatile(instance, (short) 5); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.setVolatile(instance, Short.valueOf((short) 6)); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.setVolatile(instance, (int) 7); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.setVolatile(instance, Integer.valueOf(8)); |
| System.out.println((long) varHandle.get(instance)); |
| |
| // Long non-compatible values. |
| try { |
| varHandle.setVolatile(instance, true); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.setVolatile(instance, "3"); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.setVolatile(instance, 3.0f); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.setVolatile(instance, 3.0); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| } |
| |
| public static void testSetRelease(VarHandle varHandle) { |
| System.out.println("testSetRelease"); |
| |
| InstanceLongField instance = new InstanceLongField(); |
| System.out.println((long) varHandle.get(instance)); |
| |
| // Long value. |
| varHandle.setRelease(instance, (long) 1); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.setRelease(instance, Long.valueOf(2)); |
| System.out.println(varHandle.get(instance)); |
| |
| // Long compatible values. |
| varHandle.setRelease(instance, (byte) 3); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.setRelease(instance, Byte.valueOf((byte) 4)); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.setRelease(instance, '0'); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.setRelease(instance, Character.valueOf('1')); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.setRelease(instance, (short) 5); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.setRelease(instance, Short.valueOf((short) 6)); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.setRelease(instance, (int) 7); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.setRelease(instance, Integer.valueOf(8)); |
| System.out.println((long) varHandle.get(instance)); |
| |
| // Long non-compatible values. |
| try { |
| varHandle.setRelease(instance, true); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.setRelease(instance, "3"); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.setRelease(instance, 3.0f); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.setRelease(instance, 3.0); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| } |
| |
| public static void testCompareAndSet(VarHandle varHandle) { |
| System.out.println("testCompareAndSet"); |
| |
| InstanceLongField instance = new InstanceLongField(); |
| |
| // Long value. |
| varHandle.compareAndSet(instance, 1L, 2L); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.compareAndSet(instance, 0L, 1L); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.compareAndSet(instance, Long.valueOf(1), 2); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.compareAndSet(instance, 2, Long.valueOf(3)); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.compareAndSet(instance, Long.valueOf(3), Long.valueOf(4)); |
| System.out.println((long) varHandle.get(instance)); |
| |
| // Long compatible values. |
| varHandle.compareAndSet(instance, (byte) 4, 5); |
| System.out.println(varHandle.get(instance)); |
| varHandle.compareAndSet(instance, 5, (byte) 6); |
| System.out.println(varHandle.get(instance)); |
| varHandle.compareAndSet(instance, (byte) 6, (byte) 7); |
| System.out.println(varHandle.get(instance)); |
| varHandle.compareAndSet(instance, Byte.valueOf((byte) 7), (byte) 8); |
| System.out.println(varHandle.get(instance)); |
| varHandle.compareAndSet(instance, (byte) 8, Byte.valueOf((byte) 9)); |
| System.out.println(varHandle.get(instance)); |
| varHandle.compareAndSet(instance, Byte.valueOf((byte) 9), Byte.valueOf((byte) 10)); |
| System.out.println(varHandle.get(instance)); |
| varHandle.compareAndSet(instance, 10, '0'); |
| System.out.println(varHandle.get(instance)); |
| varHandle.compareAndSet(instance, '0', 49); |
| System.out.println(varHandle.get(instance)); |
| varHandle.compareAndSet(instance, '1', '2'); |
| System.out.println(varHandle.get(instance)); |
| varHandle.compareAndSet(instance, (byte) 50, '3'); |
| System.out.println(varHandle.get(instance)); |
| varHandle.compareAndSet(instance, '3', (byte) 52); |
| System.out.println(varHandle.get(instance)); |
| varHandle.compareAndSet(instance, '4', '5'); |
| System.out.println(varHandle.get(instance)); |
| varHandle.compareAndSet(instance, '5', (int) 11); |
| System.out.println(varHandle.get(instance)); |
| varHandle.compareAndSet(instance, (int) 11, (int) 12); |
| System.out.println(varHandle.get(instance)); |
| varHandle.compareAndSet(instance, (int) 12, Integer.valueOf(13)); |
| System.out.println(varHandle.get(instance)); |
| varHandle.compareAndSet(instance, Integer.valueOf(13), Integer.valueOf(14)); |
| System.out.println(varHandle.get(instance)); |
| |
| // Long non-compatible values. |
| try { |
| varHandle.compareAndSet(instance, 6, 7.0f); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.compareAndSet(instance, 6.0f, 7); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.compareAndSet(instance, 6.0f, 7.0f); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.compareAndSet(instance, 6, 7.0); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.compareAndSet(instance, 6.0, 7); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.compareAndSet(instance, 6.0, 7.0); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| |
| try { |
| varHandle.compareAndSet(instance, 6, "7"); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.compareAndSet(instance, "6", 7); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.compareAndSet(instance, "6", "7"); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| } |
| |
| // This test is not testing weakCompareAndSet behaviour, but assuming it behaves like |
| // compareAndSet, that is without any spurious failures. This is the desugaring behaviour, as |
| // as there is no weakCompareAndSet primitive in sun.misc.Unsafe, only compareAndSwapXXX. |
| public static void testWeakCompareAndSet(VarHandle varHandle) { |
| System.out.println("testWeakCompareAndSet"); |
| |
| InstanceLongField instance = new InstanceLongField(); |
| |
| // Long value. |
| varHandle.weakCompareAndSet(instance, 1L, 2L); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.weakCompareAndSet(instance, 0L, 1L); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.weakCompareAndSet(instance, Long.valueOf(1), 2); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.weakCompareAndSet(instance, 2, Long.valueOf(3)); |
| System.out.println((long) varHandle.get(instance)); |
| varHandle.weakCompareAndSet(instance, Long.valueOf(3), Long.valueOf(4)); |
| System.out.println((long) varHandle.get(instance)); |
| |
| // Long compatible values. |
| varHandle.weakCompareAndSet(instance, (byte) 4, 5); |
| System.out.println(varHandle.get(instance)); |
| varHandle.weakCompareAndSet(instance, 5, (byte) 6); |
| System.out.println(varHandle.get(instance)); |
| varHandle.weakCompareAndSet(instance, (byte) 6, (byte) 7); |
| System.out.println(varHandle.get(instance)); |
| varHandle.weakCompareAndSet(instance, Byte.valueOf((byte) 7), (byte) 8); |
| System.out.println(varHandle.get(instance)); |
| varHandle.weakCompareAndSet(instance, (byte) 8, Byte.valueOf((byte) 9)); |
| System.out.println(varHandle.get(instance)); |
| varHandle.weakCompareAndSet(instance, Byte.valueOf((byte) 9), Byte.valueOf((byte) 10)); |
| System.out.println(varHandle.get(instance)); |
| varHandle.weakCompareAndSet(instance, 10, '0'); |
| System.out.println(varHandle.get(instance)); |
| varHandle.weakCompareAndSet(instance, '0', 49); |
| System.out.println(varHandle.get(instance)); |
| varHandle.weakCompareAndSet(instance, '1', '2'); |
| System.out.println(varHandle.get(instance)); |
| varHandle.weakCompareAndSet(instance, (byte) 50, '3'); |
| System.out.println(varHandle.get(instance)); |
| varHandle.weakCompareAndSet(instance, '3', (byte) 52); |
| System.out.println(varHandle.get(instance)); |
| varHandle.weakCompareAndSet(instance, '4', '5'); |
| System.out.println(varHandle.get(instance)); |
| varHandle.weakCompareAndSet(instance, '5', (int) 11); |
| System.out.println(varHandle.get(instance)); |
| varHandle.weakCompareAndSet(instance, (int) 11, (int) 12); |
| System.out.println(varHandle.get(instance)); |
| varHandle.weakCompareAndSet(instance, (int) 12, Integer.valueOf(13)); |
| System.out.println(varHandle.get(instance)); |
| varHandle.weakCompareAndSet(instance, Integer.valueOf(13), Integer.valueOf(14)); |
| System.out.println(varHandle.get(instance)); |
| |
| // Long non-compatible values. |
| try { |
| varHandle.weakCompareAndSet(instance, 6, 7.0f); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.weakCompareAndSet(instance, 6.0f, 7); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.weakCompareAndSet(instance, 6.0f, 7.0f); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.weakCompareAndSet(instance, 6, 7.0); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.weakCompareAndSet(instance, 6.0, 7); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.weakCompareAndSet(instance, 6.0, 7.0); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| |
| try { |
| varHandle.weakCompareAndSet(instance, 6, "7"); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.weakCompareAndSet(instance, "6", 7); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| try { |
| varHandle.weakCompareAndSet(instance, "6", "7"); |
| } catch (RuntimeException e) { |
| checkJavaLangInvokeWrongMethodTypeException(e); |
| System.out.println(varHandle.get(instance)); |
| } |
| } |
| |
| public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { |
| VarHandle varHandle = |
| MethodHandles.lookup().findVarHandle(InstanceLongField.class, "field", long.class); |
| testGet(varHandle); |
| testGetVolatile(varHandle); |
| testSet(varHandle); |
| testSetVolatile(varHandle); |
| testSetRelease(varHandle); |
| testCompareAndSet(varHandle); |
| testWeakCompareAndSet(varHandle); |
| } |
| } |