VarHandle desugar: Add support for setVolatile

Bug: b/247076137
Change-Id: Ic8340bd2dec56b8cd56800f57d8d423a146dc7c5
diff --git a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
index 01ec8f1..4bb7312 100644
--- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
@@ -363,6 +363,7 @@
   public final DexString setString = createString("set");
   public final DexString compareAndSetString = createString("compareAndSet");
   public final DexString getVolatileString = createString("getVolatile");
+  public final DexString setVolatileString = createString("setVolatile");
 
   // Method names used on MethodHandles.
   public final DexString lookupString = createString("lookup");
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaring.java
index 0342bb7..e2be4e0 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaring.java
@@ -293,7 +293,7 @@
       } else if (name.equals(factory.getString) || name.equals(factory.getVolatileString)) {
         assert arity == 1 || arity == 2;
         return computeDesugarSignaturePolymorphicMethod(invoke, arity);
-      } else if (name.equals(factory.setString)) {
+      } else if (name.equals(factory.setString) || name.equals(factory.setVolatileString)) {
         assert arity == 2 || arity == 3;
         return computeDesugarSignaturePolymorphicMethod(invoke, arity - 1);
       } else {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaringMethods.java b/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaringMethods.java
index 29fd7b9..4e9686e 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaringMethods.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaringMethods.java
@@ -145,6 +145,15 @@
                 factory.intType,
                 factory.createType(factory.createString("Ljava/lang/Class;"))),
             factory.createString("get"));
+    DexMethod setVolatileArrayInt =
+        factory.createMethod(
+            builder.getType(),
+            factory.createProto(
+                factory.voidType,
+                factory.createType(factory.createString("[I")),
+                factory.intType,
+                factory.intType),
+            factory.createString("setVolatile"));
     DexMethod setArrayInt =
         factory.createMethod(
             builder.getType(),
@@ -182,11 +191,22 @@
                 factory.intType,
                 factory.longType),
             factory.createString("set"));
+    DexMethod setVolatileArray =
+        factory.createMethod(
+            builder.getType(),
+            factory.createProto(
+                factory.voidType, factory.objectType, factory.intType, factory.objectType),
+            factory.createString("setVolatile"));
     DexMethod getInt =
         factory.createMethod(
             builder.getType(),
             factory.createProto(factory.intType, factory.objectType),
             factory.createString("get"));
+    DexMethod setVolatileLong =
+        factory.createMethod(
+            builder.getType(),
+            factory.createProto(factory.voidType, factory.objectType, factory.longType),
+            factory.createString("setVolatile"));
     DexMethod getArrayLong =
         factory.createMethod(
             builder.getType(),
@@ -213,6 +233,11 @@
                 factory.longType,
                 factory.longType),
             factory.createString("compareAndSet"));
+    DexMethod setVolatileInt =
+        factory.createMethod(
+            builder.getType(),
+            factory.createProto(factory.voidType, factory.objectType, factory.intType),
+            factory.createString("setVolatile"));
     DexMethod getInBox =
         factory.createMethod(
             builder.getType(),
@@ -244,6 +269,15 @@
                 factory.objectType,
                 factory.createType(factory.createString("Ljava/lang/Class;"))),
             factory.createString("getVolatile"));
+    DexMethod setVolatileArrayLong =
+        factory.createMethod(
+            builder.getType(),
+            factory.createProto(
+                factory.voidType,
+                factory.createType(factory.createString("[J")),
+                factory.intType,
+                factory.longType),
+            factory.createString("setVolatile"));
     DexMethod compareAndSetArrayInt =
         factory.createMethod(
             builder.getType(),
@@ -284,6 +318,11 @@
             builder.getType(),
             factory.createProto(factory.createType(factory.createString("Ljava/lang/String;"))),
             factory.createString("arrayRequiringNativeSupport"));
+    DexMethod setVolatile =
+        factory.createMethod(
+            builder.getType(),
+            factory.createProto(factory.voidType, factory.objectType, factory.objectType),
+            factory.createString("setVolatile"));
     DexMethod boxLongIfPossible =
         factory.createMethod(
             builder.getType(),
@@ -411,6 +450,14 @@
                 .disableAndroidApiLevelCheck()
                 .build(),
             DexEncodedMethod.syntheticBuilder()
+                .setMethod(setVolatileArrayInt)
+                .setAccessFlags(
+                    MethodAccessFlags.fromSharedAccessFlags(
+                        Constants.ACC_PUBLIC | Constants.ACC_SYNTHETIC, false))
+                .setCode(DesugarVarHandle_setVolatileArrayInt(factory, setVolatileArrayInt))
+                .disableAndroidApiLevelCheck()
+                .build(),
+            DexEncodedMethod.syntheticBuilder()
                 .setMethod(setArrayInt)
                 .setAccessFlags(
                     MethodAccessFlags.fromSharedAccessFlags(
@@ -453,6 +500,14 @@
                 .disableAndroidApiLevelCheck()
                 .build(),
             DexEncodedMethod.syntheticBuilder()
+                .setMethod(setVolatileArray)
+                .setAccessFlags(
+                    MethodAccessFlags.fromSharedAccessFlags(
+                        Constants.ACC_PUBLIC | Constants.ACC_SYNTHETIC, false))
+                .setCode(DesugarVarHandle_setVolatileArray(factory, setVolatileArray))
+                .disableAndroidApiLevelCheck()
+                .build(),
+            DexEncodedMethod.syntheticBuilder()
                 .setMethod(getInt)
                 .setAccessFlags(
                     MethodAccessFlags.fromSharedAccessFlags(
@@ -461,6 +516,14 @@
                 .disableAndroidApiLevelCheck()
                 .build(),
             DexEncodedMethod.syntheticBuilder()
+                .setMethod(setVolatileLong)
+                .setAccessFlags(
+                    MethodAccessFlags.fromSharedAccessFlags(
+                        Constants.ACC_PUBLIC | Constants.ACC_SYNTHETIC, false))
+                .setCode(DesugarVarHandle_setVolatileLong(factory, setVolatileLong))
+                .disableAndroidApiLevelCheck()
+                .build(),
+            DexEncodedMethod.syntheticBuilder()
                 .setMethod(getArrayLong)
                 .setAccessFlags(
                     MethodAccessFlags.fromSharedAccessFlags(
@@ -493,6 +556,14 @@
                 .disableAndroidApiLevelCheck()
                 .build(),
             DexEncodedMethod.syntheticBuilder()
+                .setMethod(setVolatileInt)
+                .setAccessFlags(
+                    MethodAccessFlags.fromSharedAccessFlags(
+                        Constants.ACC_PUBLIC | Constants.ACC_SYNTHETIC, false))
+                .setCode(DesugarVarHandle_setVolatileInt(factory, setVolatileInt))
+                .disableAndroidApiLevelCheck()
+                .build(),
+            DexEncodedMethod.syntheticBuilder()
                 .setMethod(getInBox)
                 .setAccessFlags(
                     MethodAccessFlags.fromSharedAccessFlags(
@@ -533,6 +604,14 @@
                 .disableAndroidApiLevelCheck()
                 .build(),
             DexEncodedMethod.syntheticBuilder()
+                .setMethod(setVolatileArrayLong)
+                .setAccessFlags(
+                    MethodAccessFlags.fromSharedAccessFlags(
+                        Constants.ACC_PUBLIC | Constants.ACC_SYNTHETIC, false))
+                .setCode(DesugarVarHandle_setVolatileArrayLong(factory, setVolatileArrayLong))
+                .disableAndroidApiLevelCheck()
+                .build(),
+            DexEncodedMethod.syntheticBuilder()
                 .setMethod(compareAndSetArrayInt)
                 .setAccessFlags(
                     MethodAccessFlags.fromSharedAccessFlags(
@@ -567,6 +646,14 @@
                 .disableAndroidApiLevelCheck()
                 .build(),
             DexEncodedMethod.syntheticBuilder()
+                .setMethod(setVolatile)
+                .setAccessFlags(
+                    MethodAccessFlags.fromSharedAccessFlags(
+                        Constants.ACC_PUBLIC | Constants.ACC_SYNTHETIC, false))
+                .setCode(DesugarVarHandle_setVolatile(factory, setVolatile))
+                .disableAndroidApiLevelCheck()
+                .build(),
+            DexEncodedMethod.syntheticBuilder()
                 .setMethod(boxLongIfPossible)
                 .setAccessFlags(
                     MethodAccessFlags.fromSharedAccessFlags(
@@ -5823,6 +5910,827 @@
         ImmutableList.of());
   }
 
+  public static CfCode DesugarVarHandle_setVolatile(DexItemFactory factory, DexMethod method) {
+    CfLabel label0 = new CfLabel();
+    CfLabel label1 = new CfLabel();
+    CfLabel label2 = new CfLabel();
+    CfLabel label3 = new CfLabel();
+    CfLabel label4 = new CfLabel();
+    CfLabel label5 = new CfLabel();
+    CfLabel label6 = new CfLabel();
+    return new CfCode(
+        method.holder,
+        5,
+        3,
+        ImmutableList.of(
+            label0,
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.classType,
+                    factory.createString("type"))),
+            new CfStaticFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/Integer;"),
+                    factory.classType,
+                    factory.createString("TYPE"))),
+            new CfIfCmp(If.Type.NE, ValueType.OBJECT, label2),
+            label1,
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfLoad(ValueType.OBJECT, 1),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfLoad(ValueType.OBJECT, 2),
+            new CfConstNumber(0, ValueType.INT),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.createProto(factory.intType, factory.objectType, factory.booleanType),
+                    factory.createString("toIntIfPossible")),
+                false),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.createProto(factory.voidType, factory.objectType, factory.intType),
+                    factory.createString("setVolatile")),
+                false),
+            new CfGoto(label5),
+            label2,
+            new CfFrame(
+                new Int2ObjectAVLTreeMap<>(
+                    new int[] {0, 1, 2},
+                    new FrameType[] {
+                      FrameType.initializedNonNullReference(
+                          factory.createType("Ljava/lang/invoke/VarHandle;")),
+                      FrameType.initializedNonNullReference(factory.objectType),
+                      FrameType.initializedNonNullReference(factory.objectType)
+                    })),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.classType,
+                    factory.createString("type"))),
+            new CfStaticFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/Long;"),
+                    factory.classType,
+                    factory.createString("TYPE"))),
+            new CfIfCmp(If.Type.NE, ValueType.OBJECT, label4),
+            label3,
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfLoad(ValueType.OBJECT, 1),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfLoad(ValueType.OBJECT, 2),
+            new CfConstNumber(0, ValueType.INT),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.createProto(factory.longType, factory.objectType, factory.booleanType),
+                    factory.createString("toLongIfPossible")),
+                false),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.createProto(factory.voidType, factory.objectType, factory.longType),
+                    factory.createString("setVolatile")),
+                false),
+            new CfGoto(label5),
+            label4,
+            new CfFrame(
+                new Int2ObjectAVLTreeMap<>(
+                    new int[] {0, 1, 2},
+                    new FrameType[] {
+                      FrameType.initializedNonNullReference(
+                          factory.createType("Ljava/lang/invoke/VarHandle;")),
+                      FrameType.initializedNonNullReference(factory.objectType),
+                      FrameType.initializedNonNullReference(factory.objectType)
+                    })),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.createType("Lsun/misc/Unsafe;"),
+                    factory.createString("U"))),
+            new CfLoad(ValueType.OBJECT, 1),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.longType,
+                    factory.createString("offset"))),
+            new CfLoad(ValueType.OBJECT, 2),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.createType("Lsun/misc/Unsafe;"),
+                    factory.createProto(
+                        factory.voidType, factory.objectType, factory.longType, factory.objectType),
+                    factory.createString("putObjectVolatile")),
+                false),
+            label5,
+            new CfFrame(
+                new Int2ObjectAVLTreeMap<>(
+                    new int[] {0, 1, 2},
+                    new FrameType[] {
+                      FrameType.initializedNonNullReference(
+                          factory.createType("Ljava/lang/invoke/VarHandle;")),
+                      FrameType.initializedNonNullReference(factory.objectType),
+                      FrameType.initializedNonNullReference(factory.objectType)
+                    })),
+            new CfReturnVoid(),
+            label6),
+        ImmutableList.of(),
+        ImmutableList.of());
+  }
+
+  public static CfCode DesugarVarHandle_setVolatileArray(DexItemFactory factory, DexMethod method) {
+    CfLabel label0 = new CfLabel();
+    CfLabel label1 = new CfLabel();
+    CfLabel label2 = new CfLabel();
+    CfLabel label3 = new CfLabel();
+    CfLabel label4 = new CfLabel();
+    CfLabel label5 = new CfLabel();
+    CfLabel label6 = new CfLabel();
+    CfLabel label7 = new CfLabel();
+    CfLabel label8 = new CfLabel();
+    CfLabel label9 = new CfLabel();
+    return new CfCode(
+        method.holder,
+        7,
+        6,
+        ImmutableList.of(
+            label0,
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.classType,
+                    factory.createString("recv"))),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.classType,
+                    factory.createProto(factory.booleanType),
+                    factory.createString("isArray")),
+                false),
+            new CfIf(If.Type.EQ, ValueType.INT, label1),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.classType,
+                    factory.createString("recv"))),
+            new CfLoad(ValueType.OBJECT, 1),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.objectType,
+                    factory.createProto(factory.classType),
+                    factory.createString("getClass")),
+                false),
+            new CfIfCmp(If.Type.EQ, ValueType.OBJECT, label2),
+            label1,
+            new CfFrame(
+                new Int2ObjectAVLTreeMap<>(
+                    new int[] {0, 1, 2, 3},
+                    new FrameType[] {
+                      FrameType.initializedNonNullReference(
+                          factory.createType("Ljava/lang/invoke/VarHandle;")),
+                      FrameType.initializedNonNullReference(factory.objectType),
+                      FrameType.intType(),
+                      FrameType.initializedNonNullReference(factory.objectType)
+                    })),
+            new CfNew(factory.createType("Ljava/lang/UnsupportedOperationException;")),
+            new CfStackInstruction(CfStackInstruction.Opcode.Dup),
+            new CfInvoke(
+                183,
+                factory.createMethod(
+                    factory.createType("Ljava/lang/UnsupportedOperationException;"),
+                    factory.createProto(factory.voidType),
+                    factory.createString("<init>")),
+                false),
+            new CfThrow(),
+            label2,
+            new CfFrame(
+                new Int2ObjectAVLTreeMap<>(
+                    new int[] {0, 1, 2, 3},
+                    new FrameType[] {
+                      FrameType.initializedNonNullReference(
+                          factory.createType("Ljava/lang/invoke/VarHandle;")),
+                      FrameType.initializedNonNullReference(factory.objectType),
+                      FrameType.intType(),
+                      FrameType.initializedNonNullReference(factory.objectType)
+                    })),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.longType,
+                    factory.createString("offset"))),
+            new CfLoad(ValueType.INT, 2),
+            new CfNumberConversion(NumericType.INT, NumericType.LONG),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.longType,
+                    factory.createString("arrayIndexScale"))),
+            new CfArithmeticBinop(CfArithmeticBinop.Opcode.Mul, NumericType.LONG),
+            new CfArithmeticBinop(CfArithmeticBinop.Opcode.Add, NumericType.LONG),
+            new CfStore(ValueType.LONG, 4),
+            label3,
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.classType,
+                    factory.createString("recv"))),
+            new CfConstClass(factory.intArrayType),
+            new CfIfCmp(If.Type.NE, ValueType.OBJECT, label5),
+            label4,
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.createType("Lsun/misc/Unsafe;"),
+                    factory.createString("U"))),
+            new CfLoad(ValueType.OBJECT, 1),
+            new CfLoad(ValueType.LONG, 4),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfLoad(ValueType.OBJECT, 3),
+            new CfConstNumber(0, ValueType.INT),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.createProto(factory.intType, factory.objectType, factory.booleanType),
+                    factory.createString("toIntIfPossible")),
+                false),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.createType("Lsun/misc/Unsafe;"),
+                    factory.createProto(
+                        factory.voidType, factory.objectType, factory.longType, factory.intType),
+                    factory.createString("putIntVolatile")),
+                false),
+            new CfGoto(label8),
+            label5,
+            new CfFrame(
+                new Int2ObjectAVLTreeMap<>(
+                    new int[] {0, 1, 2, 3, 4, 5},
+                    new FrameType[] {
+                      FrameType.initializedNonNullReference(
+                          factory.createType("Ljava/lang/invoke/VarHandle;")),
+                      FrameType.initializedNonNullReference(factory.objectType),
+                      FrameType.intType(),
+                      FrameType.initializedNonNullReference(factory.objectType),
+                      FrameType.longType(),
+                      FrameType.longHighType()
+                    })),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.classType,
+                    factory.createString("recv"))),
+            new CfConstClass(factory.longArrayType),
+            new CfIfCmp(If.Type.NE, ValueType.OBJECT, label7),
+            label6,
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.createType("Lsun/misc/Unsafe;"),
+                    factory.createString("U"))),
+            new CfLoad(ValueType.OBJECT, 1),
+            new CfLoad(ValueType.LONG, 4),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfLoad(ValueType.OBJECT, 3),
+            new CfConstNumber(0, ValueType.INT),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.createProto(factory.longType, factory.objectType, factory.booleanType),
+                    factory.createString("toLongIfPossible")),
+                false),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.createType("Lsun/misc/Unsafe;"),
+                    factory.createProto(
+                        factory.voidType, factory.objectType, factory.longType, factory.longType),
+                    factory.createString("putLongVolatile")),
+                false),
+            new CfGoto(label8),
+            label7,
+            new CfFrame(
+                new Int2ObjectAVLTreeMap<>(
+                    new int[] {0, 1, 2, 3, 4, 5},
+                    new FrameType[] {
+                      FrameType.initializedNonNullReference(
+                          factory.createType("Ljava/lang/invoke/VarHandle;")),
+                      FrameType.initializedNonNullReference(factory.objectType),
+                      FrameType.intType(),
+                      FrameType.initializedNonNullReference(factory.objectType),
+                      FrameType.longType(),
+                      FrameType.longHighType()
+                    })),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.createType("Lsun/misc/Unsafe;"),
+                    factory.createString("U"))),
+            new CfLoad(ValueType.OBJECT, 1),
+            new CfLoad(ValueType.LONG, 4),
+            new CfLoad(ValueType.OBJECT, 3),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.createType("Lsun/misc/Unsafe;"),
+                    factory.createProto(
+                        factory.voidType, factory.objectType, factory.longType, factory.objectType),
+                    factory.createString("putObjectVolatile")),
+                false),
+            label8,
+            new CfFrame(
+                new Int2ObjectAVLTreeMap<>(
+                    new int[] {0, 1, 2, 3, 4, 5},
+                    new FrameType[] {
+                      FrameType.initializedNonNullReference(
+                          factory.createType("Ljava/lang/invoke/VarHandle;")),
+                      FrameType.initializedNonNullReference(factory.objectType),
+                      FrameType.intType(),
+                      FrameType.initializedNonNullReference(factory.objectType),
+                      FrameType.longType(),
+                      FrameType.longHighType()
+                    })),
+            new CfReturnVoid(),
+            label9),
+        ImmutableList.of(),
+        ImmutableList.of());
+  }
+
+  public static CfCode DesugarVarHandle_setVolatileArrayInt(
+      DexItemFactory factory, DexMethod method) {
+    CfLabel label0 = new CfLabel();
+    CfLabel label1 = new CfLabel();
+    CfLabel label2 = new CfLabel();
+    CfLabel label3 = new CfLabel();
+    CfLabel label4 = new CfLabel();
+    CfLabel label5 = new CfLabel();
+    return new CfCode(
+        method.holder,
+        6,
+        6,
+        ImmutableList.of(
+            label0,
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.classType,
+                    factory.createString("recv"))),
+            new CfConstClass(factory.intArrayType),
+            new CfIfCmp(If.Type.EQ, ValueType.OBJECT, label2),
+            label1,
+            new CfNew(factory.createType("Ljava/lang/UnsupportedOperationException;")),
+            new CfStackInstruction(CfStackInstruction.Opcode.Dup),
+            new CfInvoke(
+                183,
+                factory.createMethod(
+                    factory.createType("Ljava/lang/UnsupportedOperationException;"),
+                    factory.createProto(factory.voidType),
+                    factory.createString("<init>")),
+                false),
+            new CfThrow(),
+            label2,
+            new CfFrame(
+                new Int2ObjectAVLTreeMap<>(
+                    new int[] {0, 1, 2, 3},
+                    new FrameType[] {
+                      FrameType.initializedNonNullReference(
+                          factory.createType("Ljava/lang/invoke/VarHandle;")),
+                      FrameType.initializedNonNullReference(factory.intArrayType),
+                      FrameType.intType(),
+                      FrameType.intType()
+                    })),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.longType,
+                    factory.createString("offset"))),
+            new CfLoad(ValueType.INT, 2),
+            new CfNumberConversion(NumericType.INT, NumericType.LONG),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.longType,
+                    factory.createString("arrayIndexScale"))),
+            new CfArithmeticBinop(CfArithmeticBinop.Opcode.Mul, NumericType.LONG),
+            new CfArithmeticBinop(CfArithmeticBinop.Opcode.Add, NumericType.LONG),
+            new CfStore(ValueType.LONG, 4),
+            label3,
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.createType("Lsun/misc/Unsafe;"),
+                    factory.createString("U"))),
+            new CfLoad(ValueType.OBJECT, 1),
+            new CfLoad(ValueType.LONG, 4),
+            new CfLoad(ValueType.INT, 3),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.createType("Lsun/misc/Unsafe;"),
+                    factory.createProto(
+                        factory.voidType, factory.objectType, factory.longType, factory.intType),
+                    factory.createString("putIntVolatile")),
+                false),
+            label4,
+            new CfReturnVoid(),
+            label5),
+        ImmutableList.of(),
+        ImmutableList.of());
+  }
+
+  public static CfCode DesugarVarHandle_setVolatileArrayLong(
+      DexItemFactory factory, DexMethod method) {
+    CfLabel label0 = new CfLabel();
+    CfLabel label1 = new CfLabel();
+    CfLabel label2 = new CfLabel();
+    CfLabel label3 = new CfLabel();
+    CfLabel label4 = new CfLabel();
+    CfLabel label5 = new CfLabel();
+    return new CfCode(
+        method.holder,
+        6,
+        7,
+        ImmutableList.of(
+            label0,
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.classType,
+                    factory.createString("recv"))),
+            new CfConstClass(factory.longArrayType),
+            new CfIfCmp(If.Type.EQ, ValueType.OBJECT, label2),
+            label1,
+            new CfNew(factory.createType("Ljava/lang/UnsupportedOperationException;")),
+            new CfStackInstruction(CfStackInstruction.Opcode.Dup),
+            new CfInvoke(
+                183,
+                factory.createMethod(
+                    factory.createType("Ljava/lang/UnsupportedOperationException;"),
+                    factory.createProto(factory.voidType),
+                    factory.createString("<init>")),
+                false),
+            new CfThrow(),
+            label2,
+            new CfFrame(
+                new Int2ObjectAVLTreeMap<>(
+                    new int[] {0, 1, 2, 3, 4},
+                    new FrameType[] {
+                      FrameType.initializedNonNullReference(
+                          factory.createType("Ljava/lang/invoke/VarHandle;")),
+                      FrameType.initializedNonNullReference(factory.longArrayType),
+                      FrameType.intType(),
+                      FrameType.longType(),
+                      FrameType.longHighType()
+                    })),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.longType,
+                    factory.createString("offset"))),
+            new CfLoad(ValueType.INT, 2),
+            new CfNumberConversion(NumericType.INT, NumericType.LONG),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.longType,
+                    factory.createString("arrayIndexScale"))),
+            new CfArithmeticBinop(CfArithmeticBinop.Opcode.Mul, NumericType.LONG),
+            new CfArithmeticBinop(CfArithmeticBinop.Opcode.Add, NumericType.LONG),
+            new CfStore(ValueType.LONG, 5),
+            label3,
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.createType("Lsun/misc/Unsafe;"),
+                    factory.createString("U"))),
+            new CfLoad(ValueType.OBJECT, 1),
+            new CfLoad(ValueType.LONG, 5),
+            new CfLoad(ValueType.LONG, 3),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.createType("Lsun/misc/Unsafe;"),
+                    factory.createProto(
+                        factory.voidType, factory.objectType, factory.longType, factory.longType),
+                    factory.createString("putLongVolatile")),
+                false),
+            label4,
+            new CfReturnVoid(),
+            label5),
+        ImmutableList.of(),
+        ImmutableList.of());
+  }
+
+  public static CfCode DesugarVarHandle_setVolatileInt(DexItemFactory factory, DexMethod method) {
+    CfLabel label0 = new CfLabel();
+    CfLabel label1 = new CfLabel();
+    CfLabel label2 = new CfLabel();
+    CfLabel label3 = new CfLabel();
+    CfLabel label4 = new CfLabel();
+    CfLabel label5 = new CfLabel();
+    CfLabel label6 = new CfLabel();
+    return new CfCode(
+        method.holder,
+        6,
+        3,
+        ImmutableList.of(
+            label0,
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.classType,
+                    factory.createString("type"))),
+            new CfStaticFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/Integer;"),
+                    factory.classType,
+                    factory.createString("TYPE"))),
+            new CfIfCmp(If.Type.NE, ValueType.OBJECT, label2),
+            label1,
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.createType("Lsun/misc/Unsafe;"),
+                    factory.createString("U"))),
+            new CfLoad(ValueType.OBJECT, 1),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.longType,
+                    factory.createString("offset"))),
+            new CfLoad(ValueType.INT, 2),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.createType("Lsun/misc/Unsafe;"),
+                    factory.createProto(
+                        factory.voidType, factory.objectType, factory.longType, factory.intType),
+                    factory.createString("putIntVolatile")),
+                false),
+            new CfGoto(label5),
+            label2,
+            new CfFrame(
+                new Int2ObjectAVLTreeMap<>(
+                    new int[] {0, 1, 2},
+                    new FrameType[] {
+                      FrameType.initializedNonNullReference(
+                          factory.createType("Ljava/lang/invoke/VarHandle;")),
+                      FrameType.initializedNonNullReference(factory.objectType),
+                      FrameType.intType()
+                    })),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.classType,
+                    factory.createString("type"))),
+            new CfStaticFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/Long;"),
+                    factory.classType,
+                    factory.createString("TYPE"))),
+            new CfIfCmp(If.Type.NE, ValueType.OBJECT, label4),
+            label3,
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.createType("Lsun/misc/Unsafe;"),
+                    factory.createString("U"))),
+            new CfLoad(ValueType.OBJECT, 1),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.longType,
+                    factory.createString("offset"))),
+            new CfLoad(ValueType.INT, 2),
+            new CfNumberConversion(NumericType.INT, NumericType.LONG),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.createType("Lsun/misc/Unsafe;"),
+                    factory.createProto(
+                        factory.voidType, factory.objectType, factory.longType, factory.longType),
+                    factory.createString("putLongVolatile")),
+                false),
+            new CfGoto(label5),
+            label4,
+            new CfFrame(
+                new Int2ObjectAVLTreeMap<>(
+                    new int[] {0, 1, 2},
+                    new FrameType[] {
+                      FrameType.initializedNonNullReference(
+                          factory.createType("Ljava/lang/invoke/VarHandle;")),
+                      FrameType.initializedNonNullReference(factory.objectType),
+                      FrameType.intType()
+                    })),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfLoad(ValueType.OBJECT, 1),
+            new CfLoad(ValueType.INT, 2),
+            new CfInvoke(
+                184,
+                factory.createMethod(
+                    factory.createType("Ljava/lang/Integer;"),
+                    factory.createProto(factory.createType("Ljava/lang/Integer;"), factory.intType),
+                    factory.createString("valueOf")),
+                false),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.createProto(factory.voidType, factory.objectType, factory.objectType),
+                    factory.createString("setVolatile")),
+                false),
+            label5,
+            new CfFrame(
+                new Int2ObjectAVLTreeMap<>(
+                    new int[] {0, 1, 2},
+                    new FrameType[] {
+                      FrameType.initializedNonNullReference(
+                          factory.createType("Ljava/lang/invoke/VarHandle;")),
+                      FrameType.initializedNonNullReference(factory.objectType),
+                      FrameType.intType()
+                    })),
+            new CfReturnVoid(),
+            label6),
+        ImmutableList.of(),
+        ImmutableList.of());
+  }
+
+  public static CfCode DesugarVarHandle_setVolatileLong(DexItemFactory factory, DexMethod method) {
+    CfLabel label0 = new CfLabel();
+    CfLabel label1 = new CfLabel();
+    CfLabel label2 = new CfLabel();
+    CfLabel label3 = new CfLabel();
+    CfLabel label4 = new CfLabel();
+    CfLabel label5 = new CfLabel();
+    CfLabel label6 = new CfLabel();
+    return new CfCode(
+        method.holder,
+        6,
+        4,
+        ImmutableList.of(
+            label0,
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.classType,
+                    factory.createString("type"))),
+            new CfStaticFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/Long;"),
+                    factory.classType,
+                    factory.createString("TYPE"))),
+            new CfIfCmp(If.Type.NE, ValueType.OBJECT, label2),
+            label1,
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.createType("Lsun/misc/Unsafe;"),
+                    factory.createString("U"))),
+            new CfLoad(ValueType.OBJECT, 1),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.longType,
+                    factory.createString("offset"))),
+            new CfLoad(ValueType.LONG, 2),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.createType("Lsun/misc/Unsafe;"),
+                    factory.createProto(
+                        factory.voidType, factory.objectType, factory.longType, factory.longType),
+                    factory.createString("putLongVolatile")),
+                false),
+            new CfGoto(label5),
+            label2,
+            new CfFrame(
+                new Int2ObjectAVLTreeMap<>(
+                    new int[] {0, 1, 2, 3},
+                    new FrameType[] {
+                      FrameType.initializedNonNullReference(
+                          factory.createType("Ljava/lang/invoke/VarHandle;")),
+                      FrameType.initializedNonNullReference(factory.objectType),
+                      FrameType.longType(),
+                      FrameType.longHighType()
+                    })),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.classType,
+                    factory.createString("type"))),
+            new CfStaticFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/Integer;"),
+                    factory.classType,
+                    factory.createString("TYPE"))),
+            new CfIfCmp(If.Type.NE, ValueType.OBJECT, label4),
+            label3,
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.createProto(factory.createType("Ljava/lang/RuntimeException;")),
+                    factory.createString("desugarWrongMethodTypeException")),
+                false),
+            new CfThrow(),
+            label4,
+            new CfFrame(
+                new Int2ObjectAVLTreeMap<>(
+                    new int[] {0, 1, 2, 3},
+                    new FrameType[] {
+                      FrameType.initializedNonNullReference(
+                          factory.createType("Ljava/lang/invoke/VarHandle;")),
+                      FrameType.initializedNonNullReference(factory.objectType),
+                      FrameType.longType(),
+                      FrameType.longHighType()
+                    })),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.createType("Lsun/misc/Unsafe;"),
+                    factory.createString("U"))),
+            new CfLoad(ValueType.OBJECT, 1),
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInstanceFieldRead(
+                factory.createField(
+                    factory.createType("Ljava/lang/invoke/VarHandle;"),
+                    factory.longType,
+                    factory.createString("offset"))),
+            new CfLoad(ValueType.LONG, 2),
+            new CfInvoke(
+                184,
+                factory.createMethod(
+                    factory.createType("Ljava/lang/Long;"),
+                    factory.createProto(factory.createType("Ljava/lang/Long;"), factory.longType),
+                    factory.createString("valueOf")),
+                false),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.createType("Lsun/misc/Unsafe;"),
+                    factory.createProto(
+                        factory.voidType, factory.objectType, factory.longType, factory.objectType),
+                    factory.createString("putObjectVolatile")),
+                false),
+            label5,
+            new CfFrame(
+                new Int2ObjectAVLTreeMap<>(
+                    new int[] {0, 1, 2, 3},
+                    new FrameType[] {
+                      FrameType.initializedNonNullReference(
+                          factory.createType("Ljava/lang/invoke/VarHandle;")),
+                      FrameType.initializedNonNullReference(factory.objectType),
+                      FrameType.longType(),
+                      FrameType.longHighType()
+                    })),
+            new CfReturnVoid(),
+            label6),
+        ImmutableList.of(),
+        ImmutableList.of());
+  }
+
   public static CfCode DesugarVarHandle_toIntIfPossible(DexItemFactory factory, DexMethod method) {
     CfLabel label0 = new CfLabel();
     CfLabel label1 = new CfLabel();
diff --git a/src/test/examplesJava9/varhandle/ArrayOfInt.java b/src/test/examplesJava9/varhandle/ArrayOfInt.java
index f3eaf8a..927dbc1 100644
--- a/src/test/examplesJava9/varhandle/ArrayOfInt.java
+++ b/src/test/examplesJava9/varhandle/ArrayOfInt.java
@@ -318,6 +318,144 @@
     }
   }
 
+  public static void testSetVolatile() {
+    System.out.println("testSetVolatile");
+
+    VarHandle arrayVarHandle = MethodHandles.arrayElementVarHandle(int[].class);
+    int[] array = new int[2];
+
+    // int and Integer values.
+    arrayVarHandle.setVolatile(array, 0, 1);
+    System.out.println((int) arrayVarHandle.get(array, 0));
+    System.out.println((int) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 1, 2);
+    System.out.println((int) arrayVarHandle.get(array, 0));
+    System.out.println((int) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 0, Integer.valueOf(3));
+    System.out.println((int) arrayVarHandle.get(array, 0));
+    System.out.println((int) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 1, Integer.valueOf(4));
+    System.out.println((int) arrayVarHandle.get(array, 0));
+    System.out.println((int) arrayVarHandle.get(array, 1));
+
+    // int and Integer compatible values.
+    arrayVarHandle.setVolatile(array, 0, (byte) 5);
+    System.out.println((int) arrayVarHandle.get(array, 0));
+    System.out.println((int) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 1, (byte) 6);
+    System.out.println((int) arrayVarHandle.get(array, 0));
+    System.out.println((int) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 0, Byte.valueOf((byte) 7));
+    System.out.println((int) arrayVarHandle.get(array, 0));
+    System.out.println((int) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 1, Byte.valueOf((byte) 8));
+    System.out.println((int) arrayVarHandle.get(array, 0));
+    System.out.println((int) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 0, '0');
+    System.out.println((int) arrayVarHandle.get(array, 0));
+    System.out.println((int) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 1, '1');
+    System.out.println((int) arrayVarHandle.get(array, 0));
+    System.out.println((int) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 0, Character.valueOf('2'));
+    System.out.println((int) arrayVarHandle.get(array, 0));
+    System.out.println((int) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 1, Character.valueOf('3'));
+    System.out.println((int) arrayVarHandle.get(array, 0));
+    System.out.println((int) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 0, (short) 9);
+    System.out.println((int) arrayVarHandle.get(array, 0));
+    System.out.println((int) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 1, (short) 10);
+    System.out.println((int) arrayVarHandle.get(array, 0));
+    System.out.println((int) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 0, Short.valueOf((short) 11));
+    System.out.println((int) arrayVarHandle.get(array, 0));
+    System.out.println((int) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 1, Short.valueOf((short) 12));
+    System.out.println((int) arrayVarHandle.get(array, 0));
+    System.out.println((int) arrayVarHandle.get(array, 1));
+
+    // int and Integer non-compatible values.
+    try {
+      arrayVarHandle.setVolatile(array, 0, true);
+      System.out.println("Unexpected success");
+    } catch (RuntimeException e) {
+      checkJavaLangInvokeWrongMethodTypeException(e);
+      System.out.println((int) arrayVarHandle.get(array, 0));
+      System.out.println((int) arrayVarHandle.get(array, 1));
+    }
+    try {
+      arrayVarHandle.setVolatile(array, 0, 13L);
+      System.out.println("Unexpected success");
+    } catch (RuntimeException e) {
+      checkJavaLangInvokeWrongMethodTypeException(e);
+      System.out.println((int) arrayVarHandle.get(array, 0));
+      System.out.println((int) arrayVarHandle.get(array, 1));
+    }
+    try {
+      arrayVarHandle.setVolatile(array, 0, Long.valueOf(13L));
+      System.out.println("Unexpected success");
+    } catch (RuntimeException e) {
+      checkJavaLangInvokeWrongMethodTypeException(e);
+      System.out.println((int) arrayVarHandle.get(array, 0));
+      System.out.println((int) arrayVarHandle.get(array, 1));
+    }
+    try {
+      arrayVarHandle.setVolatile(array, 0, 1.3f);
+      System.out.println("Unexpected success");
+    } catch (RuntimeException e) {
+      checkJavaLangInvokeWrongMethodTypeException(e);
+      System.out.println((int) arrayVarHandle.get(array, 0));
+      System.out.println((int) arrayVarHandle.get(array, 1));
+    }
+    try {
+      arrayVarHandle.setVolatile(array, 0, Float.valueOf(1.3f));
+      System.out.println("Unexpected success");
+    } catch (RuntimeException e) {
+      checkJavaLangInvokeWrongMethodTypeException(e);
+      System.out.println((int) arrayVarHandle.get(array, 0));
+      System.out.println((int) arrayVarHandle.get(array, 1));
+    }
+    try {
+      arrayVarHandle.setVolatile(array, 0, 1.4);
+      System.out.println("Unexpected success");
+    } catch (RuntimeException e) {
+      checkJavaLangInvokeWrongMethodTypeException(e);
+      System.out.println((int) arrayVarHandle.get(array, 0));
+      System.out.println((int) arrayVarHandle.get(array, 1));
+    }
+    try {
+      arrayVarHandle.setVolatile(array, 0, Double.valueOf(1.4));
+      System.out.println("Unexpected success");
+    } catch (RuntimeException e) {
+      checkJavaLangInvokeWrongMethodTypeException(e);
+      System.out.println((int) arrayVarHandle.get(array, 0));
+      System.out.println((int) arrayVarHandle.get(array, 1));
+    }
+    try {
+      arrayVarHandle.setVolatile(array, 0, new Object());
+      System.out.println("Unexpected success");
+    } catch (ClassCastException e) {
+      // The reference implementation throws ClassCastException.
+      System.out.println((int) arrayVarHandle.get(array, 0));
+      System.out.println((int) arrayVarHandle.get(array, 1));
+    } catch (RuntimeException e) {
+      // The Art and desugaring throws WrongMethodTypeException.
+      checkJavaLangInvokeWrongMethodTypeException(e);
+      System.out.println((int) arrayVarHandle.get(array, 0));
+      System.out.println((int) arrayVarHandle.get(array, 1));
+    }
+    try {
+      arrayVarHandle.setVolatile(array, 0, "X");
+      System.out.println("Unexpected success");
+    } catch (RuntimeException e) {
+      checkJavaLangInvokeWrongMethodTypeException(e);
+      System.out.println((int) arrayVarHandle.get(array, 0));
+      System.out.println((int) arrayVarHandle.get(array, 1));
+    }
+  }
+
   public void testCompareAndSet() {
     VarHandle arrayVarHandle = MethodHandles.arrayElementVarHandle(int[].class);
     int[] array = new int[2];
@@ -357,6 +495,7 @@
     testGet();
     testGetVolatile();
     testSet();
+    testSetVolatile();
     testArrayVarHandleForNonSingleDimension();
   }
 }
diff --git a/src/test/examplesJava9/varhandle/ArrayOfLong.java b/src/test/examplesJava9/varhandle/ArrayOfLong.java
index bd6a735..680a403 100644
--- a/src/test/examplesJava9/varhandle/ArrayOfLong.java
+++ b/src/test/examplesJava9/varhandle/ArrayOfLong.java
@@ -334,6 +334,140 @@
     }
   }
 
+  public static void testSetVolatile() {
+    System.out.println("testSetVolatile");
+
+    VarHandle arrayVarHandle = MethodHandles.arrayElementVarHandle(long[].class);
+    long[] array = new long[2];
+
+    // long and Long values.
+    arrayVarHandle.setVolatile(array, 0, 1L);
+    System.out.println((long) arrayVarHandle.get(array, 0));
+    System.out.println((long) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 1, 2L);
+    System.out.println((long) arrayVarHandle.get(array, 0));
+    System.out.println((long) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 0, Long.valueOf(3L));
+    System.out.println((long) arrayVarHandle.get(array, 0));
+    System.out.println((long) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 1, Long.valueOf(4L));
+    System.out.println((long) arrayVarHandle.get(array, 0));
+    System.out.println((long) arrayVarHandle.get(array, 1));
+
+    // long and Long compatible values.
+    arrayVarHandle.setVolatile(array, 0, (byte) 5);
+    System.out.println((long) arrayVarHandle.get(array, 0));
+    System.out.println((long) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 1, (byte) 6);
+    System.out.println((long) arrayVarHandle.get(array, 0));
+    System.out.println((long) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 0, Byte.valueOf((byte) 7));
+    System.out.println((long) arrayVarHandle.get(array, 0));
+    System.out.println((long) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 1, Byte.valueOf((byte) 8));
+    System.out.println((long) arrayVarHandle.get(array, 0));
+    System.out.println((long) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 0, '0');
+    System.out.println((long) arrayVarHandle.get(array, 0));
+    System.out.println((long) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 1, '1');
+    System.out.println((long) arrayVarHandle.get(array, 0));
+    System.out.println((long) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 0, Character.valueOf('2'));
+    System.out.println((long) arrayVarHandle.get(array, 0));
+    System.out.println((long) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 1, Character.valueOf('3'));
+    System.out.println((long) arrayVarHandle.get(array, 0));
+    System.out.println((long) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 0, (short) 9);
+    System.out.println((long) arrayVarHandle.get(array, 0));
+    System.out.println((long) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 1, (short) 10);
+    System.out.println((long) arrayVarHandle.get(array, 0));
+    System.out.println((long) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 0, Short.valueOf((short) 11));
+    System.out.println((long) arrayVarHandle.get(array, 0));
+    System.out.println((long) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 1, Short.valueOf((short) 12));
+    System.out.println((long) arrayVarHandle.get(array, 0));
+    System.out.println((long) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 0, 13);
+    System.out.println((long) arrayVarHandle.get(array, 0));
+    System.out.println((long) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 1, 14);
+    System.out.println((long) arrayVarHandle.get(array, 0));
+    System.out.println((long) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 0, Integer.valueOf(15));
+    System.out.println((long) arrayVarHandle.get(array, 0));
+    System.out.println((long) arrayVarHandle.get(array, 1));
+    arrayVarHandle.setVolatile(array, 1, Integer.valueOf(16));
+    System.out.println((long) arrayVarHandle.get(array, 0));
+    System.out.println((long) arrayVarHandle.get(array, 1));
+
+    // long and Long non-compatible values.
+    try {
+      arrayVarHandle.setVolatile(array, 0, true);
+      System.out.println("Unexpected success");
+    } catch (RuntimeException e) {
+      checkJavaLangInvokeWrongMethodTypeException(e);
+      System.out.println((long) arrayVarHandle.get(array, 0));
+      System.out.println((long) arrayVarHandle.get(array, 1));
+    }
+    try {
+      arrayVarHandle.setVolatile(array, 0, 1.3f);
+      System.out.println("Unexpected success");
+    } catch (RuntimeException e) {
+      checkJavaLangInvokeWrongMethodTypeException(e);
+      System.out.println((long) arrayVarHandle.get(array, 0));
+      System.out.println((long) arrayVarHandle.get(array, 1));
+    }
+    try {
+      arrayVarHandle.setVolatile(array, 0, Float.valueOf(1.3f));
+      System.out.println("Unexpected success");
+    } catch (RuntimeException e) {
+      checkJavaLangInvokeWrongMethodTypeException(e);
+      System.out.println((long) arrayVarHandle.get(array, 0));
+      System.out.println((long) arrayVarHandle.get(array, 1));
+    }
+    try {
+      arrayVarHandle.setVolatile(array, 0, 1.4);
+      System.out.println("Unexpected success");
+    } catch (RuntimeException e) {
+      checkJavaLangInvokeWrongMethodTypeException(e);
+      System.out.println((long) arrayVarHandle.get(array, 0));
+      System.out.println((long) arrayVarHandle.get(array, 1));
+    }
+    try {
+      arrayVarHandle.setVolatile(array, 0, Double.valueOf(1.4));
+      System.out.println("Unexpected success");
+    } catch (RuntimeException e) {
+      checkJavaLangInvokeWrongMethodTypeException(e);
+      System.out.println((long) arrayVarHandle.get(array, 0));
+      System.out.println((long) arrayVarHandle.get(array, 1));
+    }
+    try {
+      arrayVarHandle.setVolatile(array, 0, new Object());
+      System.out.println("Unexpected success");
+    } catch (ClassCastException e) {
+      // The reference implementation throws ClassCastException.
+      System.out.println((long) arrayVarHandle.get(array, 0));
+      System.out.println((long) arrayVarHandle.get(array, 1));
+    } catch (RuntimeException e) {
+      // The Art and desugaring throws WrongMethodTypeException.
+      checkJavaLangInvokeWrongMethodTypeException(e);
+      System.out.println((long) arrayVarHandle.get(array, 0));
+      System.out.println((long) arrayVarHandle.get(array, 1));
+    }
+    try {
+      arrayVarHandle.setVolatile(array, 0, "X");
+      System.out.println("Unexpected success");
+    } catch (RuntimeException e) {
+      checkJavaLangInvokeWrongMethodTypeException(e);
+      System.out.println((long) arrayVarHandle.get(array, 0));
+      System.out.println((long) arrayVarHandle.get(array, 1));
+    }
+  }
+
   public static void testArrayVarHandleForNonSingleDimension() {
     System.out.println("testArrayVarHandleForNonSingleDimension");
     try {
@@ -354,6 +488,7 @@
     testGet();
     testGetVolatile();
     testSet();
+    testSetVolatile();
     testArrayVarHandleForNonSingleDimension();
   }
 }
diff --git a/src/test/examplesJava9/varhandle/ArrayOfObject.java b/src/test/examplesJava9/varhandle/ArrayOfObject.java
index 508b740..20eaa6e 100644
--- a/src/test/examplesJava9/varhandle/ArrayOfObject.java
+++ b/src/test/examplesJava9/varhandle/ArrayOfObject.java
@@ -402,6 +402,105 @@
     }
   }
 
+  public static void testSetVolatile() {
+    System.out.println("testSetVolatile");
+
+    VarHandle arrayVarHandle = MethodHandles.arrayElementVarHandle(Object[].class);
+    Object[] array = new Object[2];
+
+    Object o;
+    {
+      int index = 0;
+      byte b;
+      arrayVarHandle.setVolatile(array, index, (byte) 5);
+      System.out.println(arrayVarHandle.get(array, index));
+      System.out.println((byte) arrayVarHandle.get(array, index));
+      o = arrayVarHandle.get(array, index);
+      System.out.println(o instanceof Byte);
+      b = (byte) arrayVarHandle.get(array, index);
+      System.out.println(b == (byte) 5);
+      arrayVarHandle.setVolatile(array, index, Byte.valueOf((byte) 6));
+      System.out.println(arrayVarHandle.get(array, index));
+      System.out.println((byte) arrayVarHandle.get(array, index));
+      o = arrayVarHandle.get(array, index);
+      System.out.println(o instanceof Byte);
+      b = (byte) arrayVarHandle.get(array, index);
+      System.out.println(b == 6);
+    }
+    {
+      int index = 0;
+      short s;
+      arrayVarHandle.setVolatile(array, index, (short) 7);
+      System.out.println(arrayVarHandle.get(array, index));
+      System.out.println((short) arrayVarHandle.get(array, index));
+      o = arrayVarHandle.get(array, index);
+      System.out.println(o instanceof Short);
+      s = (short) arrayVarHandle.get(array, index);
+      System.out.println(s == (short) 7);
+      arrayVarHandle.setVolatile(array, index, Short.valueOf((short) 8));
+      System.out.println(arrayVarHandle.get(array, index));
+      System.out.println((short) arrayVarHandle.get(array, index));
+      o = arrayVarHandle.get(array, index);
+      System.out.println(o instanceof Short);
+      s = (short) arrayVarHandle.get(array, index);
+      System.out.println(s == 8);
+    }
+    {
+      int index = 0;
+      float f;
+      arrayVarHandle.setVolatile(array, index, (float) 9.0f);
+      System.out.println(arrayVarHandle.get(array, index));
+      System.out.println((float) arrayVarHandle.get(array, index));
+      o = arrayVarHandle.get(array, index);
+      System.out.println(o instanceof Float);
+      f = (float) arrayVarHandle.get(array, index);
+      System.out.println(f == (float) 9.0f);
+      arrayVarHandle.setVolatile(array, index, Float.valueOf(10.0f));
+      System.out.println(arrayVarHandle.get(array, index));
+      System.out.println((float) arrayVarHandle.get(array, index));
+      o = arrayVarHandle.get(array, index);
+      System.out.println(o instanceof Float);
+      f = (float) arrayVarHandle.get(array, index);
+      System.out.println(f == 10.0f);
+    }
+    {
+      int index = 0;
+      double d;
+      arrayVarHandle.setVolatile(array, index, (double) 11.0);
+      System.out.println(arrayVarHandle.get(array, index));
+      System.out.println((double) arrayVarHandle.get(array, index));
+      o = arrayVarHandle.get(array, index);
+      System.out.println(o instanceof Double);
+      d = (double) arrayVarHandle.get(array, index);
+      System.out.println(d == (double) 11.0);
+      arrayVarHandle.setVolatile(array, index, Double.valueOf(12.0));
+      System.out.println(arrayVarHandle.get(array, index));
+      System.out.println((double) arrayVarHandle.get(array, index));
+      o = arrayVarHandle.get(array, index);
+      System.out.println(o instanceof Double);
+      d = (double) arrayVarHandle.get(array, index);
+      System.out.println(d == 12.0);
+    }
+    {
+      int index = 0;
+      char c;
+      arrayVarHandle.setVolatile(array, index, 'A');
+      System.out.println(arrayVarHandle.get(array, index));
+      System.out.println((char) arrayVarHandle.get(array, index));
+      o = arrayVarHandle.get(array, index);
+      System.out.println(o instanceof Character);
+      c = (char) arrayVarHandle.get(array, index);
+      System.out.println(c == 'A');
+      arrayVarHandle.setVolatile(array, index, Character.valueOf('B'));
+      System.out.println(arrayVarHandle.get(array, index));
+      System.out.println((char) arrayVarHandle.get(array, index));
+      o = arrayVarHandle.get(array, index);
+      System.out.println(o instanceof Character);
+      c = (char) arrayVarHandle.get(array, index);
+      System.out.println(c == 'B');
+    }
+  }
+
   public static void testCompareAndSet() {
     System.out.println("testCompareAndSet");
 
@@ -505,6 +604,7 @@
     testGet();
     testGetVolatile();
     testSet();
+    testSetVolatile();
     testCompareAndSet();
     testArrayVarHandleForNonSingleDimension();
   }
diff --git a/src/test/examplesJava9/varhandle/InstanceIntField.java b/src/test/examplesJava9/varhandle/InstanceIntField.java
index 3b4edfb..cddf19e 100644
--- a/src/test/examplesJava9/varhandle/InstanceIntField.java
+++ b/src/test/examplesJava9/varhandle/InstanceIntField.java
@@ -171,6 +171,71 @@
     }
   }
 
+  public static void testSetVolatile(VarHandle varHandle) {
+    System.out.println("testSetVolatile");
+
+    InstanceIntField instance = new InstanceIntField();
+    System.out.println((int) varHandle.get(instance));
+
+    // int and Integer values.
+    varHandle.setVolatile(instance, (int) 1);
+    System.out.println((int) varHandle.get(instance));
+    varHandle.setVolatile(instance, Integer.valueOf(2));
+    System.out.println(varHandle.get(instance));
+
+    // int and Integer compatible values.
+    varHandle.setVolatile(instance, (byte) 3);
+    System.out.println((int) varHandle.get(instance));
+    varHandle.setVolatile(instance, Byte.valueOf((byte) 4));
+    System.out.println((int) varHandle.get(instance));
+    varHandle.setVolatile(instance, '0');
+    System.out.println((int) varHandle.get(instance));
+    varHandle.setVolatile(instance, Character.valueOf('1'));
+    System.out.println((int) varHandle.get(instance));
+    varHandle.setVolatile(instance, (short) 5);
+    System.out.println((int) varHandle.get(instance));
+    varHandle.setVolatile(instance, Short.valueOf((short) 6));
+    System.out.println((int) varHandle.get(instance));
+
+    // int and Integer non-compatible values.
+    try {
+      varHandle.setVolatile(instance, true);
+    } catch (RuntimeException e) {
+      checkJavaLangInvokeWrongMethodTypeException(e);
+      System.out.println(varHandle.get(instance));
+    }
+    try {
+      varHandle.setVolatile(instance, 3L);
+    } catch (RuntimeException e) {
+      checkJavaLangInvokeWrongMethodTypeException(e);
+      System.out.println(varHandle.get(instance));
+    }
+    try {
+      varHandle.setVolatile(instance, Long.valueOf(3));
+    } 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 testCompareAndSet(VarHandle varHandle) {
     System.out.println("testCompareAndSet");
 
@@ -308,6 +373,7 @@
     testGet(varHandle);
     testGetVolatile(varHandle);
     testSet(varHandle);
+    testSetVolatile(varHandle);
     testCompareAndSet(varHandle);
   }
 }
diff --git a/src/test/examplesJava9/varhandle/InstanceLongField.java b/src/test/examplesJava9/varhandle/InstanceLongField.java
index 484ed87..dc5b772 100644
--- a/src/test/examplesJava9/varhandle/InstanceLongField.java
+++ b/src/test/examplesJava9/varhandle/InstanceLongField.java
@@ -173,6 +173,63 @@
     }
   }
 
+  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 testCompareAndSet(VarHandle varHandle) {
     System.out.println("testCompareAndSet");
 
@@ -288,6 +345,7 @@
     testGet(varHandle);
     testGetVolatile(varHandle);
     testSet(varHandle);
+    testSetVolatile(varHandle);
     testCompareAndSet(varHandle);
   }
 }
diff --git a/src/test/examplesJava9/varhandle/InstanceObjectField.java b/src/test/examplesJava9/varhandle/InstanceObjectField.java
index bd17d04..15f2545 100644
--- a/src/test/examplesJava9/varhandle/InstanceObjectField.java
+++ b/src/test/examplesJava9/varhandle/InstanceObjectField.java
@@ -161,32 +161,32 @@
     }
   }
 
-  public static void testSetGetVolatile(VarHandle varHandle) {
-    System.out.println("testSetGetVolatile");
+  public static void testSetVolatileGetVolatile(VarHandle varHandle) {
+    System.out.println("testSetVolatileGetVolatile");
 
     InstanceObjectField instance = new InstanceObjectField();
 
     System.out.println(varHandle.getVolatile(instance));
     A a1 = new A(1);
-    varHandle.set(instance, a1);
+    varHandle.setVolatile(instance, a1);
     System.out.println(varHandle.getVolatile(instance));
     System.out.println(varHandle.getVolatile(instance) == a1);
     A a2 = new A(2);
-    varHandle.set(instance, a2);
+    varHandle.setVolatile(instance, a2);
     System.out.println(varHandle.getVolatile(instance));
     System.out.println(varHandle.getVolatile(instance) == a2);
 
     Object o;
     {
       int i;
-      varHandle.set(instance, 1);
+      varHandle.setVolatile(instance, 1);
       System.out.println(varHandle.getVolatile(instance));
       System.out.println((int) varHandle.getVolatile(instance));
       o = varHandle.getVolatile(instance);
       System.out.println(o instanceof Integer);
       i = (int) varHandle.getVolatile(instance);
       System.out.println(i == 1);
-      varHandle.set(instance, Integer.valueOf(2));
+      varHandle.setVolatile(instance, Integer.valueOf(2));
       System.out.println(varHandle.getVolatile(instance));
       System.out.println((int) varHandle.getVolatile(instance));
       o = varHandle.getVolatile(instance);
@@ -196,14 +196,14 @@
     }
     {
       long l;
-      varHandle.set(instance, 3L);
+      varHandle.setVolatile(instance, 3L);
       System.out.println(varHandle.getVolatile(instance));
       System.out.println((long) varHandle.getVolatile(instance));
       o = varHandle.getVolatile(instance);
       System.out.println(o instanceof Long);
       l = (long) varHandle.getVolatile(instance);
       System.out.println(l == 3L);
-      varHandle.set(instance, Long.valueOf(4L));
+      varHandle.setVolatile(instance, Long.valueOf(4L));
       System.out.println(varHandle.getVolatile(instance));
       System.out.println((long) varHandle.getVolatile(instance));
       o = varHandle.getVolatile(instance);
@@ -213,14 +213,14 @@
     }
     {
       byte b;
-      varHandle.set(instance, (byte) 5);
+      varHandle.setVolatile(instance, (byte) 5);
       System.out.println(varHandle.getVolatile(instance));
       System.out.println((byte) varHandle.getVolatile(instance));
       o = varHandle.getVolatile(instance);
       System.out.println(o instanceof Byte);
       b = (byte) varHandle.getVolatile(instance);
       System.out.println(b == (byte) 5);
-      varHandle.set(instance, Byte.valueOf((byte) 6));
+      varHandle.setVolatile(instance, Byte.valueOf((byte) 6));
       System.out.println(varHandle.getVolatile(instance));
       System.out.println((byte) varHandle.getVolatile(instance));
       o = varHandle.getVolatile(instance);
@@ -230,14 +230,14 @@
     }
     {
       short s;
-      varHandle.set(instance, (short) 7);
+      varHandle.setVolatile(instance, (short) 7);
       System.out.println(varHandle.getVolatile(instance));
       System.out.println((short) varHandle.getVolatile(instance));
       o = varHandle.getVolatile(instance);
       System.out.println(o instanceof Short);
       s = (short) varHandle.getVolatile(instance);
       System.out.println(s == (short) 7);
-      varHandle.set(instance, Short.valueOf((short) 8));
+      varHandle.setVolatile(instance, Short.valueOf((short) 8));
       System.out.println(varHandle.getVolatile(instance));
       System.out.println((short) varHandle.getVolatile(instance));
       o = varHandle.getVolatile(instance);
@@ -247,14 +247,14 @@
     }
     {
       float f;
-      varHandle.set(instance, (float) 9.0f);
+      varHandle.setVolatile(instance, (float) 9.0f);
       System.out.println(varHandle.getVolatile(instance));
       System.out.println((float) varHandle.getVolatile(instance));
       o = varHandle.getVolatile(instance);
       System.out.println(o instanceof Float);
       f = (float) varHandle.getVolatile(instance);
       System.out.println(f == (float) 9.0f);
-      varHandle.set(instance, Float.valueOf(10.0f));
+      varHandle.setVolatile(instance, Float.valueOf(10.0f));
       System.out.println(varHandle.getVolatile(instance));
       System.out.println((float) varHandle.getVolatile(instance));
       o = varHandle.getVolatile(instance);
@@ -264,14 +264,14 @@
     }
     {
       double d;
-      varHandle.set(instance, (double) 11.0);
+      varHandle.setVolatile(instance, (double) 11.0);
       System.out.println(varHandle.getVolatile(instance));
       System.out.println((double) varHandle.getVolatile(instance));
       o = varHandle.getVolatile(instance);
       System.out.println(o instanceof Double);
       d = (double) varHandle.getVolatile(instance);
       System.out.println(d == (double) 11.0);
-      varHandle.set(instance, Double.valueOf(12.0));
+      varHandle.setVolatile(instance, Double.valueOf(12.0));
       System.out.println(varHandle.getVolatile(instance));
       System.out.println((double) varHandle.getVolatile(instance));
       o = varHandle.getVolatile(instance);
@@ -281,14 +281,14 @@
     }
     {
       char c;
-      varHandle.set(instance, 'A');
+      varHandle.setVolatile(instance, 'A');
       System.out.println(varHandle.getVolatile(instance));
       System.out.println((char) varHandle.getVolatile(instance));
       o = varHandle.getVolatile(instance);
       System.out.println(o instanceof Character);
       c = (char) varHandle.getVolatile(instance);
       System.out.println(c == 'A');
-      varHandle.set(instance, Character.valueOf('B'));
+      varHandle.setVolatile(instance, Character.valueOf('B'));
       System.out.println(varHandle.getVolatile(instance));
       System.out.println((char) varHandle.getVolatile(instance));
       o = varHandle.getVolatile(instance);
@@ -409,7 +409,7 @@
     VarHandle varHandle =
         MethodHandles.lookup().findVarHandle(InstanceObjectField.class, "field", Object.class);
     testSetGet(varHandle);
-    testSetGetVolatile(varHandle);
+    testSetVolatileGetVolatile(varHandle);
     testCompareAndSet(varHandle);
     testReturnValueClassCastException(varHandle);
   }
diff --git a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringArrayOfIntTest.java b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringArrayOfIntTest.java
index 42815bc..ee771a5 100644
--- a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringArrayOfIntTest.java
+++ b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringArrayOfIntTest.java
@@ -93,6 +93,57 @@
           "12",
           "11",
           "12",
+          "testSetVolatile",
+          "1",
+          "0",
+          "1",
+          "2",
+          "3",
+          "2",
+          "3",
+          "4",
+          "5",
+          "4",
+          "5",
+          "6",
+          "7",
+          "6",
+          "7",
+          "8",
+          "48",
+          "8",
+          "48",
+          "49",
+          "50",
+          "49",
+          "50",
+          "51",
+          "9",
+          "51",
+          "9",
+          "10",
+          "11",
+          "10",
+          "11",
+          "12",
+          "11",
+          "12",
+          "11",
+          "12",
+          "11",
+          "12",
+          "11",
+          "12",
+          "11",
+          "12",
+          "11",
+          "12",
+          "11",
+          "12",
+          "11",
+          "12",
+          "11",
+          "12",
           "testArrayVarHandleForNonSingleDimension",
           "IllegalArgumentException");
 
diff --git a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringArrayOfLongTest.java b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringArrayOfLongTest.java
index 84ad4f4..55cb5e8 100644
--- a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringArrayOfLongTest.java
+++ b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringArrayOfLongTest.java
@@ -93,6 +93,61 @@
           "16",
           "15",
           "16",
+          "testSetVolatile",
+          "1",
+          "0",
+          "1",
+          "2",
+          "3",
+          "2",
+          "3",
+          "4",
+          "5",
+          "4",
+          "5",
+          "6",
+          "7",
+          "6",
+          "7",
+          "8",
+          "48",
+          "8",
+          "48",
+          "49",
+          "50",
+          "49",
+          "50",
+          "51",
+          "9",
+          "51",
+          "9",
+          "10",
+          "11",
+          "10",
+          "11",
+          "12",
+          "13",
+          "12",
+          "13",
+          "14",
+          "15",
+          "14",
+          "15",
+          "16",
+          "15",
+          "16",
+          "15",
+          "16",
+          "15",
+          "16",
+          "15",
+          "16",
+          "15",
+          "16",
+          "15",
+          "16",
+          "15",
+          "16",
           "testArrayVarHandleForNonSingleDimension",
           "IllegalArgumentException");
 
diff --git a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringArrayOfObjectTest.java b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringArrayOfObjectTest.java
index e274fa0..a4be0b8 100644
--- a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringArrayOfObjectTest.java
+++ b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringArrayOfObjectTest.java
@@ -103,6 +103,47 @@
           "B",
           "true",
           "true",
+          "testSetVolatile",
+          "5",
+          "5",
+          "true",
+          "true",
+          "6",
+          "6",
+          "true",
+          "true",
+          "7",
+          "7",
+          "true",
+          "true",
+          "8",
+          "8",
+          "true",
+          "true",
+          "9.0",
+          "9.0",
+          "true",
+          "true",
+          "10.0",
+          "10.0",
+          "true",
+          "true",
+          "11.0",
+          "11.0",
+          "true",
+          "true",
+          "12.0",
+          "12.0",
+          "true",
+          "true",
+          "A",
+          "A",
+          "true",
+          "true",
+          "B",
+          "B",
+          "true",
+          "true",
           "testCompareAndSet",
           "null",
           "A(1)",
diff --git a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceIntFieldTest.java b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceIntFieldTest.java
index fc84aaa..6db6d96 100644
--- a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceIntFieldTest.java
+++ b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceIntFieldTest.java
@@ -46,6 +46,22 @@
           "6",
           "6",
           "6",
+          "testSetVolatile",
+          "0",
+          "1",
+          "2",
+          "3",
+          "4",
+          "48",
+          "49",
+          "5",
+          "6",
+          "6",
+          "6",
+          "6",
+          "6",
+          "6",
+          "6",
           "testCompareAndSet",
           "0",
           "1",
diff --git a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceLongFieldTest.java b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceLongFieldTest.java
index a471568..9832941 100644
--- a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceLongFieldTest.java
+++ b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceLongFieldTest.java
@@ -44,6 +44,22 @@
           "8",
           "8",
           "8",
+          "testSetVolatile",
+          "0",
+          "1",
+          "2",
+          "3",
+          "4",
+          "48",
+          "49",
+          "5",
+          "6",
+          "7",
+          "8",
+          "8",
+          "8",
+          "8",
+          "8",
           "testCompareAndSet",
           "0",
           "1",
diff --git a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceObjectFieldTest.java b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceObjectFieldTest.java
index 4491944..488e833 100644
--- a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceObjectFieldTest.java
+++ b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceObjectFieldTest.java
@@ -78,7 +78,7 @@
           "B",
           "true",
           "true",
-          "testSetGetVolatile",
+          "testSetVolatileGetVolatile",
           "null",
           "A(1)",
           "true",
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/varhandle/DesugarVarHandle.java b/src/test/java/com/android/tools/r8/ir/desugar/varhandle/DesugarVarHandle.java
index 8a66a75..a59ba49 100644
--- a/src/test/java/com/android/tools/r8/ir/desugar/varhandle/DesugarVarHandle.java
+++ b/src/test/java/com/android/tools/r8/ir/desugar/varhandle/DesugarVarHandle.java
@@ -57,14 +57,26 @@
       throw new RuntimeException("Stub called.");
     }
 
+    public void putIntVolatile(Object obj, long offset, int newValue) {
+      throw new RuntimeException("Stub called.");
+    }
+
     public long getLongVolatile(Object obj, long offset) {
       throw new RuntimeException("Stub called.");
     }
 
+    public void putLongVolatile(Object obj, long offset, long newValue) {
+      throw new RuntimeException("Stub called.");
+    }
+
     public Object getObjectVolatile(Object obj, long offset) {
       throw new RuntimeException("Stub called.");
     }
 
+    public void putObjectVolatile(Object obj, long offset, Object newValue) {
+      throw new RuntimeException("Stub called.");
+    }
+
     public int arrayBaseOffset(Class<?> clazz) {
       throw new RuntimeException("Stub called.");
     }
@@ -299,6 +311,37 @@
     }
   }
 
+  // setVolatile variants.
+  void setVolatile(Object ct1, Object newValue) {
+    if (type == int.class) {
+      setVolatileInt(ct1, toIntIfPossible(newValue, false));
+    } else if (type == long.class) {
+      setVolatileLong(ct1, toLongIfPossible(newValue, false));
+    } else {
+      U.putObjectVolatile(ct1, offset, newValue);
+    }
+  }
+
+  void setVolatileInt(Object ct1, int newValue) {
+    if (type == int.class) {
+      U.putIntVolatile(ct1, offset, newValue);
+    } else if (type == long.class) {
+      U.putLongVolatile(ct1, offset, newValue);
+    } else {
+      setVolatile(ct1, newValue);
+    }
+  }
+
+  void setVolatileLong(Object ct1, long newValue) {
+    if (type == long.class) {
+      U.putLongVolatile(ct1, offset, newValue);
+    } else if (type == int.class) {
+      throw desugarWrongMethodTypeException();
+    } else {
+      U.putObjectVolatile(ct1, offset, Long.valueOf(newValue));
+    }
+  }
+
   boolean compareAndSet(Object ct1, Object expectedValue, Object newValue) {
     if (type == int.class) {
       return U.compareAndSwapInt(
@@ -463,6 +506,37 @@
     U.putLong(ct1, elementOffset, newValue);
   }
 
+  // setVolatile array variants.
+  void setVolatileArray(Object ct1, int ct2, Object newValue) {
+    if (!recv.isArray() || recv != ct1.getClass()) {
+      throw new UnsupportedOperationException();
+    }
+    long elementOffset = offset + ((long) ct2) * arrayIndexScale;
+    if (recv == int[].class) {
+      U.putIntVolatile(ct1, elementOffset, toIntIfPossible(newValue, false));
+    } else if (recv == long[].class) {
+      U.putLongVolatile(ct1, elementOffset, toLongIfPossible(newValue, false));
+    } else {
+      U.putObjectVolatile(ct1, elementOffset, newValue);
+    }
+  }
+
+  void setVolatileArrayInt(int[] ct1, int ct2, int newValue) {
+    if (recv != int[].class) {
+      throw new UnsupportedOperationException();
+    }
+    long elementOffset = offset + ((long) ct2) * arrayIndexScale;
+    U.putIntVolatile(ct1, elementOffset, newValue);
+  }
+
+  void setVolatileArrayLong(long[] ct1, int ct2, long newValue) {
+    if (recv != long[].class) {
+      throw new UnsupportedOperationException();
+    }
+    long elementOffset = offset + ((long) ct2) * arrayIndexScale;
+    U.putLongVolatile(ct1, elementOffset, newValue);
+  }
+
   // compareAndSet array variants.
   boolean compareAndSetArray(Object ct1, int ct2, Object expetedValue, Object newValue) {
     if (!recv.isArray() || recv != ct1.getClass()) {
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/varhandle/GenerateVarHandleMethods.java b/src/test/java/com/android/tools/r8/ir/desugar/varhandle/GenerateVarHandleMethods.java
index 3fb1d92..00b9635 100644
--- a/src/test/java/com/android/tools/r8/ir/desugar/varhandle/GenerateVarHandleMethods.java
+++ b/src/test/java/com/android/tools/r8/ir/desugar/varhandle/GenerateVarHandleMethods.java
@@ -229,7 +229,8 @@
   private static String mapMethodName(String name) {
     Set<String> postfixes =
         ImmutableSet.of("InBox", "Int", "Long", "Array", "ArrayInBox", "ArrayInt", "ArrayLong");
-    for (String prefix : ImmutableList.of("get", "set", "compareAndSet", "getVolatile")) {
+    for (String prefix :
+        ImmutableList.of("get", "set", "compareAndSet", "getVolatile", "setVolatile")) {
       if (name.startsWith(prefix)) {
         String postfix = name.substring(prefix.length());
         if (postfixes.contains(postfix)) {