Extend the VarHandle test of instance field of type reference

Bug: b/247076137
Change-Id: Ib7f1f32943085dceba167690c82a636549468ad9
diff --git a/src/test/examplesJava9/varhandle/InstanceObjectField.java b/src/test/examplesJava9/varhandle/InstanceObjectField.java
index e7b4970..b22c2bd 100644
--- a/src/test/examplesJava9/varhandle/InstanceObjectField.java
+++ b/src/test/examplesJava9/varhandle/InstanceObjectField.java
@@ -10,14 +10,154 @@
 
   private Object field;
 
+  public static class A {
+
+    private final int i;
+
+    public A(int i) {
+      this.i = i;
+    }
+
+    public String toString() {
+      return "A(" + i + ")";
+    }
+  }
+
   public static void testSet(VarHandle varHandle) {
-    System.out.println("testGet");
+    System.out.println("testSet");
 
     InstanceObjectField instance = new InstanceObjectField();
 
     System.out.println(varHandle.get(instance));
-    varHandle.set(instance, 1);
+    A a1 = new A(1);
+    varHandle.set(instance, a1);
     System.out.println(varHandle.get(instance));
+    System.out.println(varHandle.get(instance) == a1);
+    A a2 = new A(2);
+    varHandle.set(instance, a2);
+    System.out.println(varHandle.get(instance));
+    System.out.println(varHandle.get(instance) == a2);
+
+    Object o;
+    {
+      int i;
+      varHandle.set(instance, 1);
+      System.out.println(varHandle.get(instance));
+      System.out.println((int) varHandle.get(instance));
+      o = varHandle.get(instance);
+      System.out.println(o instanceof Integer);
+      i = (int) varHandle.get(instance);
+      System.out.println(i == 1);
+      varHandle.set(instance, Integer.valueOf(2));
+      System.out.println(varHandle.get(instance));
+      System.out.println((int) varHandle.get(instance));
+      o = varHandle.get(instance);
+      System.out.println(o instanceof Integer);
+      i = (int) varHandle.get(instance);
+      System.out.println(i == 2);
+    }
+    {
+      long l;
+      varHandle.set(instance, 3L);
+      System.out.println(varHandle.get(instance));
+      System.out.println((long) varHandle.get(instance));
+      o = varHandle.get(instance);
+      System.out.println(o instanceof Long);
+      l = (long) varHandle.get(instance);
+      System.out.println(l == 3L);
+      varHandle.set(instance, Long.valueOf(4L));
+      System.out.println(varHandle.get(instance));
+      System.out.println((long) varHandle.get(instance));
+      o = varHandle.get(instance);
+      System.out.println(o instanceof Long);
+      l = (long) varHandle.get(instance);
+      System.out.println(l == 4L);
+    }
+    {
+      byte b;
+      varHandle.set(instance, (byte) 5);
+      System.out.println(varHandle.get(instance));
+      System.out.println((byte) varHandle.get(instance));
+      o = varHandle.get(instance);
+      System.out.println(o instanceof Byte);
+      b = (byte) varHandle.get(instance);
+      System.out.println(b == (byte) 5);
+      varHandle.set(instance, Byte.valueOf((byte) 6));
+      System.out.println(varHandle.get(instance));
+      System.out.println((byte) varHandle.get(instance));
+      o = varHandle.get(instance);
+      System.out.println(o instanceof Byte);
+      b = (byte) varHandle.get(instance);
+      System.out.println(b == 6);
+    }
+    {
+      short s;
+      varHandle.set(instance, (short) 7);
+      System.out.println(varHandle.get(instance));
+      System.out.println((short) varHandle.get(instance));
+      o = varHandle.get(instance);
+      System.out.println(o instanceof Short);
+      s = (short) varHandle.get(instance);
+      System.out.println(s == (short) 7);
+      varHandle.set(instance, Short.valueOf((short) 8));
+      System.out.println(varHandle.get(instance));
+      System.out.println((short) varHandle.get(instance));
+      o = varHandle.get(instance);
+      System.out.println(o instanceof Short);
+      s = (short) varHandle.get(instance);
+      System.out.println(s == 8);
+    }
+    {
+      float f;
+      varHandle.set(instance, (float) 9.0f);
+      System.out.println(varHandle.get(instance));
+      System.out.println((float) varHandle.get(instance));
+      o = varHandle.get(instance);
+      System.out.println(o instanceof Float);
+      f = (float) varHandle.get(instance);
+      System.out.println(f == (float) 9.0f);
+      varHandle.set(instance, Float.valueOf(10.0f));
+      System.out.println(varHandle.get(instance));
+      System.out.println((float) varHandle.get(instance));
+      o = varHandle.get(instance);
+      System.out.println(o instanceof Float);
+      f = (float) varHandle.get(instance);
+      System.out.println(f == 10.0f);
+    }
+    {
+      double d;
+      varHandle.set(instance, (double) 11.0);
+      System.out.println(varHandle.get(instance));
+      System.out.println((double) varHandle.get(instance));
+      o = varHandle.get(instance);
+      System.out.println(o instanceof Double);
+      d = (double) varHandle.get(instance);
+      System.out.println(d == (double) 11.0);
+      varHandle.set(instance, Double.valueOf(12.0));
+      System.out.println(varHandle.get(instance));
+      System.out.println((double) varHandle.get(instance));
+      o = varHandle.get(instance);
+      System.out.println(o instanceof Double);
+      d = (double) varHandle.get(instance);
+      System.out.println(d == 12.0);
+    }
+    {
+      char c;
+      varHandle.set(instance, 'A');
+      System.out.println(varHandle.get(instance));
+      System.out.println((char) varHandle.get(instance));
+      o = varHandle.get(instance);
+      System.out.println(o instanceof Character);
+      c = (char) varHandle.get(instance);
+      System.out.println(c == 'A');
+      varHandle.set(instance, Character.valueOf('B'));
+      System.out.println(varHandle.get(instance));
+      System.out.println((char) varHandle.get(instance));
+      o = varHandle.get(instance);
+      System.out.println(o instanceof Character);
+      c = (char) varHandle.get(instance);
+      System.out.println(c == 'B');
+    }
   }
 
   public static void testCompareAndSet(VarHandle varHandle) {
@@ -25,9 +165,45 @@
 
     InstanceObjectField instance = new InstanceObjectField();
 
-    varHandle.compareAndSet(instance, 0, 1);
+    A a1 = new A(1);
+    varHandle.compareAndSet(instance, 0, a1);
     System.out.println(varHandle.get(instance));
-    varHandle.compareAndSet(instance, null, 1);
+    varHandle.compareAndSet(instance, null, a1);
+    System.out.println(varHandle.get(instance));
+    System.out.println(varHandle.get(instance) == a1);
+    A a2 = new A(2);
+    varHandle.compareAndSet(instance, a1, a2);
+    System.out.println(varHandle.get(instance));
+    System.out.println(varHandle.get(instance) == a2);
+
+    varHandle.compareAndSet(instance, a2, 1);
+    System.out.println(varHandle.get(instance));
+    varHandle.compareAndSet(instance, Integer.valueOf(1), 2);
+    System.out.println(varHandle.get(instance));
+    varHandle.compareAndSet(instance, Integer.valueOf(2), Integer.valueOf(3));
+    System.out.println(varHandle.get(instance));
+    varHandle.compareAndSet(instance, Integer.valueOf(3), 4);
+    System.out.println(varHandle.get(instance));
+    varHandle.compareAndSet(instance, 4L, 5);
+    System.out.println(varHandle.get(instance));
+    varHandle.compareAndSet(instance, (byte) 4, 5);
+    System.out.println(varHandle.get(instance));
+    varHandle.compareAndSet(instance, (short) 4, 5);
+    System.out.println(varHandle.get(instance));
+
+    varHandle.compareAndSet(instance, 4, 5L);
+    System.out.println(varHandle.get(instance));
+    varHandle.compareAndSet(instance, Long.valueOf(5), 6L);
+    System.out.println(varHandle.get(instance));
+    varHandle.compareAndSet(instance, Long.valueOf(6), Long.valueOf(7));
+    System.out.println(varHandle.get(instance));
+    varHandle.compareAndSet(instance, Long.valueOf(7), 8L);
+    System.out.println(varHandle.get(instance));
+    varHandle.compareAndSet(instance, 8, 9L);
+    System.out.println(varHandle.get(instance));
+    varHandle.compareAndSet(instance, (byte) 8, 9);
+    System.out.println(varHandle.get(instance));
+    varHandle.compareAndSet(instance, (short) 8, 9);
     System.out.println(varHandle.get(instance));
   }
 
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 af62516..e89e6a6 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
@@ -6,6 +6,8 @@
 
 import com.android.tools.r8.examples.jdk9.VarHandle;
 import com.android.tools.r8.utils.StringUtils;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
@@ -23,8 +25,8 @@
   }
 
   @Override
-  protected String getJarEntry() {
-    return JAR_ENTRY;
+  protected List<String> getJarEntries() {
+    return ImmutableList.of(JAR_ENTRY);
   }
 
   @Override
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 46e130f..3e485b9 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
@@ -6,6 +6,8 @@
 
 import com.android.tools.r8.examples.jdk9.VarHandle;
 import com.android.tools.r8.utils.StringUtils;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
@@ -23,8 +25,8 @@
   }
 
   @Override
-  protected String getJarEntry() {
-    return JAR_ENTRY;
+  protected List<String> getJarEntries() {
+    return ImmutableList.of(JAR_ENTRY);
   }
 
   @Override
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 9ae8ecd..2d94946 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
@@ -6,6 +6,8 @@
 
 import com.android.tools.r8.examples.jdk9.VarHandle;
 import com.android.tools.r8.utils.StringUtils;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
@@ -76,8 +78,8 @@
   }
 
   @Override
-  protected String getJarEntry() {
-    return JAR_ENTRY;
+  protected List<String> getJarEntries() {
+    return ImmutableList.of(JAR_ENTRY);
   }
 
   @Override
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 c50db54..d110976 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
@@ -6,6 +6,8 @@
 
 import com.android.tools.r8.examples.jdk9.VarHandle;
 import com.android.tools.r8.utils.StringUtils;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
@@ -75,8 +77,8 @@
   }
 
   @Override
-  protected String getJarEntry() {
-    return JAR_ENTRY;
+  protected List<String> getJarEntries() {
+    return ImmutableList.of(JAR_ENTRY);
   }
 
   @Override
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 b9b2b8e..4b68117 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
@@ -6,6 +6,8 @@
 
 import com.android.tools.r8.examples.jdk9.VarHandle;
 import com.android.tools.r8.utils.StringUtils;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
@@ -13,9 +15,93 @@
 public class VarHandleDesugaringInstanceObjectFieldTest extends VarHandleDesugaringTestBase {
 
   private static final String EXPECTED_OUTPUT =
-      StringUtils.lines("testGet", "null", "1", "testCompareAndSet", "null", "1");
+      StringUtils.lines(
+          "testSet",
+          "null",
+          "A(1)",
+          "true",
+          "A(2)",
+          "true",
+          "1",
+          "1",
+          "true",
+          "true",
+          "2",
+          "2",
+          "true",
+          "true",
+          "3",
+          "3",
+          "true",
+          "true",
+          "4",
+          "4",
+          "true",
+          "true",
+          "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)",
+          "true",
+          "A(2)",
+          "true",
+          "1",
+          "2",
+          "3",
+          "4",
+          "4",
+          "4",
+          "4",
+          "5",
+          "6",
+          "7",
+          "8",
+          "8",
+          "8",
+          "8");
   private static final String MAIN_CLASS = VarHandle.InstanceObjectField.typeName();
-  private static final String JAR_ENTRY = "varhandle/InstanceObjectField.class";
+  private static final List<String> JAR_ENTRIES =
+      ImmutableList.of(
+          "varhandle/InstanceObjectField.class", "varhandle/InstanceObjectField$A.class");
 
   @Override
   protected String getMainClass() {
@@ -28,8 +114,8 @@
   }
 
   @Override
-  protected String getJarEntry() {
-    return JAR_ENTRY;
+  protected List<String> getJarEntries() {
+    return JAR_ENTRIES;
   }
 
   @Override
diff --git a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceStringFieldTest.java b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceStringFieldTest.java
index dfd32cf..c901306 100644
--- a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceStringFieldTest.java
+++ b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceStringFieldTest.java
@@ -6,6 +6,8 @@
 
 import com.android.tools.r8.examples.jdk9.VarHandle;
 import com.android.tools.r8.utils.StringUtils;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
@@ -28,8 +30,8 @@
   }
 
   @Override
-  protected String getJarEntry() {
-    return JAR_ENTRY;
+  protected List<String> getJarEntries() {
+    return ImmutableList.of(JAR_ENTRY);
   }
 
   @Override
diff --git a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringTestBase.java b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringTestBase.java
index 6a6c9d5..2b51a6b 100644
--- a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringTestBase.java
+++ b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringTestBase.java
@@ -6,6 +6,7 @@
 
 import static org.junit.Assume.assumeTrue;
 
+import com.android.tools.r8.JdkClassFileProvider;
 import com.android.tools.r8.R8TestBuilder;
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
@@ -16,6 +17,10 @@
 import com.android.tools.r8.examples.jdk9.VarHandle;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.ZipUtils;
+import java.io.IOException;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.jetbrains.annotations.Nullable;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -45,7 +50,7 @@
     return "";
   }
 
-  protected abstract String getJarEntry();
+  protected abstract List<String> getJarEntries();
 
   protected abstract String getExpectedOutput();
 
@@ -63,12 +68,27 @@
         .assertSuccessWithOutput(getExpectedOutput());
   }
 
+  @Nullable
+  private List<byte[]> getProgramClassFileData() {
+    return getJarEntries().stream()
+        .map(
+            name -> {
+              try {
+                return ZipUtils.readSingleEntry(VarHandle.jar(), name);
+              } catch (IOException e) {
+                return null;
+              }
+            })
+        .collect(Collectors.toList());
+  }
+
+  // TODO(b/247076137: Also turn on VarHandle desugaring for R8 tests.
   @Test
   public void testD8() throws Throwable {
     assumeTrue(parameters.isDexRuntime());
     if (getTestWithDesugaring()) {
       testForD8(parameters.getBackend())
-          .addProgramClassFileData(ZipUtils.readSingleEntry(VarHandle.jar(), getJarEntry()))
+          .addProgramClassFileData(getProgramClassFileData())
           .setMinApi(parameters.getApiLevel())
           .addOptionsModification(options -> options.enableVarHandleDesugaring = true)
           .run(parameters.getRuntime(), getMainClass())
@@ -82,7 +102,7 @@
               r -> r.assertSuccessWithOutput(getExpectedOutput()));
     } else {
       testForD8(parameters.getBackend())
-          .addProgramClassFileData(ZipUtils.readSingleEntry(VarHandle.jar(), getJarEntry()))
+          .addProgramClassFileData(getProgramClassFileData())
           .setMinApi(parameters.getApiLevel())
           .run(parameters.getRuntime(), getMainClass())
           .applyIf(
@@ -101,10 +121,13 @@
   @Test
   public void testR8() throws Throwable {
     testForR8(parameters.getBackend())
-        // Use android.jar from Android T to get the VarHandle type.
-        .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.T))
-        .addProgramClassFileData(ZipUtils.readSingleEntry(VarHandle.jar(), getJarEntry()))
-        .addLibraryFiles()
+        .applyIf(
+            parameters.isDexRuntime(),
+            // Use android.jar from Android T to get the VarHandle type.
+            b -> b.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.T)),
+            // Use system JDK to have references types including StringConcatFactory.
+            b -> b.addLibraryProvider(JdkClassFileProvider.fromSystemJdk()))
+        .addProgramClassFileData(getProgramClassFileData())
         .setMinApi(parameters.getApiLevel())
         .addKeepMainRule(getMainClass())
         .addKeepRules(getKeepRules())