Merge "Refactor name minification into strategies"
diff --git a/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java b/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java
index e2127dd..e419d5a 100644
--- a/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java
@@ -19,8 +19,9 @@
class FieldNameMinifier extends MemberNameMinifier<DexField, DexType> {
- FieldNameMinifier(AppView<AppInfoWithLiveness> appView, RootSet rootSet) {
- super(appView, rootSet);
+ FieldNameMinifier(
+ AppView<AppInfoWithLiveness> appView, RootSet rootSet, MemberNamingStrategy strategy) {
+ super(appView, rootSet, strategy);
}
@Override
@@ -106,7 +107,8 @@
private void renameField(DexEncodedField encodedField, NamingState<DexType, ?> state) {
DexField field = encodedField.field;
if (!state.isReserved(field.name, field.type)) {
- renaming.put(field, state.assignNewNameFor(field.name, field.type, useUniqueMemberNames));
+ renaming.put(
+ field, state.assignNewNameFor(field, field.name, field.type, useUniqueMemberNames));
}
}
diff --git a/src/main/java/com/android/tools/r8/naming/InterfaceMethodNameMinifier.java b/src/main/java/com/android/tools/r8/naming/InterfaceMethodNameMinifier.java
index b643be3..6c46119 100644
--- a/src/main/java/com/android/tools/r8/naming/InterfaceMethodNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/InterfaceMethodNameMinifier.java
@@ -234,7 +234,8 @@
sourceMethods.addAll(sourceMethodsMap.get(k));
for (NamingState<DexProto, ?> namingState : globalStateMap.get(k)) {
collectedStates.add(
- new MethodNamingState(namingState, unifiedMethod.name, unifiedMethod.proto));
+ new MethodNamingState(
+ namingState, unifiedMethod, unifiedMethod.name, unifiedMethod.proto));
}
}
@@ -249,7 +250,7 @@
}
MethodNamingState originState =
- new MethodNamingState(originStates.get(key), method.name, method.proto);
+ new MethodNamingState(originStates.get(key), method, method.name, method.proto);
assignNameForInterfaceMethodInAllStates(collectedStates, sourceMethods, originState);
}
diff --git a/src/main/java/com/android/tools/r8/naming/MemberNameMinifier.java b/src/main/java/com/android/tools/r8/naming/MemberNameMinifier.java
index 53957e4..d60de88 100644
--- a/src/main/java/com/android/tools/r8/naming/MemberNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/MemberNameMinifier.java
@@ -5,8 +5,10 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.CachedHashValueDexItem;
+import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.naming.NamingState.InternalState;
import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
import com.android.tools.r8.utils.InternalOptions;
@@ -36,7 +38,8 @@
// which is useful for debugging.
private final BiMap<DexType, NamingState<StateType, ?>> states = HashBiMap.create();
- MemberNameMinifier(AppView<AppInfoWithLiveness> appView, RootSet rootSet) {
+ MemberNameMinifier(
+ AppView<AppInfoWithLiveness> appView, RootSet rootSet, MemberNamingStrategy strategy) {
this.appView = appView;
this.appInfo = appView.appInfo();
this.rootSet = rootSet;
@@ -45,8 +48,9 @@
this.useUniqueMemberNames = options.getProguardConfiguration().isUseUniqueClassMemberNames();
this.overloadAggressively =
options.getProguardConfiguration().isOverloadAggressivelyWithoutUseUniqueClassMemberNames();
- this.globalState = NamingState.createRoot(
- appInfo.dexItemFactory, dictionary, getKeyTransform(), useUniqueMemberNames);
+ this.globalState =
+ NamingState.createRoot(
+ appInfo.dexItemFactory, dictionary, getKeyTransform(), strategy, useUniqueMemberNames);
}
abstract Function<StateType, ?> getKeyTransform();
@@ -88,4 +92,10 @@
return useUniqueMemberNames;
}
}
+
+ interface MemberNamingStrategy {
+ DexString next(DexReference source, InternalState internalState);
+
+ boolean bypassDictionary();
+ }
}
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 2cd8712..e97910f 100644
--- a/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java
@@ -91,9 +91,12 @@
private final Equivalence<DexMethod> equivalence;
private final FrontierState frontierState = new FrontierState();
+ private final MemberNamingStrategy strategy;
- MethodNameMinifier(AppView<AppInfoWithLiveness> appView, RootSet rootSet) {
- super(appView, rootSet);
+ MethodNameMinifier(
+ AppView<AppInfoWithLiveness> appView, RootSet rootSet, MemberNamingStrategy strategy) {
+ super(appView, rootSet, strategy);
+ this.strategy = strategy;
equivalence =
overloadAggressively
? MethodSignatureEquivalence.get()
@@ -188,7 +191,8 @@
DexString renamedName =
renamingAtThisLevel.computeIfAbsent(
equivalence.wrap(method),
- key -> state.assignNewNameFor(method.name, method.proto, useUniqueMemberNames));
+ key ->
+ state.assignNewNameFor(method, method.name, method.proto, useUniqueMemberNames));
renaming.put(method, renamedName);
}
}
@@ -233,6 +237,7 @@
appInfo.dexItemFactory,
dictionary,
getKeyTransform(),
+ strategy,
useUniqueMemberNames)
: parent.createChild());
@@ -276,8 +281,11 @@
private final NamingState<DexProto, ?> parent;
private final DexString name;
private final DexProto proto;
+ private final DexMethod method;
- MethodNamingState(NamingState<DexProto, ?> parent, DexString name, DexProto proto) {
+ MethodNamingState(
+ NamingState<DexProto, ?> parent, DexMethod method, DexString name, DexProto proto) {
+ this.method = method;
assert parent != null;
this.parent = parent;
this.name = name;
@@ -285,11 +293,7 @@
}
DexString assignNewName() {
- return parent.assignNewNameFor(name, proto, false);
- }
-
- void reserveName() {
- parent.reserveName(name, proto);
+ return parent.assignNewNameFor(method, name, proto, false);
}
boolean isReserved() {
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 f0f4011..9aa8502 100644
--- a/src/main/java/com/android/tools/r8/naming/Minifier.java
+++ b/src/main/java/com/android/tools/r8/naming/Minifier.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.naming.ClassNameMinifier.ClassNamingStrategy;
@@ -13,7 +14,9 @@
import com.android.tools.r8.naming.ClassNameMinifier.Namespace;
import com.android.tools.r8.naming.ClassNameMinifier.PackageNamingStrategy;
import com.android.tools.r8.naming.FieldNameMinifier.FieldRenaming;
+import com.android.tools.r8.naming.MemberNameMinifier.MemberNamingStrategy;
import com.android.tools.r8.naming.MethodNameMinifier.MethodRenaming;
+import com.android.tools.r8.naming.NamingState.InternalState;
import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
import com.android.tools.r8.utils.InternalOptions;
@@ -60,16 +63,19 @@
classRenaming, MethodRenaming.empty(), FieldRenaming.empty(), appInfo)
.verifyNoCollisions(appInfo.classes(), appInfo.dexItemFactory);
+ MemberNamingStrategy minifyMembers = new MinifierMemberNamingStrategy(appView.dexItemFactory());
timing.begin("MinifyMethods");
MethodRenaming methodRenaming =
- new MethodNameMinifier(appView, rootSet).computeRenaming(desugaredCallSites, timing);
+ new MethodNameMinifier(appView, rootSet, minifyMembers)
+ .computeRenaming(desugaredCallSites, timing);
timing.end();
assert new MinifiedRenaming(classRenaming, methodRenaming, FieldRenaming.empty(), appInfo)
.verifyNoCollisions(appInfo.classes(), appInfo.dexItemFactory);
timing.begin("MinifyFields");
- FieldRenaming fieldRenaming = new FieldNameMinifier(appView, rootSet).computeRenaming(timing);
+ FieldRenaming fieldRenaming =
+ new FieldNameMinifier(appView, rootSet, minifyMembers).computeRenaming(timing);
timing.end();
NamingLens lens = new MinifiedRenaming(classRenaming, methodRenaming, fieldRenaming, appInfo);
@@ -129,4 +135,26 @@
return false;
}
}
+
+ static class MinifierMemberNamingStrategy implements MemberNamingStrategy {
+
+ char[] EMPTY_CHAR_ARRAY = new char[0];
+
+ private final DexItemFactory factory;
+
+ public MinifierMemberNamingStrategy(DexItemFactory factory) {
+ this.factory = factory;
+ }
+
+ @Override
+ public DexString next(DexReference dexReference, InternalState internalState) {
+ int counter = internalState.incrementAndGet();
+ return factory.createString(StringUtils.numberToIdentifier(EMPTY_CHAR_ARRAY, counter, false));
+ }
+
+ @Override
+ public boolean bypassDictionary() {
+ return false;
+ }
+ }
}
diff --git a/src/main/java/com/android/tools/r8/naming/NamingState.java b/src/main/java/com/android/tools/r8/naming/NamingState.java
index d414b3b..a3352ad 100644
--- a/src/main/java/com/android/tools/r8/naming/NamingState.java
+++ b/src/main/java/com/android/tools/r8/naming/NamingState.java
@@ -5,8 +5,9 @@
import com.android.tools.r8.graph.CachedHashValueDexItem;
import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexString;
-import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.naming.MemberNameMinifier.MemberNamingStrategy;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
@@ -27,14 +28,17 @@
private final DexItemFactory itemFactory;
private final List<String> dictionary;
private final Function<ProtoType, KeyType> keyTransform;
+ private final MemberNamingStrategy strategy;
private final boolean useUniqueMemberNames;
static <S, T extends CachedHashValueDexItem> NamingState<T, S> createRoot(
DexItemFactory itemFactory,
List<String> dictionary,
Function<T, S> keyTransform,
+ MemberNamingStrategy strategy,
boolean useUniqueMemberNames) {
- return new NamingState<>(null, itemFactory, dictionary, keyTransform, useUniqueMemberNames);
+ return new NamingState<>(
+ null, itemFactory, dictionary, keyTransform, strategy, useUniqueMemberNames);
}
private NamingState(
@@ -42,16 +46,19 @@
DexItemFactory itemFactory,
List<String> dictionary,
Function<ProtoType, KeyType> keyTransform,
+ MemberNamingStrategy strategy,
boolean useUniqueMemberNames) {
this.parent = parent;
this.itemFactory = itemFactory;
this.dictionary = dictionary;
this.keyTransform = keyTransform;
+ this.strategy = strategy;
this.useUniqueMemberNames = useUniqueMemberNames;
}
public NamingState<ProtoType, KeyType> createChild() {
- return new NamingState<>(this, itemFactory, dictionary, keyTransform, useUniqueMemberNames);
+ return new NamingState<>(
+ this, itemFactory, dictionary, keyTransform, strategy, useUniqueMemberNames);
}
private InternalState findInternalStateFor(KeyType key) {
@@ -85,12 +92,13 @@
return state.getAssignedNameFor(name, key);
}
- public DexString assignNewNameFor(DexString original, ProtoType proto, boolean markAsUsed) {
+ public DexString assignNewNameFor(
+ DexReference source, DexString original, ProtoType proto, boolean markAsUsed) {
KeyType key = keyTransform.apply(proto);
DexString result = getAssignedNameFor(original, key);
if (result == null) {
InternalState state = getOrCreateInternalStateFor(key);
- result = state.getNameFor(original, key, markAsUsed);
+ result = state.getNameFor(source, original, key, markAsUsed);
}
return result;
}
@@ -146,7 +154,6 @@
class InternalState {
private static final int INITIAL_NAME_COUNT = 1;
- private final char[] EMPTY_CHAR_ARRAY = new char[0];
protected final DexItemFactory itemFactory;
private final InternalState parentInternalState;
@@ -193,6 +200,10 @@
reservedNames.add(name);
}
+ public int incrementAndGet() {
+ return nameCount++;
+ }
+
DexString getAssignedNameFor(DexString original, KeyType proto) {
DexString result = null;
if (renamings != null) {
@@ -215,13 +226,14 @@
return result;
}
- DexString getNameFor(DexString original, KeyType proto, boolean markAsUsed) {
+ DexString getNameFor(
+ DexReference source, DexString original, KeyType proto, boolean markAsUsed) {
DexString name = getAssignedNameFor(original, proto);
if (name != null) {
return name;
}
do {
- name = itemFactory.createString(nextSuggestedName());
+ name = nextSuggestedName(source);
} while (!isAvailable(name));
if (markAsUsed) {
addRenaming(original, proto, name);
@@ -236,11 +248,11 @@
renamings.put(original, proto, newName);
}
- String nextSuggestedName() {
- if (dictionaryIterator.hasNext()) {
- return dictionaryIterator.next();
+ DexString nextSuggestedName(DexReference source) {
+ if (!strategy.bypassDictionary() && dictionaryIterator.hasNext()) {
+ return itemFactory.createString(dictionaryIterator.next());
} else {
- return StringUtils.numberToIdentifier(EMPTY_CHAR_ARRAY, nameCount++, false);
+ return strategy.next(source, this);
}
}