Merge commit 'c84e62f93a659aa8d6a615f4dcece356e3d04066' into dev-release

Change-Id: Icd226722922be2d3fa5db27bd6b1465799914d59
diff --git a/build.gradle b/build.gradle
index 9316f6d..501df47 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1175,15 +1175,6 @@
     }
 }
 
-task buildPreNJdwpTestsJar(type: Jar) {
-    archiveFileName = 'jdwp-tests-preN.jar'
-    from zipTree('third_party/jdwp-tests/apache-harmony-jdwp-tests-host.jar')
-    // Exclude the classes containing java8
-    exclude 'org/apache/harmony/jpda/tests/jdwp/InterfaceType/*.class'
-    exclude 'org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefault*.class'
-    includeEmptyDirs = false
-}
-
 task generateR8TestKeepRules {
     def path = "build/generated/r8tests-keep.txt"
     outputs.file path
@@ -1742,7 +1733,6 @@
         }
         dependsOn downloadDeps
         dependsOn buildExamples
-        dependsOn buildPreNJdwpTestsJar
     } else {
         logger.lifecycle("WARNING: Testing in not supported on your platform. Testing is only fully supported on " +
             "Linux and partially supported on Mac OS and Windows. Art does not run on other platforms.")
diff --git a/d8_r8/commonBuildSrc/src/main/kotlin/DependenciesPlugin.kt b/d8_r8/commonBuildSrc/src/main/kotlin/DependenciesPlugin.kt
index 2214408..21c4b19 100644
--- a/d8_r8/commonBuildSrc/src/main/kotlin/DependenciesPlugin.kt
+++ b/d8_r8/commonBuildSrc/src/main/kotlin/DependenciesPlugin.kt
@@ -416,6 +416,10 @@
     Paths.get("third_party", "framework").toFile(),
     Paths.get("third_party", "framework.tar.gz.sha1").toFile(),
     DependencyType.X20)
+  val googleJavaFormat = ThirdPartyDependency(
+    "google-java-format",
+    Paths.get("third_party", "google-java-format").toFile(),
+    Paths.get("third_party", "google-java-format.tar.gz.sha1").toFile())
   val gson = ThirdPartyDependency(
     "gson",
     Paths.get("third_party", "gson", "gson-2.10.1").toFile(),
@@ -451,6 +455,10 @@
     "jdk-11-test",
     Paths.get("third_party", "openjdk", "jdk-11-test").toFile(),
     Paths.get("third_party", "openjdk", "jdk-11-test.tar.gz.sha1").toFile())
+  val junit = ThirdPartyDependency(
+    "junit",
+    Paths.get("third_party", "junit").toFile(),
+    Paths.get("third_party", "junit.tar.gz.sha1").toFile())
   val jdwpTests = ThirdPartyDependency(
     "jdwp-tests",
     Paths.get("third_party", "jdwp-tests").toFile(),
@@ -628,7 +636,8 @@
     "1.0.10",
     "1.1.0",
     "1.1.1",
-    "1.1.5")
+    "1.1.5",
+    "2.0.3")
     .map { ThirdPartyDependency(
       "desugar-library-release-$it",
       Paths.get("third_party", "openjdk", "desugar_jdk_libs_releases", it).toFile(),
diff --git a/d8_r8/commonBuildSrc/src/main/kotlin/TestConfigurationHelper.kt b/d8_r8/commonBuildSrc/src/main/kotlin/TestConfigurationHelper.kt
index c63476c..9a8c17f 100644
--- a/d8_r8/commonBuildSrc/src/main/kotlin/TestConfigurationHelper.kt
+++ b/d8_r8/commonBuildSrc/src/main/kotlin/TestConfigurationHelper.kt
@@ -85,13 +85,15 @@
 
       // Forward project properties into system properties.
       listOf(
+        "local_development",
         "slow_tests",
         "desugar_jdk_json_dir",
         "desugar_jdk_libs",
         "test_dir",
         "command_cache_dir").forEach {
-        if (project.hasProperty(it)) {
-          project.property(it)?.let { v -> test.systemProperty("slow_tests", v) }
+        val propertyName = it
+        if (project.hasProperty(propertyName)) {
+          project.property(propertyName)?.let { v -> test.systemProperty(propertyName, v) }
         }
       }
 
@@ -147,7 +149,7 @@
         test.maxParallelForks = processors.div(userDefinedCoresPerFork.toInt())
       } else {
         // On work machines this seems to give the best test execution time (without freezing).
-        test.maxParallelForks = processors.div(3)
+        test.maxParallelForks = maxOf(processors.div(3), 1)
         // On low cpu count machines (bots) we under subscribe, so increase the count.
         if (processors == 32) {
           test.maxParallelForks = 15
diff --git a/d8_r8/main/build.gradle.kts b/d8_r8/main/build.gradle.kts
index ba2c1a9..f5b75b8 100644
--- a/d8_r8/main/build.gradle.kts
+++ b/d8_r8/main/build.gradle.kts
@@ -224,7 +224,7 @@
   println("NOTE: Running with JDK: " + org.gradle.internal.jvm.Jvm.current().javaHome)
 
   // Enable error prone for D8/R8 main sources.
-  options.errorprone.isEnabled.set(true)
+  options.errorprone.isEnabled.set(!project.hasProperty("disable_errorprone"))
 
   // Make all warnings errors. Warnings that we have chosen not to fix (or suppress) are disabled
   // outright below.
diff --git a/d8_r8/settings.gradle.kts b/d8_r8/settings.gradle.kts
index f4ff5e0..ac9216a 100644
--- a/d8_r8/settings.gradle.kts
+++ b/d8_r8/settings.gradle.kts
@@ -4,6 +4,8 @@
 
 // TODO(b/270105162): Move this file out the repository root when old gradle is removed.
 
+import java.nio.file.Files
+import java.nio.file.attribute.FileTime
 import org.gradle.internal.os.OperatingSystem
 
 rootProject.name = "d8-r8"
@@ -54,6 +56,12 @@
                     java.nio.charset.StandardCharsets.UTF_8)}\n"
         + String(process.getInputStream().readAllBytes(),
                  java.nio.charset.StandardCharsets.UTF_8))
+  } else {
+    // Ensure that the gz file is more recent than the .sha1 file
+    // People that upload a new version will generally have an older .sha1 file
+    println("Updating timestamp on " + targz)
+    val now = FileTime.fromMillis(System.currentTimeMillis())
+    Files.setLastModifiedTime(targz.toPath(), now)
   }
 }
 
diff --git a/d8_r8/test/build.gradle.kts b/d8_r8/test/build.gradle.kts
index b7fd7b5..a0119aa 100644
--- a/d8_r8/test/build.gradle.kts
+++ b/d8_r8/test/build.gradle.kts
@@ -30,6 +30,7 @@
 val java8TestJarTask = projectTask("tests_java_8", "testJar")
 val java8TestsDepsJarTask = projectTask("tests_java_8", "depsJar")
 val bootstrapTestsDepsJarTask = projectTask("tests_bootstrap", "depsJar")
+val testsJava8SourceSetDependenciesTask = projectTask("tests_java_8", "sourceSetDependencyTask")
 
 tasks {
   withType<Exec> {
@@ -286,6 +287,7 @@
     if (!project.hasProperty("no_internal")) {
       dependsOn(gradle.includedBuild("shared").task(":downloadDepsInternal"))
     }
+    dependsOn(testsJava8SourceSetDependenciesTask)
     val r8LibJar = r8LibWithRelocatedDeps.get().outputs.files.singleFile
     this.configure(isR8Lib = true, r8Jar = r8LibJar)
 
@@ -305,6 +307,9 @@
     systemProperty("RETRACE_RUNTIME_PATH", r8LibJar)
     systemProperty("R8_DEPS", mainDepsJarTask.outputs.files.singleFile)
     systemProperty("com.android.tools.r8.artprofilerewritingcompletenesscheck", "true")
+
+    reports.junitXml.outputLocation.set(getRoot().resolveAll("build", "test-results", "test"))
+    reports.html.outputLocation.set(getRoot().resolveAll("build", "reports", "tests", "test"))
   }
 
   val sourcesJar by registering(Jar::class) {
diff --git a/d8_r8/test_modules/tests_java_8/build.gradle.kts b/d8_r8/test_modules/tests_java_8/build.gradle.kts
index 881089b..d46599a 100644
--- a/d8_r8/test_modules/tests_java_8/build.gradle.kts
+++ b/d8_r8/test_modules/tests_java_8/build.gradle.kts
@@ -94,6 +94,10 @@
     enabled = false
   }
 
+  val sourceSetDependencyTask by registering {
+    dependsOn(*sourceSetDependenciesTasks)
+  }
+
   withType<Test> {
     TestingState.setUpTestingState(this)
     dependsOn(mainDepsJarTask)
@@ -101,7 +105,7 @@
     if (!project.hasProperty("no_internal")) {
       dependsOn(gradle.includedBuild("shared").task(":downloadDepsInternal"))
     }
-    dependsOn(*sourceSetDependenciesTasks)
+    dependsOn(sourceSetDependencyTask)
     systemProperty("TEST_DATA_LOCATION",
                    layout.buildDirectory.dir("classes/java/test").get().toString())
     systemProperty("KEEP_ANNO_JAVAC_BUILD_DIR", keepAnnoCompileTask.outputs.files.getAsPath())
diff --git a/infra/config/global/generated/cr-buildbucket.cfg b/infra/config/global/generated/cr-buildbucket.cfg
index 1c1f973..4cac940 100644
--- a/infra/config/global/generated/cr-buildbucket.cfg
+++ b/infra/config/global/generated/cr-buildbucket.cfg
@@ -1105,7 +1105,6 @@
         '    "--runtimes=dex-default",'
         '    "--command_cache_dir=/tmp/ccache",'
         '    "--new-gradle",'
-        '    "--no-r8lib",'
         '    "--tool=r8",'
         '    "--no_internal",'
         '    "--one_line_per_test",'
diff --git a/infra/config/global/main.star b/infra/config/global/main.star
index aca08c1..9013087 100755
--- a/infra/config/global/main.star
+++ b/infra/config/global/main.star
@@ -312,7 +312,7 @@
   dimensions = get_dimensions(normal=True),
   max_concurrent_invocations = 1,
   properties = {
-    "test_options" : ["--runtimes=dex-default", "--command_cache_dir=/tmp/ccache", "--new-gradle", "--no-r8lib"] + common_test_options,
+    "test_options" : ["--runtimes=dex-default", "--command_cache_dir=/tmp/ccache", "--new-gradle"] + common_test_options,
     "builder_group" : "internal.client.r8"
   }
 )
diff --git a/src/main/java/com/android/tools/r8/dex/Marker.java b/src/main/java/com/android/tools/r8/dex/Marker.java
index 0fa52a1..c507995 100644
--- a/src/main/java/com/android/tools/r8/dex/Marker.java
+++ b/src/main/java/com/android/tools/r8/dex/Marker.java
@@ -52,6 +52,7 @@
   private static final String D8_PREFIX = PREFIX + Tool.D8 + "{";
   private static final String R8_PREFIX = PREFIX + Tool.R8 + "{";
   private static final String L8_PREFIX = PREFIX + Tool.L8 + "{";
+  private static final String RELOCATOR_PREFIX = PREFIX + Tool.Relocator + "{";
 
   private final JsonObject jsonObject;
   private final Tool tool;
@@ -272,6 +273,9 @@
       if (str.startsWith(L8_PREFIX)) {
         return internalParse(Tool.L8, str.substring(L8_PREFIX.length() - 1));
       }
+      if (str.startsWith(RELOCATOR_PREFIX)) {
+        return internalParse(Tool.Relocator, str.substring(RELOCATOR_PREFIX.length() - 1));
+      }
     }
     return null;
   }
diff --git a/src/main/java/com/android/tools/r8/graph/DexField.java b/src/main/java/com/android/tools/r8/graph/DexField.java
index 02cced2..939c529 100644
--- a/src/main/java/com/android/tools/r8/graph/DexField.java
+++ b/src/main/java/com/android/tools/r8/graph/DexField.java
@@ -22,6 +22,15 @@
 
 public class DexField extends DexMember<DexEncodedField, DexField> {
 
+  @SuppressWarnings("ReferenceEquality")
+  public static boolean identical(DexField t1, DexField t2) {
+    return t1 == t2;
+  }
+
+  public final boolean isIdenticalTo(DexField other) {
+    return identical(this, other);
+  }
+
   public final DexType type;
 
   DexField(DexType holder, DexType type, DexString name, boolean skipNameValidationForTesting) {
@@ -191,9 +200,8 @@
   }
 
   @Override
-  @SuppressWarnings("ReferenceEquality")
   public boolean match(DexField field) {
-    return field.name == name && field.type == type;
+    return name.isIdenticalTo(field.name) && type.isIdenticalTo(field.type);
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/graph/DexMember.java b/src/main/java/com/android/tools/r8/graph/DexMember.java
index 635b48e..cd13cc7 100644
--- a/src/main/java/com/android/tools/r8/graph/DexMember.java
+++ b/src/main/java/com/android/tools/r8/graph/DexMember.java
@@ -9,6 +9,11 @@
 public abstract class DexMember<D extends DexEncodedMember<D, R>, R extends DexMember<D, R>>
     extends DexReference implements NamingLensComparable<R> {
 
+  @SuppressWarnings("ReferenceEquality")
+  public static boolean identical(DexMember<?, ?> t1, DexMember<?, ?> t2) {
+    return t1 == t2;
+  }
+
   public final DexType holder;
   public final DexString name;
 
diff --git a/src/main/java/com/android/tools/r8/graph/DexMethod.java b/src/main/java/com/android/tools/r8/graph/DexMethod.java
index 156bfb1..c4ee457 100644
--- a/src/main/java/com/android/tools/r8/graph/DexMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexMethod.java
@@ -22,6 +22,15 @@
 
 public class DexMethod extends DexMember<DexEncodedMethod, DexMethod> {
 
+  @SuppressWarnings("ReferenceEquality")
+  public static boolean identical(DexMethod t1, DexMethod t2) {
+    return t1 == t2;
+  }
+
+  public final boolean isIdenticalTo(DexMethod other) {
+    return identical(this, other);
+  }
+
   public final DexProto proto;
 
   DexMethod(DexType holder, DexProto proto, DexString name, boolean skipNameValidationForTesting) {
@@ -244,18 +253,16 @@
   }
 
   @Override
-  @SuppressWarnings("ReferenceEquality")
   public boolean match(DexMethod method) {
-    return method == this || match(method.getProto(), method.getName());
+    return isIdenticalTo(method) || match(method.getProto(), method.getName());
   }
 
   public boolean match(DexMethodSignature method) {
     return match(method.getProto(), method.getName());
   }
 
-  @SuppressWarnings("ReferenceEquality")
   public boolean match(DexProto methodProto, DexString methodName) {
-    return proto == methodProto && name == methodName;
+    return proto.isIdenticalTo(methodProto) && name.isIdenticalTo(methodName);
   }
 
   @Override
@@ -307,10 +314,9 @@
     return builder.append(")").toString();
   }
 
-  @SuppressWarnings("ReferenceEquality")
   public boolean isLambdaDeserializeMethod(DexItemFactory dexItemFactory) {
-    return name == dexItemFactory.deserializeLambdaMethodName
-        && proto == dexItemFactory.deserializeLambdaMethodProto;
+    return dexItemFactory.deserializeLambdaMethodName.isIdenticalTo(name)
+        && dexItemFactory.deserializeLambdaMethodProto.isIdenticalTo(proto);
   }
 
   public boolean isInstanceInitializer(DexItemFactory factory) {
diff --git a/src/main/java/com/android/tools/r8/graph/DexProto.java b/src/main/java/com/android/tools/r8/graph/DexProto.java
index c00c8ce..9721adc 100644
--- a/src/main/java/com/android/tools/r8/graph/DexProto.java
+++ b/src/main/java/com/android/tools/r8/graph/DexProto.java
@@ -17,6 +17,15 @@
 public class DexProto extends IndexedDexItem
     implements NamingLensComparable<DexProto>, LirConstant {
 
+  @SuppressWarnings("ReferenceEquality")
+  public static boolean identical(DexProto t1, DexProto t2) {
+    return t1 == t2;
+  }
+
+  public final boolean isIdenticalTo(DexProto other) {
+    return identical(this, other);
+  }
+
   public static final DexProto SENTINEL = new DexProto(null, null);
 
   public final DexType returnType;
diff --git a/src/main/java/com/android/tools/r8/graph/DexReference.java b/src/main/java/com/android/tools/r8/graph/DexReference.java
index 4f633d3..4f5dbfd 100644
--- a/src/main/java/com/android/tools/r8/graph/DexReference.java
+++ b/src/main/java/com/android/tools/r8/graph/DexReference.java
@@ -14,6 +14,11 @@
 /** A common interface for {@link DexType}, {@link DexField}, and {@link DexMethod}. */
 public abstract class DexReference extends IndexedDexItem implements LirConstant {
 
+  @SuppressWarnings("ReferenceEquality")
+  public static boolean identical(DexReference t1, DexReference t2) {
+    return t1 == t2;
+  }
+
   public abstract <T> T apply(
       Function<DexType, T> classConsumer,
       Function<DexField, T> fieldConsumer,
diff --git a/src/main/java/com/android/tools/r8/graph/DexString.java b/src/main/java/com/android/tools/r8/graph/DexString.java
index 24e13a6..95be1fa 100644
--- a/src/main/java/com/android/tools/r8/graph/DexString.java
+++ b/src/main/java/com/android/tools/r8/graph/DexString.java
@@ -21,6 +21,15 @@
 public class DexString extends IndexedDexItem
     implements NamingLensComparable<DexString>, LirConstant {
 
+  @SuppressWarnings("ReferenceEquality")
+  public static boolean identical(DexString t1, DexString t2) {
+    return t1 == t2;
+  }
+
+  public final boolean isIdenticalTo(DexString other) {
+    return identical(this, other);
+  }
+
   public static final DexString[] EMPTY_ARRAY = {};
   private static final int ARRAY_CHARACTER = '[';
 
diff --git a/src/main/java/com/android/tools/r8/graph/DexType.java b/src/main/java/com/android/tools/r8/graph/DexType.java
index 81f65e4..ecac370 100644
--- a/src/main/java/com/android/tools/r8/graph/DexType.java
+++ b/src/main/java/com/android/tools/r8/graph/DexType.java
@@ -30,6 +30,16 @@
 import java.util.function.Predicate;
 
 public class DexType extends DexReference implements NamingLensComparable<DexType> {
+
+  @SuppressWarnings("ReferenceEquality")
+  public static boolean identical(DexType t1, DexType t2) {
+    return t1 == t2;
+  }
+
+  public final boolean isIdenticalTo(DexType other) {
+    return identical(this, other);
+  }
+
   public static final DexType[] EMPTY_ARRAY = {};
 
   // Bundletool is merging classes that may originate from a build with an old version of R8.
@@ -325,10 +335,9 @@
     return descriptor.getFirstByteAsChar() == 'D';
   }
 
-  @SuppressWarnings("ReferenceEquality")
   public boolean isNullValueType() {
     boolean isNullValueType = descriptor.getFirstByteAsChar() == 'N';
-    assert !isNullValueType || this == DexItemFactory.nullValueType;
+    assert !isNullValueType || isIdenticalTo(DexItemFactory.nullValueType);
     return isNullValueType;
   }
 
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java
index 1c56876..fe4eea6 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java
@@ -40,10 +40,6 @@
   private static final class WriteMetadataFieldInfo {
     final boolean writeKind;
     final boolean writeMetadataVersion;
-
-    @SuppressWarnings("UnusedVariable")
-    final boolean writeByteCodeVersion;
-
     final boolean writeData1;
     final boolean writeData2;
     final boolean writeExtraString;
@@ -53,7 +49,6 @@
     private WriteMetadataFieldInfo(
         boolean writeKind,
         boolean writeMetadataVersion,
-        boolean writeByteCodeVersion,
         boolean writeData1,
         boolean writeData2,
         boolean writeExtraString,
@@ -61,7 +56,6 @@
         boolean writeExtraInt) {
       this.writeKind = writeKind;
       this.writeMetadataVersion = writeMetadataVersion;
-      this.writeByteCodeVersion = writeByteCodeVersion;
       this.writeData1 = writeData1;
       this.writeData2 = writeData2;
       this.writeExtraString = writeExtraString;
@@ -70,7 +64,7 @@
     }
 
     private static WriteMetadataFieldInfo rewriteAll() {
-      return new WriteMetadataFieldInfo(true, true, true, true, true, true, true, true);
+      return new WriteMetadataFieldInfo(true, true, true, true, true, true, true);
     }
   }
 
@@ -103,7 +97,6 @@
             : new WriteMetadataFieldInfo(
                 kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.kind),
                 kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.metadataVersion),
-                kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.bytecodeVersion),
                 kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.data1),
                 kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.data2),
                 kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.extraString),
diff --git a/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxy.java b/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxy.java
index 08598e7..263ca19 100644
--- a/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxy.java
+++ b/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxy.java
@@ -9,7 +9,9 @@
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.references.TypeReference;
-import java.util.Arrays;
+import com.google.common.base.Splitter;
+import java.util.ArrayList;
+import java.util.List;
 
 @Keep
 public abstract class StackTraceElementProxy<T, ST extends StackTraceElementProxy<T, ST>> {
@@ -42,6 +44,17 @@
 
   public abstract String getMethodArguments();
 
+  public List<TypeReference> getMethodArgumentTypeReferences() {
+    if (!hasMethodArguments()) {
+      return null;
+    }
+    List<TypeReference> typeReferences = new ArrayList<>();
+    for (String typeName : Splitter.onPattern(",\\s*").split(getMethodArguments())) {
+      typeReferences.add(Reference.typeFromTypeName(typeName));
+    }
+    return typeReferences;
+  }
+
   public abstract T toRetracedItem(
       RetraceStackTraceElementProxy<T, ST> retracedProxy, boolean verbose);
 
@@ -51,21 +64,21 @@
       mappingSupplier.registerClassUse(diagnosticsHandler, getClassReference());
     }
     if (hasMethodArguments()) {
-      Arrays.stream(getMethodArguments().split(","))
+      getMethodArgumentTypeReferences()
           .forEach(
-              typeName ->
-                  registerUseFromTypeReference(mappingSupplier, typeName, diagnosticsHandler));
+              typeReference ->
+                  registerUseFromTypeReference(mappingSupplier, typeReference, diagnosticsHandler));
     }
     if (hasFieldOrReturnType() && !getFieldOrReturnType().equals("void")) {
-      registerUseFromTypeReference(mappingSupplier, getFieldOrReturnType(), diagnosticsHandler);
+      registerUseFromTypeReference(
+          mappingSupplier, Reference.typeFromTypeName(getFieldOrReturnType()), diagnosticsHandler);
     }
   }
 
   private static void registerUseFromTypeReference(
       MappingSupplierBase<?> mappingSupplier,
-      String typeName,
+      TypeReference typeReference,
       DiagnosticsHandler diagnosticsHandler) {
-    TypeReference typeReference = Reference.typeFromTypeName(typeName);
     if (typeReference.isArray()) {
       typeReference = typeReference.asArray().getBaseType();
     }
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementProxyRetracerImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementProxyRetracerImpl.java
index 18623af..e8ef899 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementProxyRetracerImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementProxyRetracerImpl.java
@@ -29,7 +29,6 @@
 import com.android.tools.r8.utils.Box;
 import com.android.tools.r8.utils.ListUtils;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 import java.util.OptionalInt;
 import java.util.function.Consumer;
@@ -280,8 +279,8 @@
       return currentResult;
     }
     List<RetraceTypeResult> retracedResults =
-        Arrays.stream(element.getMethodArguments().split(","))
-            .map(typeName -> retracer.retraceType(Reference.typeFromTypeName(typeName)))
+        element.getMethodArgumentTypeReferences().stream()
+            .map(retracer::retraceType)
             .collect(Collectors.toList());
     List<List<RetracedTypeReference>> initial = new ArrayList<>();
     initial.add(new ArrayList<>());
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementStringProxy.java b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementStringProxy.java
index b7bdf62..9c8569f 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementStringProxy.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementStringProxy.java
@@ -312,8 +312,31 @@
                 if (!retraced.hasRetracedMethodArguments()) {
                   return original.getMethodArguments();
                 }
-                return StringUtils.join(
-                    ",", retraced.getRetracedMethodArguments(), RetracedTypeReference::getTypeName);
+                if (retraced.getRetracedMethodArguments().isEmpty()) {
+                  return "";
+                }
+                // Create a new arguments string matching the old one but maintain all spacing.
+                StringBuilder result = new StringBuilder();
+                String originalMethodArguments = original.getMethodArguments();
+                int argumentSeparatorIndex = 0;
+                boolean isNotFirst = false;
+                for (RetracedTypeReference retracedMethodArgument :
+                    retraced.getRetracedMethodArguments()) {
+                  if (isNotFirst) {
+                    result.append(",");
+                  }
+                  int spacesToInsert =
+                      StringUtils.firstNonWhitespaceCharacter(
+                              originalMethodArguments, argumentSeparatorIndex)
+                          - argumentSeparatorIndex;
+                  result.append(" ".repeat(spacesToInsert));
+                  result.append(retracedMethodArgument.getTypeName());
+                  argumentSeparatorIndex =
+                      originalMethodArguments.indexOf(',', argumentSeparatorIndex + spacesToInsert)
+                          + 1;
+                  isNotFirst = true;
+                }
+                return result.toString();
               });
       orderedIndices.add(methodArguments);
       return this;
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceRegularExpressionParser.java b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceRegularExpressionParser.java
index d9935ac..360621e 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceRegularExpressionParser.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceRegularExpressionParser.java
@@ -21,7 +21,7 @@
   // Seems like Proguard retrace is expecting the form "Caused by: <class>".
   public static final String DEFAULT_REGULAR_EXPRESSION =
       "(?:.*?\\bat\\s+%c\\.%m\\s*\\(%S\\)\\p{Z}*(?:~\\[.*\\])?)"
-          + "|(?:(?:(?:%c|.*)?[:\"]\\s+)?%c(?::.*)?)";
+          + "|(?:(?:(?:%c|.*)?[:\"]\\s+)?%c(?:(:|]).*)?)";
 
   private final Pattern compiledPattern;
 
@@ -158,7 +158,7 @@
     }
   }
 
-  private static final String notAllowedCharacters = "\\s\\[;:(<";
+  private static final String notAllowedCharacters = "\\s\\[\\];:()<>";
   private static final String identifierPrefix = "[^\\d" + notAllowedCharacters + "]";
   private static final String identifierSuffix = "[^" + notAllowedCharacters + "]*";
   private static final String identifierSegment = identifierPrefix + identifierSuffix;
@@ -389,7 +389,11 @@
 
     @Override
     String subExpression() {
-      return "((" + JAVA_TYPE_REGULAR_EXPRESSION + "\\,)*" + JAVA_TYPE_REGULAR_EXPRESSION + ")?";
+      return "(("
+          + JAVA_TYPE_REGULAR_EXPRESSION
+          + "\\,\\s*)*"
+          + JAVA_TYPE_REGULAR_EXPRESSION
+          + ")?";
     }
 
     @Override
diff --git a/src/main/java/com/android/tools/r8/utils/AndroidApp.java b/src/main/java/com/android/tools/r8/utils/AndroidApp.java
index 52bc5f5..ac6c169 100644
--- a/src/main/java/com/android/tools/r8/utils/AndroidApp.java
+++ b/src/main/java/com/android/tools/r8/utils/AndroidApp.java
@@ -10,6 +10,7 @@
 import static com.android.tools.r8.utils.FileUtils.isDexFile;
 import static com.android.tools.r8.utils.InternalOptions.ASM_VERSION;
 import static com.android.tools.r8.utils.ZipUtils.writeToZipStream;
+import static java.nio.charset.StandardCharsets.UTF_8;
 
 import com.android.tools.r8.ClassFileConsumer;
 import com.android.tools.r8.ClassFileResourceProvider;
@@ -57,7 +58,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.NoSuchFileException;
 import java.nio.file.OpenOption;
@@ -483,24 +483,23 @@
     return programResourcesMainDescriptor.get(resource);
   }
 
-  @SuppressWarnings("DefaultCharset")
   public void dump(Path output, DumpOptions dumpOptions, InternalOptions options) {
     int nextDexIndex = 0;
     OpenOption[] openOptions =
         new OpenOption[] {StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING};
     try (ZipOutputStream out = new ZipOutputStream(Files.newOutputStream(output, openOptions))) {
       writeToZipStream(
-          out, dumpVersionFileName, Version.getVersionString().getBytes(), ZipEntry.DEFLATED);
+          out, dumpVersionFileName, Version.getVersionString().getBytes(UTF_8), ZipEntry.DEFLATED);
       writeToZipStream(
           out,
           dumpBuildPropertiesFileName,
-          dumpOptions.getBuildPropertiesFileContent().getBytes(),
+          dumpOptions.getBuildPropertiesFileContent().getBytes(UTF_8),
           ZipEntry.DEFLATED);
       if (dumpOptions.getDesugaredLibraryJsonSource() != null) {
         writeToZipStream(
             out,
             dumpDesugaredLibraryFileName,
-            dumpOptions.getDesugaredLibraryJsonSource().getBytes(),
+            dumpOptions.getDesugaredLibraryJsonSource().getBytes(UTF_8),
             ZipEntry.DEFLATED);
         if (dumpOptions.dumpInputToFile()) {
           options.reporter.warning(
@@ -510,7 +509,8 @@
       }
       if (dumpOptions.getParsedProguardConfiguration() != null) {
         String proguardConfig = dumpOptions.getParsedProguardConfiguration();
-        writeToZipStream(out, dumpConfigFileName, proguardConfig.getBytes(), ZipEntry.DEFLATED);
+        writeToZipStream(
+            out, dumpConfigFileName, proguardConfig.getBytes(UTF_8), ZipEntry.DEFLATED);
       }
       if (proguardMapInputData != null) {
         options.reporter.warning(
@@ -518,7 +518,7 @@
         writeToZipStream(
             out,
             dumpInputConfigFileName,
-            proguardMapInputData.getString().getBytes(),
+            proguardMapInputData.getString().getBytes(UTF_8),
             ZipEntry.DEFLATED);
       }
       if (hasMainDexList()) {
@@ -534,13 +534,14 @@
           mainDexList.add(mainDexClass.replace(".", "/") + CLASS_EXTENSION);
         }
         String join = StringUtils.join("\n", mainDexList);
-        writeToZipStream(out, dumpMainDexListResourceFileName, join.getBytes(), ZipEntry.DEFLATED);
+        writeToZipStream(
+            out, dumpMainDexListResourceFileName, join.getBytes(UTF_8), ZipEntry.DEFLATED);
       }
       if (dumpOptions.hasMainDexKeepRules()) {
         writeToZipStream(
             out,
             dumpMainDexRulesResourceFileName,
-            StringUtils.joinLines(dumpOptions.getMainDexKeepRules()).getBytes(),
+            StringUtils.joinLines(dumpOptions.getMainDexKeepRules()).getBytes(UTF_8),
             ZipEntry.DEFLATED);
       }
       if (dumpOptions.hasArtProfileProviders()) {
@@ -579,7 +580,6 @@
     return nextDexIndex;
   }
 
-  @SuppressWarnings("DefaultCharset")
   private void dumpArtProfileProviders(
       Collection<ArtProfileProvider> artProfileProviders, ZipOutputStream out) throws IOException {
     int artProfileProviderIndex = 1;
@@ -588,13 +588,12 @@
       writeToZipStream(
           out,
           artProfileFileName,
-          ArtProfileProviderUtils.serializeToString(artProfileProvider).getBytes(),
+          ArtProfileProviderUtils.serializeToString(artProfileProvider).getBytes(UTF_8),
           ZipEntry.DEFLATED);
       artProfileProviderIndex++;
     }
   }
 
-  @SuppressWarnings("DefaultCharset")
   private void dumpStartupProfileProviders(
       Collection<StartupProfileProvider> startupProfileProviders,
       InternalOptions options,
@@ -606,7 +605,8 @@
       writeToZipStream(
           out,
           startupProfileFileName,
-          StartupProfileProviderUtils.serializeToString(options, startupProfileProvider).getBytes(),
+          StartupProfileProviderUtils.serializeToString(options, startupProfileProvider)
+              .getBytes(UTF_8),
           ZipEntry.DEFLATED);
       startupProfileProviderIndex++;
     }
@@ -909,7 +909,7 @@
           (entry, input) -> {
             String name = entry.getName();
             if (name.equals(dumpVersionFileName)) {
-              String content = new String(ByteStreams.toByteArray(input), StandardCharsets.UTF_8);
+              String content = new String(ByteStreams.toByteArray(input), UTF_8);
               System.out.println("Dump produced by R8 version: " + content);
             } else if (name.equals(dumpProgramFileName)) {
               readProgramDump(origin, input);
diff --git a/src/main/java/com/android/tools/r8/utils/StringUtils.java b/src/main/java/com/android/tools/r8/utils/StringUtils.java
index 7f22a4b..082fa95 100644
--- a/src/main/java/com/android/tools/r8/utils/StringUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/StringUtils.java
@@ -459,6 +459,15 @@
     return string.length();
   }
 
+  public static int firstNonWhitespaceCharacter(String string, int index) {
+    for (int i = index; i < string.length(); i++) {
+      if (!isWhitespace(string.charAt(i))) {
+        return i;
+      }
+    }
+    return string.length();
+  }
+
   public static String replaceAll(String subject, Map<String, String> map) {
     for (Entry<String, String> entry : map.entrySet()) {
       subject = replaceAll(subject, entry.getKey(), entry.getValue());
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index f550b71..d902754 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -1243,12 +1243,11 @@
   }
 
   public static Path getJdwpTestsCfJarPath(AndroidApiLevel minSdk) {
-    if (minSdk.getLevel() >= AndroidApiLevel.N.getLevel()) {
-      return Paths.get(
-          ToolHelper.THIRD_PARTY_DIR, "jdwp-tests", "apache-harmony-jdwp-tests-host.jar");
-    } else {
-      return Paths.get(ToolHelper.BUILD_DIR, "libs", "jdwp-tests-preN.jar");
-    }
+    String jar =
+        minSdk.isLessThan(AndroidApiLevel.N)
+            ? "apache-harmony-jdwp-tests-host-preN.jar"
+            : "apache-harmony-jdwp-tests-host.jar";
+    return Paths.get(ToolHelper.THIRD_PARTY_DIR, "jdwp-tests", jar);
   }
 
   public static Path getJunitFromDeps() {
diff --git a/src/test/java/com/android/tools/r8/retrace/RetraceTests.java b/src/test/java/com/android/tools/r8/retrace/RetraceTests.java
index 984d8e2..edb6475 100644
--- a/src/test/java/com/android/tools/r8/retrace/RetraceTests.java
+++ b/src/test/java/com/android/tools/r8/retrace/RetraceTests.java
@@ -281,9 +281,6 @@
 
   @Test
   public void testCircularReferenceStackTrace() throws Exception {
-    // Proguard retrace (and therefore the default regular expression) will not retrace circular
-    // reference exceptions.
-    assumeTrue("b/178599214", false);
     runRetraceTest(new CircularReferenceStackTrace());
   }
 
diff --git a/src/test/java/com/android/tools/r8/retrace/StackTraceRegularExpressionParserTests.java b/src/test/java/com/android/tools/r8/retrace/StackTraceRegularExpressionParserTests.java
index abcf319..27e6084 100644
--- a/src/test/java/com/android/tools/r8/retrace/StackTraceRegularExpressionParserTests.java
+++ b/src/test/java/com/android/tools/r8/retrace/StackTraceRegularExpressionParserTests.java
@@ -826,6 +826,87 @@
   }
 
   @Test
+  public void testArgumentsWithWhitespace() {
+    runRetraceTest(
+        "%c.%m\\(%a\\)",
+        new StackTraceForTest() {
+          @Override
+          public List<String> obfuscatedStackTrace() {
+            return ImmutableList.of("a.b.c.a(int, a.a.a[], a.b.c)");
+          }
+
+          @Override
+          public String mapping() {
+            return StringUtils.lines(
+                "com.android.tools.r8.D8 -> a.a.a:",
+                "com.android.tools.r8.R8 -> a.b.c:",
+                "  void foo(int,original.signature) -> a");
+          }
+
+          @Override
+          public List<String> retracedStackTrace() {
+            return ImmutableList.of(
+                "com.android.tools.r8.R8.foo"
+                    + "(int, com.android.tools.r8.D8[], com.android.tools.r8.R8)");
+          }
+
+          @Override
+          public List<String> retraceVerboseStackTrace() {
+            return ImmutableList.of(
+                "com.android.tools.r8.R8.void foo"
+                    + "(int,original.signature)"
+                    + "(int, com.android.tools.r8.D8[], com.android.tools.r8.R8)");
+          }
+
+          @Override
+          public int expectedWarnings() {
+            return 0;
+          }
+        });
+  }
+
+  @Test
+  public void testArgumentsWithDifferentWhitespace() {
+    runRetraceTest(
+        "%c.%m\\(%a\\)",
+        new StackTraceForTest() {
+          @Override
+          public List<String> obfuscatedStackTrace() {
+            return ImmutableList.of("a.b.c.a(int,a.a.a[], a.a.a,  a.b.c)");
+          }
+
+          @Override
+          public String mapping() {
+            return StringUtils.lines(
+                "com.android.tools.r8.D8 -> a.a.a:",
+                "com.android.tools.r8.R8 -> a.b.c:",
+                "  void foo(int,original.signature) -> a");
+          }
+
+          @Override
+          public List<String> retracedStackTrace() {
+            return ImmutableList.of(
+                "com.android.tools.r8.R8.foo(int,com.android.tools.r8.D8[],"
+                    + " com.android.tools.r8.D8,  com.android.tools.r8.R8)");
+          }
+
+          @Override
+          public List<String> retraceVerboseStackTrace() {
+            return ImmutableList.of(
+                "com.android.tools.r8.R8.void foo"
+                    + "(int,original.signature)"
+                    + "(int,com.android.tools.r8.D8[],"
+                    + " com.android.tools.r8.D8,  com.android.tools.r8.R8)");
+          }
+
+          @Override
+          public int expectedWarnings() {
+            return 0;
+          }
+        });
+  }
+
+  @Test
   public void testNoArguments() {
     runRetraceTest(
         "%c.%m\\(%a\\)",
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/CircularReferenceStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/CircularReferenceStackTrace.java
index c0b1977..00d8332 100644
--- a/src/test/java/com/android/tools/r8/retrace/stacktraces/CircularReferenceStackTrace.java
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/CircularReferenceStackTrace.java
@@ -13,15 +13,15 @@
   @Override
   public List<String> obfuscatedStackTrace() {
     return Arrays.asList(
-        "        [CIRCULAR REFERENCE:A.A]",
-        " [CIRCULAR REFERENCE:A.B]",
-        "        [CIRCULAR REFERENCE:None.existing.class]",
-        "        [CIRCULAR REFERENCE:A.A] ",
+        "        [CIRCULAR REFERENCE: A.A]",
+        " [CIRCULAR REFERENCE: A.B]",
+        "        [CIRCULAR REFERENCE: None.existing.class]",
+        "        [CIRCULAR REFERENCE: A.A] ",
         // Invalid Circular Reference lines.
         "        [CIRCU:AA]",
-        "        [CIRCULAR REFERENCE:A.A",
-        "        [CIRCULAR REFERENCE:]",
-        "        [CIRCULAR REFERENCE:None existing class]");
+        "        [CIRCULAR REFERENCE: A.A",
+        "        [CIRCULAR REFERENCE: ]",
+        "        [CIRCULAR REFERENCE: None existing class]");
   }
 
   @Override
@@ -32,27 +32,27 @@
   @Override
   public List<String> retracedStackTrace() {
     return Arrays.asList(
-        "        [CIRCULAR REFERENCE:foo.bar.Baz]",
-        " [CIRCULAR REFERENCE:foo.bar.Qux]",
-        "        [CIRCULAR REFERENCE:None.existing.class]",
-        "        [CIRCULAR REFERENCE:foo.bar.Baz] ",
+        "        [CIRCULAR REFERENCE: foo.bar.Baz]",
+        " [CIRCULAR REFERENCE: foo.bar.Qux]",
+        "        [CIRCULAR REFERENCE: None.existing.class]",
+        "        [CIRCULAR REFERENCE: foo.bar.Baz] ",
         "        [CIRCU:AA]",
-        "        [CIRCULAR REFERENCE:A.A",
-        "        [CIRCULAR REFERENCE:]",
-        "        [CIRCULAR REFERENCE:None existing class]");
+        "        [CIRCULAR REFERENCE: foo.bar.Baz",
+        "        [CIRCULAR REFERENCE: ]",
+        "        [CIRCULAR REFERENCE: None existing class]");
   }
 
   @Override
   public List<String> retraceVerboseStackTrace() {
     return Arrays.asList(
-        "        [CIRCULAR REFERENCE:foo.bar.Baz]",
-        " [CIRCULAR REFERENCE:foo.bar.Qux]",
-        "        [CIRCULAR REFERENCE:None.existing.class]",
-        "        [CIRCULAR REFERENCE:foo.bar.Baz] ",
+        "        [CIRCULAR REFERENCE: foo.bar.Baz]",
+        " [CIRCULAR REFERENCE: foo.bar.Qux]",
+        "        [CIRCULAR REFERENCE: None.existing.class]",
+        "        [CIRCULAR REFERENCE: foo.bar.Baz] ",
         "        [CIRCU:AA]",
-        "        [CIRCULAR REFERENCE:A.A",
-        "        [CIRCULAR REFERENCE:]",
-        "        [CIRCULAR REFERENCE:None existing class]");
+        "        [CIRCULAR REFERENCE: foo.bar.Baz",
+        "        [CIRCULAR REFERENCE: ]",
+        "        [CIRCULAR REFERENCE: None existing class]");
   }
 
   @Override
diff --git a/third_party/jdwp-tests.tar.gz.sha1 b/third_party/jdwp-tests.tar.gz.sha1
index 0da9451..2336888 100644
--- a/third_party/jdwp-tests.tar.gz.sha1
+++ b/third_party/jdwp-tests.tar.gz.sha1
@@ -1 +1 @@
-86eeaa4cfe57d20b03af02310acac89892db3bd3
\ No newline at end of file
+63441e6be020e613cf7cf2002c15c01c8cbf2577
\ No newline at end of file
diff --git a/tools/compiledump.py b/tools/compiledump.py
index c0bdced..aaca981 100755
--- a/tools/compiledump.py
+++ b/tools/compiledump.py
@@ -93,8 +93,8 @@
     default=False,
     action='store_true')
   parser.add_argument(
-    '--ea',
-    help='Enable Java assertions when running the compiler (default disabled)',
+    '--disable-assertions', '--disable_assertions', '-da',
+    help='Disable Java assertions when running the compiler (default enabled)',
     default=False,
     action='store_true')
   parser.add_argument(
@@ -515,7 +515,7 @@
           '-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005')
     if args.xmx:
       cmd.append('-Xmx' + args.xmx)
-    if args.ea:
+    if not args.disable_assertions:
       cmd.append('-ea')
       cmd.append('-Dcom.android.tools.r8.enableTestAssertions=1')
     if args.print_times:
diff --git a/tools/run_on_app.py b/tools/run_on_app.py
index 48449ca..cbf1762 100755
--- a/tools/run_on_app.py
+++ b/tools/run_on_app.py
@@ -5,8 +5,8 @@
 
 from __future__ import print_function
 from glob import glob
+import argparse
 import copy
-import optparse
 import os
 import shutil
 import sys
@@ -41,157 +41,158 @@
 FIND_MIN_XMX_DIR = 'find_min_xmx'
 
 def ParseOptions(argv):
-  result = optparse.OptionParser()
-  result.add_option('--compiler',
+  result = argparse.ArgumentParser()
+  result.add_argument('--compiler',
                     help='The compiler to use',
                     choices=COMPILERS)
-  result.add_option('--compiler-build',
+  result.add_argument('--compiler-build',
                     help='Compiler build to use',
                     choices=COMPILER_BUILDS,
                     default='lib')
-  result.add_option('--no-fail-fast',
+  result.add_argument('--no-fail-fast',
                     help='Whether run_on_app.py should report all failures '
                          'and not just the first one',
                     default=False,
                     action='store_true')
-  result.add_option('--hash',
+  result.add_argument('--hash',
                     help='The version of D8/R8 to use')
-  result.add_option('--app',
+  result.add_argument('--app',
                     help='What app to run on',
                     choices=APPS)
-  result.add_option('--run-all',
+  result.add_argument('--run-all',
                     help='Compile all possible combinations',
                     default=False,
                     action='store_true')
-  result.add_option('--expect-oom',
+  result.add_argument('--expect-oom',
                     help='Expect that compilation will fail with an OOM',
                     default=False,
                     action='store_true')
-  result.add_option('--type',
+  result.add_argument('--type',
                     help='Default for R8: deploy, for D8: proguarded',
                     choices=TYPES)
-  result.add_option('--out',
+  result.add_argument('--out',
                     help='Where to place the output',
                     default=utils.BUILD)
-  result.add_option('--no-build',
+  result.add_argument('--no-build',
                     help='Run without building first',
                     default=False,
                     action='store_true')
-  result.add_option('--max-memory',
+  result.add_argument('--max-memory',
                     help='The maximum memory in MB to run with',
-                    type='int')
-  result.add_option('--find-min-xmx',
+                    type=int)
+  result.add_argument('--find-min-xmx',
                     help='Find the minimum amount of memory we can run in',
                     default=False,
                     action='store_true')
-  result.add_option('--find-min-xmx-min-memory',
+  result.add_argument('--find-min-xmx-min-memory',
                     help='Setting the minimum memory baseline to run in',
-                    type='int')
-  result.add_option('--find-min-xmx-max-memory',
+                    type=int)
+  result.add_argument('--find-min-xmx-max-memory',
                     help='Setting the maximum memory baseline to run in',
-                    type='int')
-  result.add_option('--find-min-xmx-range-size',
+                    type=int)
+  result.add_argument('--find-min-xmx-range-size',
                     help='Setting the size of the acceptable memory range',
-                    type='int',
+                    type=int,
                     default=32)
-  result.add_option('--find-min-xmx-archive',
+  result.add_argument('--find-min-xmx-archive',
                     help='Archive find-min-xmx results on GCS',
                     default=False,
                     action='store_true')
-  result.add_option('--no-extra-pgconf', '--no_extra_pgconf',
+  result.add_argument('--no-extra-pgconf', '--no_extra_pgconf',
                     help='Build without the following extra rules: ' +
                          '-printconfiguration, -printmapping, -printseeds, ' +
                          '-printusage',
                     default=False,
                     action='store_true')
-  result.add_option('--timeout',
-                    type='int',
+  result.add_argument('--timeout',
+                    type=int,
                     default=0,
                     help='Set timeout instead of waiting for OOM.')
-  result.add_option('--ignore-java-version',
+  result.add_argument('--ignore-java-version',
                     help='Do not check java version',
                     default=False,
                     action='store_true')
-  result.add_option('--no-libraries',
+  result.add_argument('--no-libraries',
                     help='Do not pass in libraries, even if they exist in conf',
                     default=False,
                     action='store_true')
-  result.add_option('--no-debug',
-                    help='Run without debug asserts.',
+  result.add_argument('--disable-assertions', '--disable_assertions', '-da',
+                    help='Disable Java assertions when running the compiler '
+                         '(default enabled)',
                     default=False,
                     action='store_true')
-  result.add_option('--debug-agent',
+  result.add_argument('--debug-agent',
                     help='Run with debug agent.',
                     default=False,
                     action='store_true')
-  result.add_option('--version',
+  result.add_argument('--version',
                     help='The version of the app to run')
-  result.add_option('-k',
+  result.add_argument('-k',
                     help='Override the default ProGuard keep rules')
-  result.add_option('--compiler-flags',
+  result.add_argument('--compiler-flags',
                     help='Additional option(s) for the compiler. ' +
                          'If passing several options use a quoted string.')
-  result.add_option('--r8-flags',
+  result.add_argument('--r8-flags',
                     help='Additional option(s) for the compiler. ' +
                          'Same as --compiler-flags, keeping it for backward'
                          ' compatibility. ' +
                          'If passing several options use a quoted string.')
-  result.add_option('--track-memory-to-file',
+  result.add_argument('--track-memory-to-file',
                     help='Track how much memory the jvm is using while ' +
                     ' compiling. Output to the specified file.')
-  result.add_option('--profile',
+  result.add_argument('--profile',
                     help='Profile R8 run.',
                     default=False,
                     action='store_true')
-  result.add_option('--dump-args-file',
+  result.add_argument('--dump-args-file',
                     help='Dump a file with the arguments for the specified ' +
                     'configuration. For use as a @<file> argument to perform ' +
                     'the run.')
-  result.add_option('--print-runtimeraw',
+  result.add_argument('--print-runtimeraw',
                     metavar='BENCHMARKNAME',
                     help='Print the line \'<BENCHMARKNAME>(RunTimeRaw):' +
                         ' <elapsed> ms\' at the end where <elapsed> is' +
                         ' the elapsed time in milliseconds.')
-  result.add_option('--print-memoryuse',
+  result.add_argument('--print-memoryuse',
                     metavar='BENCHMARKNAME',
                     help='Print the line \'<BENCHMARKNAME>(MemoryUse):' +
                         ' <mem>\' at the end where <mem> is the peak' +
                         ' peak resident set size (VmHWM) in bytes.')
-  result.add_option('--print-dexsegments',
+  result.add_argument('--print-dexsegments',
                     metavar='BENCHMARKNAME',
                     help='Print the sizes of individual dex segments as ' +
                         '\'<BENCHMARKNAME>-<segment>(CodeSize): <bytes>\'')
-  result.add_option('--track-time-in-memory',
+  result.add_argument('--track-time-in-memory',
                     help='Plot the times taken from memory starting point to '
                          'end-point with defined memory increment',
                     default=False,
                     action='store_true')
-  result.add_option('--track-time-in-memory-max',
+  result.add_argument('--track-time-in-memory-max',
                     help='Setting the maximum memory baseline to run in',
-                    type='int')
-  result.add_option('--track-time-in-memory-min',
+                    type=int)
+  result.add_argument('--track-time-in-memory-min',
                     help='Setting the minimum memory baseline to run in',
-                    type='int')
-  result.add_option('--track-time-in-memory-increment',
+                    type=int)
+  result.add_argument('--track-time-in-memory-increment',
                     help='Setting the increment',
-                    type='int',
+                    type=int,
                     default=32)
-  result.add_option('--print-times',
+  result.add_argument('--print-times',
                     help='Include timing',
                     default=False,
                     action='store_true')
-  result.add_option('--cpu-list',
+  result.add_argument('--cpu-list',
                     help='Run under \'taskset\' with these CPUs. See '
                          'the \'taskset\' -c option for the format')
-  result.add_option('--quiet',
+  result.add_argument('--quiet',
                     help='Disable compiler logging',
                     default=False,
                     action='store_true')
-  result.add_option('--workers',
+  result.add_argument('--workers',
                     help='Number of workers to use',
                     default=1,
                     type=int)
-  (options, args) = result.parse_args(argv)
+  (options, args) = result.parse_known_args(argv)
   assert not options.hash or options.no_build, (
       'Argument --no-build is required when using --hash')
   assert not options.hash or options.compiler_build == 'full', (
@@ -514,7 +515,7 @@
   exit_code = toolhelper.run(
       tool, args,
       build=should_build(options),
-      debug=not options.no_debug,
+      debug=not options.disable_assertions,
       quiet=quiet,
       jar=jar,
       main=main)
@@ -543,7 +544,7 @@
   if options.print_times:
     extra_args.append('-Dcom.android.tools.r8.printtimes=1')
 
-  if not options.no_debug:
+  if not options.disable_assertions:
     extra_args.append('-Dcom.android.tools.r8.enableTestAssertions=1')
 
   outdir = options.out
@@ -715,7 +716,7 @@
         t0 = time.time()
         exit_code = toolhelper.run(tool, args,
             build=False,
-            debug=not options.no_debug,
+            debug=not options.disable_assertions,
             profile=options.profile,
             track_memory_file=options.track_memory_to_file,
             extra_args=extra_args,
diff --git a/tools/run_on_app_dump.py b/tools/run_on_app_dump.py
index 44239b8..2b07526 100755
--- a/tools/run_on_app_dump.py
+++ b/tools/run_on_app_dump.py
@@ -919,8 +919,9 @@
                            '(default disabled)',
                       default=False,
                       action='store_true')
-  result.add_argument('--disable-assertions', '--disable_assertions',
-                      help='Disable assertions when compiling',
+  result.add_argument('--disable-assertions', '--disable_assertions', '-da',
+                      help='Disable Java assertions when running the compiler '
+                           '(default enabled)',
                       default=False,
                       action='store_true')
   result.add_argument('--emulator-id', '--emulator_id',
diff --git a/tools/test.py b/tools/test.py
index 89b4ee5..0dbc827 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -7,7 +7,7 @@
 # if an argument is given, run only tests with that pattern. This script will
 # force the tests to run, even if no input changed.
 
-import optparse
+import argparse
 import os
 import shutil
 import subprocess
@@ -64,147 +64,148 @@
 ] + [ 'dex-%s' % dexvm for dexvm in ALL_ART_VMS ]
 
 def ParseOptions():
-  result = optparse.OptionParser()
-  result.add_option('--no-internal', '--no_internal',
+  result = argparse.ArgumentParser()
+  result.add_argument('--no-internal', '--no_internal',
       help='Do not run Google internal tests.',
       default=False, action='store_true')
-  result.add_option('--archive-failures', '--archive_failures',
+  result.add_argument('--archive-failures', '--archive_failures',
       help='Upload test results to cloud storage on failure.',
       default=False, action='store_true')
-  result.add_option('--archive-failures-file-name',
+  result.add_argument('--archive-failures-file-name',
                     '--archive_failures_file_name',
                     help='Set file name for the archived failures file name',
                     default=uuid.uuid4())
-  result.add_option('--only-internal', '--only_internal',
+  result.add_argument('--only-internal', '--only_internal',
       help='Only run Google internal tests.',
       default=False, action='store_true')
-  result.add_option('--all-tests', '--all_tests',
+  result.add_argument('--all-tests', '--all_tests',
       help='Run tests in all configurations.',
       default=False, action='store_true')
-  result.add_option('--slow-tests', '--slow_tests',
+  result.add_argument('--slow-tests', '--slow_tests',
       help='Also run slow tests.',
       default=False, action='store_true')
-  result.add_option('-v', '--verbose',
+  result.add_argument('-v', '--verbose',
       help='Print test stdout to, well, stdout.',
       default=False, action='store_true')
-  result.add_option('--dex-vm', '--dex_vm',
+  result.add_argument('--dex-vm', '--dex_vm',
       help='The android version of the vm to use. "all" will run the tests on '
            'all art vm versions (stopping after first failed execution)',
       default="default",
       choices=ALL_ART_VMS + ["all"])
-  result.add_option('--dex-vm-kind', '--dex_vm_kind',
+  result.add_argument('--dex-vm-kind', '--dex_vm_kind',
                     help='Whether to use host or target version of runtime',
                     default="host",
                     nargs=1,
                     choices=["host", "target"])
-  result.add_option('--one-line-per-test', '--one_line_per_test',
+  result.add_argument('--one-line-per-test', '--one_line_per_test',
       help='Print a line before a tests starts and after it ends to stdout.',
       default=False, action='store_true')
-  result.add_option('--tool',
+  result.add_argument('--tool',
       help='Tool to run ART tests with: "r8" (default) or "d8" or "r8cf"'
           ' (r8 w/CF-backend). Ignored if "--all_tests" enabled.',
       default=None, choices=["r8", "d8", "r8cf"])
-  result.add_option('--disable-assertions', '--disable_assertions',
-      help='Disable assertions when running tests.',
+  result.add_argument('--disable-assertions', '--disable_assertions', '-da',
+      help='Disable Java assertions when running the compiler '
+           '(default enabled)',
       default=False, action='store_true')
-  result.add_option('--with-code-coverage', '--with_code_coverage',
+  result.add_argument('--with-code-coverage', '--with_code_coverage',
       help='Enable code coverage with Jacoco.',
       default=False, action='store_true')
-  result.add_option('--test-dir', '--test_dir',
+  result.add_argument('--test-dir', '--test_dir',
       help='Use a custom directory for the test artifacts instead of a'
           ' temporary (which is automatically removed after the test).'
           ' Note that the directory will not be cleared before the test.')
-  result.add_option('--command-cache-dir', '--command_cache_dir',
+  result.add_argument('--command-cache-dir', '--command_cache_dir',
       help='Cache command invocations to this directory, speeds up test runs',
       default=os.environ.get('R8_COMMAND_CACHE_DIR'))
-  result.add_option('--java-home', '--java_home',
+  result.add_argument('--java-home', '--java_home',
       help='Use a custom java version to run tests.')
-  result.add_option('--java-max-memory-size', '--java_max_memory_size',
+  result.add_argument('--java-max-memory-size', '--java_max_memory_size',
       help='Set memory for running tests, default 4G',
       default=os.environ.get('R8_JAVA_MAX_MEMORY_SIZE', '4G'))
-  result.add_option('--test-namespace', '--test_namespace',
+  result.add_argument('--test-namespace', '--test_namespace',
       help='Only run tests in  this namespace. The namespace is relative to '
           'com/android/tools/r8, e.g., desugar/desugaredlibrary',
       default=None)
-  result.add_option('--shard-count', '--shard_count',
+  result.add_argument('--shard-count', '--shard_count',
       help='We are running this many shards.')
-  result.add_option('--shard-number', '--shard_number',
+  result.add_argument('--shard-number', '--shard_number',
       help='We are running this shard.')
-  result.add_option('--generate-golden-files-to', '--generate_golden_files_to',
+  result.add_argument('--generate-golden-files-to', '--generate_golden_files_to',
       help='Store dex files produced by tests in the specified directory.'
            ' It is aimed to be read on platforms with no host runtime available'
            ' for comparison.')
-  result.add_option('--use-golden-files-in', '--use_golden_files_in',
+  result.add_argument('--use-golden-files-in', '--use_golden_files_in',
       help='Download golden files hierarchy for this commit in the specified'
            ' location and use them instead of executing on host runtime.')
-  result.add_option('--no-r8lib', '--no_r8lib',
+  result.add_argument('--no-r8lib', '--no_r8lib',
       default=False, action='store_true',
       help='Run the tests on R8 full with relocated dependencies.')
-  result.add_option('--no-arttests', '--no_arttests',
+  result.add_argument('--no-arttests', '--no_arttests',
       default=False, action='store_true',
       help='Do not run the art tests.')
-  result.add_option('--r8lib-no-deps', '--r8lib_no_deps',
+  result.add_argument('--r8lib-no-deps', '--r8lib_no_deps',
       default=False, action='store_true',
       help='Run the tests on r8lib without relocated dependencies.')
-  result.add_option('--failed',
+  result.add_argument('--failed',
       default=False, action='store_true',
       help='Run the tests that failed last execution.')
-  result.add_option('--fail-fast', '--fail_fast',
+  result.add_argument('--fail-fast', '--fail_fast',
       default=False, action='store_true',
       help='Stop on first failure. Passes --fail-fast to gradle test runner.')
-  result.add_option('--worktree',
+  result.add_argument('--worktree',
       default=False, action='store_true',
       help='Tests are run in worktree and should not use gradle user home.')
-  result.add_option('--runtimes',
+  result.add_argument('--runtimes',
       default=None,
       help='Test parameter runtimes to use, separated by : (eg, none:jdk9).'
           ' Special values include: all (for all runtimes)'
           ' and empty (for no runtimes).')
-  result.add_option('--print-hanging-stacks', '--print_hanging_stacks',
-      default=-1, type="int", help='Print hanging stacks after timeout in seconds')
-  result.add_option('--print-full-stacktraces', '--print_full_stacktraces',
+  result.add_argument('--print-hanging-stacks', '--print_hanging_stacks',
+      default=-1, type=int, help='Print hanging stacks after timeout in seconds')
+  result.add_argument('--print-full-stacktraces', '--print_full_stacktraces',
       default=False, action='store_true',
       help='Print the full stacktraces without any filtering applied')
-  result.add_option(
+  result.add_argument(
       '--print-obfuscated-stacktraces', '--print_obfuscated_stacktraces',
       default=False, action='store_true',
       help='Print the obfuscated stacktraces')
-  result.add_option(
+  result.add_argument(
       '--debug-agent', '--debug_agent',
       help='Enable Java debug agent and suspend compilation (default disabled)',
       default=False,
       action='store_true')
-  result.add_option('--desugared-library-configuration',
+  result.add_argument('--desugared-library-configuration',
       '--desugared_library-configuration',
       help='Use alternative desugared library configuration.')
-  result.add_option('--desugared-library', '--desugared_library',
+  result.add_argument('--desugared-library', '--desugared_library',
       help='Build and use desugared library from GitHub.')
-  result.add_option('--print-times', '--print_times',
+  result.add_argument('--print-times', '--print_times',
       help='Print the execution time of the slowest tests..',
       default=False, action='store_true')
-  result.add_option(
+  result.add_argument(
       '--testing-state-dir',
       help='Explicitly set the testing state directory '
            '(defaults to build/test-state/<git-branch>).')
-  result.add_option(
+  result.add_argument(
       '--rerun',
       help='Rerun tests (implicitly enables testing state).',
       choices=testing_state.CHOICES)
-  result.add_option(
+  result.add_argument(
       '--stacktrace',
       help='Pass --stacktrace to the gradle run',
       default=False, action='store_true')
-  result.add_option('--kotlin-compiler-dev',
+  result.add_argument('--kotlin-compiler-dev',
                     help='Specify to download a kotlin dev compiler and run '
                          'tests with that',
                     default=False, action='store_true')
-  result.add_option('--kotlin-compiler-old',
+  result.add_argument('--kotlin-compiler-old',
                     help='Specify to run tests on older kotlin compilers',
                     default=False, action='store_true')
-  result.add_option('--new-gradle',
+  result.add_argument('--new-gradle',
                     help='Specify to run in the new gradle setup',
                     default=False, action='store_true')
-  return result.parse_args()
+  return result.parse_known_args()
 
 def has_failures(classes_file):
   with open(classes_file) as f: