Avoid resolution in naming lens
Fixes: 167385969
Change-Id: Icec1f2b2749756cec51da6498d8de5c587ea9fc9
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java
index dc34e88..60e9559 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java
@@ -493,7 +493,6 @@
@Override
public void fixup(DexEncodedField field, MutableFieldOptimizationInfo optimizationInfo) {
optimizationInfo
- .asMutableFieldOptimizationInfo()
.fixupClassTypeReferences(appView, appView.graphLens())
.fixupAbstractValue(appView, appView.graphLens());
}
diff --git a/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java b/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java
index 0f50ecb..6ca2736 100644
--- a/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java
@@ -9,16 +9,24 @@
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.MethodAccessInfoCollection;
+import com.android.tools.r8.graph.ResolutionResult;
import com.android.tools.r8.graph.SubtypingInfo;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableMap;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.IdentityHashMap;
+import java.util.List;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
import java.util.function.Function;
/**
@@ -87,8 +95,10 @@
// from the method name minifier to the interface method name minifier.
class State {
- void putRenaming(DexEncodedMethod key, DexString value) {
- renaming.put(key.getReference(), value);
+ void putRenaming(DexEncodedMethod key, DexString newName) {
+ if (newName != key.getName()) {
+ renaming.put(key.getReference(), newName);
+ }
}
MethodReservationState<?> getReservationState(DexType type) {
@@ -173,7 +183,9 @@
}
}
- MethodRenaming computeRenaming(Iterable<DexClass> interfaces, Timing timing) {
+ MethodRenaming computeRenaming(
+ Iterable<DexClass> interfaces, ExecutorService executorService, Timing timing)
+ throws ExecutionException {
// Phase 1: Reserve all the names that need to be kept and allocate linked state in the
// library part.
timing.begin("Phase 1");
@@ -193,6 +205,9 @@
timing.begin("Phase 4");
assignNamesToClassesMethods(appView.dexItemFactory().objectType, rootNamingState);
timing.end();
+ timing.begin("Phase 5: non-rebound references");
+ renameNonReboundReferences(executorService);
+ timing.end();
return new MethodRenaming(renaming);
}
@@ -322,6 +337,60 @@
return reservationState;
}
+ private void renameNonReboundReferences(ExecutorService executorService)
+ throws ExecutionException {
+ Map<DexMethod, DexString> nonReboundRenamings = new ConcurrentHashMap<>();
+ MethodAccessInfoCollection methodAccessInfoCollection =
+ appView.appInfo().getMethodAccessInfoCollection();
+ ThreadUtils.processItems(
+ methodAccessInfoCollection::forEachMethodReference,
+ method -> renameNonReboundMethodReference(method, nonReboundRenamings),
+ executorService);
+ renaming.putAll(nonReboundRenamings);
+ }
+
+ private void renameNonReboundMethodReference(
+ DexMethod method, Map<DexMethod, DexString> nonReboundRenamings) {
+ if (method.getHolderType().isArrayType()) {
+ return;
+ }
+
+ DexClass holder = appView.contextIndependentDefinitionFor(method.getHolderType());
+ if (holder == null) {
+ return;
+ }
+
+ ResolutionResult resolutionResult = appView.appInfo().resolveMethodOn(holder, method);
+ if (resolutionResult.isSingleResolution()) {
+ DexEncodedMethod resolvedMethod = resolutionResult.getSingleTarget();
+ if (resolvedMethod.getReference() == method) {
+ return;
+ }
+
+ DexString newName = renaming.get(resolvedMethod.getReference());
+ if (newName != null) {
+ assert newName != resolvedMethod.getName();
+ nonReboundRenamings.put(method, newName);
+ }
+ return;
+ }
+
+ // If resolution fails, the method must be renamed consistently with the targets that give rise
+ // to the failure.
+ assert resolutionResult.isFailedResolution();
+
+ List<DexEncodedMethod> targets = new ArrayList<>();
+ resolutionResult.asFailedResolution().forEachFailureDependency(targets::add);
+ if (!targets.isEmpty()) {
+ DexString newName = renaming.get(targets.get(0).getReference());
+ assert targets.stream().allMatch(target -> renaming.get(target.getReference()) == newName);
+ if (newName != null) {
+ assert newName != targets.get(0).getName();
+ nonReboundRenamings.put(method, newName);
+ }
+ }
+ }
+
// Shuffles the given methods if assertions are enabled and deterministic debugging is disabled.
// Used to ensure that the generated output is deterministic.
private static Iterable<DexEncodedMethod> shuffleMethods(
diff --git a/src/main/java/com/android/tools/r8/naming/MinifiedRenaming.java b/src/main/java/com/android/tools/r8/naming/MinifiedRenaming.java
index a51edde..c44d311 100644
--- a/src/main/java/com/android/tools/r8/naming/MinifiedRenaming.java
+++ b/src/main/java/com/android/tools/r8/naming/MinifiedRenaming.java
@@ -20,9 +20,7 @@
import com.android.tools.r8.naming.NamingLens.NonIdentityNamingLens;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.InternalOptions;
-import java.util.ArrayList;
import java.util.IdentityHashMap;
-import java.util.List;
import java.util.Map;
class MinifiedRenaming extends NonIdentityNamingLens {
@@ -89,36 +87,12 @@
@Override
public DexString lookupName(DexMethod method) {
- DexString renamed = renaming.get(method);
- if (renamed != null) {
- return renamed;
- }
- // If the method does not have a direct renaming, return the resolutions mapping.
- ResolutionResult resolutionResult = appView.appInfo().unsafeResolveMethodDueToDexFormat(method);
- if (resolutionResult.isSingleResolution()) {
- return renaming.getOrDefault(resolutionResult.getSingleTarget().getReference(), method.name);
- }
- // If resolution fails, the method must be renamed consistently with the targets that give rise
- // to the failure.
- if (resolutionResult.isFailedResolution()) {
- List<DexEncodedMethod> targets = new ArrayList<>();
- resolutionResult.asFailedResolution().forEachFailureDependency(targets::add);
- if (!targets.isEmpty()) {
- DexString firstRename = renaming.get(targets.get(0).getReference());
- assert targets.stream()
- .allMatch(target -> renaming.get(target.getReference()) == firstRename);
- if (firstRename != null) {
- return firstRename;
- }
- }
- }
- // If no renaming can be found the default is the methods name.
- return method.name;
+ return renaming.getOrDefault(method, method.getName());
}
@Override
public DexString lookupName(DexField field) {
- return renaming.getOrDefault(field, field.name);
+ return renaming.getOrDefault(field, field.getName());
}
/**
diff --git a/src/main/java/com/android/tools/r8/naming/Minifier.java b/src/main/java/com/android/tools/r8/naming/Minifier.java
index c5b8ced..e7106a6 100644
--- a/src/main/java/com/android/tools/r8/naming/Minifier.java
+++ b/src/main/java/com/android/tools/r8/naming/Minifier.java
@@ -67,7 +67,7 @@
timing.begin("MinifyMethods");
MethodRenaming methodRenaming =
new MethodNameMinifier(appView, subtypingInfo, minifyMembers)
- .computeRenaming(interfaces, timing);
+ .computeRenaming(interfaces, executorService, timing);
timing.end();
assert new MinifiedRenaming(appView, classRenaming, methodRenaming, FieldRenaming.empty())
diff --git a/src/main/java/com/android/tools/r8/naming/ProguardMapMinifier.java b/src/main/java/com/android/tools/r8/naming/ProguardMapMinifier.java
index 92a507b..74737eb 100644
--- a/src/main/java/com/android/tools/r8/naming/ProguardMapMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/ProguardMapMinifier.java
@@ -145,7 +145,7 @@
timing.begin("MinifyMethods");
MethodRenaming methodRenaming =
new MethodNameMinifier(appView, subtypingInfo, nameStrategy)
- .computeRenaming(interfaces, timing);
+ .computeRenaming(interfaces, executorService, timing);
// Amend the method renamings with the default interface methods.
methodRenaming.renaming.putAll(defaultInterfaceMethodImplementationNames);
methodRenaming.renaming.putAll(additionalMethodNamings);