Don't use reflective access for startup profiles in compiledump

Bug: b/377606434
Change-Id: Ib7ce114f06b2ab94a10efacc5ed9524da9e5ddb1
diff --git a/src/main/java/com/android/tools/r8/utils/CompileDumpBase.java b/src/main/java/com/android/tools/r8/utils/CompileDumpBase.java
index 54f2ff4..684dab3 100644
--- a/src/main/java/com/android/tools/r8/utils/CompileDumpBase.java
+++ b/src/main/java/com/android/tools/r8/utils/CompileDumpBase.java
@@ -10,13 +10,9 @@
 import java.lang.reflect.Method;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.function.Consumer;
-import java.util.function.Function;
 
 public class CompileDumpBase {
 
@@ -48,29 +44,6 @@
     }
   }
 
-  static void addStartupProfileProviders(Object builder, List<Path> startupProfileFiles) {
-    getReflectiveBuilderMethod(builder, "addStartupProfileProviders", Collection.class)
-        .accept(new Object[] {createStartupProfileProviders(startupProfileFiles)});
-  }
-
-  static Collection<Object> createStartupProfileProviders(List<Path> startupProfileFiles) {
-    List<Object> startupProfileProviders = new ArrayList<>();
-    for (Path startupProfileFile : startupProfileFiles) {
-      boolean found =
-          callReflectiveUtilsMethod(
-              "createStartupProfileProviderFromDumpFile",
-              new Class<?>[] {Path.class},
-              fn -> startupProfileProviders.add(fn.apply(new Object[] {startupProfileFile})));
-      if (!found) {
-        System.out.println(
-            "Unable to add startup profiles as input. "
-                + "Method createStartupProfileProviderFromDumpFile() was not found.");
-        break;
-      }
-    }
-    return startupProfileProviders;
-  }
-
   static Consumer<Object[]> getReflectiveBuilderMethod(
       Object builder, String setter, Class<?>... parameters) {
     try {
@@ -89,33 +62,6 @@
     }
   }
 
-  static boolean callReflectiveUtilsMethod(
-      String methodName, Class<?>[] parameters, Consumer<Function<Object[], Object>> fnConsumer) {
-    Class<?> utilsClass;
-    try {
-      utilsClass = Class.forName("com.android.tools.r8.utils.CompileDumpUtils");
-    } catch (ClassNotFoundException e) {
-      return false;
-    }
-
-    Method declaredMethod;
-    try {
-      declaredMethod = utilsClass.getDeclaredMethod(methodName, parameters);
-    } catch (NoSuchMethodException e) {
-      return false;
-    }
-
-    fnConsumer.accept(
-        args -> {
-          try {
-            return declaredMethod.invoke(null, args);
-          } catch (Exception e) {
-            throw new RuntimeException(e);
-          }
-        });
-    return true;
-  }
-
   @SuppressWarnings({"CatchAndPrintStackTrace", "DefaultCharset"})
   // We cannot use StringResource since this class is added to the class path and has access only
   // to the public APIs.
diff --git a/src/main/java/com/android/tools/r8/utils/CompileDumpCompatR8.java b/src/main/java/com/android/tools/r8/utils/CompileDumpCompatR8.java
index 023d8e1..d13ef27 100644
--- a/src/main/java/com/android/tools/r8/utils/CompileDumpCompatR8.java
+++ b/src/main/java/com/android/tools/r8/utils/CompileDumpCompatR8.java
@@ -11,7 +11,8 @@
 import com.android.tools.r8.R8;
 import com.android.tools.r8.R8Command;
 import com.android.tools.r8.StringConsumer;
-import com.android.tools.r8.utils.compiledump.ResourceShrinker;
+import com.android.tools.r8.utils.compiledump.ResourceShrinkerDumpUtils;
+import com.android.tools.r8.utils.compiledump.StartupProfileDumpUtils;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
@@ -238,7 +239,11 @@
             .setOutput(outputPath, outputMode)
             .setMode(compilationMode);
     addArtProfilesForRewriting(commandBuilder, artProfileFiles);
-    addStartupProfileProviders(commandBuilder, startupProfileFiles);
+    if (!startupProfileFiles.isEmpty()) {
+      runIgnoreMissing(
+          () -> StartupProfileDumpUtils.addStartupProfiles(startupProfileFiles, commandBuilder),
+          "Could not add startup profiles.");
+    }
     setAndroidPlatformBuild(commandBuilder, androidPlatformBuild);
     setIsolatedSplits(commandBuilder, isolatedSplits);
     setEnableExperimentalMissingLibraryApiModeling(commandBuilder, enableMissingLibraryApiModeling);
@@ -250,7 +255,7 @@
       Path finalAndroidResourcesOutput = androidResourcesOutput;
       runIgnoreMissing(
           () ->
-              ResourceShrinker.setupBaseResourceShrinking(
+              ResourceShrinkerDumpUtils.setupBaseResourceShrinking(
                   finalAndroidResourcesInput, finalAndroidResourcesOutput, commandBuilder),
           "Failed initializing resource shrinker.");
     }
diff --git a/src/main/java/com/android/tools/r8/utils/CompileDumpD8.java b/src/main/java/com/android/tools/r8/utils/CompileDumpD8.java
index 137dfe7..27ee2f1 100644
--- a/src/main/java/com/android/tools/r8/utils/CompileDumpD8.java
+++ b/src/main/java/com/android/tools/r8/utils/CompileDumpD8.java
@@ -9,6 +9,7 @@
 import com.android.tools.r8.D8Command;
 import com.android.tools.r8.OutputMode;
 import com.android.tools.r8.StringConsumer;
+import com.android.tools.r8.utils.compiledump.StartupProfileDumpUtils;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
@@ -177,7 +178,11 @@
             .setOutput(outputPath, outputMode)
             .setMode(compilationMode);
     addArtProfilesForRewriting(commandBuilder, artProfileFiles);
-    addStartupProfileProviders(commandBuilder, startupProfileFiles);
+    if (!startupProfileFiles.isEmpty()) {
+      runIgnoreMissing(
+          () -> StartupProfileDumpUtils.addStartupProfiles(startupProfileFiles, commandBuilder),
+          "Could not add startup profiles.");
+    }
     setAndroidPlatformBuild(commandBuilder, androidPlatformBuild);
     setEnableExperimentalMissingLibraryApiModeling(commandBuilder, enableMissingLibraryApiModeling);
     if (desugaredLibJson != null) {
diff --git a/src/main/java/com/android/tools/r8/utils/CompileDumpUtils.java b/src/main/java/com/android/tools/r8/utils/CompileDumpUtils.java
deleted file mode 100644
index c2e3592..0000000
--- a/src/main/java/com/android/tools/r8/utils/CompileDumpUtils.java
+++ /dev/null
@@ -1,56 +0,0 @@
-// 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.utils;
-
-import com.android.tools.r8.KeepMethodForCompileDump;
-import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.origin.PathOrigin;
-import com.android.tools.r8.references.MethodReference;
-import com.android.tools.r8.references.Reference;
-import com.android.tools.r8.startup.StartupProfileBuilder;
-import com.android.tools.r8.startup.StartupProfileProvider;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-
-class CompileDumpUtils {
-
-  @KeepMethodForCompileDump
-  static StartupProfileProvider createStartupProfileProviderFromDumpFile(Path path) {
-    return new StartupProfileProvider() {
-
-      @Override
-      public void getStartupProfile(StartupProfileBuilder startupProfileBuilder) {
-        try {
-          try (BufferedReader bufferedReader = Files.newBufferedReader(path)) {
-            while (bufferedReader.ready()) {
-              String rule = bufferedReader.readLine();
-              MethodReference methodReference = MethodReferenceUtils.parseSmaliString(rule);
-              if (methodReference != null) {
-                startupProfileBuilder.addStartupMethod(
-                    startupMethodBuilder ->
-                        startupMethodBuilder.setMethodReference(methodReference));
-              } else {
-                assert DescriptorUtils.isClassDescriptor(rule);
-                startupProfileBuilder.addStartupClass(
-                    startupClassBuilder ->
-                        startupClassBuilder.setClassReference(Reference.classFromDescriptor(rule)));
-              }
-            }
-          }
-        } catch (IOException e) {
-          throw new UncheckedIOException(e);
-        }
-      }
-
-      @Override
-      public Origin getOrigin() {
-        return new PathOrigin(path);
-      }
-    };
-  }
-}
diff --git a/src/main/java/com/android/tools/r8/utils/compiledump/ResourceShrinker.java b/src/main/java/com/android/tools/r8/utils/compiledump/ResourceShrinkerDumpUtils.java
similarity index 94%
rename from src/main/java/com/android/tools/r8/utils/compiledump/ResourceShrinker.java
rename to src/main/java/com/android/tools/r8/utils/compiledump/ResourceShrinkerDumpUtils.java
index 67d0322..7be55c1 100644
--- a/src/main/java/com/android/tools/r8/utils/compiledump/ResourceShrinker.java
+++ b/src/main/java/com/android/tools/r8/utils/compiledump/ResourceShrinkerDumpUtils.java
@@ -9,7 +9,7 @@
 import com.android.tools.r8.R8Command;
 import java.nio.file.Path;
 
-public class ResourceShrinker {
+public class ResourceShrinkerDumpUtils {
   public static void setupBaseResourceShrinking(
       Path input, Path output, R8Command.Builder builder) {
     builder.setAndroidResourceProvider(new ArchiveProtoAndroidResourceProvider(input));
diff --git a/src/main/java/com/android/tools/r8/utils/compiledump/StartupProfileDumpUtils.java b/src/main/java/com/android/tools/r8/utils/compiledump/StartupProfileDumpUtils.java
new file mode 100644
index 0000000..c78a082
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/utils/compiledump/StartupProfileDumpUtils.java
@@ -0,0 +1,53 @@
+// 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.utils.compiledump;
+
+import com.android.tools.r8.D8Command;
+import com.android.tools.r8.R8Command;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.origin.PathOrigin;
+import com.android.tools.r8.startup.StartupProfileBuilder;
+import com.android.tools.r8.startup.StartupProfileProvider;
+import com.android.tools.r8.utils.UTF8TextInputStream;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class StartupProfileDumpUtils {
+  public static void addStartupProfiles(List<Path> inputs, R8Command.Builder builder) {
+    builder.addStartupProfileProviders(createProviders(inputs));
+  }
+
+  public static void addStartupProfiles(List<Path> inputs, D8Command.Builder builder) {
+    builder.addStartupProfileProviders(createProviders(inputs));
+  }
+
+  private static List<StartupProfileProvider> createProviders(List<Path> inputs) {
+    return inputs.stream()
+        .map(StartupProfileDumpUtils::createStartupProfileProvider)
+        .collect(Collectors.toList());
+  }
+
+  private static StartupProfileProvider createStartupProfileProvider(Path path) {
+    return new StartupProfileProvider() {
+      @Override
+      public void getStartupProfile(StartupProfileBuilder startupProfileBuilder) {
+        try {
+          startupProfileBuilder.addHumanReadableArtProfile(
+              new UTF8TextInputStream(path), builder -> {});
+        } catch (IOException e) {
+          throw new UncheckedIOException(e);
+        }
+      }
+
+      @Override
+      public Origin getOrigin() {
+        return new PathOrigin(path);
+      }
+    };
+  }
+}
diff --git a/src/main/keep.txt b/src/main/keep.txt
index ddb667f..6034f07 100644
--- a/src/main/keep.txt
+++ b/src/main/keep.txt
@@ -2,8 +2,6 @@
 # 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.
 
--keepclasseswithmembers class * { @com.android.tools.r8.KeepMethodForCompileDump <methods>; }
-
 -keep public class com.android.tools.r8.D8 { public static void main(java.lang.String[]); }
 -keep public class com.android.tools.r8.R8 { public static void main(java.lang.String[]); }
 -keep public class com.android.tools.r8.ExtractMarker { public static void main(java.lang.String[]); }