[Retrace] Add benchmarking test for retracing

Change-Id: I2bc4674f70915e82324d6f14b0e65b17924f3e48
diff --git a/src/test/java/com/android/tools/r8/benchmarks/BenchmarkCollection.java b/src/test/java/com/android/tools/r8/benchmarks/BenchmarkCollection.java
index 5dc4bd9..a8f662f 100644
--- a/src/test/java/com/android/tools/r8/benchmarks/BenchmarkCollection.java
+++ b/src/test/java/com/android/tools/r8/benchmarks/BenchmarkCollection.java
@@ -8,6 +8,7 @@
 import com.android.tools.r8.benchmarks.appdumps.TiviBenchmarks;
 import com.android.tools.r8.benchmarks.desugaredlib.LegacyDesugaredLibraryBenchmark;
 import com.android.tools.r8.benchmarks.helloworld.HelloWorldBenchmark;
+import com.android.tools.r8.benchmarks.retrace.RetraceStackTraceBenchmark;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -47,6 +48,7 @@
     HelloWorldBenchmark.configs().forEach(collection::addBenchmark);
     LegacyDesugaredLibraryBenchmark.configs().forEach(collection::addBenchmark);
     TiviBenchmarks.configs().forEach(collection::addBenchmark);
+    RetraceStackTraceBenchmark.configs().forEach(collection::addBenchmark);
     return collection;
   }
 
diff --git a/src/test/java/com/android/tools/r8/benchmarks/retrace/RetraceStackTraceBenchmark.java b/src/test/java/com/android/tools/r8/benchmarks/retrace/RetraceStackTraceBenchmark.java
new file mode 100644
index 0000000..371ef95
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/benchmarks/retrace/RetraceStackTraceBenchmark.java
@@ -0,0 +1,86 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.benchmarks.retrace;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.benchmarks.BenchmarkBase;
+import com.android.tools.r8.benchmarks.BenchmarkConfig;
+import com.android.tools.r8.benchmarks.BenchmarkDependency;
+import com.android.tools.r8.benchmarks.BenchmarkMethod;
+import com.android.tools.r8.benchmarks.BenchmarkTarget;
+import com.android.tools.r8.retrace.ProguardMapProducer;
+import com.android.tools.r8.retrace.Retrace;
+import com.android.tools.r8.retrace.RetraceCommand;
+import com.google.common.collect.ImmutableList;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/** Example of setting up a benchmark based on the testing infrastructure. */
+@RunWith(Parameterized.class)
+public class RetraceStackTraceBenchmark extends BenchmarkBase {
+
+  private static final BenchmarkDependency benchmarkDependency =
+      new BenchmarkDependency("retrace_benchmark", "retrace_benchmark", Paths.get("third_party"));
+
+  @Parameters(name = "{0}")
+  public static List<Object[]> data() {
+    return parametersFromConfigs(configs());
+  }
+
+  public RetraceStackTraceBenchmark(BenchmarkConfig config, TestParameters parameters) {
+    super(config, parameters);
+  }
+
+  /** Static method to add benchmarks to the benchmark collection. */
+  public static List<BenchmarkConfig> configs() {
+    return ImmutableList.<BenchmarkConfig>builder()
+        .add(
+            BenchmarkConfig.builder()
+                .setName("RetraceStackTraceWithProguardMap")
+                .setTarget(BenchmarkTarget.R8_NON_COMPAT)
+                .measureRunTime()
+                .setMethod(benchmarkRetrace())
+                .setFromRevision(12266)
+                .measureWarmup()
+                .addDependency(benchmarkDependency)
+                .build())
+        .build();
+  }
+
+  public static BenchmarkMethod benchmarkRetrace() {
+    return environment ->
+        runner(environment.getConfig())
+            .setWarmupIterations(1)
+            .setBenchmarkIterations(4)
+            .reportResultSum()
+            .run(
+                results -> {
+                  Path dependencyRoot = benchmarkDependency.getRoot(environment);
+                  List<String> stackTrace =
+                      Files.readAllLines(dependencyRoot.resolve("stacktrace.txt"));
+                  List<String> retraced = new ArrayList<>();
+                  long start = System.nanoTime();
+                  Retrace.run(
+                      RetraceCommand.builder()
+                          .setProguardMapProducer(
+                              ProguardMapProducer.fromPath(dependencyRoot.resolve("r8lib.jar.map")))
+                          .setStackTrace(stackTrace)
+                          .setRetracedStackTraceConsumer(retraced::addAll)
+                          .build());
+                  long end = System.nanoTime();
+                  // Add a simple check to ensure that we do not, in case of invalid retracing,
+                  // record an optimal benchmark result.
+                  if (retraced.size() < stackTrace.size()) {
+                    throw new RuntimeException("Unexpected missing lines in retraced result");
+                  }
+                  results.addRuntimeResult(end - start);
+                });
+  }
+}