R8/D8 working on dex for hello

- Remove direct use of ConcurrentHashMap in D8/R8
  instance variables and parameters.

Bug:142621961
Change-Id: Iaaec1686bb658b2fc6de3e9ad59c6326e90fd605
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 0cc264a..bed2abeb 100644
--- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
@@ -62,12 +62,12 @@
 
   public static final String throwableDescriptorString = "Ljava/lang/Throwable;";
 
-  private final ConcurrentHashMap<DexString, DexString> strings = new ConcurrentHashMap<>();
-  private final ConcurrentHashMap<DexString, DexType> types = new ConcurrentHashMap<>();
-  private final ConcurrentHashMap<DexField, DexField> fields = new ConcurrentHashMap<>();
-  private final ConcurrentHashMap<DexProto, DexProto> protos = new ConcurrentHashMap<>();
-  private final ConcurrentHashMap<DexMethod, DexMethod> methods = new ConcurrentHashMap<>();
-  private final ConcurrentHashMap<DexMethodHandle, DexMethodHandle> methodHandles =
+  private final Map<DexString, DexString> strings = new ConcurrentHashMap<>();
+  private final Map<DexString, DexType> types = new ConcurrentHashMap<>();
+  private final Map<DexField, DexField> fields = new ConcurrentHashMap<>();
+  private final Map<DexProto, DexProto> protos = new ConcurrentHashMap<>();
+  private final Map<DexMethod, DexMethod> methods = new ConcurrentHashMap<>();
+  private final Map<DexMethodHandle, DexMethodHandle> methodHandles =
       new ConcurrentHashMap<>();
 
   // DexDebugEvent Canonicalization.
@@ -1152,7 +1152,7 @@
     }
   }
 
-  private static <T extends DexItem> T canonicalize(ConcurrentHashMap<T, T> map, T item) {
+  private static <T extends DexItem> T canonicalize(Map<T, T> map, T item) {
     assert item != null;
     assert !DexItemFactory.isInternalSentinel(item);
     T previous = map.putIfAbsent(item, item);
diff --git a/src/main/java/com/android/tools/r8/utils/ClassMap.java b/src/main/java/com/android/tools/r8/utils/ClassMap.java
index 416b389..474f5d0 100644
--- a/src/main/java/com/android/tools/r8/utils/ClassMap.java
+++ b/src/main/java/com/android/tools/r8/utils/ClassMap.java
@@ -42,7 +42,7 @@
    * We also allow the transition from Supplier of a null value to the actual value null and vice
    * versa.
    */
-  private final ConcurrentHashMap<DexType, Supplier<T>> classes;
+  private final Map<DexType, Supplier<T>> classes;
 
   /**
    * Class provider if available.
@@ -55,7 +55,7 @@
    */
   private final AtomicReference<ClassProvider<T>> classProvider = new AtomicReference<>();
 
-  ClassMap(ConcurrentHashMap<DexType, Supplier<T>> classes, ClassProvider<T> classProvider) {
+  ClassMap(Map<DexType, Supplier<T>> classes, ClassProvider<T> classProvider) {
     assert classProvider == null || classProvider.getClassKind() == getClassKind();
     this.classes = classes == null ? new ConcurrentHashMap<>() : classes;
     this.classProvider.set(classProvider);
diff --git a/src/test/examples/hello/keep-rules.txt b/src/test/examples/hello/keep-rules.txt
new file mode 100644
index 0000000..5a49e41
--- /dev/null
+++ b/src/test/examples/hello/keep-rules.txt
@@ -0,0 +1 @@
+-keep class hello.Hello { public static void main(...);}
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/HelloWorldCompiledOnArtTest.java b/src/test/java/com/android/tools/r8/desugar/corelib/HelloWorldCompiledOnArtTest.java
new file mode 100644
index 0000000..6e56dd1
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/HelloWorldCompiledOnArtTest.java
@@ -0,0 +1,107 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.desugar.corelib;
+
+import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
+import static junit.framework.TestCase.assertEquals;
+
+import com.android.tools.r8.D8;
+import com.android.tools.r8.D8TestCompileResult;
+import com.android.tools.r8.R8;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
+import com.android.tools.r8.ToolHelper.ProcessResult;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.StringUtils;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class HelloWorldCompiledOnArtTest extends CoreLibDesugarTestBase {
+
+  private final TestParameters parameters;
+
+  // TODO(b/142621961): Parametrize at least L and P instead of just P.
+  @Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters()
+        .withDexRuntime(Version.V9_0_0)
+        .withApiLevelsStartingAtIncluding(AndroidApiLevel.L)
+        .build();
+  }
+
+  public HelloWorldCompiledOnArtTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  private static String commandLinePathFor(String string) {
+    return Paths.get(string).toAbsolutePath().toString();
+  }
+
+  private static final String HELLO_KEEP =
+      commandLinePathFor("src/test/examples/hello/keep-rules.txt");
+  private static final String HELLO_PATH =
+      commandLinePathFor(ToolHelper.EXAMPLES_BUILD_DIR + "hello" + JAR_EXTENSION);
+
+  @Test
+  public void testHelloCompiledWithR8Dex() throws Exception {
+    Path helloOutput = temp.newFolder("helloOutput").toPath().resolve("out.zip").toAbsolutePath();
+    compileR8ToDexWithD8()
+        .run(
+            parameters.getRuntime(),
+            R8.class,
+            "--release",
+            "--output",
+            helloOutput.toString(),
+            "--lib",
+            commandLinePathFor(ToolHelper.JAVA_8_RUNTIME),
+            "--pg-conf",
+            HELLO_KEEP,
+            HELLO_PATH)
+        .assertSuccess();
+    verifyResult(helloOutput);
+  }
+
+  @Test
+  public void testHelloCompiledWithD8Dex() throws Exception {
+    Path helloOutput = temp.newFolder("helloOutput").toPath().resolve("out.zip").toAbsolutePath();
+    compileR8ToDexWithD8()
+        .run(
+            parameters.getRuntime(),
+            D8.class,
+            "--release",
+            "--output",
+            helloOutput.toString(),
+            "--lib",
+            commandLinePathFor(ToolHelper.JAVA_8_RUNTIME),
+            HELLO_PATH)
+        .assertSuccess();
+    verifyResult(helloOutput);
+  }
+
+  private void verifyResult(Path helloOutput) throws IOException {
+    ProcessResult processResult = ToolHelper.runArtRaw(helloOutput.toString(), "hello.Hello");
+    assertEquals(StringUtils.lines("Hello, world"), processResult.stdout);
+  }
+
+  private D8TestCompileResult compileR8ToDexWithD8()
+      throws com.android.tools.r8.CompilationFailedException {
+    return testForD8()
+        .addProgramFiles(ToolHelper.R8_WITH_RELOCATED_DEPS_JAR)
+        .setMinApi(parameters.getApiLevel())
+        .enableCoreLibraryDesugaring(parameters.getApiLevel())
+        .compile()
+        .addDesugaredCoreLibraryRunClassPath(this::buildDesugaredLibrary, parameters.getApiLevel())
+        .withArt6Plus64BitsLib()
+        .withArtFrameworks();
+  }
+}