Implement new startup API
Change-Id: I32b5999179c4e5cbb8e95dd91659b25e07eaef4d
diff --git a/src/main/java/com/android/tools/r8/D8Command.java b/src/main/java/com/android/tools/r8/D8Command.java
index 172bfa2..24df37d 100644
--- a/src/main/java/com/android/tools/r8/D8Command.java
+++ b/src/main/java/com/android/tools/r8/D8Command.java
@@ -690,10 +690,7 @@
internal.configureAndroidPlatformBuild(getAndroidPlatformBuild());
- // TODO(b/238173796): Change StartupOptions to store a Collection<StartupProfileProvider>.
- if (getStartupProfileProviders().size() == 1) {
- internal.getStartupOptions().setStartupProfileProvider(getStartupProfileProviders().get(0));
- }
+ internal.getStartupOptions().setStartupProfileProviders(getStartupProfileProviders());
internal.setDumpInputFlags(getDumpInputFlags());
internal.dumpOptions = dumpOptions();
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index 6adecce..c9fd4f2 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -1067,10 +1067,7 @@
internal.configureAndroidPlatformBuild(getAndroidPlatformBuild());
- // TODO(b/238173796): Change StartupOptions to store a Collection<StartupProfileProvider>.
- if (getStartupProfileProviders().size() == 1) {
- internal.getStartupOptions().setStartupProfileProvider(getStartupProfileProviders().get(0));
- }
+ internal.getStartupOptions().setStartupProfileProviders(getStartupProfileProviders());
if (!DETERMINISTIC_DEBUGGING) {
assert internal.threadCount == ThreadUtils.NOT_SPECIFIED;
diff --git a/src/main/java/com/android/tools/r8/StringResource.java b/src/main/java/com/android/tools/r8/StringResource.java
index 515f2ab..4d097e0 100644
--- a/src/main/java/com/android/tools/r8/StringResource.java
+++ b/src/main/java/com/android/tools/r8/StringResource.java
@@ -105,13 +105,5 @@
throw new ResourceException(origin, e);
}
}
-
- public String getStringWithRuntimeException() {
- try {
- return getString();
- } catch (ResourceException e) {
- throw new RuntimeException(e);
- }
- }
}
}
diff --git a/src/main/java/com/android/tools/r8/dex/StartupMixedSectionLayoutStrategy.java b/src/main/java/com/android/tools/r8/dex/StartupMixedSectionLayoutStrategy.java
index 4d9a8ca..0833358 100644
--- a/src/main/java/com/android/tools/r8/dex/StartupMixedSectionLayoutStrategy.java
+++ b/src/main/java/com/android/tools/r8/dex/StartupMixedSectionLayoutStrategy.java
@@ -82,21 +82,23 @@
virtualFile.classes().size());
LensCodeRewriterUtils rewriter = new LensCodeRewriterUtils(appView, true);
StartupIndexedItemCollection indexedItemCollection = new StartupIndexedItemCollection();
- for (StartupItem<DexType, DexMethod, ?> startupItem : startupOrderForWriting.getItems()) {
- // All synthetic startup items should be removed after calling
- // StartupOrder#toStartupOrderForWriting.
- assert !startupItem.isSynthetic();
+ for (StartupItem startupItem : startupOrderForWriting.getItems()) {
startupItem.accept(
startupClass ->
collectStartupItems(startupClass, indexedItemCollection, virtualFileDefinitions),
startupMethod ->
collectStartupItems(
- startupMethod, indexedItemCollection, virtualFileDefinitions, rewriter));
+ startupMethod, indexedItemCollection, virtualFileDefinitions, rewriter),
+ syntheticStartupMethod -> {
+ // All synthetic startup items should be removed after calling
+ // StartupOrder#toStartupOrderForWriting.
+ assert false;
+ });
}
}
private void collectStartupItems(
- StartupClass<DexType, DexMethod> startupClass,
+ StartupClass startupClass,
StartupIndexedItemCollection indexedItemCollection,
Map<DexType, DexProgramClass> virtualFileDefinitions) {
DexProgramClass definition = virtualFileDefinitions.get(startupClass.getReference());
@@ -119,7 +121,7 @@
}
private void collectStartupItems(
- StartupMethod<DexType, DexMethod> startupMethod,
+ StartupMethod startupMethod,
StartupIndexedItemCollection indexedItemCollection,
Map<DexType, DexProgramClass> virtualFileDefinitions,
LensCodeRewriterUtils rewriter) {
diff --git a/src/main/java/com/android/tools/r8/dex/VirtualFile.java b/src/main/java/com/android/tools/r8/dex/VirtualFile.java
index fafe700..f6b057a 100644
--- a/src/main/java/com/android/tools/r8/dex/VirtualFile.java
+++ b/src/main/java/com/android/tools/r8/dex/VirtualFile.java
@@ -1396,7 +1396,7 @@
return;
}
- assert options.getStartupOptions().hasStartupProfileProvider();
+ assert options.getStartupOptions().hasStartupProfileProviders();
// In practice, all startup classes should fit in a single dex file, so optimistically try to
// commit the startup classes using a single transaction.
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/EmptyStartupOrder.java b/src/main/java/com/android/tools/r8/experimental/startup/EmptyStartupOrder.java
index 8913368..fb1fc24 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/EmptyStartupOrder.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/EmptyStartupOrder.java
@@ -6,7 +6,6 @@
import com.android.tools.r8.experimental.startup.profile.StartupItem;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.PrunedItems;
@@ -24,7 +23,7 @@
}
@Override
- public Collection<StartupItem<DexType, DexMethod, ?>> getItems() {
+ public Collection<StartupItem> getItems() {
return Collections.emptyList();
}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/NonEmptyStartupOrder.java b/src/main/java/com/android/tools/r8/experimental/startup/NonEmptyStartupOrder.java
index 164475b..76020fc 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/NonEmptyStartupOrder.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/NonEmptyStartupOrder.java
@@ -7,11 +7,10 @@
import com.android.tools.r8.experimental.startup.profile.StartupClass;
import com.android.tools.r8.experimental.startup.profile.StartupItem;
import com.android.tools.r8.experimental.startup.profile.StartupMethod;
+import com.android.tools.r8.experimental.startup.profile.SyntheticStartupMethod;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
-import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.PrunedItems;
@@ -28,24 +27,22 @@
public class NonEmptyStartupOrder extends StartupOrder {
- private final LinkedHashSet<StartupItem<DexType, DexMethod, ?>> startupItems;
+ private final LinkedHashSet<StartupItem> startupItems;
// Sets to allow efficient querying without boxing.
private final Set<DexType> nonSyntheticStartupClasses = Sets.newIdentityHashSet();
private final Set<DexType> syntheticStartupClasses = Sets.newIdentityHashSet();
- NonEmptyStartupOrder(LinkedHashSet<StartupItem<DexType, DexMethod, ?>> startupItems) {
+ NonEmptyStartupOrder(LinkedHashSet<StartupItem> startupItems) {
assert !startupItems.isEmpty();
this.startupItems = startupItems;
- for (StartupItem<DexType, DexMethod, ?> startupItem : startupItems) {
- if (startupItem.isSynthetic()) {
- assert startupItem.isStartupClass();
- syntheticStartupClasses.add(startupItem.asStartupClass().getReference());
- } else {
- DexReference reference =
- startupItem.apply(StartupClass::getReference, StartupMethod::getReference);
- nonSyntheticStartupClasses.add(reference.getContextType());
- }
+ for (StartupItem startupItem : startupItems) {
+ startupItem.apply(
+ startupClass -> nonSyntheticStartupClasses.add(startupClass.getReference()),
+ startupMethod ->
+ nonSyntheticStartupClasses.add(startupMethod.getReference().getHolderType()),
+ syntheticStartupMethod ->
+ syntheticStartupClasses.add(syntheticStartupMethod.getSyntheticContextType()));
}
}
@@ -72,7 +69,7 @@
}
@Override
- public Collection<StartupItem<DexType, DexMethod, ?>> getItems() {
+ public Collection<StartupItem> getItems() {
return startupItems;
}
@@ -83,27 +80,28 @@
@Override
public StartupOrder rewrittenWithLens(GraphLens graphLens) {
- LinkedHashSet<StartupItem<DexType, DexMethod, ?>> rewrittenStartupItems =
- new LinkedHashSet<>(startupItems.size());
- for (StartupItem<DexType, DexMethod, ?> startupItem : startupItems) {
- if (startupItem.isStartupClass()) {
- StartupClass<DexType, DexMethod> startupClass = startupItem.asStartupClass();
- rewrittenStartupItems.add(
- StartupClass.dexBuilder()
- .setClassReference(graphLens.lookupType(startupClass.getReference()))
- .setSynthetic(startupItem.isSynthetic())
- .build());
- } else {
- assert !startupItem.isSynthetic();
- StartupMethod<DexType, DexMethod> startupMethod = startupItem.asStartupMethod();
- // TODO(b/238173796): This should account for one-to-many mappings. e.g., when a bridge is
- // created.
- rewrittenStartupItems.add(
- StartupMethod.dexBuilder()
- .setMethodReference(
- graphLens.getRenamedMethodSignature(startupMethod.getReference()))
- .build());
- }
+ LinkedHashSet<StartupItem> rewrittenStartupItems = new LinkedHashSet<>(startupItems.size());
+ for (StartupItem startupItem : startupItems) {
+ // TODO(b/238173796): This should account for one-to-many mappings. e.g., when a bridge is
+ // created.
+ startupItem.apply(
+ startupClass ->
+ rewrittenStartupItems.add(
+ StartupClass.builder()
+ .setClassReference(graphLens.lookupType(startupClass.getReference()))
+ .build()),
+ startupMethod ->
+ rewrittenStartupItems.add(
+ StartupMethod.builder()
+ .setMethodReference(
+ graphLens.getRenamedMethodSignature(startupMethod.getReference()))
+ .build()),
+ syntheticStartupMethod ->
+ rewrittenStartupItems.add(
+ SyntheticStartupMethod.builder()
+ .setSyntheticContextReference(
+ graphLens.lookupType(syntheticStartupMethod.getSyntheticContextType()))
+ .build()));
}
return createNonEmpty(rewrittenStartupItems);
}
@@ -129,29 +127,27 @@
*/
@Override
public StartupOrder toStartupOrderForWriting(AppView<?> appView) {
- LinkedHashSet<StartupItem<DexType, DexMethod, ?>> rewrittenStartupItems =
- new LinkedHashSet<>(startupItems.size());
+ LinkedHashSet<StartupItem> rewrittenStartupItems = new LinkedHashSet<>(startupItems.size());
Map<DexType, List<DexProgramClass>> syntheticContextsToSyntheticClasses =
appView.getSyntheticItems().computeSyntheticContextsToSyntheticClasses(appView);
- for (StartupItem<DexType, DexMethod, ?> startupItem : startupItems) {
+ for (StartupItem startupItem : startupItems) {
addStartupItem(
startupItem, rewrittenStartupItems, syntheticContextsToSyntheticClasses, appView);
}
- assert rewrittenStartupItems.stream().noneMatch(StartupItem::isSynthetic);
+ assert rewrittenStartupItems.stream().noneMatch(StartupItem::isSyntheticStartupMethod);
return createNonEmpty(rewrittenStartupItems);
}
private static void addStartupItem(
- StartupItem<DexType, DexMethod, ?> startupItem,
- LinkedHashSet<StartupItem<DexType, DexMethod, ?>> rewrittenStartupItems,
+ StartupItem startupItem,
+ LinkedHashSet<StartupItem> rewrittenStartupItems,
Map<DexType, List<DexProgramClass>> syntheticContextsToSyntheticClasses,
AppView<?> appView) {
- if (startupItem.isSynthetic()) {
- assert startupItem.isStartupClass();
- StartupClass<DexType, DexMethod> startupClass = startupItem.asStartupClass();
+ if (startupItem.isSyntheticStartupMethod()) {
+ SyntheticStartupMethod syntheticStartupMethod = startupItem.asSyntheticStartupMethod();
List<DexProgramClass> syntheticClassesForContext =
syntheticContextsToSyntheticClasses.getOrDefault(
- startupClass.getReference(), Collections.emptyList());
+ syntheticStartupMethod.getSyntheticContextType(), Collections.emptyList());
for (DexProgramClass clazz : syntheticClassesForContext) {
addClassAndParentClasses(clazz, rewrittenStartupItems, appView);
addAllMethods(clazz, rewrittenStartupItems);
@@ -167,16 +163,13 @@
}
private static boolean addClass(
- DexProgramClass clazz,
- LinkedHashSet<StartupItem<DexType, DexMethod, ?>> rewrittenStartupItems) {
+ DexProgramClass clazz, LinkedHashSet<StartupItem> rewrittenStartupItems) {
return rewrittenStartupItems.add(
- StartupClass.dexBuilder().setClassReference(clazz.getType()).build());
+ StartupClass.builder().setClassReference(clazz.getType()).build());
}
private static void addClassAndParentClasses(
- DexType type,
- LinkedHashSet<StartupItem<DexType, DexMethod, ?>> rewrittenStartupItems,
- AppView<?> appView) {
+ DexType type, LinkedHashSet<StartupItem> rewrittenStartupItems, AppView<?> appView) {
DexProgramClass definition = appView.app().programDefinitionFor(type);
if (definition != null) {
addClassAndParentClasses(definition, rewrittenStartupItems, appView);
@@ -184,54 +177,53 @@
}
private static void addClassAndParentClasses(
- DexProgramClass clazz,
- LinkedHashSet<StartupItem<DexType, DexMethod, ?>> rewrittenStartupItems,
- AppView<?> appView) {
+ DexProgramClass clazz, LinkedHashSet<StartupItem> rewrittenStartupItems, AppView<?> appView) {
if (addClass(clazz, rewrittenStartupItems)) {
addParentClasses(clazz, rewrittenStartupItems, appView);
}
}
private static void addParentClasses(
- DexProgramClass clazz,
- LinkedHashSet<StartupItem<DexType, DexMethod, ?>> rewrittenStartupItems,
- AppView<?> appView) {
+ DexProgramClass clazz, LinkedHashSet<StartupItem> rewrittenStartupItems, AppView<?> appView) {
clazz.forEachImmediateSupertype(
supertype -> addClassAndParentClasses(supertype, rewrittenStartupItems, appView));
}
private static void addAllMethods(
- DexProgramClass clazz,
- LinkedHashSet<StartupItem<DexType, DexMethod, ?>> rewrittenStartupItems) {
+ DexProgramClass clazz, LinkedHashSet<StartupItem> rewrittenStartupItems) {
clazz.forEachProgramMethod(
method ->
rewrittenStartupItems.add(
- StartupMethod.dexBuilder().setMethodReference(method.getReference()).build()));
+ StartupMethod.builder().setMethodReference(method.getReference()).build()));
}
@Override
public StartupOrder withoutPrunedItems(PrunedItems prunedItems, SyntheticItems syntheticItems) {
- LinkedHashSet<StartupItem<DexType, DexMethod, ?>> rewrittenStartupItems =
- new LinkedHashSet<>(startupItems.size());
+ LinkedHashSet<StartupItem> rewrittenStartupItems = new LinkedHashSet<>(startupItems.size());
LazyBox<Set<DexType>> contextsOfLiveSynthetics =
new LazyBox<>(
() -> computeContextsOfLiveSynthetics(prunedItems.getPrunedApp(), syntheticItems));
- for (StartupItem<DexType, DexMethod, ?> startupItem : startupItems) {
+ for (StartupItem startupItem : startupItems) {
// Only prune non-synthetic classes, since the pruning of a class does not imply that all
// classes synthesized from it have been pruned.
- if (startupItem.isSynthetic()) {
- assert startupItem.isStartupClass();
- StartupClass<DexType, DexMethod> startupClass = startupItem.asStartupClass();
- if (contextsOfLiveSynthetics.computeIfAbsent().contains(startupClass.getReference())) {
- rewrittenStartupItems.add(startupClass);
- }
- } else {
- DexReference reference =
- startupItem.apply(StartupClass::getReference, StartupMethod::getReference);
- if (!prunedItems.isRemoved(reference)) {
- rewrittenStartupItems.add(startupItem);
- }
- }
+ startupItem.accept(
+ startupClass -> {
+ if (!prunedItems.isRemoved(startupClass.getReference())) {
+ rewrittenStartupItems.add(startupItem);
+ }
+ },
+ startupMethod -> {
+ if (!prunedItems.isRemoved(startupMethod.getReference())) {
+ rewrittenStartupItems.add(startupItem);
+ }
+ },
+ syntheticStartupMethod -> {
+ if (contextsOfLiveSynthetics
+ .computeIfAbsent()
+ .contains(syntheticStartupMethod.getSyntheticContextType())) {
+ rewrittenStartupItems.add(syntheticStartupMethod);
+ }
+ });
}
return createNonEmpty(rewrittenStartupItems);
}
@@ -248,8 +240,7 @@
return contextsOfLiveSynthetics;
}
- private StartupOrder createNonEmpty(
- LinkedHashSet<StartupItem<DexType, DexMethod, ?>> startupItems) {
+ private StartupOrder createNonEmpty(LinkedHashSet<StartupItem> startupItems) {
if (startupItems.isEmpty()) {
assert false;
return empty();
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/StartupCompleteness.java b/src/main/java/com/android/tools/r8/experimental/startup/StartupCompleteness.java
index 43e306a..e6a0f85 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/StartupCompleteness.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/StartupCompleteness.java
@@ -4,12 +4,9 @@
package com.android.tools.r8.experimental.startup;
-import com.android.tools.r8.experimental.startup.profile.StartupClass;
import com.android.tools.r8.experimental.startup.profile.StartupItem;
-import com.android.tools.r8.experimental.startup.profile.StartupMethod;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
@@ -81,26 +78,20 @@
Set<DexReference> startupItems = Sets.newIdentityHashSet();
Map<DexType, List<DexProgramClass>> syntheticContextsToSyntheticClasses =
appView.getSyntheticItems().computeSyntheticContextsToSyntheticClasses(appView);
- for (StartupItem<DexType, DexMethod, ?> startupItem : startupOrder.getItems()) {
- if (startupItem.isSynthetic()) {
- assert startupItem.isStartupClass();
- List<DexProgramClass> syntheticClasses =
- syntheticContextsToSyntheticClasses.getOrDefault(
- startupItem.asStartupClass().getReference(), Collections.emptyList());
- for (DexProgramClass syntheticClass : syntheticClasses) {
- startupItems.add(syntheticClass.getType());
- syntheticClass.forEachProgramMethod(method -> startupItems.add(method.getReference()));
- }
- } else {
- if (startupItem.isStartupClass()) {
- StartupClass<DexType, DexMethod> startupClass = startupItem.asStartupClass();
- startupItems.add(startupClass.getReference());
- } else {
- assert startupItem.isStartupMethod();
- StartupMethod<DexType, DexMethod> startupMethod = startupItem.asStartupMethod();
- startupItems.add(startupMethod.getReference());
- }
- }
+ for (StartupItem startupItem : startupOrder.getItems()) {
+ startupItem.accept(
+ startupClass -> startupItems.add(startupClass.getReference()),
+ startupMethod -> startupItems.add(startupMethod.getReference()),
+ syntheticStartupMethod -> {
+ List<DexProgramClass> syntheticClasses =
+ syntheticContextsToSyntheticClasses.getOrDefault(
+ syntheticStartupMethod.getSyntheticContextType(), Collections.emptyList());
+ for (DexProgramClass syntheticClass : syntheticClasses) {
+ startupItems.add(syntheticClass.getType());
+ syntheticClass.forEachProgramMethod(
+ method -> startupItems.add(method.getReference()));
+ }
+ });
}
return startupItems;
}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/StartupOptions.java b/src/main/java/com/android/tools/r8/experimental/startup/StartupOptions.java
index 86df003..01bfd2b 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/StartupOptions.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/StartupOptions.java
@@ -6,13 +6,13 @@
import static com.android.tools.r8.utils.SystemPropertyUtils.parseSystemPropertyForDevelopmentOrDefault;
-import com.android.tools.r8.StringResource;
-import com.android.tools.r8.errors.Unimplemented;
-import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.startup.StartupProfileBuilder;
import com.android.tools.r8.startup.StartupProfileProvider;
+import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.SystemPropertyUtils;
+import com.google.common.collect.ImmutableList;
import java.nio.file.Paths;
+import java.util.Collection;
+import java.util.Collections;
public class StartupOptions {
@@ -52,28 +52,18 @@
private boolean enableStartupLayoutOptimizations =
parseSystemPropertyForDevelopmentOrDefault("com.android.tools.r8.startup.layout", true);
- private StartupProfileProvider startupProfileProvider =
- SystemPropertyUtils.applySystemProperty(
- "com.android.tools.r8.startup.profile",
- propertyValue ->
- new StartupProfileProvider() {
- @Override
- public String get() {
- return StringResource.fromFile(Paths.get(propertyValue))
- .getStringWithRuntimeException();
- }
+ private Collection<StartupProfileProvider> startupProfileProviders;
- @Override
- public void getStartupProfile(StartupProfileBuilder startupProfileBuilder) {
- throw new Unimplemented();
- }
-
- @Override
- public Origin getOrigin() {
- return Origin.unknown();
- }
- },
- () -> null);
+ public StartupOptions(InternalOptions options) {
+ this.startupProfileProviders =
+ SystemPropertyUtils.applySystemProperty(
+ "com.android.tools.r8.startup.profile",
+ propertyValue ->
+ ImmutableList.of(
+ StartupProfileProviderUtils.createFromFile(
+ Paths.get(propertyValue), options.reporter)),
+ Collections::emptyList);
+ }
public boolean isMinimalStartupDexEnabled() {
return enableMinimalStartupDex;
@@ -112,16 +102,17 @@
return this;
}
- public boolean hasStartupProfileProvider() {
- return startupProfileProvider != null;
+ public boolean hasStartupProfileProviders() {
+ return startupProfileProviders != null && !startupProfileProviders.isEmpty();
}
- public StartupProfileProvider getStartupProfileProvider() {
- return startupProfileProvider;
+ public Collection<StartupProfileProvider> getStartupProfileProviders() {
+ return startupProfileProviders;
}
- public StartupOptions setStartupProfileProvider(StartupProfileProvider startupProfileProvider) {
- this.startupProfileProvider = startupProfileProvider;
+ public StartupOptions setStartupProfileProviders(
+ Collection<StartupProfileProvider> startupProfileProviders) {
+ this.startupProfileProviders = startupProfileProviders;
return this;
}
}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/StartupOrder.java b/src/main/java/com/android/tools/r8/experimental/startup/StartupOrder.java
index aa3d454..78a5970 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/StartupOrder.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/StartupOrder.java
@@ -7,7 +7,6 @@
import com.android.tools.r8.experimental.startup.profile.StartupItem;
import com.android.tools.r8.experimental.startup.profile.StartupProfile;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.PrunedItems;
@@ -34,7 +33,7 @@
public abstract boolean contains(DexType type, SyntheticItems syntheticItems);
- public abstract Collection<StartupItem<DexType, DexMethod, ?>> getItems();
+ public abstract Collection<StartupItem> getItems();
public abstract boolean isEmpty();
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
new file mode 100644
index 0000000..2924e48
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/experimental/startup/StartupProfileProviderUtils.java
@@ -0,0 +1,46 @@
+// 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.experimental.startup;
+
+import com.android.tools.r8.experimental.startup.profile.StartupProfileParser;
+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.FileUtils;
+import com.android.tools.r8.utils.Reporter;
+import com.android.tools.r8.utils.StringDiagnostic;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Path;
+
+public class StartupProfileProviderUtils {
+
+ public static StartupProfileProvider createFromFile(Path path, Reporter reporter) {
+ return new StartupProfileProvider() {
+
+ @Override
+ public void getStartupProfile(StartupProfileBuilder startupProfileBuilder) {
+ try {
+ StartupProfileParser.create()
+ .parseLines(
+ FileUtils.readAllLines(path).stream(),
+ startupProfileBuilder,
+ error ->
+ reporter.warning(
+ new StringDiagnostic(
+ "Invalid descriptor for startup class or method: " + error)));
+ } 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/experimental/startup/profile/StartupClass.java b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupClass.java
index baab7f9..dbd8ef6 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
@@ -4,79 +4,104 @@
package com.android.tools.r8.experimental.startup.profile;
-import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.references.MethodReference;
+import com.android.tools.r8.startup.StartupClassBuilder;
+import com.android.tools.r8.utils.ClassReferenceUtils;
import java.util.function.Consumer;
import java.util.function.Function;
-// TODO(b/238173796): When updating the compiler to have support for taking a list of startup
-// methods, this class may likely be removed along with the StartupItem class, so that only
-// StartupMethod remains.
-public class StartupClass<C, M> extends StartupItem<C, M, C> {
+public class StartupClass extends StartupItem {
- public StartupClass(int flags, C reference) {
- super(flags, reference);
+ private final DexType type;
+
+ StartupClass(DexType type) {
+ this.type = type;
}
- public static <C, M> Builder<C, M> builder() {
- return new Builder<>();
+ public static Builder builder() {
+ return new Builder();
}
- public static Builder<DexType, DexMethod> dexBuilder() {
- return new Builder<>();
- }
-
- public static Builder<ClassReference, MethodReference> referenceBuilder() {
- return new Builder<>();
+ public static Builder builder(DexItemFactory dexItemFactory) {
+ return new Builder(dexItemFactory);
}
@Override
public void accept(
- Consumer<StartupClass<C, M>> classConsumer, Consumer<StartupMethod<C, M>> methodConsumer) {
+ Consumer<StartupClass> classConsumer,
+ Consumer<StartupMethod> methodConsumer,
+ Consumer<SyntheticStartupMethod> syntheticMethodConsumer) {
classConsumer.accept(this);
}
@Override
public <T> T apply(
- Function<StartupClass<C, M>, T> classFunction,
- Function<StartupMethod<C, M>, T> methodFunction) {
+ Function<StartupClass, T> classFunction,
+ Function<StartupMethod, T> methodFunction,
+ Function<SyntheticStartupMethod, T> syntheticMethodFunction) {
return classFunction.apply(this);
}
+ public DexType getReference() {
+ return type;
+ }
+
@Override
public boolean isStartupClass() {
return true;
}
@Override
- public StartupClass<C, M> asStartupClass() {
+ public StartupClass asStartupClass() {
return this;
}
@Override
- public void serializeToString(
- StringBuilder builder,
- Function<C, String> classSerializer,
- Function<M, String> methodSerializer) {
- if (isSynthetic()) {
- builder.append('S');
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
}
- builder.append(classSerializer.apply(getReference()));
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ StartupClass that = (StartupClass) o;
+ return type == that.type;
}
- public static class Builder<C, M> extends StartupItem.Builder<C, M, Builder<C, M>> {
+ @Override
+ public int hashCode() {
+ return type.hashCode();
+ }
- @Override
- public Builder<C, M> setMethodReference(M reference) {
- throw new Unreachable();
+ public static class Builder implements StartupClassBuilder {
+
+ private final DexItemFactory dexItemFactory;
+
+ private DexType type;
+
+ Builder() {
+ this(null);
+ }
+
+ Builder(DexItemFactory dexItemFactory) {
+ this.dexItemFactory = dexItemFactory;
}
@Override
- public StartupClass<C, M> build() {
- return new StartupClass<>(flags, classReference);
+ public Builder setClassReference(ClassReference classReference) {
+ assert dexItemFactory != null;
+ return setClassReference(ClassReferenceUtils.toDexType(classReference, dexItemFactory));
+ }
+
+ public Builder setClassReference(DexType type) {
+ this.type = type;
+ return this;
+ }
+
+ public StartupClass build() {
+ return new StartupClass(type);
}
}
}
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 4590a3f..1854c07 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
@@ -4,35 +4,27 @@
package com.android.tools.r8.experimental.startup.profile;
-import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexType;
import java.util.function.Consumer;
import java.util.function.Function;
-public abstract class StartupItem<C, M, R> {
-
- private static final int FLAG_SYNTHETIC = 1;
-
- protected final int flags;
- protected final R reference;
-
- public StartupItem(int flags, R reference) {
- this.flags = flags;
- this.reference = reference;
- }
+public abstract class StartupItem {
public abstract void accept(
- Consumer<StartupClass<C, M>> classConsumer, Consumer<StartupMethod<C, M>> methodConsumer);
+ Consumer<StartupClass> classConsumer,
+ Consumer<StartupMethod> methodConsumer,
+ Consumer<SyntheticStartupMethod> syntheticMethodConsumer);
public abstract <T> T apply(
- Function<StartupClass<C, M>, T> classFunction,
- Function<StartupMethod<C, M>, T> methodFunction);
+ Function<StartupClass, T> classFunction,
+ Function<StartupMethod, T> methodFunction,
+ Function<SyntheticStartupMethod, T> syntheticMethodFunction);
public boolean isStartupClass() {
return false;
}
- public StartupClass<C, M> asStartupClass() {
+ public StartupClass asStartupClass() {
+ assert false;
return null;
}
@@ -40,126 +32,17 @@
return false;
}
- public StartupMethod<C, M> asStartupMethod() {
+ public StartupMethod asStartupMethod() {
+ assert false;
return null;
}
- public static <C, M> Builder<C, M, ?> builder() {
- return new Builder<>();
+ public boolean isSyntheticStartupMethod() {
+ return false;
}
- public static Builder<DexType, DexMethod, ?> dexBuilder() {
- return new Builder<>();
- }
-
- public int getFlags() {
- return flags;
- }
-
- public R getReference() {
- return reference;
- }
-
- public boolean isSynthetic() {
- return (flags & FLAG_SYNTHETIC) != 0;
- }
-
- public abstract void serializeToString(
- StringBuilder builder,
- Function<C, String> classSerializer,
- Function<M, String> methodSerializer);
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- StartupItem<?, ?, ?> startupItem = (StartupItem<?, ?, ?>) obj;
- return flags == startupItem.flags && reference.equals(startupItem.reference);
- }
-
- @Override
- public int hashCode() {
- return (reference.hashCode() << 1) | flags;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- if (isSynthetic()) {
- builder.append('S');
- }
- builder.append(reference);
- return builder.toString();
- }
-
- public static class Builder<C, M, B extends Builder<C, M, B>> {
-
- protected int flags;
- protected C classReference;
- protected M methodReference;
-
- public B applyIf(boolean condition, Consumer<B> thenConsumer, Consumer<B> elseConsumer) {
- if (condition) {
- thenConsumer.accept(self());
- } else {
- elseConsumer.accept(self());
- }
- return self();
- }
-
- public B setFlags(int flags) {
- this.flags = flags;
- return self();
- }
-
- public B setClassReference(C reference) {
- this.classReference = reference;
- return self();
- }
-
- public B setMethodReference(M reference) {
- this.methodReference = reference;
- return self();
- }
-
- public B setSynthetic() {
- this.flags |= FLAG_SYNTHETIC;
- return self();
- }
-
- public B setSynthetic(boolean synthetic) {
- if (synthetic) {
- return setSynthetic();
- }
- assert (flags & FLAG_SYNTHETIC) == 0;
- return self();
- }
-
- public StartupItem<C, M, ?> build() {
- if (classReference != null) {
- return buildStartupClass();
- } else {
- return buildStartupMethod();
- }
- }
-
- public StartupClass<C, M> buildStartupClass() {
- assert classReference != null;
- return new StartupClass<>(flags, classReference);
- }
-
- public StartupMethod<C, M> buildStartupMethod() {
- assert methodReference != null;
- return new StartupMethod<>(flags, methodReference);
- }
-
- @SuppressWarnings("unchecked")
- public B self() {
- return (B) this;
- }
+ public SyntheticStartupMethod asSyntheticStartupMethod() {
+ assert false;
+ return null;
}
}
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 b6eb04b..9e45798 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
@@ -4,66 +4,104 @@
package com.android.tools.r8.experimental.startup.profile;
-import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.references.ClassReference;
+import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.references.MethodReference;
+import com.android.tools.r8.startup.StartupMethodBuilder;
+import com.android.tools.r8.utils.MethodReferenceUtils;
import java.util.function.Consumer;
import java.util.function.Function;
-public class StartupMethod<C, M> extends StartupItem<C, M, M> {
+public class StartupMethod extends StartupItem {
- public StartupMethod(int flags, M reference) {
- super(flags, reference);
+ private final DexMethod method;
+
+ StartupMethod(DexMethod method) {
+ this.method = method;
}
- public static Builder<ClassReference, MethodReference> referenceBuilder() {
- return new Builder<>();
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static Builder builder(DexItemFactory dexItemFactory) {
+ return new Builder(dexItemFactory);
}
@Override
public void accept(
- Consumer<StartupClass<C, M>> classConsumer, Consumer<StartupMethod<C, M>> methodConsumer) {
+ Consumer<StartupClass> classConsumer,
+ Consumer<StartupMethod> methodConsumer,
+ Consumer<SyntheticStartupMethod> syntheticMethodConsumer) {
methodConsumer.accept(this);
}
@Override
public <T> T apply(
- Function<StartupClass<C, M>, T> classFunction,
- Function<StartupMethod<C, M>, T> methodFunction) {
+ Function<StartupClass, T> classFunction,
+ Function<StartupMethod, T> methodFunction,
+ Function<SyntheticStartupMethod, T> syntheticMethodFunction) {
return methodFunction.apply(this);
}
+ public DexMethod getReference() {
+ return method;
+ }
+
@Override
public boolean isStartupMethod() {
return true;
}
@Override
- public StartupMethod<C, M> asStartupMethod() {
+ public StartupMethod asStartupMethod() {
return this;
}
@Override
- public void serializeToString(
- StringBuilder builder,
- Function<C, String> classSerializer,
- Function<M, String> methodSerializer) {
- if (isSynthetic()) {
- builder.append('S');
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
}
- builder.append(methodSerializer.apply(getReference()));
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ StartupMethod that = (StartupMethod) o;
+ return method == that.method;
}
- public static class Builder<C, M> extends StartupItem.Builder<C, M, Builder<C, M>> {
+ @Override
+ public int hashCode() {
+ return method.hashCode();
+ }
- @Override
- public Builder<C, M> setClassReference(C reference) {
- throw new Unreachable();
+ public static class Builder implements StartupMethodBuilder {
+
+ private final DexItemFactory dexItemFactory;
+
+ private DexMethod method;
+
+ Builder() {
+ this(null);
+ }
+
+ Builder(DexItemFactory dexItemFactory) {
+ this.dexItemFactory = dexItemFactory;
}
@Override
- public StartupMethod<C, M> build() {
- return new StartupMethod<>(flags, methodReference);
+ public Builder setMethodReference(MethodReference classReference) {
+ assert dexItemFactory != null;
+ return setMethodReference(MethodReferenceUtils.toDexMethod(classReference, dexItemFactory));
+ }
+
+ public Builder setMethodReference(DexMethod method) {
+ this.method = method;
+ return this;
+ }
+
+ public StartupMethod build() {
+ return new StartupMethod(method);
}
}
}
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 c2e65b7..a0d6204 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
@@ -4,22 +4,23 @@
package com.android.tools.r8.experimental.startup.profile;
-import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.startup.StartupClassBuilder;
+import com.android.tools.r8.startup.StartupMethodBuilder;
+import com.android.tools.r8.startup.StartupProfileBuilder;
import com.android.tools.r8.startup.StartupProfileProvider;
+import com.android.tools.r8.startup.SyntheticStartupMethodBuilder;
import com.android.tools.r8.utils.InternalOptions;
-import com.android.tools.r8.utils.StringDiagnostic;
-import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.ImmutableList;
-import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;
public class StartupProfile {
- private final List<StartupItem<DexType, DexMethod, ?>> startupItems;
+ private final List<StartupItem> startupItems;
- public StartupProfile(List<StartupItem<DexType, DexMethod, ?>> startupItems) {
+ public StartupProfile(List<StartupItem> startupItems) {
this.startupItems = startupItems;
}
@@ -27,6 +28,10 @@
return new Builder();
}
+ public static Builder builder(DexItemFactory dexItemFactory) {
+ return new Builder(dexItemFactory);
+ }
+
/**
* Parses the supplied startup configuration, if any. The startup configuration is a list of class
* and method descriptors.
@@ -43,60 +48,63 @@
* </pre>
*/
public static StartupProfile parseStartupProfile(InternalOptions options) {
- if (!options.getStartupOptions().hasStartupProfileProvider()) {
+ if (!options.getStartupOptions().hasStartupProfileProviders()) {
return null;
}
- StartupProfileProvider resource = options.getStartupOptions().getStartupProfileProvider();
- List<String> startupDescriptors = StringUtils.splitLines(resource.get());
- return createStartupConfigurationFromLines(options, startupDescriptors);
+ Collection<StartupProfileProvider> startupProfileProviders =
+ options.getStartupOptions().getStartupProfileProviders();
+ StartupProfile.Builder startupProfileBuilder = StartupProfile.builder(options.dexItemFactory());
+ for (StartupProfileProvider startupProfileProvider : startupProfileProviders) {
+ startupProfileProvider.getStartupProfile(startupProfileBuilder);
+ }
+ return startupProfileBuilder.build();
}
- public static StartupProfile createStartupConfigurationFromLines(
- InternalOptions options, List<String> startupDescriptors) {
- List<StartupItem<DexType, DexMethod, ?>> startupItems = new ArrayList<>();
- StartupProfileParser.createDexParser(options.dexItemFactory())
- .parseLines(
- startupDescriptors,
- startupItems::add,
- startupItems::add,
- error ->
- options.reporter.warning(
- new StringDiagnostic(
- "Invalid descriptor for startup class or method: " + error)));
- return new StartupProfile(startupItems);
- }
-
- public List<StartupItem<DexType, DexMethod, ?>> getStartupItems() {
+ public List<StartupItem> getStartupItems() {
return startupItems;
}
- public String serializeToString() {
- StringBuilder builder = new StringBuilder();
- for (StartupItem<DexType, DexMethod, ?> startupItem : startupItems) {
- startupItem.serializeToString(builder, DexType::toSmaliString, DexMethod::toSmaliString);
- builder.append('\n');
+ public static class Builder implements StartupProfileBuilder {
+
+ private final DexItemFactory dexItemFactory;
+ private final ImmutableList.Builder<StartupItem> startupItemsBuilder = ImmutableList.builder();
+
+ Builder() {
+ this(null);
}
- return builder.toString();
- }
- public static class Builder {
+ Builder(DexItemFactory dexItemFactory) {
+ this.dexItemFactory = dexItemFactory;
+ }
- private final ImmutableList.Builder<StartupItem<DexType, DexMethod, ?>> startupItemsBuilder =
- ImmutableList.builder();
+ @Override
+ public Builder addStartupClass(Consumer<StartupClassBuilder> startupClassBuilderConsumer) {
+ StartupClass.Builder startupClassBuilder = StartupClass.builder(dexItemFactory);
+ startupClassBuilderConsumer.accept(startupClassBuilder);
+ return addStartupItem(startupClassBuilder.build());
+ }
- public Builder addStartupItem(StartupItem<DexType, DexMethod, ?> startupItem) {
+ @Override
+ public Builder addStartupMethod(Consumer<StartupMethodBuilder> startupMethodBuilderConsumer) {
+ StartupMethod.Builder startupMethodBuilder = StartupMethod.builder(dexItemFactory);
+ startupMethodBuilderConsumer.accept(startupMethodBuilder);
+ return addStartupItem(startupMethodBuilder.build());
+ }
+
+ @Override
+ public StartupProfileBuilder addSyntheticStartupMethod(
+ Consumer<SyntheticStartupMethodBuilder> syntheticStartupMethodBuilderConsumer) {
+ SyntheticStartupMethod.Builder syntheticStartupMethodBuilder =
+ SyntheticStartupMethod.builder(dexItemFactory);
+ syntheticStartupMethodBuilderConsumer.accept(syntheticStartupMethodBuilder);
+ return addStartupItem(syntheticStartupMethodBuilder.build());
+ }
+
+ private Builder addStartupItem(StartupItem startupItem) {
this.startupItemsBuilder.add(startupItem);
return this;
}
- public Builder addStartupClass(StartupClass<DexType, DexMethod> startupClass) {
- return addStartupItem(startupClass);
- }
-
- public Builder addStartupMethod(StartupMethod<DexType, DexMethod> startupMethod) {
- return addStartupItem(startupMethod);
- }
-
public Builder apply(Consumer<Builder> consumer) {
consumer.accept(this);
return this;
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileParser.java b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileParser.java
index a386c31..cc205bf 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileParser.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileParser.java
@@ -4,90 +4,49 @@
package com.android.tools.r8.experimental.startup.profile;
-import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.references.TypeReference;
+import com.android.tools.r8.startup.StartupProfileBuilder;
+import com.android.tools.r8.utils.BooleanBox;
import com.android.tools.r8.utils.DescriptorUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
-import java.util.function.Function;
+import java.util.stream.Stream;
-public class StartupProfileParser<C, M, T> {
+public class StartupProfileParser {
- interface MethodFactory<C, M, T> {
-
- M createMethod(
- C methodHolder, String methodName, List<T> methodParameterTypes, T methodReturnType);
- }
-
- private final Function<String, C> classFactory;
- private final MethodFactory<C, M, T> methodFactory;
- private final Function<String, T> typeFactory;
-
- StartupProfileParser(
- Function<String, C> classFactory,
- MethodFactory<C, M, T> methodFactory,
- Function<String, T> typeFactory) {
- this.classFactory = classFactory;
- this.methodFactory = methodFactory;
- this.typeFactory = typeFactory;
- }
-
- public static StartupProfileParser<DexType, DexMethod, DexType> createDexParser(
- DexItemFactory dexItemFactory) {
- return new StartupProfileParser<>(
- dexItemFactory::createType,
- (methodHolder, methodName, methodParameters, methodReturnType) ->
- dexItemFactory.createMethod(
- methodHolder,
- dexItemFactory.createProto(methodReturnType, methodParameters),
- dexItemFactory.createString(methodName)),
- dexItemFactory::createType);
- }
-
- public static StartupProfileParser<ClassReference, MethodReference, TypeReference>
- createReferenceParser() {
- return new StartupProfileParser<>(
- Reference::classFromDescriptor, Reference::method, Reference::returnTypeFromDescriptor);
+ public static StartupProfileParser create() {
+ return new StartupProfileParser();
}
public void parseLines(
- List<String> startupDescriptors,
- Consumer<? super StartupClass<C, M>> startupClassConsumer,
- Consumer<? super StartupMethod<C, M>> startupMethodConsumer,
+ Stream<String> startupDescriptors,
+ StartupProfileBuilder startupProfileBuilder,
Consumer<String> parseErrorHandler) {
- for (String startupDescriptor : startupDescriptors) {
- if (!startupDescriptor.isEmpty()) {
- parseLine(
- startupDescriptor, startupClassConsumer, startupMethodConsumer, parseErrorHandler);
- }
- }
+ startupDescriptors.forEach(
+ startupDescriptor -> {
+ if (!startupDescriptor.isEmpty()) {
+ parseLine(startupDescriptor, startupProfileBuilder, parseErrorHandler);
+ }
+ });
}
public void parseLine(
String startupDescriptor,
- Consumer<? super StartupClass<C, M>> startupClassConsumer,
- Consumer<? super StartupMethod<C, M>> startupMethodConsumer,
+ StartupProfileBuilder startupProfileBuilder,
Consumer<String> parseErrorHandler) {
- StartupItem.Builder<C, M, ?> startupItemBuilder = StartupItem.builder();
- startupDescriptor = parseSyntheticFlag(startupDescriptor, startupItemBuilder);
+ BooleanBox syntheticFlag = new BooleanBox();
+ startupDescriptor = parseSyntheticFlag(startupDescriptor, syntheticFlag);
parseStartupClassOrMethod(
- startupDescriptor,
- startupItemBuilder,
- startupClassConsumer,
- startupMethodConsumer,
- parseErrorHandler);
+ startupDescriptor, startupProfileBuilder, syntheticFlag, parseErrorHandler);
}
- private static String parseSyntheticFlag(
- String startupDescriptor, StartupItem.Builder<?, ?, ?> startupItemBuilder) {
+ private static String parseSyntheticFlag(String startupDescriptor, BooleanBox syntheticFlag) {
if (!startupDescriptor.isEmpty() && startupDescriptor.charAt(0) == 'S') {
- startupItemBuilder.setSynthetic();
+ syntheticFlag.set();
return startupDescriptor.substring(1);
}
return startupDescriptor;
@@ -95,24 +54,34 @@
private void parseStartupClassOrMethod(
String startupDescriptor,
- StartupItem.Builder<C, M, ?> startupItemBuilder,
- Consumer<? super StartupClass<C, M>> startupClassConsumer,
- Consumer<? super StartupMethod<C, M>> startupMethodConsumer,
+ StartupProfileBuilder startupProfileBuilder,
+ BooleanBox syntheticFlag,
Consumer<String> parseErrorHandler) {
int arrowStartIndex = getArrowStartIndex(startupDescriptor);
if (arrowStartIndex >= 0) {
- M startupMethod = parseStartupMethodDescriptor(startupDescriptor, arrowStartIndex);
- if (startupMethod != null) {
- startupMethodConsumer.accept(
- startupItemBuilder.setMethodReference(startupMethod).buildStartupMethod());
+ if (syntheticFlag.isFalse()) {
+ MethodReference startupMethod =
+ parseStartupMethodDescriptor(startupDescriptor, arrowStartIndex);
+ if (startupMethod != null) {
+ startupProfileBuilder.addStartupMethod(
+ startupMethodBuilder -> startupMethodBuilder.setMethodReference(startupMethod));
+ } else {
+ parseErrorHandler.accept(startupDescriptor);
+ }
} else {
parseErrorHandler.accept(startupDescriptor);
}
} else {
- C startupClass = parseStartupClassDescriptor(startupDescriptor);
+ ClassReference startupClass = parseStartupClassDescriptor(startupDescriptor);
if (startupClass != null) {
- startupClassConsumer.accept(
- startupItemBuilder.setClassReference(startupClass).buildStartupClass());
+ if (syntheticFlag.isFalse()) {
+ startupProfileBuilder.addStartupClass(
+ startupClassBuilder -> startupClassBuilder.setClassReference(startupClass));
+ } else {
+ startupProfileBuilder.addSyntheticStartupMethod(
+ syntheticStartupMethodBuilder ->
+ syntheticStartupMethodBuilder.setSyntheticContextReference(startupClass));
+ }
} else {
parseErrorHandler.accept(startupDescriptor);
}
@@ -123,17 +92,18 @@
return startupDescriptor.indexOf("->");
}
- private C parseStartupClassDescriptor(String startupClassDescriptor) {
+ private ClassReference parseStartupClassDescriptor(String startupClassDescriptor) {
if (DescriptorUtils.isClassDescriptor(startupClassDescriptor)) {
- return classFactory.apply(startupClassDescriptor);
+ return Reference.classFromDescriptor(startupClassDescriptor);
} else {
return null;
}
}
- private M parseStartupMethodDescriptor(String startupMethodDescriptor, int arrowStartIndex) {
+ private MethodReference parseStartupMethodDescriptor(
+ String startupMethodDescriptor, int arrowStartIndex) {
String classDescriptor = startupMethodDescriptor.substring(0, arrowStartIndex);
- C methodHolder = parseStartupClassDescriptor(classDescriptor);
+ ClassReference methodHolder = parseStartupClassDescriptor(classDescriptor);
if (methodHolder == null) {
return null;
}
@@ -150,14 +120,15 @@
return parseStartupMethodProto(methodHolder, methodName, protoDescriptor);
}
- private M parseStartupMethodProto(C methodHolder, String methodName, String protoDescriptor) {
- List<T> parameterTypes = new ArrayList<>();
+ private MethodReference parseStartupMethodProto(
+ ClassReference methodHolder, String methodName, String protoDescriptor) {
+ List<TypeReference> parameterTypes = new ArrayList<>();
for (String parameterTypeDescriptor :
DescriptorUtils.getArgumentTypeDescriptors(protoDescriptor)) {
- parameterTypes.add(typeFactory.apply(parameterTypeDescriptor));
+ parameterTypes.add(Reference.typeFromDescriptor(parameterTypeDescriptor));
}
String returnTypeDescriptor = DescriptorUtils.getReturnTypeDescriptor(protoDescriptor);
- T returnType = typeFactory.apply(returnTypeDescriptor);
- return methodFactory.createMethod(methodHolder, methodName, parameterTypes, returnType);
+ TypeReference returnType = Reference.returnTypeFromDescriptor(returnTypeDescriptor);
+ return Reference.method(methodHolder, methodName, parameterTypes, returnType);
}
}
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
new file mode 100644
index 0000000..eedcadd
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/experimental/startup/profile/SyntheticStartupMethod.java
@@ -0,0 +1,108 @@
+// 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.experimental.startup.profile;
+
+import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.references.ClassReference;
+import com.android.tools.r8.startup.SyntheticStartupMethodBuilder;
+import com.android.tools.r8.utils.ClassReferenceUtils;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+public class SyntheticStartupMethod extends StartupItem {
+
+ private final DexType syntheticContextType;
+
+ SyntheticStartupMethod(DexType syntheticContextType) {
+ this.syntheticContextType = syntheticContextType;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static Builder builder(DexItemFactory dexItemFactory) {
+ return new Builder(dexItemFactory);
+ }
+
+ @Override
+ public void accept(
+ Consumer<StartupClass> classConsumer,
+ Consumer<StartupMethod> methodConsumer,
+ Consumer<SyntheticStartupMethod> syntheticMethodConsumer) {
+ syntheticMethodConsumer.accept(this);
+ }
+
+ @Override
+ public <T> T apply(
+ Function<StartupClass, T> classFunction,
+ Function<StartupMethod, T> methodFunction,
+ Function<SyntheticStartupMethod, T> syntheticMethodFunction) {
+ return syntheticMethodFunction.apply(this);
+ }
+
+ public DexType getSyntheticContextType() {
+ return syntheticContextType;
+ }
+
+ @Override
+ public boolean isSyntheticStartupMethod() {
+ return true;
+ }
+
+ @Override
+ public SyntheticStartupMethod asSyntheticStartupMethod() {
+ return this;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ SyntheticStartupMethod that = (SyntheticStartupMethod) o;
+ return syntheticContextType == that.syntheticContextType;
+ }
+
+ @Override
+ public int hashCode() {
+ return syntheticContextType.hashCode();
+ }
+
+ public static class Builder implements SyntheticStartupMethodBuilder {
+
+ private final DexItemFactory dexItemFactory;
+
+ private DexType syntheticContextReference;
+
+ Builder() {
+ this(null);
+ }
+
+ Builder(DexItemFactory dexItemFactory) {
+ this.dexItemFactory = dexItemFactory;
+ }
+
+ @Override
+ public Builder setSyntheticContextReference(ClassReference syntheticContextReference) {
+ assert dexItemFactory != null;
+ return setSyntheticContextReference(
+ ClassReferenceUtils.toDexType(syntheticContextReference, dexItemFactory));
+ }
+
+ public Builder setSyntheticContextReference(DexType syntheticContextReference) {
+ this.syntheticContextReference = syntheticContextReference;
+ return this;
+ }
+
+ public SyntheticStartupMethod build() {
+ return new SyntheticStartupMethod(syntheticContextReference);
+ }
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/startup/StartupProfileProvider.java b/src/main/java/com/android/tools/r8/startup/StartupProfileProvider.java
index 4d98373..39ad8fc 100644
--- a/src/main/java/com/android/tools/r8/startup/StartupProfileProvider.java
+++ b/src/main/java/com/android/tools/r8/startup/StartupProfileProvider.java
@@ -11,10 +11,6 @@
@Keep
public interface StartupProfileProvider extends Resource {
- // TODO(b/238173796): Change the implementation to use the new API below.
- /** Return the startup profile. */
- String get();
-
/** Provides the startup profile by callbacks to the given {@param startupProfileBuilder}. */
void getStartupProfile(StartupProfileBuilder startupProfileBuilder);
}
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index f02405c..78c17ec 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -816,7 +816,7 @@
new KotlinOptimizationOptions();
private final ApiModelTestingOptions apiModelTestingOptions = new ApiModelTestingOptions();
private final DesugarSpecificOptions desugarSpecificOptions = new DesugarSpecificOptions();
- private final StartupOptions startupOptions = new StartupOptions();
+ private final StartupOptions startupOptions = new StartupOptions(this);
private final StartupInstrumentationOptions startupInstrumentationOptions =
new StartupInstrumentationOptions();
public final TestingOptions testing = new TestingOptions();
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 9ab1f03..f9b2f74 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
@@ -7,11 +7,9 @@
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.errors.Unimplemented;
-import com.android.tools.r8.experimental.startup.profile.StartupClass;
-import com.android.tools.r8.experimental.startup.profile.StartupProfile;
-import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.references.ClassReference;
+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.BooleanUtils;
@@ -52,30 +50,18 @@
.addKeepClassAndMembersRules(Main.class)
.addOptionsModification(
options -> {
- DexItemFactory dexItemFactory = options.dexItemFactory();
- StartupProfile startupProfile =
- StartupProfile.builder()
- .apply(
- builder ->
- getStartupClasses()
- .forEach(
- startupClass ->
- builder.addStartupClass(
- StartupClass.dexBuilder()
- .setClassReference(
- toDexType(startupClass, dexItemFactory))
- .build())))
- .build();
StartupProfileProvider startupProfileProvider =
new StartupProfileProvider() {
- @Override
- public String get() {
- return startupProfile.serializeToString();
- }
@Override
public void getStartupProfile(StartupProfileBuilder startupProfileBuilder) {
- throw new Unimplemented();
+ for (Class<?> startupClass : getStartupClasses()) {
+ ClassReference startupClassReference =
+ Reference.classFromClass(startupClass);
+ startupProfileBuilder.addStartupClass(
+ startupClassBuilder ->
+ startupClassBuilder.setClassReference(startupClassReference));
+ }
}
@Override
@@ -83,7 +69,9 @@
return Origin.unknown();
}
};
- options.getStartupOptions().setStartupProfileProvider(startupProfileProvider);
+ options
+ .getStartupOptions()
+ .setStartupProfileProviders(Collections.singleton(startupProfileProvider));
})
.addHorizontallyMergedClassesInspector(
inspector ->
diff --git a/src/test/java/com/android/tools/r8/compilerapi/startupprofile/StartupProfileApiTest.java b/src/test/java/com/android/tools/r8/compilerapi/startupprofile/StartupProfileApiTest.java
index f8bc404..b6572fc 100644
--- a/src/test/java/com/android/tools/r8/compilerapi/startupprofile/StartupProfileApiTest.java
+++ b/src/test/java/com/android/tools/r8/compilerapi/startupprofile/StartupProfileApiTest.java
@@ -82,9 +82,8 @@
testRunner.accept(new DexIndexedConsumer.DirectoryConsumer(output));
assertThat(
new CodeInspector(output.resolve("classes.dex")).clazz(test.getMockClass()), isPresent());
- // TODO(b/238173796): The PostStartupMockClass should be in classes2.dex.
assertThat(
- new CodeInspector(output.resolve("classes.dex")).clazz(test.getPostStartupMockClass()),
+ new CodeInspector(output.resolve("classes2.dex")).clazz(test.getPostStartupMockClass()),
isPresent());
}
@@ -96,11 +95,6 @@
private StartupProfileProvider getStartupProfileProvider() {
return new StartupProfileProvider() {
- @Override
- public String get() {
- // Intentionally empty. All uses of this API should be rewritten to use getStartupProfile.
- return "";
- }
@Override
public void getStartupProfile(StartupProfileBuilder startupProfileBuilder) {
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 a44f221..35ef96e 100644
--- a/src/test/java/com/android/tools/r8/internal/YouTubeV1719Test.java
+++ b/src/test/java/com/android/tools/r8/internal/YouTubeV1719Test.java
@@ -38,6 +38,7 @@
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;
@@ -149,7 +150,8 @@
if (startupProfileProvider != null) {
options
.getStartupOptions()
- .setStartupProfileProvider(startupProfileProvider)
+ .setStartupProfileProviders(
+ Collections.singleton(startupProfileProvider))
.setEnableMinimalStartupDex(enableMinimalStartupDex)
.setEnableStartupBoundaryOptimizations(
enableStartupBoundaryOptimizations);
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 c7211db..0af6a45 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
@@ -13,23 +13,22 @@
import com.android.tools.r8.ArchiveProgramResourceProvider;
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.R8FullTestBuilder;
-import com.android.tools.r8.StringResource;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ThrowableConsumer;
import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.errors.Unimplemented;
-import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.startup.StartupProfileBuilder;
+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.Reporter;
import com.android.tools.r8.utils.ZipUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import java.io.IOException;
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;
@@ -238,25 +237,10 @@
boolean enableStartupBoundaryOptimizations,
Path outDirectory)
throws Exception {
+ Reporter reporter = new Reporter();
StartupProfileProvider startupProfileProvider =
- new StartupProfileProvider() {
- @Override
- public String get() {
- return StringResource.fromFile(chromeDirectory.resolve("startup.txt"))
- .getStringWithRuntimeException();
- }
-
- @Override
- public void getStartupProfile(StartupProfileBuilder startupProfileBuilder) {
- throw new Unimplemented();
- }
-
- @Override
- public Origin getOrigin() {
- return Origin.unknown();
- }
- };
-
+ StartupProfileProviderUtils.createFromFile(
+ chromeDirectory.resolve("startup.txt"), reporter);
buildR8(
testBuilder ->
testBuilder.addOptionsModification(
@@ -265,7 +249,7 @@
.getStartupOptions()
.setEnableMinimalStartupDex(enableMinimalStartupDex)
.setEnableStartupBoundaryOptimizations(enableStartupBoundaryOptimizations)
- .setStartupProfileProvider(startupProfileProvider)),
+ .setStartupProfileProviders(Collections.singleton(startupProfileProvider))),
outDirectory);
}
diff --git a/src/test/java/com/android/tools/r8/startup/InliningOutOfStartupPartitionTest.java b/src/test/java/com/android/tools/r8/startup/InliningOutOfStartupPartitionTest.java
index b26ff87..b171421 100644
--- a/src/test/java/com/android/tools/r8/startup/InliningOutOfStartupPartitionTest.java
+++ b/src/test/java/com/android/tools/r8/startup/InliningOutOfStartupPartitionTest.java
@@ -11,12 +11,10 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.experimental.startup.profile.StartupClass;
-import com.android.tools.r8.experimental.startup.profile.StartupItem;
-import com.android.tools.r8.experimental.startup.profile.StartupMethod;
-import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.startup.profile.ExternalStartupClass;
+import com.android.tools.r8.startup.profile.ExternalStartupItem;
+import com.android.tools.r8.startup.profile.ExternalStartupMethod;
import com.android.tools.r8.startup.utils.StartupTestingUtils;
import com.android.tools.r8.utils.MethodReferenceUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
@@ -41,12 +39,12 @@
@Test
public void test() throws Exception {
- List<StartupItem<ClassReference, MethodReference, ?>> startupItems =
+ List<ExternalStartupItem> startupItems =
ImmutableList.of(
- StartupClass.referenceBuilder()
+ ExternalStartupClass.builder()
.setClassReference(Reference.classFromClass(Main.class))
.build(),
- StartupMethod.referenceBuilder()
+ ExternalStartupMethod.builder()
.setMethodReference(MethodReferenceUtils.mainMethod(Main.class))
.build());
testForR8(parameters.getBackend())
diff --git a/src/test/java/com/android/tools/r8/startup/MinimalStartupDexTest.java b/src/test/java/com/android/tools/r8/startup/MinimalStartupDexTest.java
index eda0c51..d6d12a8 100644
--- a/src/test/java/com/android/tools/r8/startup/MinimalStartupDexTest.java
+++ b/src/test/java/com/android/tools/r8/startup/MinimalStartupDexTest.java
@@ -12,9 +12,7 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.experimental.startup.profile.StartupItem;
-import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.references.MethodReference;
+import com.android.tools.r8.startup.profile.ExternalStartupItem;
import com.android.tools.r8.startup.utils.StartupTestingUtils;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
@@ -45,7 +43,7 @@
@Test
public void test() throws Exception {
- List<StartupItem<ClassReference, MethodReference, ?>> startupList = new ArrayList<>();
+ List<ExternalStartupItem> startupList = new ArrayList<>();
testForD8(parameters.getBackend())
.addInnerClasses(getClass())
.apply(
diff --git a/src/test/java/com/android/tools/r8/startup/StartupInstrumentationTest.java b/src/test/java/com/android/tools/r8/startup/StartupInstrumentationTest.java
index 13257e1..faa893b 100644
--- a/src/test/java/com/android/tools/r8/startup/StartupInstrumentationTest.java
+++ b/src/test/java/com/android/tools/r8/startup/StartupInstrumentationTest.java
@@ -9,12 +9,10 @@
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.experimental.startup.profile.StartupClass;
-import com.android.tools.r8.experimental.startup.profile.StartupItem;
-import com.android.tools.r8.experimental.startup.profile.StartupMethod;
-import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.startup.profile.ExternalStartupClass;
+import com.android.tools.r8.startup.profile.ExternalStartupItem;
+import com.android.tools.r8.startup.profile.ExternalStartupMethod;
import com.android.tools.r8.startup.utils.StartupTestingUtils;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.MethodReferenceUtils;
@@ -48,7 +46,7 @@
@Test
public void test() throws Exception {
Path out = temp.newFolder().toPath().resolve("out.txt").toAbsolutePath();
- List<StartupItem<ClassReference, MethodReference, ?>> startupList = new ArrayList<>();
+ List<ExternalStartupItem> startupList = new ArrayList<>();
testForD8(parameters.getBackend())
.addInnerClasses(getClass())
.applyIf(
@@ -75,19 +73,18 @@
return ImmutableList.of("foo");
}
- private List<StartupItem<ClassReference, MethodReference, ?>> getExpectedStartupList()
- throws NoSuchMethodException {
+ private List<ExternalStartupItem> getExpectedStartupList() throws NoSuchMethodException {
return ImmutableList.of(
- StartupClass.referenceBuilder()
+ ExternalStartupClass.builder()
.setClassReference(Reference.classFromClass(Main.class))
.build(),
- StartupMethod.referenceBuilder()
+ ExternalStartupMethod.builder()
.setMethodReference(MethodReferenceUtils.mainMethod(Main.class))
.build(),
- StartupClass.referenceBuilder()
+ ExternalStartupClass.builder()
.setClassReference(Reference.classFromClass(AStartupClass.class))
.build(),
- StartupMethod.referenceBuilder()
+ ExternalStartupMethod.builder()
.setMethodReference(
Reference.methodFromMethod(AStartupClass.class.getDeclaredMethod("foo")))
.build());
diff --git a/src/test/java/com/android/tools/r8/startup/StartupSyntheticPlacementTest.java b/src/test/java/com/android/tools/r8/startup/StartupSyntheticPlacementTest.java
index 64c4c56..e9c4224 100644
--- a/src/test/java/com/android/tools/r8/startup/StartupSyntheticPlacementTest.java
+++ b/src/test/java/com/android/tools/r8/startup/StartupSyntheticPlacementTest.java
@@ -16,14 +16,14 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestCompilerBuilder;
import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.experimental.startup.profile.StartupClass;
-import com.android.tools.r8.experimental.startup.profile.StartupItem;
-import com.android.tools.r8.experimental.startup.profile.StartupMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.ir.desugar.LambdaClass;
import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.startup.profile.ExternalStartupClass;
+import com.android.tools.r8.startup.profile.ExternalStartupItem;
+import com.android.tools.r8.startup.profile.ExternalStartupMethod;
+import com.android.tools.r8.startup.profile.ExternalSyntheticStartupMethod;
import com.android.tools.r8.startup.utils.MixedSectionLayoutInspector;
import com.android.tools.r8.startup.utils.StartupTestingUtils;
import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
@@ -90,7 +90,7 @@
Path optimizedApp = r8CompileResult.writeToZip();
// Then instrument the app to generate a startup list for the minified app.
- List<StartupItem<ClassReference, MethodReference, ?>> startupList = new ArrayList<>();
+ List<ExternalStartupItem> startupList = new ArrayList<>();
testForD8(parameters.getBackend())
.addProgramFiles(optimizedApp)
.apply(
@@ -125,7 +125,7 @@
@Test
public void testLayoutUsingR8() throws Exception {
// First generate a startup list for the original app.
- List<StartupItem<ClassReference, MethodReference, ?>> startupList = new ArrayList<>();
+ List<ExternalStartupItem> startupList = new ArrayList<>();
D8TestCompileResult instrumentationCompileResult =
testForD8(parameters.getBackend())
.addInnerClasses(getClass())
@@ -167,7 +167,7 @@
private void configureStartupOptions(
TestCompilerBuilder<?, ?, ?, ?, ?> testBuilder,
CodeInspector inspector,
- List<StartupItem<ClassReference, MethodReference, ?>> startupList) {
+ List<ExternalStartupItem> startupList) {
testBuilder
.addOptionsModification(
options -> {
@@ -188,36 +188,30 @@
}
@SuppressWarnings("unchecked")
- private List<StartupItem<ClassReference, MethodReference, ?>> getExpectedStartupList(
+ private List<ExternalStartupItem> getExpectedStartupList(
CodeInspector inspector, boolean isStartupListForOriginalApp) throws NoSuchMethodException {
- ImmutableList.Builder<StartupItem<ClassReference, MethodReference, ?>> builder =
- ImmutableList.builder();
+ ImmutableList.Builder<ExternalStartupItem> builder = ImmutableList.builder();
builder.add(
- StartupClass.referenceBuilder()
+ ExternalStartupClass.builder()
.setClassReference(Reference.classFromClass(Main.class))
.build(),
- StartupMethod.referenceBuilder()
+ ExternalStartupMethod.builder()
.setMethodReference(MethodReferenceUtils.mainMethod(Main.class))
.build(),
- StartupClass.referenceBuilder()
- .setClassReference(Reference.classFromClass(A.class))
- .build(),
- StartupMethod.referenceBuilder()
+ ExternalStartupClass.builder().setClassReference(Reference.classFromClass(A.class)).build(),
+ ExternalStartupMethod.builder()
.setMethodReference(Reference.methodFromMethod(A.class.getDeclaredMethod("a")))
.build(),
- StartupClass.referenceBuilder()
- .setClassReference(Reference.classFromClass(B.class))
- .build(),
- StartupMethod.referenceBuilder()
+ ExternalStartupClass.builder().setClassReference(Reference.classFromClass(B.class)).build(),
+ ExternalStartupMethod.builder()
.setMethodReference(
Reference.methodFromMethod(B.class.getDeclaredMethod("b", boolean.class)))
.build());
if (useLambda) {
if (isStartupListForOriginalApp) {
builder.add(
- StartupClass.referenceBuilder()
- .setClassReference(Reference.classFromClass(B.class))
- .setSynthetic()
+ ExternalSyntheticStartupMethod.builder()
+ .setSyntheticContextReference(Reference.classFromClass(B.class))
.build());
} else {
ClassSubject bClassSubject = inspector.clazz(B.class);
@@ -238,14 +232,14 @@
externalSyntheticLambdaClassSubject.getFinalReference();
builder.add(
- StartupClass.referenceBuilder()
+ ExternalStartupClass.builder()
.setClassReference(externalSyntheticLambdaClassReference)
.build(),
- StartupMethod.referenceBuilder()
+ ExternalStartupMethod.builder()
.setMethodReference(
MethodReferenceUtils.instanceConstructor(externalSyntheticLambdaClassReference))
.build(),
- StartupMethod.referenceBuilder()
+ ExternalStartupMethod.builder()
.setMethodReference(
Reference.method(
externalSyntheticLambdaClassReference,
@@ -253,7 +247,7 @@
ImmutableList.of(Reference.classFromClass(Object.class)),
null))
.build(),
- StartupMethod.referenceBuilder()
+ ExternalStartupMethod.builder()
.setMethodReference(
Reference.method(
Reference.classFromClass(B.class),
@@ -263,16 +257,14 @@
.build());
}
builder.add(
- StartupMethod.referenceBuilder()
+ ExternalStartupMethod.builder()
.setMethodReference(
Reference.methodFromMethod(B.class.getDeclaredMethod("lambda$b$0", Object.class)))
.build());
}
builder.add(
- StartupClass.referenceBuilder()
- .setClassReference(Reference.classFromClass(C.class))
- .build(),
- StartupMethod.referenceBuilder()
+ ExternalStartupClass.builder().setClassReference(Reference.classFromClass(C.class)).build(),
+ ExternalStartupMethod.builder()
.setMethodReference(Reference.methodFromMethod(C.class.getDeclaredMethod("c")))
.build());
return builder.build();
diff --git a/src/test/java/com/android/tools/r8/startup/StartupSyntheticWithoutContextTest.java b/src/test/java/com/android/tools/r8/startup/StartupSyntheticWithoutContextTest.java
index 5b30a0a..a824cc4 100644
--- a/src/test/java/com/android/tools/r8/startup/StartupSyntheticWithoutContextTest.java
+++ b/src/test/java/com/android/tools/r8/startup/StartupSyntheticWithoutContextTest.java
@@ -14,13 +14,13 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.experimental.startup.profile.StartupClass;
-import com.android.tools.r8.experimental.startup.profile.StartupItem;
-import com.android.tools.r8.experimental.startup.profile.StartupMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.startup.profile.ExternalStartupClass;
+import com.android.tools.r8.startup.profile.ExternalStartupItem;
+import com.android.tools.r8.startup.profile.ExternalStartupMethod;
+import com.android.tools.r8.startup.profile.ExternalSyntheticStartupMethod;
import com.android.tools.r8.startup.utils.MixedSectionLayoutInspector;
import com.android.tools.r8.startup.utils.StartupTestingUtils;
import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
@@ -61,7 +61,7 @@
@Test
public void test() throws Exception {
- List<StartupItem<ClassReference, MethodReference, ?>> startupList = new ArrayList<>();
+ List<ExternalStartupItem> startupList = new ArrayList<>();
testForD8(parameters.getBackend())
.addInnerClasses(getClass())
.apply(
@@ -101,38 +101,30 @@
return ImmutableList.of("A", "B", "C");
}
- private List<StartupItem<ClassReference, MethodReference, ?>> getExpectedStartupList()
- throws NoSuchMethodException {
+ private List<ExternalStartupItem> getExpectedStartupList() throws NoSuchMethodException {
return ImmutableList.of(
- StartupClass.referenceBuilder()
+ ExternalStartupClass.builder()
.setClassReference(Reference.classFromClass(Main.class))
.build(),
- StartupMethod.referenceBuilder()
+ ExternalStartupMethod.builder()
.setMethodReference(MethodReferenceUtils.mainMethod(Main.class))
.build(),
- StartupClass.referenceBuilder()
- .setClassReference(Reference.classFromClass(A.class))
- .build(),
- StartupMethod.referenceBuilder()
+ ExternalStartupClass.builder().setClassReference(Reference.classFromClass(A.class)).build(),
+ ExternalStartupMethod.builder()
.setMethodReference(Reference.methodFromMethod(A.class.getDeclaredMethod("a")))
.build(),
- StartupClass.referenceBuilder()
- .setClassReference(Reference.classFromClass(B.class))
- .build(),
- StartupMethod.referenceBuilder()
+ ExternalStartupClass.builder().setClassReference(Reference.classFromClass(B.class)).build(),
+ ExternalStartupMethod.builder()
.setMethodReference(Reference.methodFromMethod(B.class.getDeclaredMethod("b")))
.build(),
- StartupClass.referenceBuilder()
- .setClassReference(Reference.classFromClass(B.class))
- .setSynthetic()
+ ExternalSyntheticStartupMethod.builder()
+ .setSyntheticContextReference(Reference.classFromClass(B.class))
.build(),
- StartupMethod.referenceBuilder()
+ ExternalStartupMethod.builder()
.setMethodReference(Reference.methodFromMethod(B.class.getDeclaredMethod("lambda$b$0")))
.build(),
- StartupClass.referenceBuilder()
- .setClassReference(Reference.classFromClass(C.class))
- .build(),
- StartupMethod.referenceBuilder()
+ ExternalStartupClass.builder().setClassReference(Reference.classFromClass(C.class)).build(),
+ ExternalStartupMethod.builder()
.setMethodReference(Reference.methodFromMethod(C.class.getDeclaredMethod("c")))
.build());
}
diff --git a/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupClass.java b/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupClass.java
new file mode 100644
index 0000000..c6caccf
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupClass.java
@@ -0,0 +1,66 @@
+// 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.profile;
+
+import com.android.tools.r8.references.ClassReference;
+import com.android.tools.r8.startup.StartupClassBuilder;
+import java.util.function.Function;
+
+public class ExternalStartupClass extends ExternalStartupItem {
+
+ private final ClassReference classReference;
+
+ ExternalStartupClass(ClassReference classReference) {
+ this.classReference = classReference;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ @Override
+ public <T> T apply(
+ Function<ExternalStartupClass, T> classFunction,
+ Function<ExternalStartupMethod, T> methodFunction,
+ Function<ExternalSyntheticStartupMethod, T> syntheticMethodFunction) {
+ return classFunction.apply(this);
+ }
+
+ public ClassReference getReference() {
+ return classReference;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ ExternalStartupClass that = (ExternalStartupClass) o;
+ return classReference.equals(that.classReference);
+ }
+
+ @Override
+ public int hashCode() {
+ return classReference.hashCode();
+ }
+
+ public static class Builder implements StartupClassBuilder {
+
+ private ClassReference classReference;
+
+ @Override
+ public Builder setClassReference(ClassReference classReference) {
+ this.classReference = classReference;
+ return this;
+ }
+
+ public ExternalStartupClass build() {
+ return new ExternalStartupClass(classReference);
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupItem.java b/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupItem.java
new file mode 100644
index 0000000..e3aa745
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupItem.java
@@ -0,0 +1,15 @@
+// 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.profile;
+
+import java.util.function.Function;
+
+public abstract class ExternalStartupItem {
+
+ public abstract <T> T apply(
+ Function<ExternalStartupClass, T> classFunction,
+ Function<ExternalStartupMethod, T> methodFunction,
+ Function<ExternalSyntheticStartupMethod, T> syntheticMethodFunction);
+}
diff --git a/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupMethod.java b/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupMethod.java
new file mode 100644
index 0000000..0d73a7a
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupMethod.java
@@ -0,0 +1,67 @@
+// 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.profile;
+
+import com.android.tools.r8.references.MethodReference;
+import com.android.tools.r8.startup.StartupMethodBuilder;
+import com.android.tools.r8.startup.profile.ExternalStartupClass.Builder;
+import java.util.function.Function;
+
+public class ExternalStartupMethod extends ExternalStartupItem {
+
+ private final MethodReference methodReference;
+
+ ExternalStartupMethod(MethodReference methodReference) {
+ this.methodReference = methodReference;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ @Override
+ public <T> T apply(
+ Function<ExternalStartupClass, T> classFunction,
+ Function<ExternalStartupMethod, T> methodFunction,
+ Function<ExternalSyntheticStartupMethod, T> syntheticMethodFunction) {
+ return methodFunction.apply(this);
+ }
+
+ public MethodReference getReference() {
+ return methodReference;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ ExternalStartupMethod that = (ExternalStartupMethod) o;
+ return methodReference.equals(that.methodReference);
+ }
+
+ @Override
+ public int hashCode() {
+ return methodReference.hashCode();
+ }
+
+ public static class Builder implements StartupMethodBuilder {
+
+ private MethodReference methodReference;
+
+ @Override
+ public Builder setMethodReference(MethodReference methodReference) {
+ this.methodReference = methodReference;
+ return this;
+ }
+
+ public ExternalStartupMethod build() {
+ return new ExternalStartupMethod(methodReference);
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/startup/profile/ExternalSyntheticStartupMethod.java b/src/test/java/com/android/tools/r8/startup/profile/ExternalSyntheticStartupMethod.java
new file mode 100644
index 0000000..628cdec
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/startup/profile/ExternalSyntheticStartupMethod.java
@@ -0,0 +1,66 @@
+// 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.profile;
+
+import com.android.tools.r8.references.ClassReference;
+import com.android.tools.r8.startup.SyntheticStartupMethodBuilder;
+import java.util.function.Function;
+
+public class ExternalSyntheticStartupMethod extends ExternalStartupItem {
+
+ private final ClassReference syntheticContextReference;
+
+ ExternalSyntheticStartupMethod(ClassReference syntheticContextReference) {
+ this.syntheticContextReference = syntheticContextReference;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ @Override
+ public <T> T apply(
+ Function<ExternalStartupClass, T> classFunction,
+ Function<ExternalStartupMethod, T> methodFunction,
+ Function<ExternalSyntheticStartupMethod, T> syntheticMethodFunction) {
+ return syntheticMethodFunction.apply(this);
+ }
+
+ public ClassReference getSyntheticContextReference() {
+ return syntheticContextReference;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ ExternalSyntheticStartupMethod that = (ExternalSyntheticStartupMethod) o;
+ return syntheticContextReference.equals(that.syntheticContextReference);
+ }
+
+ @Override
+ public int hashCode() {
+ return syntheticContextReference.hashCode();
+ }
+
+ public static class Builder implements SyntheticStartupMethodBuilder {
+
+ private ClassReference syntheticContextReference;
+
+ @Override
+ public Builder setSyntheticContextReference(ClassReference syntheticContextReference) {
+ this.syntheticContextReference = syntheticContextReference;
+ return this;
+ }
+
+ public ExternalSyntheticStartupMethod build() {
+ return new ExternalSyntheticStartupMethod(syntheticContextReference);
+ }
+ }
+}
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 2011ff1..a9ca8c5 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
@@ -14,28 +14,25 @@
import com.android.tools.r8.TestCompilerBuilder;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ThrowableConsumer;
-import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.experimental.startup.instrumentation.StartupInstrumentationOptions;
-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.StartupProfileParser;
-import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.references.MethodReference;
-import com.android.tools.r8.references.TypeReference;
+import com.android.tools.r8.startup.StartupClassBuilder;
+import com.android.tools.r8.startup.StartupMethodBuilder;
import com.android.tools.r8.startup.StartupProfileBuilder;
import com.android.tools.r8.startup.StartupProfileProvider;
+import com.android.tools.r8.startup.SyntheticStartupMethodBuilder;
+import com.android.tools.r8.startup.profile.ExternalStartupClass;
+import com.android.tools.r8.startup.profile.ExternalStartupItem;
+import com.android.tools.r8.startup.profile.ExternalStartupMethod;
+import com.android.tools.r8.startup.profile.ExternalSyntheticStartupMethod;
import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.ClassReferenceUtils;
-import com.android.tools.r8.utils.MethodReferenceUtils;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.ThrowingConsumer;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import org.junit.rules.TemporaryFolder;
@@ -53,6 +50,39 @@
}
}
+ private static StartupProfileBuilder createStartupItemFactory(
+ Consumer<ExternalStartupItem> startupItemConsumer) {
+ return new StartupProfileBuilder() {
+ @Override
+ public StartupProfileBuilder addStartupClass(
+ Consumer<StartupClassBuilder> startupClassBuilderConsumer) {
+ ExternalStartupClass.Builder startupClassBuilder = ExternalStartupClass.builder();
+ startupClassBuilderConsumer.accept(startupClassBuilder);
+ startupItemConsumer.accept(startupClassBuilder.build());
+ return this;
+ }
+
+ @Override
+ public StartupProfileBuilder addStartupMethod(
+ Consumer<StartupMethodBuilder> startupMethodBuilderConsumer) {
+ ExternalStartupMethod.Builder startupMethodBuilder = ExternalStartupMethod.builder();
+ startupMethodBuilderConsumer.accept(startupMethodBuilder);
+ startupItemConsumer.accept(startupMethodBuilder.build());
+ return this;
+ }
+
+ @Override
+ public StartupProfileBuilder addSyntheticStartupMethod(
+ Consumer<SyntheticStartupMethodBuilder> syntheticStartupMethodBuilderConsumer) {
+ ExternalSyntheticStartupMethod.Builder syntheticStartupMethodBuilder =
+ ExternalSyntheticStartupMethod.builder();
+ syntheticStartupMethodBuilderConsumer.accept(syntheticStartupMethodBuilder);
+ startupItemConsumer.accept(syntheticStartupMethodBuilder.build());
+ return this;
+ }
+ };
+ }
+
public static ThrowableConsumer<D8TestBuilder>
enableStartupInstrumentationForOriginalAppUsingFile(TestParameters parameters) {
return testBuilder ->
@@ -66,12 +96,6 @@
}
public static ThrowableConsumer<D8TestBuilder>
- enableStartupInstrumentationForOptimizedAppUsingFile(TestParameters parameters) {
- return testBuilder ->
- enableStartupInstrumentation(testBuilder, parameters, AppVariant.OPTIMIZED, false);
- }
-
- public static ThrowableConsumer<D8TestBuilder>
enableStartupInstrumentationForOptimizedAppUsingLogcat(TestParameters parameters) {
return testBuilder ->
enableStartupInstrumentation(testBuilder, parameters, AppVariant.OPTIMIZED, true);
@@ -108,26 +132,22 @@
}
public static void readStartupListFromFile(
- Path path, Consumer<StartupItem<ClassReference, MethodReference, ?>> startupItemConsumer)
- throws IOException {
- StartupProfileParser.createReferenceParser()
+ Path path, Consumer<ExternalStartupItem> startupItemConsumer) throws IOException {
+ StartupProfileParser.create()
.parseLines(
- Files.readAllLines(path),
- startupItemConsumer,
- startupItemConsumer,
+ Files.readAllLines(path).stream(),
+ createStartupItemFactory(startupItemConsumer),
error -> fail("Unexpected parse error: " + error));
}
public static ThrowingConsumer<D8TestRunResult, RuntimeException> removeStartupListFromStdout(
- Consumer<StartupItem<ClassReference, MethodReference, ?>> startupItemConsumer) {
+ Consumer<ExternalStartupItem> startupItemConsumer) {
return runResult -> removeStartupListFromStdout(runResult, startupItemConsumer);
}
public static void removeStartupListFromStdout(
- D8TestRunResult runResult,
- Consumer<StartupItem<ClassReference, MethodReference, ?>> startupItemConsumer) {
- StartupProfileParser<ClassReference, MethodReference, TypeReference> parser =
- StartupProfileParser.createReferenceParser();
+ D8TestRunResult runResult, Consumer<ExternalStartupItem> startupItemConsumer) {
+ StartupProfileParser parser = StartupProfileParser.create();
StringBuilder stdoutBuilder = new StringBuilder();
String startupDescriptorPrefix = "[" + startupInstrumentationTag + "] ";
for (String line : StringUtils.splitLines(runResult.getStdOut(), true)) {
@@ -135,8 +155,7 @@
String message = line.substring(startupDescriptorPrefix.length());
parser.parseLine(
message,
- startupItemConsumer,
- startupItemConsumer,
+ createStartupItemFactory(startupItemConsumer),
error -> fail("Unexpected parse error: " + error));
} else {
stdoutBuilder.append(line).append(System.lineSeparator());
@@ -146,30 +165,31 @@
}
public static void setStartupConfiguration(
- TestCompilerBuilder<?, ?, ?, ?, ?> testBuilder,
- List<StartupItem<ClassReference, MethodReference, ?>> startupItems) {
+ TestCompilerBuilder<?, ?, ?, ?, ?> testBuilder, List<ExternalStartupItem> startupItems) {
testBuilder.addOptionsModification(
options -> {
- DexItemFactory dexItemFactory = options.dexItemFactory();
- StartupProfile startupProfile =
- StartupProfile.builder()
- .apply(
- builder ->
- startupItems.forEach(
- startupItem ->
- builder.addStartupItem(
- convertStartupItemToDex(startupItem, dexItemFactory))))
- .build();
StartupProfileProvider startupProfileProvider =
new StartupProfileProvider() {
@Override
- public String get() {
- return startupProfile.serializeToString();
- }
-
- @Override
public void getStartupProfile(StartupProfileBuilder startupProfileBuilder) {
- throw new Unimplemented();
+ 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
@@ -177,27 +197,12 @@
return Origin.unknown();
}
};
- options.getStartupOptions().setStartupProfileProvider(startupProfileProvider);
+ options
+ .getStartupOptions()
+ .setStartupProfileProviders(Collections.singleton(startupProfileProvider));
});
}
- private static StartupItem<DexType, DexMethod, ?> convertStartupItemToDex(
- StartupItem<ClassReference, MethodReference, ?> startupItem, DexItemFactory dexItemFactory) {
- return StartupItem.dexBuilder()
- .applyIf(
- startupItem.isStartupClass(),
- builder ->
- builder.setClassReference(
- ClassReferenceUtils.toDexType(
- startupItem.asStartupClass().getReference(), dexItemFactory)),
- builder ->
- builder.setMethodReference(
- MethodReferenceUtils.toDexMethod(
- startupItem.asStartupMethod().getReference(), dexItemFactory)))
- .setFlags(startupItem.getFlags())
- .build();
- }
-
private static byte[] getTransformedAndroidUtilLog() throws IOException {
return transformer(Log.class).setClassDescriptor("Landroid/util/Log;").transform();
}
diff --git a/third_party/binary_compatibility_tests/compiler_api_tests.tar.gz.sha1 b/third_party/binary_compatibility_tests/compiler_api_tests.tar.gz.sha1
index 040d696..4753c76 100644
--- a/third_party/binary_compatibility_tests/compiler_api_tests.tar.gz.sha1
+++ b/third_party/binary_compatibility_tests/compiler_api_tests.tar.gz.sha1
@@ -1 +1 @@
-98dc48c246bd0855133e138c2cd2b5835cf862cf
\ No newline at end of file
+46ac3bedbdba8732e48d13fcc94967f43ae1d91b
\ No newline at end of file