Include serialization of startup profile providers in dumps
Fixes: b/232032895
Change-Id: I14e797acf1f16187828367d6d601a4cfb53ff7da
diff --git a/src/main/java/com/android/tools/r8/BaseCompilerCommand.java b/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
index dc5bca3..1694c22 100644
--- a/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
+++ b/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
@@ -144,7 +144,8 @@
.setMinApi(getMinApiLevel())
.setOptimizeMultidexForLinearAlloc(isOptimizeMultidexForLinearAlloc())
.setThreadCount(getThreadCount())
- .setDesugarState(getDesugarState());
+ .setDesugarState(getDesugarState())
+ .setStartupProfileProviders(getStartupProfileProviders());
if (getAndroidPlatformBuild()) {
builder.setAndroidPlatformBuild(true);
}
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 1d55987..27dddcc 100644
--- a/src/main/java/com/android/tools/r8/dump/DumpOptions.java
+++ b/src/main/java/com/android/tools/r8/dump/DumpOptions.java
@@ -10,9 +10,11 @@
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecification;
import com.android.tools.r8.shaking.ProguardConfiguration;
import com.android.tools.r8.shaking.ProguardConfigurationRule;
+import com.android.tools.r8.startup.StartupProfileProvider;
import com.android.tools.r8.utils.InternalOptions.DesugarState;
import com.android.tools.r8.utils.ThreadUtils;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
@@ -62,6 +64,7 @@
private final FeatureSplitConfiguration featureSplitConfiguration;
private final ProguardConfiguration proguardConfiguration;
private final List<ProguardConfigurationRule> mainDexKeepRules;
+ private final Collection<StartupProfileProvider> startupProfileProviders;
private final boolean enableMissingLibraryApiModeling;
private final boolean isAndroidPlatformBuild;
@@ -86,6 +89,7 @@
FeatureSplitConfiguration featureSplitConfiguration,
ProguardConfiguration proguardConfiguration,
List<ProguardConfigurationRule> mainDexKeepRules,
+ Collection<StartupProfileProvider> startupProfileProviders,
boolean enableMissingLibraryApiModeling,
boolean isAndroidPlatformBuild,
Map<String, String> systemProperties,
@@ -105,6 +109,7 @@
this.featureSplitConfiguration = featureSplitConfiguration;
this.proguardConfiguration = proguardConfiguration;
this.mainDexKeepRules = mainDexKeepRules;
+ this.startupProfileProviders = startupProfileProviders;
this.enableMissingLibraryApiModeling = enableMissingLibraryApiModeling;
this.isAndroidPlatformBuild = isAndroidPlatformBuild;
this.systemProperties = systemProperties;
@@ -268,6 +273,14 @@
return mainDexKeepRules;
}
+ public boolean hasStartupProfileProviders() {
+ return startupProfileProviders != null && !startupProfileProviders.isEmpty();
+ }
+
+ public Collection<StartupProfileProvider> getStartupProfileProviders() {
+ return startupProfileProviders;
+ }
+
public boolean dumpInputToFile() {
return dumpInputToFile;
}
@@ -293,6 +306,7 @@
private FeatureSplitConfiguration featureSplitConfiguration;
private ProguardConfiguration proguardConfiguration;
private List<ProguardConfigurationRule> mainDexKeepRules;
+ private Collection<StartupProfileProvider> startupProfileProviders;
private boolean enableMissingLibraryApiModeling = false;
private boolean isAndroidPlatformBuild = false;
@@ -386,6 +400,12 @@
return this;
}
+ public Builder setStartupProfileProviders(
+ Collection<StartupProfileProvider> startupProfileProviders) {
+ this.startupProfileProviders = startupProfileProviders;
+ return this;
+ }
+
public Builder setEnableMissingLibraryApiModeling(boolean value) {
enableMissingLibraryApiModeling = value;
return this;
@@ -432,6 +452,7 @@
featureSplitConfiguration,
proguardConfiguration,
mainDexKeepRules,
+ startupProfileProviders,
enableMissingLibraryApiModeling,
isAndroidPlatformBuild,
systemProperties,
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/StartupProfileProviderUtils.java b/src/main/java/com/android/tools/r8/experimental/startup/StartupProfileProviderUtils.java
index bcd5b25..ae95407 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/StartupProfileProviderUtils.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/StartupProfileProviderUtils.java
@@ -4,11 +4,16 @@
package com.android.tools.r8.experimental.startup;
+import com.android.tools.r8.experimental.startup.profile.StartupItem;
+import com.android.tools.r8.experimental.startup.profile.StartupProfile;
+import com.android.tools.r8.experimental.startup.profile.art.ARTProfileBuilderUtils.SyntheticToSyntheticContextGeneralization;
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.startup.diagnostic.MissingStartupProfileItemsDiagnostic;
import com.android.tools.r8.utils.ConsumerUtils;
+import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.UTF8TextInputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
@@ -35,4 +40,31 @@
}
};
}
+
+ /** Serialize the given {@param startupProfileProvider} to a string for writing it to a dump. */
+ public static String serializeToString(
+ InternalOptions options, StartupProfileProvider startupProfileProvider) {
+ // Do not report missing items.
+ MissingStartupProfileItemsDiagnostic.Builder missingItemsDiagnosticBuilder =
+ MissingStartupProfileItemsDiagnostic.Builder.nop();
+ // Do not generalize synthetic items to their synthetic context.
+ SyntheticToSyntheticContextGeneralization syntheticToSyntheticContextGeneralization =
+ SyntheticToSyntheticContextGeneralization.createForD8();
+ StartupProfile.Builder startupProfileBuilder =
+ StartupProfile.builder(
+ options,
+ missingItemsDiagnosticBuilder,
+ startupProfileProvider,
+ syntheticToSyntheticContextGeneralization);
+ // Do not report warnings for lines that cannot be parsed.
+ startupProfileBuilder.setIgnoreWarnings();
+ // Populate the startup profile builder.
+ startupProfileProvider.getStartupProfile(startupProfileBuilder);
+ // Serialize the startup items.
+ StringBuilder resultBuilder = new StringBuilder();
+ for (StartupItem startupItem : startupProfileBuilder.build().getStartupItems()) {
+ resultBuilder.append(startupItem.serializeToString()).append('\n');
+ }
+ return resultBuilder.toString();
+ }
}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupClass.java b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupClass.java
index dbd8ef6..d281a65 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupClass.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupClass.java
@@ -75,6 +75,11 @@
return type.hashCode();
}
+ @Override
+ public String serializeToString() {
+ return getReference().toDescriptorString();
+ }
+
public static class Builder implements StartupClassBuilder {
private final DexItemFactory dexItemFactory;
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupItem.java b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupItem.java
index 1854c07..b7e6f1c 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupItem.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupItem.java
@@ -45,4 +45,6 @@
assert false;
return null;
}
+
+ public abstract String serializeToString();
}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupMethod.java b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupMethod.java
index 9e45798..18045ef 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupMethod.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupMethod.java
@@ -75,6 +75,11 @@
return method.hashCode();
}
+ @Override
+ public String serializeToString() {
+ return method.toSmaliString();
+ }
+
public static class Builder implements StartupMethodBuilder {
private final DexItemFactory dexItemFactory;
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfile.java b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfile.java
index 842e181..767ec7f 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfile.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfile.java
@@ -19,9 +19,9 @@
import com.android.tools.r8.startup.StartupProfileProvider;
import com.android.tools.r8.startup.SyntheticStartupMethodBuilder;
import com.android.tools.r8.startup.diagnostic.MissingStartupProfileItemsDiagnostic;
-import com.android.tools.r8.startup.diagnostic.MissingStartupProfileItemsDiagnostic.Builder;
import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.Reporter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
@@ -108,7 +108,7 @@
private final DexItemFactory dexItemFactory;
private final MissingStartupProfileItemsDiagnostic.Builder missingItemsDiagnosticBuilder;
- private final InternalOptions options;
+ private Reporter reporter;
private final StartupProfileProvider startupProfileProvider;
private final SyntheticToSyntheticContextGeneralization
syntheticToSyntheticContextGeneralization;
@@ -122,7 +122,7 @@
SyntheticToSyntheticContextGeneralization syntheticToSyntheticContextGeneralization) {
this.dexItemFactory = options.dexItemFactory();
this.missingItemsDiagnosticBuilder = missingItemsDiagnosticBuilder;
- this.options = options;
+ this.reporter = options.reporter;
this.startupProfileProvider = startupProfileProvider;
this.syntheticToSyntheticContextGeneralization = syntheticToSyntheticContextGeneralization;
}
@@ -180,7 +180,7 @@
HumanReadableARTProfileParser parser =
HumanReadableARTProfileParser.builder()
- .setReporter(options.reporter)
+ .setReporter(reporter)
.setProfileBuilder(
ARTProfileBuilderUtils.createBuilderForARTProfileToStartupProfileConversion(
this, rulePredicateBox.get(), syntheticToSyntheticContextGeneralization))
@@ -199,6 +199,15 @@
return this;
}
+ public Builder setIgnoreWarnings() {
+ return setReporter(null);
+ }
+
+ public Builder setReporter(Reporter reporter) {
+ this.reporter = reporter;
+ return this;
+ }
+
public StartupProfile build() {
return new StartupProfile(startupItems);
}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/profile/SyntheticStartupMethod.java b/src/main/java/com/android/tools/r8/experimental/startup/profile/SyntheticStartupMethod.java
index eedcadd..c68a198 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/profile/SyntheticStartupMethod.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/profile/SyntheticStartupMethod.java
@@ -75,6 +75,11 @@
return syntheticContextType.hashCode();
}
+ @Override
+ public String serializeToString() {
+ return 'S' + syntheticContextType.toDescriptorString();
+ }
+
public static class Builder implements SyntheticStartupMethodBuilder {
private final DexItemFactory dexItemFactory;
diff --git a/src/main/java/com/android/tools/r8/startup/diagnostic/MissingStartupProfileItemsDiagnostic.java b/src/main/java/com/android/tools/r8/startup/diagnostic/MissingStartupProfileItemsDiagnostic.java
index 716480d..5faf4b7 100644
--- a/src/main/java/com/android/tools/r8/startup/diagnostic/MissingStartupProfileItemsDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/startup/diagnostic/MissingStartupProfileItemsDiagnostic.java
@@ -77,6 +77,10 @@
this.definitions = definitions;
}
+ public static Builder nop() {
+ return new Builder(null);
+ }
+
public boolean hasMissingStartupItems() {
return !missingStartupItems.isEmpty();
}
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 14b4d67..679e3c7 100644
--- a/src/main/java/com/android/tools/r8/utils/AndroidApp.java
+++ b/src/main/java/com/android/tools/r8/utils/AndroidApp.java
@@ -35,6 +35,7 @@
import com.android.tools.r8.errors.InternalCompilerError;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.experimental.startup.StartupOrder;
+import com.android.tools.r8.experimental.startup.StartupProfileProviderUtils;
import com.android.tools.r8.features.ClassToFeatureSplitMap;
import com.android.tools.r8.features.FeatureSplitConfiguration;
import com.android.tools.r8.graph.DexType;
@@ -42,6 +43,7 @@
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
import com.android.tools.r8.shaking.FilteredClassPath;
+import com.android.tools.r8.startup.StartupProfileProvider;
import com.android.tools.r8.synthesis.SyntheticItems;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -524,6 +526,9 @@
StringUtils.joinLines(dumpOptions.getMainDexKeepRules()).getBytes(),
ZipEntry.DEFLATED);
}
+ if (dumpOptions.hasStartupProfileProviders()) {
+ dumpStartupProfileProviders(dumpOptions.getStartupProfileProviders(), options, out);
+ }
nextDexIndex =
dumpProgramResources(
dumpProgramFileName,
@@ -553,6 +558,24 @@
return nextDexIndex;
}
+ private void dumpStartupProfileProviders(
+ Collection<StartupProfileProvider> startupProfileProviders,
+ InternalOptions options,
+ ZipOutputStream out)
+ throws IOException {
+ int startupProfileProviderIndex = 1;
+ for (StartupProfileProvider startupProfileProvider : startupProfileProviders) {
+ String startupProfileProviderFileName =
+ "startup-profile-" + startupProfileProviderIndex + ".txt";
+ writeToZipStream(
+ out,
+ startupProfileProviderFileName,
+ StartupProfileProviderUtils.serializeToString(options, startupProfileProvider).getBytes(),
+ ZipEntry.DEFLATED);
+ startupProfileProviderIndex++;
+ }
+ }
+
private static ClassFileResourceProvider createClassFileResourceProvider(
Map<String, ProgramResource> classPathResources) {
return new ClassFileResourceProvider() {
diff --git a/src/main/java/com/android/tools/r8/utils/MethodReferenceUtils.java b/src/main/java/com/android/tools/r8/utils/MethodReferenceUtils.java
index 8e240d7..4e1a4bc 100644
--- a/src/main/java/com/android/tools/r8/utils/MethodReferenceUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/MethodReferenceUtils.java
@@ -115,6 +115,13 @@
methodReference.getMethodName());
}
+ public static String toSmaliString(MethodReference methodReference) {
+ return methodReference.getHolderClass().getDescriptor()
+ + "->"
+ + methodReference.getMethodName()
+ + methodReference.getMethodDescriptor();
+ }
+
public static String toSourceStringWithoutHolderAndReturnType(MethodReference methodReference) {
return toSourceString(methodReference, false, false);
}
diff --git a/src/test/java/com/android/tools/r8/D8TestBuilder.java b/src/test/java/com/android/tools/r8/D8TestBuilder.java
index d14b01f..8f465ff 100644
--- a/src/test/java/com/android/tools/r8/D8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/D8TestBuilder.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.TestBase.Backend;
import com.android.tools.r8.benchmarks.BenchmarkResults;
import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.startup.StartupProfileProvider;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
import java.nio.file.Path;
@@ -30,6 +31,16 @@
private StringBuilder proguardMapOutputBuilder = null;
@Override
+ public boolean isD8TestBuilder() {
+ return true;
+ }
+
+ @Override
+ public D8TestBuilder asD8TestBuilder() {
+ return this;
+ }
+
+ @Override
D8TestBuilder self() {
return this;
}
@@ -118,4 +129,16 @@
getBuilder().setProguardMapConsumer((s, h) -> proguardMapOutputBuilder.append(s));
return self();
}
+
+ public D8TestBuilder addStartupProfileProviders(
+ StartupProfileProvider... startupProfileProviders) {
+ builder.addStartupProfileProviders(startupProfileProviders);
+ return self();
+ }
+
+ public D8TestBuilder addStartupProfileProviders(
+ Collection<StartupProfileProvider> startupProfileProviders) {
+ builder.addStartupProfileProviders(startupProfileProviders);
+ return self();
+ }
}
diff --git a/src/test/java/com/android/tools/r8/R8TestBuilder.java b/src/test/java/com/android/tools/r8/R8TestBuilder.java
index 824203a..53ff395 100644
--- a/src/test/java/com/android/tools/r8/R8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/R8TestBuilder.java
@@ -28,6 +28,7 @@
import com.android.tools.r8.shaking.NoVerticalClassMergingRule;
import com.android.tools.r8.shaking.ProguardConfiguration;
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.FileUtils;
import com.android.tools.r8.utils.InternalOptions;
@@ -72,6 +73,16 @@
private boolean createDefaultProguardMapConsumer = true;
@Override
+ public boolean isR8TestBuilder() {
+ return true;
+ }
+
+ @Override
+ public R8TestBuilder<?> asR8TestBuilder() {
+ return this;
+ }
+
+ @Override
R8TestCompileResult internalCompile(
Builder builder,
Consumer<InternalOptions> optionsConsumer,
@@ -766,4 +777,14 @@
createDefaultProguardMapConsumer = false;
return self();
}
+
+ public T addStartupProfileProviders(StartupProfileProvider... startupProfileProviders) {
+ builder.addStartupProfileProviders(startupProfileProviders);
+ return self();
+ }
+
+ public T addStartupProfileProviders(Collection<StartupProfileProvider> startupProfileProviders) {
+ builder.addStartupProfileProviders(startupProfileProviders);
+ return self();
+ }
}
diff --git a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
index 5d9d7f5..141f879 100644
--- a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
@@ -91,6 +91,22 @@
LibraryDesugaringTestConfiguration libraryDesugaringTestConfiguration =
LibraryDesugaringTestConfiguration.DISABLED;
+ public boolean isD8TestBuilder() {
+ return false;
+ }
+
+ public D8TestBuilder asD8TestBuilder() {
+ return null;
+ }
+
+ public boolean isR8TestBuilder() {
+ return false;
+ }
+
+ public R8TestBuilder<?> asR8TestBuilder() {
+ return null;
+ }
+
public boolean isTestShrinkerBuilder() {
return false;
}
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/HorizontalClassMergingWithStartupClassesTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/HorizontalClassMergingWithStartupClassesTest.java
index f9b2f74..8546374 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/HorizontalClassMergingWithStartupClassesTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/HorizontalClassMergingWithStartupClassesTest.java
@@ -48,31 +48,6 @@
testForR8(parameters.getBackend())
.addInnerClasses(getClass())
.addKeepClassAndMembersRules(Main.class)
- .addOptionsModification(
- options -> {
- StartupProfileProvider startupProfileProvider =
- new StartupProfileProvider() {
-
- @Override
- public void getStartupProfile(StartupProfileBuilder startupProfileBuilder) {
- for (Class<?> startupClass : getStartupClasses()) {
- ClassReference startupClassReference =
- Reference.classFromClass(startupClass);
- startupProfileBuilder.addStartupClass(
- startupClassBuilder ->
- startupClassBuilder.setClassReference(startupClassReference));
- }
- }
-
- @Override
- public Origin getOrigin() {
- return Origin.unknown();
- }
- };
- options
- .getStartupOptions()
- .setStartupProfileProviders(Collections.singleton(startupProfileProvider));
- })
.addHorizontallyMergedClassesInspector(
inspector ->
inspector
@@ -89,6 +64,24 @@
.assertIsCompleteMergeGroup(
OnClickHandlerA.class, OnClickHandlerB.class))
.assertNoOtherClassesMerged())
+ .addStartupProfileProviders(
+ new StartupProfileProvider() {
+
+ @Override
+ public void getStartupProfile(StartupProfileBuilder startupProfileBuilder) {
+ for (Class<?> startupClass : getStartupClasses()) {
+ ClassReference startupClassReference = Reference.classFromClass(startupClass);
+ startupProfileBuilder.addStartupClass(
+ startupClassBuilder ->
+ startupClassBuilder.setClassReference(startupClassReference));
+ }
+ }
+
+ @Override
+ public Origin getOrigin() {
+ return Origin.unknown();
+ }
+ })
.enableInliningAnnotations()
.setMinApi(parameters.getApiLevel())
.compile()
diff --git a/src/test/java/com/android/tools/r8/internal/YouTubeV1719Test.java b/src/test/java/com/android/tools/r8/internal/YouTubeV1719Test.java
index 35ef96e..dbeb66b 100644
--- a/src/test/java/com/android/tools/r8/internal/YouTubeV1719Test.java
+++ b/src/test/java/com/android/tools/r8/internal/YouTubeV1719Test.java
@@ -38,7 +38,6 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
-import java.util.Collections;
import java.util.concurrent.ExecutionException;
import org.junit.After;
import org.junit.Test;
@@ -145,18 +144,20 @@
R8TestCompileResult r8CompileResult =
compileApplicationWithR8(
testBuilder ->
- testBuilder.addOptionsModification(
- options -> {
- if (startupProfileProvider != null) {
- options
- .getStartupOptions()
- .setStartupProfileProviders(
- Collections.singleton(startupProfileProvider))
- .setEnableMinimalStartupDex(enableMinimalStartupDex)
- .setEnableStartupBoundaryOptimizations(
- enableStartupBoundaryOptimizations);
- }
- }));
+ testBuilder
+ .addOptionsModification(
+ options -> {
+ if (startupProfileProvider != null) {
+ options
+ .getStartupOptions()
+ .setEnableMinimalStartupDex(enableMinimalStartupDex)
+ .setEnableStartupBoundaryOptimizations(
+ enableStartupBoundaryOptimizations);
+ }
+ })
+ .applyIf(
+ startupProfileProvider != null,
+ b -> b.addStartupProfileProviders(startupProfileProvider)));
// Compile desugared library using cf backend (without keep rules).
L8TestCompileResult l8CompileResult = compileDesugaredLibraryWithL8();
diff --git a/src/test/java/com/android/tools/r8/internal/startup/ChromeStartupTest.java b/src/test/java/com/android/tools/r8/internal/startup/ChromeStartupTest.java
index 051126a..f6ac982 100644
--- a/src/test/java/com/android/tools/r8/internal/startup/ChromeStartupTest.java
+++ b/src/test/java/com/android/tools/r8/internal/startup/ChromeStartupTest.java
@@ -19,7 +19,6 @@
import com.android.tools.r8.ThrowableConsumer;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.experimental.startup.StartupProfileProviderUtils;
-import com.android.tools.r8.startup.StartupProfileProvider;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.ZipUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
@@ -27,7 +26,6 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
-import java.util.Collections;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -236,18 +234,19 @@
boolean enableStartupBoundaryOptimizations,
Path outDirectory)
throws Exception {
- StartupProfileProvider startupProfileProvider =
- StartupProfileProviderUtils.createFromHumanReadableARTProfile(
- chromeDirectory.resolve("startup.txt"));
buildR8(
testBuilder ->
- testBuilder.addOptionsModification(
- options ->
- options
- .getStartupOptions()
- .setEnableMinimalStartupDex(enableMinimalStartupDex)
- .setEnableStartupBoundaryOptimizations(enableStartupBoundaryOptimizations)
- .setStartupProfileProviders(Collections.singleton(startupProfileProvider))),
+ testBuilder
+ .addOptionsModification(
+ options ->
+ options
+ .getStartupOptions()
+ .setEnableMinimalStartupDex(enableMinimalStartupDex)
+ .setEnableStartupBoundaryOptimizations(
+ enableStartupBoundaryOptimizations))
+ .addStartupProfileProviders(
+ StartupProfileProviderUtils.createFromHumanReadableARTProfile(
+ chromeDirectory.resolve("startup.txt"))),
outDirectory);
}
diff --git a/src/test/java/com/android/tools/r8/startup/diagnostic/MissingStartupProfileItemsDiagnosticTest.java b/src/test/java/com/android/tools/r8/startup/diagnostic/MissingStartupProfileItemsDiagnosticTest.java
index f687df4..60cf897 100644
--- a/src/test/java/com/android/tools/r8/startup/diagnostic/MissingStartupProfileItemsDiagnosticTest.java
+++ b/src/test/java/com/android/tools/r8/startup/diagnostic/MissingStartupProfileItemsDiagnosticTest.java
@@ -44,11 +44,7 @@
public void testD8() throws Exception {
testForD8(Backend.DEX)
.addProgramClasses(Main.class)
- .addOptionsModification(
- options ->
- options
- .getStartupOptions()
- .setStartupProfileProviders(getStartupProfileProviders()))
+ .addStartupProfileProviders(getStartupProfileProviders())
.release()
.setIntermediate(true)
.setMinApi(AndroidApiLevel.LATEST)
@@ -60,11 +56,7 @@
testForR8(Backend.DEX)
.addProgramClasses(Main.class)
.addKeepMainRule(Main.class)
- .addOptionsModification(
- options ->
- options
- .getStartupOptions()
- .setStartupProfileProviders(getStartupProfileProviders()))
+ .addStartupProfileProviders(getStartupProfileProviders())
.allowDiagnosticWarningMessages()
.setMinApi(AndroidApiLevel.LATEST)
.compileWithExpectedDiagnostics(this::inspectDiagnostics);
diff --git a/src/test/java/com/android/tools/r8/startup/dump/DumpStartupProfileProvidersTest.java b/src/test/java/com/android/tools/r8/startup/dump/DumpStartupProfileProvidersTest.java
new file mode 100644
index 0000000..f2cb975
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/startup/dump/DumpStartupProfileProvidersTest.java
@@ -0,0 +1,127 @@
+// 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.startup.dump;
+
+import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.startup.StartupProfileBuilder;
+import com.android.tools.r8.startup.StartupProfileProvider;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.DumpInputFlags;
+import com.android.tools.r8.utils.FileUtils;
+import com.android.tools.r8.utils.MethodReferenceUtils;
+import com.android.tools.r8.utils.ZipUtils;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collection;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class DumpStartupProfileProvidersTest extends TestBase {
+
+ @Parameter(0)
+ public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withNoneRuntime().build();
+ }
+
+ @Test
+ public void test() throws Exception {
+ Path dump = temp.newFile("dump.zip").toPath();
+ try {
+ testForR8(Backend.DEX)
+ .addProgramClasses(Main.class)
+ .addKeepMainRule(Main.class)
+ .addOptionsModification(
+ options -> options.setDumpInputFlags(DumpInputFlags.dumpToFile(dump)))
+ .addStartupProfileProviders(getStartupProfileProviders())
+ .allowDiagnosticErrorMessages()
+ .setMinApi(AndroidApiLevel.LATEST)
+ .compileWithExpectedDiagnostics(
+ diagnostics ->
+ diagnostics.assertErrorsMatch(
+ diagnosticMessage(containsString("Dumped compilation inputs to:"))));
+ fail("Expected compilation to fail");
+ } catch (CompilationFailedException e) {
+ // Expected.
+ }
+ verifyDump(dump);
+ }
+
+ private Collection<StartupProfileProvider> getStartupProfileProviders() {
+ return ImmutableList.of(
+ new StartupProfileProvider() {
+
+ @Override
+ public void getStartupProfile(StartupProfileBuilder startupProfileBuilder) {
+ startupProfileBuilder.addStartupClass(
+ startupClassBuilder ->
+ startupClassBuilder.setClassReference(Reference.classFromClass(Main.class)));
+ }
+
+ @Override
+ public Origin getOrigin() {
+ return Origin.unknown();
+ }
+ },
+ new StartupProfileProvider() {
+
+ @Override
+ public void getStartupProfile(StartupProfileBuilder startupProfileBuilder) {
+ startupProfileBuilder.addStartupMethod(
+ startupMethodBuilder ->
+ startupMethodBuilder.setMethodReference(
+ MethodReferenceUtils.mainMethod(Main.class)));
+ }
+
+ @Override
+ public Origin getOrigin() {
+ return Origin.unknown();
+ }
+ });
+ }
+
+ private void verifyDump(Path dump) throws IOException {
+ assertTrue(Files.exists(dump));
+ Path unzipped = temp.newFolder().toPath();
+ ZipUtils.unzip(dump.toString(), unzipped.toFile());
+
+ Path startupProfile1 = unzipped.resolve("startup-profile-1.txt");
+ assertTrue(Files.exists(startupProfile1));
+ assertEquals(
+ Lists.newArrayList(Reference.classFromClass(Main.class).getDescriptor()),
+ FileUtils.readAllLines(startupProfile1));
+
+ Path startupProfile2 = unzipped.resolve("startup-profile-2.txt");
+ assertTrue(Files.exists(startupProfile2));
+ assertEquals(
+ Lists.newArrayList(
+ MethodReferenceUtils.toSmaliString(MethodReferenceUtils.mainMethod(Main.class))),
+ FileUtils.readAllLines(startupProfile2));
+ }
+
+ static class Main {
+
+ public static void main(String[] args) {}
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/startup/utils/StartupTestingUtils.java b/src/test/java/com/android/tools/r8/startup/utils/StartupTestingUtils.java
index d81aadf..7007c61 100644
--- a/src/test/java/com/android/tools/r8/startup/utils/StartupTestingUtils.java
+++ b/src/test/java/com/android/tools/r8/startup/utils/StartupTestingUtils.java
@@ -42,7 +42,6 @@
import java.io.IOException;
import java.nio.file.Path;
import java.util.Collection;
-import java.util.Collections;
import java.util.function.Consumer;
import org.junit.rules.TemporaryFolder;
@@ -190,41 +189,40 @@
public static void setStartupConfiguration(
TestCompilerBuilder<?, ?, ?, ?, ?> testBuilder,
Collection<ExternalStartupItem> startupItems) {
- testBuilder.addOptionsModification(
- options -> {
- StartupProfileProvider startupProfileProvider =
- new StartupProfileProvider() {
- @Override
- public void getStartupProfile(StartupProfileBuilder startupProfileBuilder) {
- for (ExternalStartupItem startupItem : startupItems) {
- startupItem.apply(
- startupClass ->
- startupProfileBuilder.addStartupClass(
- startupClassBuilder ->
- startupClassBuilder.setClassReference(
- startupClass.getReference())),
- startupMethod ->
- startupProfileBuilder.addStartupMethod(
- startupMethodBuilder ->
- startupMethodBuilder.setMethodReference(
- startupMethod.getReference())),
- syntheticStartupMethod ->
- startupProfileBuilder.addSyntheticStartupMethod(
- syntheticStartupMethodBuilder ->
- syntheticStartupMethodBuilder.setSyntheticContextReference(
- syntheticStartupMethod.getSyntheticContextReference())));
- }
- }
+ StartupProfileProvider startupProfileProvider =
+ new StartupProfileProvider() {
+ @Override
+ public void getStartupProfile(StartupProfileBuilder startupProfileBuilder) {
+ for (ExternalStartupItem startupItem : startupItems) {
+ startupItem.apply(
+ startupClass ->
+ startupProfileBuilder.addStartupClass(
+ startupClassBuilder ->
+ startupClassBuilder.setClassReference(startupClass.getReference())),
+ startupMethod ->
+ startupProfileBuilder.addStartupMethod(
+ startupMethodBuilder ->
+ startupMethodBuilder.setMethodReference(
+ startupMethod.getReference())),
+ syntheticStartupMethod ->
+ startupProfileBuilder.addSyntheticStartupMethod(
+ syntheticStartupMethodBuilder ->
+ syntheticStartupMethodBuilder.setSyntheticContextReference(
+ syntheticStartupMethod.getSyntheticContextReference())));
+ }
+ }
- @Override
- public Origin getOrigin() {
- return Origin.unknown();
- }
- };
- options
- .getStartupOptions()
- .setStartupProfileProviders(Collections.singleton(startupProfileProvider));
- });
+ @Override
+ public Origin getOrigin() {
+ return Origin.unknown();
+ }
+ };
+ if (testBuilder.isD8TestBuilder()) {
+ testBuilder.asD8TestBuilder().addStartupProfileProviders(startupProfileProvider);
+ } else {
+ assertTrue(testBuilder.isR8TestBuilder());
+ testBuilder.asR8TestBuilder().addStartupProfileProviders(startupProfileProvider);
+ }
}
private static byte[] getTransformedAndroidUtilLog() throws IOException {