Add Chrome benchmark

README.google:

Name: Chromium
URL: https://chromium.googlesource.com/chromium/src/
Version: N/A
Revision: N/A
Date: June, 2024
License: LICENSE, LICENSE.chromium_os

LICENSE, LICENSE.chromium_os:

// Copyright 2015 The Chromium Authors
// Copyright 2006-2009 The ChromiumOS Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Change-Id: Ic5e1dec3730c740f91417cbbf7da239711d0f275
diff --git a/.gitignore b/.gitignore
index 67d9a55..f738441 100644
--- a/.gitignore
+++ b/.gitignore
@@ -219,6 +219,8 @@
 third_party/opensource-apps/applymapping.tar.gz
 third_party/opensource-apps/chanu
 third_party/opensource-apps/chanu.tar.gz
+third_party/opensource-apps/chrome
+third_party/opensource-apps/chrome.tar.gz
 third_party/opensource-apps/compose-examples/changed-bitwise-value-propagation
 third_party/opensource-apps/compose-examples/changed-bitwise-value-propagation.tar.gz
 third_party/opensource-apps/empty-activity
diff --git a/d8_r8/commonBuildSrc/src/main/kotlin/DependenciesPlugin.kt b/d8_r8/commonBuildSrc/src/main/kotlin/DependenciesPlugin.kt
index 06155f0..867616c 100644
--- a/d8_r8/commonBuildSrc/src/main/kotlin/DependenciesPlugin.kt
+++ b/d8_r8/commonBuildSrc/src/main/kotlin/DependenciesPlugin.kt
@@ -453,6 +453,10 @@
     Paths.get("third_party", "chrome", "chrome_200430").toFile(),
     Paths.get("third_party", "chrome", "chrome_200430.tar.gz.sha1").toFile(),
     DependencyType.X20)
+  val chromeBenchmark = ThirdPartyDependency(
+    "chrome-benchmark",
+    Paths.get("third_party", "opensource-apps", "chrome").toFile(),
+    Paths.get("third_party", "opensource-apps", "chrome.tar.gz.sha1").toFile())
   val compilerApi = ThirdPartyDependency(
     "compiler-api",
     Paths.get(
diff --git a/src/main/java/com/android/tools/r8/dump/DumpOptions.java b/src/main/java/com/android/tools/r8/dump/DumpOptions.java
index c52f655..3e87ab7 100644
--- a/src/main/java/com/android/tools/r8/dump/DumpOptions.java
+++ b/src/main/java/com/android/tools/r8/dump/DumpOptions.java
@@ -273,6 +273,10 @@
     throw new RuntimeException("Unknown key value pair: " + key + " = " + value);
   }
 
+  public String getAndroidApiExtensionPackages() {
+    return systemProperties.get("com.android.tools.r8.androidApiExtensionPackages");
+  }
+
   public Tool getTool() {
     return tool;
   }
@@ -281,10 +285,18 @@
     return compilationMode;
   }
 
+  public boolean getIsolatedSplits() {
+    return isolatedSplits.orElse(false);
+  }
+
   public int getMinApi() {
     return minApi;
   }
 
+  public boolean getEnableSameFilePolicy() {
+    return systemProperties.containsKey("com.android.tools.r8.enableSameFilePolicy");
+  }
+
   private void addOptionalDumpEntry(
       Map<String, String> buildProperties, String key, Optional<?> optionalValue) {
     optionalValue.ifPresent(bool -> addDumpEntry(buildProperties, key, bool));
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 e265bf9..4e2a4c2 100644
--- a/src/test/java/com/android/tools/r8/benchmarks/BenchmarkCollection.java
+++ b/src/test/java/com/android/tools/r8/benchmarks/BenchmarkCollection.java
@@ -5,6 +5,7 @@
 
 import static java.util.Collections.emptyList;
 
+import com.android.tools.r8.benchmarks.appdumps.ChromeBenchmarks;
 import com.android.tools.r8.benchmarks.appdumps.ComposeSamplesBenchmarks;
 import com.android.tools.r8.benchmarks.appdumps.NowInAndroidBenchmarks;
 import com.android.tools.r8.benchmarks.appdumps.TiviBenchmarks;
@@ -68,7 +69,8 @@
         NowInAndroidBenchmarks.configs(),
         TiviBenchmarks.configs(),
         RetraceStackTraceBenchmark.configs(),
-        ComposeSamplesBenchmarks.configs());
+        ComposeSamplesBenchmarks.configs(),
+        ChromeBenchmarks.configs());
   }
 
   /** Compute and print the golem configuration. */
diff --git a/src/test/java/com/android/tools/r8/benchmarks/appdumps/AppDumpBenchmarkBuilder.java b/src/test/java/com/android/tools/r8/benchmarks/appdumps/AppDumpBenchmarkBuilder.java
index 2cb7808..9454d6e 100644
--- a/src/test/java/com/android/tools/r8/benchmarks/appdumps/AppDumpBenchmarkBuilder.java
+++ b/src/test/java/com/android/tools/r8/benchmarks/appdumps/AppDumpBenchmarkBuilder.java
@@ -236,8 +236,21 @@
                       .addProgramFiles(dump.getProgramArchive())
                       .addLibraryFiles(dump.getLibraryArchive())
                       .addKeepRuleFiles(dump.getProguardConfigFile())
+                      .addOptionsModification(
+                          options -> {
+                            options.apiModelingOptions().androidApiExtensionPackages =
+                                dumpProperties.getAndroidApiExtensionPackages();
+                            options
+                                .horizontalClassMergerOptions()
+                                .setEnableSameFilePolicy(dumpProperties.getEnableSameFilePolicy());
+                          })
+                      .enableIsolatedSplits(dumpProperties.getIsolatedSplits())
                       .setMinApi(dumpProperties.getMinApi())
-                      .apply(b -> addDesugaredLibrary(b, dump))
+                      .apply(
+                          testBuilder -> {
+                            dump.forEachFeatureArchive(testBuilder::addFeatureSplit);
+                            addDesugaredLibrary(testBuilder, dump);
+                          })
                       .apply(configuration)
                       .applyIf(
                           enableResourceShrinking,
diff --git a/src/test/java/com/android/tools/r8/benchmarks/appdumps/ChromeBenchmarks.java b/src/test/java/com/android/tools/r8/benchmarks/appdumps/ChromeBenchmarks.java
new file mode 100644
index 0000000..9bcfcb7
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/benchmarks/appdumps/ChromeBenchmarks.java
@@ -0,0 +1,52 @@
+// Copyright (c) 2024, 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.appdumps;
+
+import com.android.tools.r8.R8FullTestBuilder;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.benchmarks.BenchmarkBase;
+import com.android.tools.r8.benchmarks.BenchmarkConfig;
+import com.google.common.collect.ImmutableList;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class ChromeBenchmarks extends BenchmarkBase {
+
+  private static final Path dir = Paths.get(ToolHelper.THIRD_PARTY_DIR, "opensource-apps/chrome");
+
+  public ChromeBenchmarks(BenchmarkConfig config, TestParameters parameters) {
+    super(config, parameters);
+  }
+
+  @Parameters(name = "{0}")
+  public static List<Object[]> data() {
+    return parametersFromConfigs(configs());
+  }
+
+  public static List<BenchmarkConfig> configs() {
+    return ImmutableList.of(
+        AppDumpBenchmarkBuilder.builder()
+            .setName("ChromeApp")
+            .setDumpDependencyPath(dir)
+            .setFromRevision(16457)
+            .buildR8(ChromeBenchmarks::configure));
+  }
+
+  private static void configure(R8FullTestBuilder testBuilder) {
+    testBuilder
+        .addDontWarn("android.adservices.common.AdServicesOutcomeReceiver")
+        .addOptionsModification(
+            options -> options.getOpenClosedInterfacesOptions().suppressAllOpenInterfaces())
+        .allowDiagnosticMessages()
+        .allowUnusedDontWarnPatterns()
+        .allowUnusedProguardConfigurationRules()
+        .allowUnnecessaryDontWarnWildcards();
+  }
+}
diff --git a/src/test/testbase/java/com/android/tools/r8/R8TestBuilder.java b/src/test/testbase/java/com/android/tools/r8/R8TestBuilder.java
index 5f68743..9d35920 100644
--- a/src/test/testbase/java/com/android/tools/r8/R8TestBuilder.java
+++ b/src/test/testbase/java/com/android/tools/r8/R8TestBuilder.java
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
-
+import com.android.tools.r8.DexIndexedConsumer.ArchiveConsumer;
 import com.android.tools.r8.R8Command.Builder;
 import com.android.tools.r8.TestBase.Backend;
 import com.android.tools.r8.androidresources.AndroidResourceTestingUtils.AndroidTestResource;
@@ -36,6 +36,7 @@
 import com.android.tools.r8.shaking.ProguardConfigurationRule;
 import com.android.tools.r8.startup.StartupProfileProvider;
 import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.utils.ArchiveResourceProvider;
 import com.android.tools.r8.utils.FileUtils;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.MapIdTemplateProvider;
@@ -859,6 +860,18 @@
     return self();
   }
 
+  public T addFeatureSplit(Path featureJar) {
+    Path featureOutJar = getState().getNewTempFileUnchecked("feature.zip");
+    builder.addFeatureSplit(
+        builder ->
+            builder
+                .addProgramResourceProvider(ArchiveResourceProvider.fromArchive(featureJar, true))
+                .setProgramConsumer(new ArchiveConsumer(featureOutJar, true))
+                .build());
+    features.add(featureOutJar);
+    return self();
+  }
+
   public T addFeatureSplitWithResources(
       Collection<Pair<String, String>> nonJavaFiles, Class<?>... classes) throws IOException {
     Path path = getState().getNewTempFolder().resolve("feature.zip");
diff --git a/src/test/testbase/java/com/android/tools/r8/R8TestCompileResult.java b/src/test/testbase/java/com/android/tools/r8/R8TestCompileResult.java
index 9b51098..4edcc33 100644
--- a/src/test/testbase/java/com/android/tools/r8/R8TestCompileResult.java
+++ b/src/test/testbase/java/com/android/tools/r8/R8TestCompileResult.java
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -239,14 +238,17 @@
       throws IOException {
     assert getBackend() == runtime.getBackend();
     ClassSubject mainClassSubject = inspector().clazz(SplitRunner.class);
-    assertThat("Did you forget a keep rule for the main method?", mainClassSubject, Matchers.isPresent());
+    assertThat(
+        "Did you forget a keep rule for the main method?", mainClassSubject, Matchers.isPresent());
     assertThat(
         "Did you forget a keep rule for the main method?",
         mainClassSubject.mainMethod(),
         Matchers.isPresent());
     ClassSubject mainFeatureClassSubject = featureInspector(feature).clazz(mainFeatureClass);
     assertThat(
-        "Did you forget a keep rule for the run method?", mainFeatureClassSubject, Matchers.isPresent());
+        "Did you forget a keep rule for the run method?",
+        mainFeatureClassSubject,
+        Matchers.isPresent());
     assertThat(
         "Did you forget a keep rule for the run method?",
         mainFeatureClassSubject.uniqueMethodWithOriginalName("run"),
@@ -280,4 +282,13 @@
     FileUtils.writeTextFile(path, getProguardMap());
     return self();
   }
+
+  @Override
+  public R8TestCompileResult benchmarkCodeSize(BenchmarkResults results)
+      throws IOException, ResourceException {
+    int applicationSizeWithFeatures =
+        AndroidApp.builder(app).addProgramFiles(features).build().applicationSize();
+    results.addCodeSizeResult(applicationSizeWithFeatures);
+    return self();
+  }
 }
diff --git a/src/test/testbase/java/com/android/tools/r8/TestState.java b/src/test/testbase/java/com/android/tools/r8/TestState.java
index 6b01a75..77d4a0b 100644
--- a/src/test/testbase/java/com/android/tools/r8/TestState.java
+++ b/src/test/testbase/java/com/android/tools/r8/TestState.java
@@ -4,6 +4,7 @@
 package com.android.tools.r8;
 
 import java.io.IOException;
+import java.io.UncheckedIOException;
 import java.nio.file.Path;
 import java.util.Set;
 import java.util.function.BiFunction;
@@ -40,6 +41,14 @@
     return getNewTempFolder().resolve(name);
   }
 
+  public Path getNewTempFileUnchecked(String name) {
+    try {
+      return getNewTempFile(name);
+    } catch (IOException e) {
+      throw new UncheckedIOException(e);
+    }
+  }
+
   public DiagnosticsHandler getDiagnosticsHandler() {
     return messages;
   }
diff --git a/src/test/testbase/java/com/android/tools/r8/dexsplitter/SplitterTestBase.java b/src/test/testbase/java/com/android/tools/r8/dexsplitter/SplitterTestBase.java
index 8ce018e..9904b9b 100644
--- a/src/test/testbase/java/com/android/tools/r8/dexsplitter/SplitterTestBase.java
+++ b/src/test/testbase/java/com/android/tools/r8/dexsplitter/SplitterTestBase.java
@@ -3,10 +3,8 @@
 import static junit.framework.TestCase.fail;
 import static org.junit.Assume.assumeTrue;
 
-import com.android.tools.r8.ByteDataView;
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.DexIndexedConsumer.ArchiveConsumer;
-import com.android.tools.r8.DiagnosticsHandler;
 import com.android.tools.r8.FeatureSplit;
 import com.android.tools.r8.R8FullTestBuilder;
 import com.android.tools.r8.R8TestCompileResult;
@@ -92,17 +90,7 @@
 
     builder
         .addProgramResourceProvider(ArchiveResourceProvider.fromArchive(featureJar, true))
-        .setProgramConsumer(
-            new ArchiveConsumer(outputPath, true) {
-              @Override
-              public void accept(
-                  int fileIndex,
-                  ByteDataView data,
-                  Set<String> descriptors,
-                  DiagnosticsHandler handler) {
-                super.accept(fileIndex, data, descriptors, handler);
-              }
-            });
+        .setProgramConsumer(new ArchiveConsumer(outputPath, true));
   }
 
   public static FeatureSplit splitWithNonJavaFile(
diff --git a/src/test/testbase/java/com/android/tools/r8/dump/CompilerDump.java b/src/test/testbase/java/com/android/tools/r8/dump/CompilerDump.java
index c95193c..f572d3d 100644
--- a/src/test/testbase/java/com/android/tools/r8/dump/CompilerDump.java
+++ b/src/test/testbase/java/com/android/tools/r8/dump/CompilerDump.java
@@ -10,6 +10,7 @@
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.function.Consumer;
 
 public class CompilerDump {
 
@@ -29,6 +30,18 @@
     this.directory = directory;
   }
 
+  public void forEachFeatureArchive(Consumer<? super Path> consumer) {
+    int i = 1;
+    while (true) {
+      Path featureJar = directory.resolve("feature-" + i + ".jar");
+      if (!Files.exists(featureJar)) {
+        break;
+      }
+      consumer.accept(featureJar);
+      i++;
+    }
+  }
+
   public Path getProgramArchive() {
     return directory.resolve("program.jar");
   }
diff --git a/third_party/opensource-apps/chrome.tar.gz.sha1 b/third_party/opensource-apps/chrome.tar.gz.sha1
new file mode 100644
index 0000000..b74ce8a
--- /dev/null
+++ b/third_party/opensource-apps/chrome.tar.gz.sha1
@@ -0,0 +1 @@
+2011d6b4b3394b50c514a9c281845b62b42db078
\ No newline at end of file
diff --git a/tools/perf.py b/tools/perf.py
index 21dfc92..e8379a6 100755
--- a/tools/perf.py
+++ b/tools/perf.py
@@ -15,7 +15,7 @@
 import utils
 
 APPS = [
-    'CraneApp', 'JetLaggedApp', 'JetNewsApp', 'JetCasterApp', 'JetChatApp',
+    'ChromeApp', 'CraneApp', 'JetLaggedApp', 'JetNewsApp', 'JetCasterApp', 'JetChatApp',
     'JetSnackApp', 'NowInAndroidApp', 'OwlApp', 'ReplyApp', 'TiviApp'
 ]
 BUCKET = "r8-perf-results"