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[]); }