Introduce a "reported set" and prepare to split reasons from witness.
Bug: 120959039
Change-Id: I512ae6e9de917bdfa90eef8202049786885697b2
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 fd9a75f..1350e17 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -176,7 +176,7 @@
* Set of types that are mentioned in the program. We at least need an empty abstract class item
* for these.
*/
- private final SetWithReason<DexProgramClass> liveTypes;
+ private final SetWithReportedReason<DexProgramClass> liveTypes;
/** Set of live types defined in the library and classpath. Used to avoid duplicate tracing. */
private final Set<DexClass> liveNonProgramTypes = Sets.newIdentityHashSet();
@@ -304,7 +304,7 @@
registerAnalysis(new ProtoEnqueuerExtension(appView));
}
- liveTypes = new SetWithReason<>(graphReporter::registerClass);
+ liveTypes = new SetWithReportedReason<>();
liveAnnotations = new SetWithReason<>(graphReporter::registerAnnotation);
instantiatedTypes = new SetWithReason<>(graphReporter::registerClass);
targetedMethods = new SetWithReason<>(graphReporter::registerMethod);
@@ -451,14 +451,14 @@
pinnedItems.add(item.toReference());
}
- private void markInterfaceAsInstantiated(DexProgramClass clazz, KeepReason reason) {
+ private void markInterfaceAsInstantiated(DexProgramClass clazz, KeepReasonWitness witness) {
assert clazz.isInterface() && !clazz.accessFlags.isAnnotation();
- if (!instantiatedInterfaceTypes.add(clazz, reason)) {
+ if (!instantiatedInterfaceTypes.add(clazz, witness)) {
return;
}
populateInstantiatedTypesCache(clazz);
- markTypeAsLive(clazz, reason);
+ markTypeAsLive(clazz, witness);
}
private void enqueueFirstNonSerializableClassInitializer(
@@ -774,7 +774,7 @@
DexProgramClass clazz = getProgramClassOrNull(type);
if (clazz != null) {
if (clazz.isInterface()) {
- markTypeAsLive(clazz, keepReason);
+ markTypeAsLive(clazz, graphReporter.registerClass(clazz, keepReason));
} else {
markInstantiated(clazz, keepReason);
}
@@ -911,7 +911,7 @@
if (clazz != null) {
KeepReason reason = KeepReason.methodHandleReferencedIn(currentMethod);
if (clazz.isInterface() && !clazz.accessFlags.isAnnotation()) {
- markInterfaceAsInstantiated(clazz, reason);
+ markInterfaceAsInstantiated(clazz, graphReporter.registerClass(clazz, reason));
} else {
markInstantiated(clazz, reason);
}
@@ -1083,10 +1083,10 @@
markTypeAsLive(
holder,
scopedMethodsForLiveTypes.computeIfAbsent(type, ignore -> new ScopedDexMethodSet()),
- reason);
+ graphReporter.registerClass(holder, reason));
}
- private void markTypeAsLive(DexType type, Function<DexProgramClass, KeepReason> reason) {
+ private void markTypeAsLive(DexType type, Function<DexProgramClass, KeepReasonWitness> reason) {
if (type.isArrayType()) {
markTypeAsLive(type.toBaseType(appView.dexItemFactory()), reason);
return;
@@ -1105,16 +1105,16 @@
reason.apply(holder));
}
- private void markTypeAsLive(DexProgramClass clazz, KeepReason reason) {
+ private void markTypeAsLive(DexProgramClass clazz, KeepReasonWitness witness) {
markTypeAsLive(
clazz,
scopedMethodsForLiveTypes.computeIfAbsent(clazz.type, ignore -> new ScopedDexMethodSet()),
- reason);
+ witness);
}
private void markTypeAsLive(
- DexProgramClass holder, ScopedDexMethodSet seen, KeepReason reasonForType) {
- if (!liveTypes.add(holder, reasonForType)) {
+ DexProgramClass holder, ScopedDexMethodSet seen, KeepReasonWitness witness) {
+ if (!liveTypes.add(holder, witness)) {
return;
}
@@ -1432,7 +1432,7 @@
Log.verbose(getClass(), "Class `%s` is instantiated, processing...", clazz);
}
// This class becomes live, so it and all its supertypes become live types.
- markTypeAsLive(clazz, reason);
+ markTypeAsLive(clazz, graphReporter.registerClass(clazz, reason));
// For all methods of the class, if we have seen a call, mark the method live.
// We only do this for virtual calls, as the other ones will be done directly.
transitionMethodsForInstantiatedClass(clazz);
@@ -2489,12 +2489,13 @@
}
}
- private void markClassAsInstantiatedWithCompatRule(DexProgramClass clazz, KeepReason reason) {
+ private void markClassAsInstantiatedWithCompatRule(
+ DexProgramClass clazz, KeepReasonWitness witness) {
if (clazz.isInterface() && !clazz.accessFlags.isAnnotation()) {
- markInterfaceAsInstantiated(clazz, reason);
+ markInterfaceAsInstantiated(clazz, witness);
return;
}
- workList.enqueueMarkInstantiatedAction(clazz, reason);
+ workList.enqueueMarkInstantiatedAction(clazz, witness);
if (clazz.hasDefaultInitializer()) {
DexEncodedMethod defaultInitializer = clazz.getDefaultInitializer();
workList.enqueueMarkReachableDirectAction(
@@ -2845,6 +2846,24 @@
}
}
+ private static class SetWithReportedReason<T> {
+
+ private final Set<T> items = Sets.newIdentityHashSet();
+
+ boolean add(T item, KeepReasonWitness witness) {
+ assert witness != null;
+ return items.add(item);
+ }
+
+ boolean contains(T item) {
+ return items.contains(item);
+ }
+
+ Set<T> getItems() {
+ return Collections.unmodifiableSet(items);
+ }
+ }
+
private static class SetWithReason<T> {
private final Set<T> items = Sets.newIdentityHashSet();
diff --git a/src/main/java/com/android/tools/r8/shaking/GraphReporter.java b/src/main/java/com/android/tools/r8/shaking/GraphReporter.java
index e87abf0..5dc405e 100644
--- a/src/main/java/com/android/tools/r8/shaking/GraphReporter.java
+++ b/src/main/java/com/android/tools/r8/shaking/GraphReporter.java
@@ -175,7 +175,7 @@
getMethodGraphNode(defaultInitializer.method),
EdgeKind.CompatibilityRule);
}
- return KeepReasonWitness.COMPAT_INSTANCE;
+ return KeepReasonWitness.INSTANCE;
}
public KeepReasonWitness reportCompatKeepMethod(DexProgramClass holder, DexEncodedMethod method) {
@@ -184,10 +184,10 @@
// The rule is stating that if the method is targeted it is live. Since such an edge does
// not contribute to additional information in the kept graph as it stands (no distinction
// of targeted vs live edges), there is little point in emitting it.
- return KeepReasonWitness.COMPAT_INSTANCE;
+ return KeepReasonWitness.INSTANCE;
}
- public KeepReason reportCompatInstantiated(
+ public KeepReasonWitness reportCompatInstantiated(
DexProgramClass instantiated, DexEncodedMethod method) {
if (keptGraphConsumer != null) {
reportEdge(
@@ -195,7 +195,7 @@
getClassGraphNode(instantiated.type),
EdgeKind.CompatibilityRule);
}
- return KeepReasonWitness.COMPAT_INSTANCE;
+ return KeepReasonWitness.INSTANCE;
}
public KeepReasonWitness reportClassReferencedFrom(
@@ -240,7 +240,7 @@
return KeepReasonWitness.INSTANCE;
}
- public KeepReason reportCompanionClass(DexProgramClass iface, DexProgramClass companion) {
+ public KeepReasonWitness reportCompanionClass(DexProgramClass iface, DexProgramClass companion) {
assert iface.isInterface();
assert InterfaceMethodRewriter.isCompanionClassType(companion.type);
if (keptGraphConsumer == null) {
@@ -250,7 +250,7 @@
getClassGraphNode(iface.type), getClassGraphNode(companion.type), EdgeKind.CompanionClass);
}
- public KeepReason reportCompanionMethod(
+ public KeepReasonWitness reportCompanionMethod(
DexEncodedMethod definition, DexEncodedMethod implementation) {
assert InterfaceMethodRewriter.isCompanionClassType(implementation.method.holder);
if (keptGraphConsumer == null) {
@@ -276,13 +276,6 @@
public static class KeepReasonWitness extends KeepReason {
private static KeepReasonWitness INSTANCE = new KeepReasonWitness();
- private static KeepReasonWitness COMPAT_INSTANCE =
- new KeepReasonWitness() {
- @Override
- public boolean isDueToProguardCompatibility() {
- return true;
- }
- };
private KeepReasonWitness() {
// Only the reporter may create instances.
@@ -301,7 +294,7 @@
private boolean skipReporting(KeepReason reason) {
assert reason != null;
- if (reason == KeepReasonWitness.INSTANCE || reason == KeepReasonWitness.COMPAT_INSTANCE) {
+ if (reason == KeepReasonWitness.INSTANCE) {
return true;
}
assert getSourceNode(reason) != null;
diff --git a/src/main/java/com/android/tools/r8/shaking/KeepReason.java b/src/main/java/com/android/tools/r8/shaking/KeepReason.java
index 5f5d772..9dbb65e 100644
--- a/src/main/java/com/android/tools/r8/shaking/KeepReason.java
+++ b/src/main/java/com/android/tools/r8/shaking/KeepReason.java
@@ -64,10 +64,6 @@
return false;
}
- public boolean isDueToProguardCompatibility() {
- return false;
- }
-
public boolean isInstantiatedIn() {
return false;
}