aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java')
-rw-r--r--src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java81
1 files changed, 50 insertions, 31 deletions
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 a6499842a..7b939ae20 100644
--- a/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java
@@ -3,10 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.naming;
-import com.android.tools.r8.utils.InternalOptions;
-import com.google.common.base.Equivalence.Wrapper;
-import com.google.common.collect.Sets;
-
import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMethod;
@@ -14,10 +10,15 @@ import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.shaking.ProguardConfiguration;
import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
+import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.MethodJavaSignatureEquivalence;
import com.android.tools.r8.utils.MethodSignatureEquivalence;
import com.android.tools.r8.utils.Timing;
-
+import com.google.common.base.Equivalence;
+import com.google.common.base.Equivalence.Wrapper;
+import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -25,6 +26,7 @@ import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.function.Function;
/**
* A pass to rename methods using common, short names.
@@ -87,10 +89,26 @@ import java.util.Set;
*/
class MethodNameMinifier extends MemberNameMinifier<DexMethod, DexProto> {
- private MethodSignatureEquivalence equivalence = MethodSignatureEquivalence.get();
+ private final Equivalence<DexMethod> equivalence;
+ private final ProguardConfiguration config;
MethodNameMinifier(AppInfoWithSubtyping appInfo, RootSet rootSet, InternalOptions options) {
super(appInfo, rootSet, options);
+ this.config = options.proguardConfiguration;
+ equivalence = config.isOverloadAggressively()
+ ? MethodSignatureEquivalence.get()
+ : MethodJavaSignatureEquivalence.get();
+ }
+
+ @Override
+ Function<DexProto, ?> getKeyTransform(ProguardConfiguration config) {
+ if (config.isOverloadAggressively()) {
+ // Use the full proto as key, hence reuse names based on full signature.
+ return a -> a;
+ } else {
+ // Only use the parameters as key, hence do not reuse names on return type.
+ return proto -> proto.parameters;
+ }
}
Map<DexMethod, DexString> computeRenaming(Timing timing) {
@@ -128,7 +146,7 @@ class MethodNameMinifier extends MemberNameMinifier<DexMethod, DexProto> {
private void assignNamesToClassesMethods(DexType type, boolean doPrivates) {
DexClass holder = appInfo.definitionFor(type);
if (holder != null && !holder.isLibraryClass()) {
- NamingState<DexProto> state =
+ NamingState<DexProto, ?> state =
computeStateIfAbsent(type, k -> getState(holder.superType).createChild());
holder.forEachMethod(method -> assignNameToMethod(method, state, doPrivates));
}
@@ -136,7 +154,7 @@ class MethodNameMinifier extends MemberNameMinifier<DexMethod, DexProto> {
}
private void assignNameToMethod(
- DexEncodedMethod encodedMethod, NamingState<DexProto> state, boolean doPrivates) {
+ DexEncodedMethod encodedMethod, NamingState<DexProto, ?> state, boolean doPrivates) {
if (encodedMethod.accessFlags.isPrivate() != doPrivates) {
return;
}
@@ -147,19 +165,19 @@ class MethodNameMinifier extends MemberNameMinifier<DexMethod, DexProto> {
}
}
- private Set<NamingState<DexProto>> getReachableStates(DexType type,
+ private Set<NamingState<DexProto, ?>> getReachableStates(DexType type,
Map<DexType, DexType> frontierMap) {
Set<DexType> interfaces = Sets.newIdentityHashSet();
interfaces.add(type);
collectSuperInterfaces(type, interfaces);
collectSubInterfaces(type, interfaces);
- Set<NamingState<DexProto>> reachableStates = new HashSet<>();
+ Set<NamingState<DexProto, ?>> reachableStates = new HashSet<>();
for (DexType iface : interfaces) {
// Add the interface itself
reachableStates.add(getState(iface));
// And the frontiers that correspond to the classes that implement the interface.
iface.forAllImplementsSubtypes(t -> {
- NamingState<DexProto> state = getState(frontierMap.get(t));
+ NamingState<DexProto, ?> state = getState(frontierMap.get(t));
assert state != null;
reachableStates.add(state);
});
@@ -173,16 +191,16 @@ class MethodNameMinifier extends MemberNameMinifier<DexMethod, DexProto> {
// reserve the names for later method naming.
timing.begin("Compute map");
// A map from DexMethods to all the states linked to interfaces they appear in.
- Map<Wrapper<DexMethod>, Set<NamingState<DexProto>>> globalStateMap = new HashMap<>();
+ Map<Wrapper<DexMethod>, Set<NamingState<DexProto, ?>>> globalStateMap = new HashMap<>();
// A map from DexMethods to all the definitions seen. Needed as the Wrapper equalizes them all.
Map<Wrapper<DexMethod>, Set<DexMethod>> sourceMethodsMap = new HashMap<>();
// A map from DexMethods to the first interface state it was seen in. Used to pick good names.
- Map<Wrapper<DexMethod>, NamingState<DexProto>> originStates = new HashMap<>();
+ Map<Wrapper<DexMethod>, NamingState<DexProto, ?>> originStates = new HashMap<>();
DexType.forAllInterfaces(appInfo.dexItemFactory, iface -> {
assert iface.isInterface();
DexClass clazz = appInfo.definitionFor(iface);
if (clazz != null) {
- Set<NamingState<DexProto>> collectedStates = getReachableStates(iface, frontierMap);
+ Set<NamingState<DexProto, ?>> collectedStates = getReachableStates(iface, frontierMap);
clazz.forEachMethod(method -> addStatesToGlobalMapForMethod(
method, collectedStates, globalStateMap, sourceMethodsMap, originStates, iface));
}
@@ -228,12 +246,12 @@ class MethodNameMinifier extends MemberNameMinifier<DexMethod, DexProto> {
}
private void addStatesToGlobalMapForMethod(
- DexEncodedMethod method, Set<NamingState<DexProto>> collectedStates,
- Map<Wrapper<DexMethod>, Set<NamingState<DexProto>>> globalStateMap,
+ DexEncodedMethod method, Set<NamingState<DexProto, ?>> collectedStates,
+ Map<Wrapper<DexMethod>, Set<NamingState<DexProto, ?>>> globalStateMap,
Map<Wrapper<DexMethod>, Set<DexMethod>> sourceMethodsMap,
- Map<Wrapper<DexMethod>, NamingState<DexProto>> originStates, DexType originInterface) {
+ Map<Wrapper<DexMethod>, NamingState<DexProto, ?>> originStates, DexType originInterface) {
Wrapper<DexMethod> key = equivalence.wrap(method.method);
- Set<NamingState<DexProto>> stateSet =
+ Set<NamingState<DexProto, ?>> stateSet =
globalStateMap.computeIfAbsent(key, k -> new HashSet<>());
stateSet.addAll(collectedStates);
sourceMethodsMap.computeIfAbsent(key, k -> new HashSet<>()).add(method.method);
@@ -242,12 +260,12 @@ class MethodNameMinifier extends MemberNameMinifier<DexMethod, DexProto> {
private void assignNameForInterfaceMethodInAllStates(
DexMethod method,
- Set<NamingState<DexProto>> collectedStates,
+ Set<NamingState<DexProto, ?>> collectedStates,
Set<DexMethod> sourceMethods,
- NamingState<DexProto> originState) {
+ NamingState<DexProto, ?> originState) {
boolean isReserved = false;
if (globalState.isReserved(method.name, method.proto)) {
- for (NamingState<DexProto> state : collectedStates) {
+ for (NamingState<DexProto, ?> state : collectedStates) {
if (state.isReserved(method.name, method.proto)) {
isReserved = true;
break;
@@ -255,7 +273,7 @@ class MethodNameMinifier extends MemberNameMinifier<DexMethod, DexProto> {
}
if (isReserved) {
// This method's name is reserved in at least on naming state, so reserve it everywhere.
- for (NamingState<DexProto> state : collectedStates) {
+ for (NamingState<DexProto, ?> state : collectedStates) {
state.reserveName(method.name, method.proto);
}
return;
@@ -267,14 +285,14 @@ class MethodNameMinifier extends MemberNameMinifier<DexMethod, DexProto> {
DexString candidate = null;
do {
candidate = originState.assignNewNameFor(method.name, method.proto, false);
- for (NamingState<DexProto> state : collectedStates) {
+ for (NamingState<DexProto, ?> state : collectedStates) {
if (!state.isAvailable(method.name, method.proto, candidate)) {
candidate = null;
break;
}
}
} while (candidate == null);
- for (NamingState<DexProto> state : collectedStates) {
+ for (NamingState<DexProto, ?> state : collectedStates) {
state.addRenaming(method.name, method.proto, candidate);
}
// Rename all methods in interfaces that gave rise to this renaming.
@@ -284,11 +302,11 @@ class MethodNameMinifier extends MemberNameMinifier<DexMethod, DexProto> {
}
private void reserveNamesInClasses(DexType type, DexType libraryFrontier,
- NamingState<DexProto> parent,
+ NamingState<DexProto, ?> parent,
Map<DexType, DexType> frontierMap) {
assert !type.isInterface();
DexClass holder = appInfo.definitionFor(type);
- NamingState<DexProto> state = allocateNamingStateAndReserve(holder, type, libraryFrontier,
+ NamingState<DexProto, ?> state = allocateNamingStateAndReserve(holder, type, libraryFrontier,
parent, frontierMap);
// If this is a library class (or effectively a library class as it is missing) move the
// frontier forward.
@@ -307,16 +325,17 @@ class MethodNameMinifier extends MemberNameMinifier<DexMethod, DexProto> {
allocateNamingStateAndReserve(holder, type, type, null, frontierMap);
}
- private NamingState<DexProto> allocateNamingStateAndReserve(DexClass holder, DexType type,
+ private NamingState<DexProto, ?> allocateNamingStateAndReserve(DexClass holder, DexType type,
DexType libraryFrontier,
- NamingState<DexProto> parent,
+ NamingState<DexProto, ?> parent,
Map<DexType, DexType> frontierMap) {
frontierMap.put(type, libraryFrontier);
- NamingState<DexProto> state =
+ NamingState<DexProto, ?> state =
computeStateIfAbsent(
libraryFrontier,
ignore -> parent == null
- ? NamingState.createRoot(appInfo.dexItemFactory, dictionary)
+ ? NamingState
+ .createRoot(appInfo.dexItemFactory, dictionary, getKeyTransform(config))
: parent.createChild());
if (holder != null) {
boolean keepAll = holder.isLibraryClass() || holder.accessFlags.isAnnotation();
@@ -326,7 +345,7 @@ class MethodNameMinifier extends MemberNameMinifier<DexMethod, DexProto> {
}
private void reserveNamesForMethod(DexEncodedMethod method,
- boolean keepAll, NamingState<DexProto> state) {
+ boolean keepAll, NamingState<DexProto, ?> state) {
if (keepAll || rootSet.noObfuscation.contains(method)) {
state.reserveName(method.method.name, method.method.proto);
globalState.reserveName(method.method.name, method.method.proto);