Update root-set and if-rule evaluation to new threading module
Bug: b/304992619
Change-Id: I483136220189e10aba1bb16d4489185b002f3ed1
diff --git a/src/main/java/com/android/tools/r8/shaking/IfRuleEvaluator.java b/src/main/java/com/android/tools/r8/shaking/IfRuleEvaluator.java
index 93268d1..16b3d76 100644
--- a/src/main/java/com/android/tools/r8/shaking/IfRuleEvaluator.java
+++ b/src/main/java/com/android/tools/r8/shaking/IfRuleEvaluator.java
@@ -22,8 +22,8 @@
import com.android.tools.r8.shaking.RootSetUtils.ConsequentRootSet;
import com.android.tools.r8.shaking.RootSetUtils.ConsequentRootSetBuilder;
import com.android.tools.r8.shaking.RootSetUtils.RootSetBuilder;
+import com.android.tools.r8.threading.TaskCollection;
import com.android.tools.r8.utils.InternalOptions.TestingOptions.ProguardIfRuleEvaluationData;
-import com.android.tools.r8.utils.ThreadUtils;
import com.google.common.base.Equivalence.Wrapper;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
@@ -36,7 +36,6 @@
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
import java.util.stream.Collectors;
public class IfRuleEvaluator {
@@ -44,10 +43,9 @@
private final AppView<? extends AppInfoWithClassHierarchy> appView;
private final SubtypingInfo subtypingInfo;
private final Enqueuer enqueuer;
- private final ExecutorService executorService;
- private final List<Future<?>> futures = new ArrayList<>();
private final Map<Wrapper<ProguardIfRule>, Set<ProguardIfRule>> ifRules;
private final ConsequentRootSetBuilder rootSetBuilder;
+ private final TaskCollection<?> tasks;
IfRuleEvaluator(
AppView<? extends AppInfoWithClassHierarchy> appView,
@@ -59,9 +57,9 @@
this.appView = appView;
this.subtypingInfo = subtypingInfo;
this.enqueuer = enqueuer;
- this.executorService = executorService;
this.ifRules = ifRules;
this.rootSetBuilder = rootSetBuilder;
+ this.tasks = new TaskCollection<>(appView.options(), executorService);
}
public ConsequentRootSet run() throws ExecutionException {
@@ -96,17 +94,16 @@
// When matching an if rule against a type, the if-rule are filled with the current
// capture of wildcards. Propagate this down to member rules with same class part
// equivalence.
- ifRulesInEquivalence.forEach(
- ifRule -> {
- registerClassCapture(ifRule, clazz, clazz);
- if (appView.options().testing.measureProguardIfRuleEvaluations) {
- ifRuleEvaluationData.numberOfProguardIfRuleMemberEvaluations++;
- }
- boolean matched = evaluateIfRuleMembersAndMaterialize(ifRule, clazz, clazz);
- if (matched && canRemoveSubsequentKeepRule(ifRule)) {
- toRemove.add(ifRule);
- }
- });
+ for (ProguardIfRule ifRule : ifRulesInEquivalence) {
+ registerClassCapture(ifRule, clazz, clazz);
+ if (appView.options().testing.measureProguardIfRuleEvaluations) {
+ ifRuleEvaluationData.numberOfProguardIfRuleMemberEvaluations++;
+ }
+ boolean matched = evaluateIfRuleMembersAndMaterialize(ifRule, clazz, clazz);
+ if (matched && canRemoveSubsequentKeepRule(ifRule)) {
+ toRemove.add(ifRule);
+ }
+ }
}
// Check if one of the types that have been merged into `clazz` satisfies the if-rule.
@@ -131,17 +128,16 @@
ifRuleEvaluationData.numberOfProguardIfRuleClassEvaluations++;
}
if (evaluateClassForIfRule(ifRuleKey, sourceClass)) {
- ifRulesInEquivalence.forEach(
- ifRule -> {
- registerClassCapture(ifRule, sourceClass, clazz);
- if (appView.options().testing.measureProguardIfRuleEvaluations) {
- ifRuleEvaluationData.numberOfProguardIfRuleMemberEvaluations++;
- }
- if (evaluateIfRuleMembersAndMaterialize(ifRule, sourceClass, clazz)
- && canRemoveSubsequentKeepRule(ifRule)) {
- toRemove.add(ifRule);
- }
- });
+ for (ProguardIfRule ifRule : ifRulesInEquivalence) {
+ registerClassCapture(ifRule, sourceClass, clazz);
+ if (appView.options().testing.measureProguardIfRuleEvaluations) {
+ ifRuleEvaluationData.numberOfProguardIfRuleMemberEvaluations++;
+ }
+ if (evaluateIfRuleMembersAndMaterialize(ifRule, sourceClass, clazz)
+ && canRemoveSubsequentKeepRule(ifRule)) {
+ toRemove.add(ifRule);
+ }
+ }
}
}
}
@@ -152,7 +148,7 @@
ifRulesInEquivalence.removeAll(toRemove);
}
}
- ThreadUtils.awaitFutures(futures);
+ tasks.await();
}
} finally {
appView.appInfo().app().timing.end();
@@ -226,7 +222,7 @@
@SuppressWarnings("ReferenceEquality")
private boolean evaluateIfRuleMembersAndMaterialize(
- ProguardIfRule rule, DexClass sourceClass, DexClass targetClass) {
+ ProguardIfRule rule, DexClass sourceClass, DexClass targetClass) throws ExecutionException {
Collection<ProguardMemberRule> memberKeepRules = rule.getMemberRules();
if (memberKeepRules.isEmpty()) {
materializeIfRule(rule, ImmutableSet.of(sourceClass.getReference()));
@@ -327,7 +323,8 @@
}
@SuppressWarnings("BadImport")
- private void materializeIfRule(ProguardIfRule rule, Set<DexReference> preconditions) {
+ private void materializeIfRule(ProguardIfRule rule, Set<DexReference> preconditions)
+ throws ExecutionException {
DexItemFactory dexItemFactory = appView.dexItemFactory();
ProguardIfRule materializedRule = rule.materialize(dexItemFactory, preconditions);
@@ -337,14 +334,13 @@
ClassInlineRule neverClassInlineRuleForCondition =
materializedRule.neverClassInlineRuleForCondition(dexItemFactory);
if (neverClassInlineRuleForCondition != null) {
- rootSetBuilder.runPerRule(executorService, futures, neverClassInlineRuleForCondition, null);
+ rootSetBuilder.runPerRule(tasks, neverClassInlineRuleForCondition, null);
}
InlineRule neverInlineForClassInliningRuleForCondition =
materializedRule.neverInlineRuleForCondition(dexItemFactory, Type.NEVER_CLASS_INLINE);
if (neverInlineForClassInliningRuleForCondition != null) {
- rootSetBuilder.runPerRule(
- executorService, futures, neverInlineForClassInliningRuleForCondition, null);
+ rootSetBuilder.runPerRule(tasks, neverInlineForClassInliningRuleForCondition, null);
}
// If the condition of the -if rule has any members, then we need to keep these members to
@@ -353,20 +349,19 @@
InlineRule neverInlineRuleForCondition =
materializedRule.neverInlineRuleForCondition(dexItemFactory, Type.NEVER);
if (neverInlineRuleForCondition != null) {
- rootSetBuilder.runPerRule(executorService, futures, neverInlineRuleForCondition, null);
+ rootSetBuilder.runPerRule(tasks, neverInlineRuleForCondition, null);
}
// Prevent horizontal class merging of any -if rule members.
NoHorizontalClassMergingRule noHorizontalClassMergingRule =
materializedRule.noHorizontalClassMergingRuleForCondition(dexItemFactory);
if (noHorizontalClassMergingRule != null) {
- rootSetBuilder.runPerRule(executorService, futures, noHorizontalClassMergingRule, null);
+ rootSetBuilder.runPerRule(tasks, noHorizontalClassMergingRule, null);
}
}
// Keep whatever is required by the -if rule.
- rootSetBuilder.runPerRule(
- executorService, futures, materializedRule.subsequentRule, materializedRule);
+ rootSetBuilder.runPerRule(tasks, materializedRule.subsequentRule, materializedRule);
rule.markAsUsed();
}
}
diff --git a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
index 74c0ada..1e8f56d 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
@@ -62,6 +62,7 @@
import com.android.tools.r8.shaking.EnqueuerEvent.LiveClassEnqueuerEvent;
import com.android.tools.r8.shaking.EnqueuerEvent.UnconditionalKeepInfoEvent;
import com.android.tools.r8.shaking.KeepInfo.Joiner;
+import com.android.tools.r8.threading.TaskCollection;
import com.android.tools.r8.utils.ArrayUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.MethodSignatureEquivalence;
@@ -69,7 +70,6 @@
import com.android.tools.r8.utils.PredicateSet;
import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.StringDiagnostic;
-import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
import com.android.tools.r8.utils.TraversalContinuation;
import com.android.tools.r8.utils.collections.ProgramMethodMap;
@@ -100,7 +100,6 @@
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -324,11 +323,8 @@
}
}
- void runPerRule(
- ExecutorService executorService,
- List<Future<?>> futures,
- ProguardConfigurationRule rule,
- ProguardIfRule ifRule) {
+ void runPerRule(TaskCollection<?> tasks, ProguardConfigurationRule rule, ProguardIfRule ifRule)
+ throws ExecutionException {
List<DexType> specifics = rule.getClassNames().asSpecificDexTypes();
if (specifics != null) {
// This keep rule only lists specific type matches.
@@ -343,25 +339,24 @@
return;
}
- futures.add(
- executorService.submit(
- () -> {
- for (DexProgramClass clazz :
- rule.relevantCandidatesForRule(appView, subtypingInfo, application.classes())) {
- process(clazz, rule, ifRule);
- }
- if (rule.applyToNonProgramClasses()) {
- for (DexLibraryClass clazz : application.libraryClasses()) {
- process(clazz, rule, ifRule);
- }
- }
- }));
+ tasks.submit(
+ () -> {
+ for (DexProgramClass clazz :
+ rule.relevantCandidatesForRule(appView, subtypingInfo, application.classes())) {
+ process(clazz, rule, ifRule);
+ }
+ if (rule.applyToNonProgramClasses()) {
+ for (DexLibraryClass clazz : application.libraryClasses()) {
+ process(clazz, rule, ifRule);
+ }
+ }
+ });
}
public RootSet build(ExecutorService executorService) throws ExecutionException {
application.timing.begin("Build root set...");
try {
- List<Future<?>> futures = new ArrayList<>();
+ TaskCollection<?> tasks = new TaskCollection<>(options, executorService);
// Mark all the things explicitly listed in keep rules.
if (rules != null) {
for (ProguardConfigurationRule rule : rules) {
@@ -369,10 +364,10 @@
ProguardIfRule ifRule = (ProguardIfRule) rule;
ifRules.add(ifRule);
} else {
- runPerRule(executorService, futures, rule, null);
+ runPerRule(tasks, rule, null);
}
}
- ThreadUtils.awaitFutures(futures);
+ tasks.await();
}
} finally {
application.timing.end();