Move pinnedItems to descriptors.
Bug:
Change-Id: I07ca870f9b641413215dc447d0d58d0a71587a93
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 0ed71b8..9977151 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -224,7 +224,7 @@
if (options.proguardConfiguration.isPrintSeeds()) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
PrintStream out = new PrintStream(bytes);
- RootSetBuilder.writeSeeds(appInfo.withLiveness().getPinnedItems(), out);
+ RootSetBuilder.writeSeeds(appInfo.withLiveness(), out);
out.flush();
proguardSeedsData = bytes.toByteArray();
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java b/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java
index 5704e0f..fdaa541 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java
@@ -179,7 +179,7 @@
}
for (Node value : nodes.values()) {
// For non-pinned methods we know the exact number of call sites.
- if (!appInfo.withLiveness().isPinned(value.method)) {
+ if (!appInfo.withLiveness().isPinned(value.method.method)) {
if (value.invokeCount == 1) {
singleCallSite.add(value.method);
} else if (value.invokeCount == 2) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
index de0bab0..d71febe 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
@@ -239,7 +239,7 @@
// Without live set information we cannot tell and assume true.
if (liveSet == null
|| liveSet.fieldsRead.contains(field.field)
- || liveSet.isPinned(field)) {
+ || liveSet.isPinned(field.field)) {
return true;
}
// For library classes we don't know whether a field is read.
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 31a81f9..ed4d34d 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -5,6 +5,7 @@
import com.android.tools.r8.dex.IndexedItemCollection;
import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.Descriptor;
import com.android.tools.r8.graph.DexAnnotation;
@@ -1149,7 +1150,7 @@
this.staticFieldWrites = enqueuer.collectStaticFieldsWritten();
this.fieldsRead = enqueuer.collectFieldsRead();
this.fieldsWritten = enqueuer.collectFieldsWritten();
- this.pinnedItems = ImmutableSet.copyOf(enqueuer.pinnedItems);
+ this.pinnedItems = rewritePinnedItemsToDescriptors(enqueuer.pinnedItems);
this.virtualInvokes = joinInvokedMethods(enqueuer.virtualInvokes);
this.superInvokes = joinInvokedMethods(enqueuer.superInvokes);
this.directInvokes = joinInvokedMethods(enqueuer.directInvokes);
@@ -1208,8 +1209,7 @@
this.staticFieldWrites = rewriteItems(previous.staticFieldWrites, lense::lookupField);
this.fieldsRead = rewriteItems(previous.fieldsRead, lense::lookupField);
this.fieldsWritten = rewriteItems(previous.fieldsWritten, lense::lookupField);
- assert assertNotModifiedByLense(previous.pinnedItems, lense);
- this.pinnedItems = previous.pinnedItems;
+ this.pinnedItems = rewriteMixedItems(previous.pinnedItems, lense);
this.virtualInvokes = rewriteItems(previous.virtualInvokes, lense::lookupMethod);
this.superInvokes = rewriteItems(previous.superInvokes, lense::lookupMethod);
this.directInvokes = rewriteItems(previous.directInvokes, lense::lookupMethod);
@@ -1231,12 +1231,12 @@
private boolean assertNoItemRemoved(Collection<DexItem> items, Collection<DexType> types) {
Set<DexType> typeSet = ImmutableSet.copyOf(types);
for (DexItem item : items) {
- if (item instanceof DexClass) {
- assert !typeSet.contains(((DexClass) item).type);
- } else if (item instanceof DexEncodedMethod) {
- assert !typeSet.contains(((DexEncodedMethod) item).method.getHolder());
- } else if (item instanceof DexEncodedField) {
- assert !typeSet.contains(((DexEncodedField) item).field.getHolder());
+ if (item instanceof DexType) {
+ assert !typeSet.contains(item);
+ } else if (item instanceof DexMethod) {
+ assert !typeSet.contains(((DexMethod) item).getHolder());
+ } else if (item instanceof DexField) {
+ assert !typeSet.contains(((DexField) item).getHolder());
} else {
assert false;
}
@@ -1282,6 +1282,23 @@
return builder.build();
}
+ private ImmutableSet<DexItem> rewritePinnedItemsToDescriptors(Collection<DexItem> source) {
+ ImmutableSet.Builder<DexItem> builder = ImmutableSet.builder();
+ for (DexItem item : source) {
+ // TODO(67934123) There should be a common interface to extract this information.
+ if (item instanceof DexClass) {
+ builder.add(((DexClass) item).type);
+ } else if (item instanceof DexEncodedMethod) {
+ builder.add(((DexEncodedMethod) item).method);
+ } else if (item instanceof DexEncodedField) {
+ builder.add(((DexEncodedField) item).field);
+ } else {
+ throw new Unreachable();
+ }
+ }
+ return builder.build();
+ }
+
private static <T extends PresortedComparable<T>> ImmutableSortedSet<T> rewriteItems(
Set<T> original, BiFunction<T, DexEncodedMethod, T> rewrite) {
ImmutableSortedSet.Builder<T> builder =
@@ -1292,6 +1309,24 @@
return builder.build();
}
+ private static ImmutableSet<DexItem> rewriteMixedItems(
+ Set<DexItem> original, GraphLense lense) {
+ ImmutableSet.Builder<DexItem> builder = ImmutableSet.builder();
+ for (DexItem item : original) {
+ // TODO(67934123) There should be a common interface to perform the dispatch.
+ if (item instanceof DexType) {
+ builder.add(lense.lookupType((DexType) item, null));
+ } else if (item instanceof DexMethod) {
+ builder.add(lense.lookupMethod((DexMethod) item, null));
+ } else if (item instanceof DexField) {
+ builder.add(lense.lookupField((DexField) item, null));
+ } else {
+ throw new Unreachable();
+ }
+ }
+ return builder.build();
+ }
+
private static <T> Set<T> mergeSets(Collection<T> first, Collection<T> second) {
ImmutableSet.Builder<T> builder = ImmutableSet.builder();
builder.addAll(first);
@@ -1323,10 +1358,22 @@
return this;
}
- public boolean isPinned(DexItem item) {
+ // TODO(67934123) Unify into one method,
+ public boolean isPinned(DexType item) {
return pinnedItems.contains(item);
}
+ // TODO(67934123) Unify into one method,
+ public boolean isPinned(DexMethod item) {
+ return pinnedItems.contains(item);
+ }
+
+ // TODO(67934123) Unify into one method,
+ public boolean isPinned(DexField item) {
+ return pinnedItems.contains(item);
+ }
+
+
public Iterable<DexItem> getPinnedItems() {
return pinnedItems;
}
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 b55a7a0..177493a 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
+import com.android.tools.r8.dex.Constants;
+import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationSet;
@@ -19,6 +21,7 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DirectMappedDexApplication;
import com.android.tools.r8.logging.Log;
+import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.MethodSignatureEquivalence;
import com.android.tools.r8.utils.StringDiagnostic;
@@ -284,32 +287,34 @@
clazz.forEachField(field -> markField(field, memberKeepRules, rule, onlyIfClassKept));
}
- public static void writeSeeds(Iterable<DexItem> seeds, PrintStream out) {
- for (DexItem seed : seeds) {
- if (seed instanceof DexClass) {
- out.println(((DexClass) seed).type.toSourceString());
- } else if (seed instanceof DexEncodedField) {
- DexField field = ((DexEncodedField) seed).field;
+ // TODO(67934426): Test this code.
+ public static void writeSeeds(AppInfoWithLiveness appInfo, PrintStream out) {
+ for (DexItem seed : appInfo.getPinnedItems()) {
+ if (seed instanceof DexType) {
+ out.println(seed.toSourceString());
+ } else if (seed instanceof DexField) {
+ DexField field = ((DexField) seed);
out.println(
field.clazz.toSourceString() + ": " + field.type.toSourceString() + " " + field.name
.toSourceString());
- } else if (seed instanceof DexEncodedMethod) {
- DexEncodedMethod encodedMethod = (DexEncodedMethod) seed;
- DexMethod method = encodedMethod.method;
+ } else if (seed instanceof DexMethod) {
+ DexMethod method = (DexMethod) seed;
out.print(method.holder.toSourceString() + ": ");
+ DexEncodedMethod encodedMethod = appInfo.definitionFor(method);
if (encodedMethod.accessFlags.isConstructor()) {
if (encodedMethod.accessFlags.isStatic()) {
- out.print("<clinit>(");
+ out.print(Constants.CLASS_INITIALIZER_NAME);
} else {
String holderName = method.holder.toSourceString();
String constrName = holderName.substring(holderName.lastIndexOf('.') + 1);
- out.print(constrName + "(");
+ out.print(constrName);
}
} else {
out.print(
- method.proto.returnType.toSourceString() + " " + method.name.toSourceString() + "(");
+ method.proto.returnType.toSourceString() + " " + method.name.toSourceString());
}
boolean first = true;
+ out.print("(");
for (DexType param : method.proto.parameters.values) {
if (!first) {
out.print(",");
@@ -318,6 +323,8 @@
out.print(param.toSourceString());
}
out.println(")");
+ } else {
+ throw new Unreachable();
}
}
out.close();
diff --git a/src/main/java/com/android/tools/r8/shaking/SimpleClassMerger.java b/src/main/java/com/android/tools/r8/shaking/SimpleClassMerger.java
index bf2b761..9affabf 100644
--- a/src/main/java/com/android/tools/r8/shaking/SimpleClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/SimpleClassMerger.java
@@ -139,7 +139,7 @@
for (DexProgramClass clazz : application.classes()) {
if (isMergeCandidate(clazz)) {
DexClass targetClass = appInfo.definitionFor(clazz.type.getSingleSubtype());
- if (appInfo.isPinned(targetClass)) {
+ if (appInfo.isPinned(targetClass.type)) {
// We have to keep the target class intact, so we cannot merge it.
continue;
}