Share subtyping computation where possible.
Bug: 155188554
Change-Id: I3be581cf671444f3a75a8c32c23877ab9e38c8c0
diff --git a/src/main/java/com/android/tools/r8/GenerateMainDexList.java b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
index 0bb17c7..42290d2 100644
--- a/src/main/java/com/android/tools/r8/GenerateMainDexList.java
+++ b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
@@ -13,6 +13,7 @@
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DirectMappedDexApplication;
+import com.android.tools.r8.graph.SubtypingInfo;
import com.android.tools.r8.shaking.Enqueuer;
import com.android.tools.r8.shaking.EnqueuerFactory;
import com.android.tools.r8.shaking.MainDexClasses;
@@ -54,8 +55,10 @@
MainDexListBuilder.checkForAssumedLibraryTypes(appView.appInfo());
+ SubtypingInfo subtypingInfo = new SubtypingInfo(application.allClasses(), application);
+
RootSet mainDexRootSet =
- new RootSetBuilder(appView, application, options.mainDexKeepRules).run(executor);
+ new RootSetBuilder(appView, subtypingInfo, options.mainDexKeepRules).run(executor);
GraphConsumer graphConsumer = options.mainDexKeptGraphConsumer;
WhyAreYouKeepingConsumer whyAreYouKeepingConsumer = null;
@@ -64,7 +67,8 @@
graphConsumer = whyAreYouKeepingConsumer;
}
- Enqueuer enqueuer = EnqueuerFactory.createForMainDexTracing(appView, graphConsumer);
+ Enqueuer enqueuer =
+ EnqueuerFactory.createForMainDexTracing(appView, subtypingInfo, graphConsumer);
Set<DexProgramClass> liveTypes = enqueuer.traceMainDex(mainDexRootSet, executor, timing);
// LiveTypes is the result.
MainDexClasses mainDexClasses = new MainDexListBuilder(liveTypes, application).run();
diff --git a/src/main/java/com/android/tools/r8/PrintSeeds.java b/src/main/java/com/android/tools/r8/PrintSeeds.java
index fb4edb5..7c2302a 100644
--- a/src/main/java/com/android/tools/r8/PrintSeeds.java
+++ b/src/main/java/com/android/tools/r8/PrintSeeds.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.graph.AppServices;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DirectMappedDexApplication;
+import com.android.tools.r8.graph.SubtypingInfo;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.shaking.Enqueuer;
import com.android.tools.r8.shaking.EnqueuerFactory;
@@ -89,10 +90,11 @@
AppView<? extends AppInfoWithClassHierarchy> appView =
AppView.createForR8(new AppInfoWithClassHierarchy(application), options);
appView.setAppServices(AppServices.builder(appView).build());
+ SubtypingInfo subtypingInfo = new SubtypingInfo(application.allClasses(), application);
RootSet rootSet =
- new RootSetBuilder(appView, application, options.getProguardConfiguration().getRules())
+ new RootSetBuilder(appView, subtypingInfo, options.getProguardConfiguration().getRules())
.run(executor);
- Enqueuer enqueuer = EnqueuerFactory.createForInitialTreeShaking(appView);
+ Enqueuer enqueuer = EnqueuerFactory.createForInitialTreeShaking(appView, subtypingInfo);
AppInfoWithLiveness appInfo =
enqueuer.traceApplication(
rootSet, options.getProguardConfiguration().getDontWarnPatterns(), executor, timing);
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index e82c7eb..30201ce 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -334,11 +334,11 @@
options.itemFactory, AndroidApiLevel.getAndroidApiLevel(options.minApiLevel)));
}
}
-
+ SubtypingInfo subtypingInfo = new SubtypingInfo(application.allClasses(), application);
appView.setRootSet(
new RootSetBuilder(
appView,
- application,
+ subtypingInfo,
Iterables.concat(
options.getProguardConfiguration().getRules(), synthesizedProguardRules))
.run(executorService));
@@ -346,7 +346,7 @@
AnnotationRemover.Builder annotationRemoverBuilder =
options.isShrinking() ? AnnotationRemover.builder() : null;
AppView<AppInfoWithLiveness> appViewWithLiveness =
- runEnqueuer(annotationRemoverBuilder, executorService, appView);
+ runEnqueuer(annotationRemoverBuilder, executorService, appView, subtypingInfo);
application = appViewWithLiveness.appInfo().app().asDirect();
assert appView.rootSet().verifyKeptFieldsAreAccessedAndLive(appViewWithLiveness.appInfo());
assert appView.rootSet().verifyKeptMethodsAreTargetedAndLive(appViewWithLiveness.appInfo());
@@ -414,11 +414,14 @@
if (!options.mainDexKeepRules.isEmpty()) {
assert appView.graphLense().isIdentityLense();
// Find classes which may have code executed before secondary dex files installation.
+ SubtypingInfo subtypingInfo =
+ new SubtypingInfo(appView.appInfo().app().asDirect().allClasses(), appView);
mainDexRootSet =
- new RootSetBuilder(appView, application, options.mainDexKeepRules).run(executorService);
+ new RootSetBuilder(appView, subtypingInfo, options.mainDexKeepRules)
+ .run(executorService);
// Live types is the tracing result.
Set<DexProgramClass> mainDexBaseClasses =
- EnqueuerFactory.createForMainDexTracing(appView)
+ EnqueuerFactory.createForMainDexTracing(appView, subtypingInfo)
.traceMainDex(mainDexRootSet, executorService, timing);
// Calculate the automatic main dex list according to legacy multidex constraints.
mainDexClasses = new MainDexListBuilder(mainDexBaseClasses, application).run();
@@ -608,7 +611,10 @@
}
Enqueuer enqueuer =
- EnqueuerFactory.createForMainDexTracing(appView, mainDexKeptGraphConsumer);
+ EnqueuerFactory.createForMainDexTracing(
+ appView,
+ new SubtypingInfo(application.allClasses(), application),
+ mainDexKeptGraphConsumer);
// Find classes which may have code executed before secondary dex files installation.
// Live types is the tracing result.
Set<DexProgramClass> mainDexBaseClasses =
@@ -657,7 +663,11 @@
}
Enqueuer enqueuer =
- EnqueuerFactory.createForFinalTreeShaking(appView, keptGraphConsumer, missingClasses);
+ EnqueuerFactory.createForFinalTreeShaking(
+ appView,
+ new SubtypingInfo(application.allClasses(), application),
+ keptGraphConsumer,
+ missingClasses);
appView.setAppInfo(
enqueuer
.traceApplication(
@@ -863,9 +873,10 @@
private AppView<AppInfoWithLiveness> runEnqueuer(
AnnotationRemover.Builder annotationRemoverBuilder,
ExecutorService executorService,
- AppView<AppInfoWithClassHierarchy> appView)
+ AppView<AppInfoWithClassHierarchy> appView,
+ SubtypingInfo subtypingInfo)
throws ExecutionException {
- Enqueuer enqueuer = EnqueuerFactory.createForInitialTreeShaking(appView);
+ Enqueuer enqueuer = EnqueuerFactory.createForInitialTreeShaking(appView, subtypingInfo);
enqueuer.setAnnotationRemoverBuilder(annotationRemoverBuilder);
if (appView.options().enableInitializedClassesInInstanceMethodsAnalysis) {
enqueuer.registerAnalysis(new InitializedClassesInInstanceMethodsAnalysis(appView));
@@ -921,11 +932,17 @@
// If there is no kept-graph info, re-run the enqueueing to compute it.
if (whyAreYouKeepingConsumer == null) {
whyAreYouKeepingConsumer = new WhyAreYouKeepingConsumer(null);
+ SubtypingInfo subtypingInfo =
+ new SubtypingInfo(appView.appInfo().app().asDirect().allClasses(), appView);
if (forMainDex) {
- enqueuer = EnqueuerFactory.createForMainDexTracing(appView, whyAreYouKeepingConsumer);
+ enqueuer =
+ EnqueuerFactory.createForMainDexTracing(
+ appView, subtypingInfo, whyAreYouKeepingConsumer);
enqueuer.traceMainDex(rootSet, executorService, timing);
} else {
- enqueuer = EnqueuerFactory.createForWhyAreYouKeeping(appView, whyAreYouKeepingConsumer);
+ enqueuer =
+ EnqueuerFactory.createForWhyAreYouKeeping(
+ appView, subtypingInfo, whyAreYouKeepingConsumer);
enqueuer.traceApplication(
rootSet,
options.getProguardConfiguration().getDontWarnPatterns(),
diff --git a/src/main/java/com/android/tools/r8/graph/SubtypingInfo.java b/src/main/java/com/android/tools/r8/graph/SubtypingInfo.java
index 6c6e3ba..662ccb0 100644
--- a/src/main/java/com/android/tools/r8/graph/SubtypingInfo.java
+++ b/src/main/java/com/android/tools/r8/graph/SubtypingInfo.java
@@ -14,6 +14,7 @@
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;
@@ -46,6 +47,18 @@
populateSubtypeMap(classes, definitions::definitionFor, factory);
}
+ public boolean verifyEquals(Collection<DexClass> classes, DexDefinitionSupplier definitions) {
+ SubtypingInfo subtypingInfo = new SubtypingInfo(classes, definitions);
+ assert typeInfo.equals(subtypingInfo.typeInfo);
+ assert subtypeMap.keySet().equals(subtypingInfo.subtypeMap.keySet());
+ subtypeMap.forEach(
+ (key, value) -> {
+ assert subtypingInfo.subtypeMap.get(key).equals(value);
+ });
+ assert missingClasses.equals(subtypingInfo.missingClasses);
+ return true;
+ }
+
private void populateSuperType(
Map<DexType, Set<DexType>> map,
DexType superType,
@@ -239,6 +252,20 @@
}
@Override
+ public int hashCode() {
+ return Objects.hash(type, directSubtypes);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof TypeInfo)) {
+ return false;
+ }
+ TypeInfo other = (TypeInfo) obj;
+ return other.type == type && other.directSubtypes.equals(directSubtypes);
+ }
+
+ @Override
public String toString() {
return "TypeInfo{" + type + ", level:" + hierarchyLevel + "}";
}
diff --git a/src/main/java/com/android/tools/r8/shaking/ConsequentRootSetBuilder.java b/src/main/java/com/android/tools/r8/shaking/ConsequentRootSetBuilder.java
index ddb649c..8288bde 100644
--- a/src/main/java/com/android/tools/r8/shaking/ConsequentRootSetBuilder.java
+++ b/src/main/java/com/android/tools/r8/shaking/ConsequentRootSetBuilder.java
@@ -5,14 +5,17 @@
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.SubtypingInfo;
class ConsequentRootSetBuilder extends RootSetBuilder {
private final Enqueuer enqueuer;
ConsequentRootSetBuilder(
- AppView<? extends AppInfoWithClassHierarchy> appView, Enqueuer enqueuer) {
- super(appView, appView.appInfo().app(), null);
+ AppView<? extends AppInfoWithClassHierarchy> appView,
+ SubtypingInfo subtypingInfo,
+ Enqueuer enqueuer) {
+ super(appView, subtypingInfo, null);
this.enqueuer = enqueuer;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 61e7ea4..5540e34 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -178,7 +178,7 @@
// Don't hold a direct pointer to app info (use appView).
private AppInfoWithClassHierarchy appInfo;
private final AppView<AppInfoWithClassHierarchy> appView;
- private final SubtypingInfo subtypingInfo;
+ private SubtypingInfo subtypingInfo;
private final InternalOptions options;
private RootSet rootSet;
private ProguardClassFilter dontWarnPatterns;
@@ -344,14 +344,15 @@
Enqueuer(
AppView<? extends AppInfoWithClassHierarchy> appView,
+ SubtypingInfo subtypingInfo,
GraphConsumer keptGraphConsumer,
Mode mode) {
assert appView.appServices() != null;
InternalOptions options = appView.options();
this.appInfo = appView.appInfo();
this.appView = appView.withClassHierarchy();
- this.subtypingInfo =
- new SubtypingInfo(appView.appInfo().app().asDirect().allClasses(), appView);
+ this.subtypingInfo = subtypingInfo;
+ assert subtypingInfo.verifyEquals(appView.appInfo().app().asDirect().allClasses(), appView);
this.forceProguardCompatibility = options.forceProguardCompatibility;
this.graphReporter = new GraphReporter(appView, keptGraphConsumer);
this.mode = mode;
@@ -2724,8 +2725,10 @@
// Now all additions are computed, the application is atomically extended with those additions.
Builder appBuilder = appInfo.app().asDirect().builder();
additions.amendApplication(appBuilder);
- appInfo = new AppInfoWithClassHierarchy(appBuilder.build());
+ DirectMappedDexApplication app = appBuilder.build();
+ appInfo = new AppInfoWithClassHierarchy(app);
appView.setAppInfo(appInfo);
+ subtypingInfo = new SubtypingInfo(app.allClasses(), app);
// Finally once all synthesized items "exist" it is now safe to continue tracing. The new work
// items are enqueued and the fixed point will continue once this subroutine returns.
@@ -3110,7 +3113,7 @@
}
}
ConsequentRootSetBuilder consequentSetBuilder =
- new ConsequentRootSetBuilder(appView, this);
+ new ConsequentRootSetBuilder(appView, subtypingInfo, this);
IfRuleEvaluator ifRuleEvaluator =
new IfRuleEvaluator(
appView,
@@ -3222,7 +3225,7 @@
}
private ConsequentRootSet computeDelayedInterfaceMethodSyntheticBridges() {
- RootSetBuilder builder = new RootSetBuilder(appView);
+ RootSetBuilder builder = new RootSetBuilder(appView, subtypingInfo);
for (DelayedRootSetActionItem delayedRootSetActionItem : rootSet.delayedRootSetActionItems) {
if (delayedRootSetActionItem.isInterfaceMethodSyntheticBridgeAction()) {
handleInterfaceMethodSyntheticBridgeAction(
diff --git a/src/main/java/com/android/tools/r8/shaking/EnqueuerFactory.java b/src/main/java/com/android/tools/r8/shaking/EnqueuerFactory.java
index ddc5f62..743f0df 100644
--- a/src/main/java/com/android/tools/r8/shaking/EnqueuerFactory.java
+++ b/src/main/java/com/android/tools/r8/shaking/EnqueuerFactory.java
@@ -8,21 +8,24 @@
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.SubtypingInfo;
import com.android.tools.r8.shaking.Enqueuer.Mode;
import java.util.Set;
public class EnqueuerFactory {
public static Enqueuer createForInitialTreeShaking(
- AppView<? extends AppInfoWithClassHierarchy> appView) {
- return new Enqueuer(appView, null, Mode.INITIAL_TREE_SHAKING);
+ AppView<? extends AppInfoWithClassHierarchy> appView, SubtypingInfo subtypingInfo) {
+ return new Enqueuer(appView, subtypingInfo, null, Mode.INITIAL_TREE_SHAKING);
}
public static Enqueuer createForFinalTreeShaking(
AppView<? extends AppInfoWithClassHierarchy> appView,
+ SubtypingInfo subtypingInfo,
GraphConsumer keptGraphConsumer,
Set<DexType> initialMissingTypes) {
- Enqueuer enqueuer = new Enqueuer(appView, keptGraphConsumer, Mode.FINAL_TREE_SHAKING);
+ Enqueuer enqueuer =
+ new Enqueuer(appView, subtypingInfo, keptGraphConsumer, Mode.FINAL_TREE_SHAKING);
appView.withProtoShrinker(
shrinker -> enqueuer.setInitialDeadProtoTypes(shrinker.getDeadProtoTypes()));
enqueuer.setInitialMissingTypes(initialMissingTypes);
@@ -30,17 +33,21 @@
}
public static Enqueuer createForMainDexTracing(
- AppView<? extends AppInfoWithClassHierarchy> appView) {
- return createForMainDexTracing(appView, null);
+ AppView<? extends AppInfoWithClassHierarchy> appView, SubtypingInfo subtypingInfo) {
+ return createForMainDexTracing(appView, subtypingInfo, null);
}
public static Enqueuer createForMainDexTracing(
- AppView<? extends AppInfoWithClassHierarchy> appView, GraphConsumer keptGraphConsumer) {
- return new Enqueuer(appView, keptGraphConsumer, Mode.MAIN_DEX_TRACING);
+ AppView<? extends AppInfoWithClassHierarchy> appView,
+ SubtypingInfo subtypingInfo,
+ GraphConsumer keptGraphConsumer) {
+ return new Enqueuer(appView, subtypingInfo, keptGraphConsumer, Mode.MAIN_DEX_TRACING);
}
public static Enqueuer createForWhyAreYouKeeping(
- AppView<? extends AppInfoWithClassHierarchy> appView, GraphConsumer keptGraphConsumer) {
- return new Enqueuer(appView, keptGraphConsumer, Mode.WHY_ARE_YOU_KEEPING);
+ AppView<? extends AppInfoWithClassHierarchy> appView,
+ SubtypingInfo subtypingInfo,
+ GraphConsumer keptGraphConsumer) {
+ return new Enqueuer(appView, subtypingInfo, keptGraphConsumer, Mode.WHY_ARE_YOU_KEEPING);
}
}
diff --git a/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java b/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
index 88c9fe2..058693e 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
@@ -115,17 +115,19 @@
public RootSetBuilder(
AppView<? extends AppInfoWithClassHierarchy> appView,
- DexApplication application,
+ SubtypingInfo subtypingInfo,
Iterable<? extends ProguardConfigurationRule> rules) {
this.appView = appView;
- this.application = application.asDirect();
- this.subtypingInfo = new SubtypingInfo(this.application.allClasses(), this.application);
+ this.subtypingInfo = subtypingInfo;
+ this.application = appView.appInfo().app().asDirect();
this.rules = rules;
this.options = appView.options();
+ assert subtypingInfo.verifyEquals(this.application.allClasses(), this.application);
}
- public RootSetBuilder(AppView<? extends AppInfoWithClassHierarchy> appView) {
- this(appView, appView.appInfo().app(), null);
+ public RootSetBuilder(
+ AppView<? extends AppInfoWithClassHierarchy> appView, SubtypingInfo subtypingInfo) {
+ this(appView, subtypingInfo, null);
}
void handleMatchedAnnotation(AnnotationMatchResult annotation) {
diff --git a/src/test/java/com/android/tools/r8/TestBase.java b/src/test/java/com/android/tools/r8/TestBase.java
index 6c3ed35..7c3ddff 100644
--- a/src/test/java/com/android/tools/r8/TestBase.java
+++ b/src/test/java/com/android/tools/r8/TestBase.java
@@ -34,6 +34,7 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DirectMappedDexApplication;
import com.android.tools.r8.graph.SmaliWriter;
+import com.android.tools.r8.graph.SubtypingInfo;
import com.android.tools.r8.jasmin.JasminBuilder;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.references.ClassReference;
@@ -618,15 +619,16 @@
AppView<AppInfoWithClassHierarchy> appView = computeAppViewWithSubtyping(app);
// Run the tree shaker to compute an instance of AppInfoWithLiveness.
ExecutorService executor = Executors.newSingleThreadExecutor();
- DexApplication application = appView.appInfo().app();
+ DirectMappedDexApplication application = appView.appInfo().app().asDirect();
+ SubtypingInfo subtypingInfo = new SubtypingInfo(application.allClasses(), application);
RootSet rootSet =
new RootSetBuilder(
appView,
- application,
+ subtypingInfo,
proguardConfigurationRulesGenerator.apply(appView.appInfo().dexItemFactory()))
.run(executor);
AppInfoWithLiveness appInfoWithLiveness =
- EnqueuerFactory.createForInitialTreeShaking(appView)
+ EnqueuerFactory.createForInitialTreeShaking(appView, subtypingInfo)
.traceApplication(rootSet, ProguardClassFilter.empty(), executor, application.timing);
// We do not run the tree pruner to ensure that the hierarchy is as designed and not modified
// due to liveness.
diff --git a/src/test/java/com/android/tools/r8/ir/InlineTest.java b/src/test/java/com/android/tools/r8/ir/InlineTest.java
index dc0585a..a2246c0 100644
--- a/src/test/java/com/android/tools/r8/ir/InlineTest.java
+++ b/src/test/java/com/android/tools/r8/ir/InlineTest.java
@@ -11,6 +11,8 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DirectMappedDexApplication;
+import com.android.tools.r8.graph.SubtypingInfo;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
@@ -47,18 +49,20 @@
MethodSubject method,
List<IRCode> additionalCode)
throws ExecutionException {
+ DirectMappedDexApplication directApp = application.asDirect();
AppView<AppInfoWithClassHierarchy> appView =
- AppView.createForR8(new AppInfoWithClassHierarchy(application.asDirect()), options);
+ AppView.createForR8(new AppInfoWithClassHierarchy(directApp), options);
appView.setAppServices(AppServices.builder(appView).build());
ExecutorService executorService = ThreadUtils.getExecutorService(options);
+ SubtypingInfo subtypingInfo = new SubtypingInfo(directApp.allClasses(), directApp);
appView.setRootSet(
new RootSetBuilder(
appView,
- application,
+ subtypingInfo,
ImmutableList.of(ProguardKeepRule.defaultKeepAllRule(unused -> {})))
.run(executorService));
Timing timing = Timing.empty();
- Enqueuer enqueuer = EnqueuerFactory.createForInitialTreeShaking(appView);
+ Enqueuer enqueuer = EnqueuerFactory.createForInitialTreeShaking(appView, subtypingInfo);
appView.setAppInfo(
enqueuer.traceApplication(
appView.rootSet(), ProguardClassFilter.empty(), executorService, timing));
diff --git a/src/test/java/com/android/tools/r8/ir/conversion/PartialCallGraphTest.java b/src/test/java/com/android/tools/r8/ir/conversion/PartialCallGraphTest.java
index 5f07b54..1ea4e67 100644
--- a/src/test/java/com/android/tools/r8/ir/conversion/PartialCallGraphTest.java
+++ b/src/test/java/com/android/tools/r8/ir/conversion/PartialCallGraphTest.java
@@ -10,21 +10,15 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-import com.android.tools.r8.dex.ApplicationReader;
-import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
-import com.android.tools.r8.graph.AppServices;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DirectMappedDexApplication;
import com.android.tools.r8.ir.conversion.CallGraph.Node;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.android.tools.r8.shaking.Enqueuer;
-import com.android.tools.r8.shaking.EnqueuerFactory;
import com.android.tools.r8.shaking.ProguardConfigurationParser;
-import com.android.tools.r8.shaking.RootSetBuilder;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.ImmutableList;
@@ -36,33 +30,24 @@
public class PartialCallGraphTest extends CallGraphTestBase {
private final AppView<AppInfoWithLiveness> appView;
- private final InternalOptions options = new InternalOptions();
- private final ExecutorService executorService = ThreadUtils.getExecutorService(options);
+ private final InternalOptions options;
+ private final ExecutorService executorService;
public PartialCallGraphTest() throws Exception {
- Timing timing = Timing.empty();
AndroidApp app = testForD8().addProgramClasses(TestClass.class).compile().app;
- DirectMappedDexApplication application =
- new ApplicationReader(app, options, timing).read().toDirect();
- AppView<AppInfoWithClassHierarchy> appView =
- AppView.createForR8(new AppInfoWithClassHierarchy(application), options);
- appView.setAppServices(AppServices.builder(appView).build());
- ProguardConfigurationParser parser =
- new ProguardConfigurationParser(appView.dexItemFactory(), options.reporter);
- parser.parse(
- createConfigurationForTesting(
- ImmutableList.of("-keep class ** { void m1(); void m5(); }")));
- appView.setRootSet(
- new RootSetBuilder(
- appView, application, parser.getConfig().getRules()).run(executorService));
- Enqueuer enqueuer = EnqueuerFactory.createForInitialTreeShaking(appView);
this.appView =
- appView.setAppInfo(
- enqueuer.traceApplication(
- appView.rootSet(),
- parser.getConfig().getDontWarnPatterns(),
- executorService,
- timing));
+ computeAppViewWithLiveness(
+ app,
+ factory -> {
+ ProguardConfigurationParser parser =
+ new ProguardConfigurationParser(factory, new Reporter());
+ parser.parse(
+ createConfigurationForTesting(
+ ImmutableList.of("-keep class ** { void m1(); void m5(); }")));
+ return parser.getConfig().getRules();
+ });
+ this.options = appView.options();
+ this.executorService = ThreadUtils.getExecutorService(options);
}
@Test
diff --git a/src/test/java/com/android/tools/r8/naming/NamingTestBase.java b/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
index 74bae45..385911c 100644
--- a/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
+++ b/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DirectMappedDexApplication;
+import com.android.tools.r8.graph.SubtypingInfo;
import com.android.tools.r8.shaking.Enqueuer;
import com.android.tools.r8.shaking.EnqueuerFactory;
import com.android.tools.r8.shaking.ProguardConfiguration;
@@ -61,6 +62,7 @@
protected NamingLens runMinifier(List<Path> configPaths) throws ExecutionException {
ProguardConfiguration configuration =
ToolHelper.loadProguardConfiguration(dexItemFactory, configPaths);
+
InternalOptions options = new InternalOptions(configuration, new Reporter());
options.programConsumer = DexIndexedConsumer.emptyConsumer();
@@ -68,11 +70,12 @@
AppView<AppInfoWithClassHierarchy> appView =
AppView.createForR8(new AppInfoWithClassHierarchy(program), options);
+ SubtypingInfo subtypingInfo = new SubtypingInfo(program.allClasses(), program);
appView.setRootSet(
- new RootSetBuilder(appView, program, configuration.getRules()).run(executor));
+ new RootSetBuilder(appView, subtypingInfo, configuration.getRules()).run(executor));
appView.setAppServices(AppServices.builder(appView).build());
- Enqueuer enqueuer = EnqueuerFactory.createForInitialTreeShaking(appView);
+ Enqueuer enqueuer = EnqueuerFactory.createForInitialTreeShaking(appView, subtypingInfo);
appView.setAppInfo(
enqueuer.traceApplication(
appView.rootSet(), configuration.getDontWarnPatterns(), executor, timing));