Allow many-to-many methods mappings in graph lens
Change-Id: I1dd2a8796d28169a323a96c5ffd726a1cda6b160
diff --git a/src/main/java/com/android/tools/r8/graph/GraphLens.java b/src/main/java/com/android/tools/r8/graph/GraphLens.java
index 398ed87..5a10844 100644
--- a/src/main/java/com/android/tools/r8/graph/GraphLens.java
+++ b/src/main/java/com/android/tools/r8/graph/GraphLens.java
@@ -14,6 +14,8 @@
import com.android.tools.r8.utils.Action;
import com.android.tools.r8.utils.IterableUtils;
import com.android.tools.r8.utils.SetUtils;
+import com.android.tools.r8.utils.collections.BidirectionalManyToManyRepresentativeMap;
+import com.android.tools.r8.utils.collections.BidirectionalOneToOneHashMap;
import com.android.tools.r8.utils.collections.ProgramMethodSet;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
@@ -229,7 +231,8 @@
protected final Map<DexField, DexField> fieldMap = new IdentityHashMap<>();
protected final BiMap<DexField, DexField> originalFieldSignatures = HashBiMap.create();
- protected final BiMap<DexMethod, DexMethod> originalMethodSignatures = HashBiMap.create();
+ protected final BidirectionalOneToOneHashMap<DexMethod, DexMethod> originalMethodSignatures =
+ new BidirectionalOneToOneHashMap<>();
public void map(DexType from, DexType to) {
if (from == to) {
@@ -965,7 +968,8 @@
// Maps that store the original signature of fields and methods that have been affected, for
// example, by vertical class merging. Needed to generate a correct Proguard map in the end.
protected final BiMap<DexField, DexField> originalFieldSignatures;
- protected BiMap<DexMethod, DexMethod> originalMethodSignatures;
+ protected BidirectionalManyToManyRepresentativeMap<DexMethod, DexMethod>
+ originalMethodSignatures;
// Overrides this if the sub type needs to be a nested lens while it doesn't have any mappings
// at all, e.g., publicizer lens that changes invocation type only.
@@ -978,7 +982,7 @@
Map<DexMethod, DexMethod> methodMap,
Map<DexField, DexField> fieldMap,
BiMap<DexField, DexField> originalFieldSignatures,
- BiMap<DexMethod, DexMethod> originalMethodSignatures,
+ BidirectionalManyToManyRepresentativeMap<DexMethod, DexMethod> originalMethodSignatures,
GraphLens previousLens,
DexItemFactory dexItemFactory) {
super(dexItemFactory, previousLens);
@@ -1138,15 +1142,11 @@
@Override
protected DexMethod internalGetPreviousMethodSignature(DexMethod method) {
- return originalMethodSignatures != null
- ? originalMethodSignatures.getOrDefault(method, method)
- : method;
+ return originalMethodSignatures.getRepresentativeValueOrDefault(method, method);
}
protected DexMethod internalGetNextMethodSignature(DexMethod method) {
- return originalMethodSignatures != null
- ? originalMethodSignatures.inverse().getOrDefault(method, method)
- : method;
+ return originalMethodSignatures.getRepresentativeKeyOrDefault(method, method);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMergerGraphLens.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMergerGraphLens.java
index cc0528f..d348b61 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMergerGraphLens.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMergerGraphLens.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
import com.android.tools.r8.ir.conversion.ExtraParameter;
import com.android.tools.r8.utils.IterableUtils;
+import com.android.tools.r8.utils.collections.BidirectionalOneToOneHashMap;
import com.google.common.collect.BiMap;
import java.util.ArrayList;
import java.util.Collections;
@@ -22,7 +23,7 @@
import java.util.function.Function;
public class HorizontalClassMergerGraphLens extends NestedGraphLens {
- private final AppView<?> appView;
+
private final Map<DexMethod, List<ExtraParameter>> methodExtraParameters;
private final Map<DexMethod, DexMethod> extraOriginalMethodSignatures;
private final HorizontallyMergedClasses mergedClasses;
@@ -35,7 +36,7 @@
Map<DexField, DexField> fieldMap,
Map<DexMethod, DexMethod> methodMap,
BiMap<DexField, DexField> originalFieldSignatures,
- BiMap<DexMethod, DexMethod> originalMethodSignatures,
+ BidirectionalOneToOneHashMap<DexMethod, DexMethod> originalMethodSignatures,
Map<DexMethod, DexMethod> extraOriginalMethodSignatures,
Map<DexField, DexField> extraOriginalFieldSignatures,
GraphLens previousLens) {
@@ -47,7 +48,6 @@
originalMethodSignatures,
previousLens,
appView.dexItemFactory());
- this.appView = appView;
this.methodExtraParameters = methodExtraParameters;
this.extraOriginalFieldSignatures = extraOriginalFieldSignatures;
this.extraOriginalMethodSignatures = extraOriginalMethodSignatures;
@@ -127,7 +127,7 @@
methodExtraParameters,
fieldMap.getForwardMap(),
methodMap.getForwardMap(),
- inverseFieldMap.getBiMap(),
+ inverseFieldMap.getBiMap().getForwardBacking(),
inverseMethodMap.getBiMap(),
inverseMethodMap.getExtraMap(),
inverseFieldMap.getExtraMap(),
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/ManyToOneInverseMap.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/ManyToOneInverseMap.java
index 8da9b0f..973162f 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/ManyToOneInverseMap.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/ManyToOneInverseMap.java
@@ -4,20 +4,20 @@
package com.android.tools.r8.horizontalclassmerging;
-import com.google.common.collect.BiMap;
+import com.android.tools.r8.utils.collections.BidirectionalOneToOneHashMap;
import java.util.Map;
/** The inverse of a {@link ManyToOneMap} used for generating graph lens maps. */
public class ManyToOneInverseMap<K, V> {
- private final BiMap<V, K> biMap;
+ private final BidirectionalOneToOneHashMap<V, K> biMap;
private final Map<V, K> extraMap;
- ManyToOneInverseMap(BiMap<V, K> biMap, Map<V, K> extraMap) {
+ ManyToOneInverseMap(BidirectionalOneToOneHashMap<V, K> biMap, Map<V, K> extraMap) {
this.biMap = biMap;
this.extraMap = extraMap;
}
- public BiMap<V, K> getBiMap() {
+ public BidirectionalOneToOneHashMap<V, K> getBiMap() {
return biMap;
}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/ManyToOneMap.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/ManyToOneMap.java
index 675d24c..5204021 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/ManyToOneMap.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/ManyToOneMap.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.horizontalclassmerging;
+import com.android.tools.r8.utils.collections.BidirectionalOneToOneHashMap;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import java.util.HashMap;
@@ -49,7 +50,7 @@
}
public ManyToOneInverseMap<K, V> inverse(Function<Set<K>, K> pickRepresentative) {
- BiMap<V, K> biMap = HashBiMap.create();
+ BidirectionalOneToOneHashMap<V, K> biMap = new BidirectionalOneToOneHashMap<>();
Map<V, K> extraMap = new HashMap<>();
for (Entry<V, Set<K>> entry : inverseMap.entrySet()) {
K representative = representativeMap.get(entry.getKey());
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriterFixup.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriterFixup.java
index 995f693..ed8077a 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriterFixup.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriterFixup.java
@@ -53,7 +53,8 @@
return null;
}
// Map default methods to their companion methods.
- DexMethod mappedMethod = graphLens.getExtraOriginalMethodSignatures().inverse().get(method);
+ DexMethod mappedMethod =
+ graphLens.getExtraOriginalMethodSignatures().getRepresentativeKey(method);
if (mappedMethod != null) {
return mappedMethod;
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
index f9086e0..88e1200 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
@@ -48,8 +48,9 @@
import com.android.tools.r8.ir.synthetic.ForwardMethodBuilder;
import com.android.tools.r8.origin.SynthesizedOrigin;
import com.android.tools.r8.utils.Pair;
+import com.android.tools.r8.utils.collections.BidirectionalManyToManyRepresentativeMap;
+import com.android.tools.r8.utils.collections.BidirectionalOneToOneHashMap;
import com.google.common.collect.BiMap;
-import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableList;
import java.util.ArrayDeque;
import java.util.ArrayList;
@@ -514,15 +515,16 @@
// are to static companion methods.
public static class InterfaceProcessorNestedGraphLens extends NestedGraphLens {
- private BiMap<DexMethod, DexMethod> extraOriginalMethodSignatures;
+ private BidirectionalManyToManyRepresentativeMap<DexMethod, DexMethod>
+ extraOriginalMethodSignatures;
public InterfaceProcessorNestedGraphLens(
Map<DexType, DexType> typeMap,
Map<DexMethod, DexMethod> methodMap,
Map<DexField, DexField> fieldMap,
BiMap<DexField, DexField> originalFieldSignatures,
- BiMap<DexMethod, DexMethod> originalMethodSignatures,
- BiMap<DexMethod, DexMethod> extraOriginalMethodSignatures,
+ BidirectionalOneToOneHashMap<DexMethod, DexMethod> originalMethodSignatures,
+ BidirectionalOneToOneHashMap<DexMethod, DexMethod> extraOriginalMethodSignatures,
GraphLens previousLens,
DexItemFactory dexItemFactory) {
super(
@@ -551,12 +553,13 @@
}
public void toggleMappingToExtraMethods() {
- BiMap<DexMethod, DexMethod> tmp = originalMethodSignatures;
+ BidirectionalManyToManyRepresentativeMap<DexMethod, DexMethod> tmp = originalMethodSignatures;
this.originalMethodSignatures = extraOriginalMethodSignatures;
this.extraOriginalMethodSignatures = tmp;
}
- public BiMap<DexMethod, DexMethod> getExtraOriginalMethodSignatures() {
+ public BidirectionalManyToManyRepresentativeMap<DexMethod, DexMethod>
+ getExtraOriginalMethodSignatures() {
return extraOriginalMethodSignatures;
}
@@ -577,16 +580,14 @@
@Override
protected DexMethod internalGetPreviousMethodSignature(DexMethod method) {
- return extraOriginalMethodSignatures.getOrDefault(
- method, originalMethodSignatures.getOrDefault(method, method));
+ return extraOriginalMethodSignatures.getRepresentativeValueOrDefault(
+ method, originalMethodSignatures.getRepresentativeValueOrDefault(method, method));
}
@Override
protected DexMethod internalGetNextMethodSignature(DexMethod method) {
- return originalMethodSignatures
- .inverse()
- .getOrDefault(
- method, extraOriginalMethodSignatures.inverse().getOrDefault(method, method));
+ return originalMethodSignatures.getRepresentativeKeyOrDefault(
+ method, extraOriginalMethodSignatures.getRepresentativeKeyOrDefault(method, method));
}
@Override
@@ -600,7 +601,8 @@
public static class Builder extends NestedGraphLens.Builder {
- private final BiMap<DexMethod, DexMethod> extraOriginalMethodSignatures = HashBiMap.create();
+ private final BidirectionalOneToOneHashMap<DexMethod, DexMethod>
+ extraOriginalMethodSignatures = new BidirectionalOneToOneHashMap<>();
public void recordCodeMovedToCompanionClass(DexMethod from, DexMethod to) {
assert from != to;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
index 9688ae8..e4d6f65 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
@@ -42,6 +42,7 @@
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.conversion.IRConverter;
import com.android.tools.r8.utils.DescriptorUtils;
+import com.android.tools.r8.utils.collections.BidirectionalOneToOneHashMap;
import com.android.tools.r8.utils.collections.SortedProgramMethodSet;
import com.google.common.base.Suppliers;
import com.google.common.collect.BiMap;
@@ -440,7 +441,7 @@
Map<DexMethod, DexMethod> methodMap,
Map<DexField, DexField> fieldMap,
BiMap<DexField, DexField> originalFieldSignatures,
- BiMap<DexMethod, DexMethod> originalMethodSignatures,
+ BidirectionalOneToOneHashMap<DexMethod, DexMethod> originalMethodSignatures,
GraphLens previousLens,
DexItemFactory dexItemFactory) {
super(
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/NestedPrivateMethodLens.java b/src/main/java/com/android/tools/r8/ir/desugar/NestedPrivateMethodLens.java
index 7f99055..8889ec2 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/NestedPrivateMethodLens.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/NestedPrivateMethodLens.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
import com.android.tools.r8.graph.RewrittenPrototypeDescription;
import com.android.tools.r8.ir.code.Invoke.Type;
+import com.android.tools.r8.utils.collections.BidirectionalManyToManyRepresentativeMap;
import com.google.common.collect.ImmutableMap;
import java.util.IdentityHashMap;
import java.util.Map;
@@ -35,7 +36,7 @@
methodMap,
ImmutableMap.of(),
null,
- null,
+ BidirectionalManyToManyRepresentativeMap.empty(),
previousLens,
appView.dexItemFactory());
// No concurrent maps here, we do not want synchronization overhead.
@@ -110,7 +111,6 @@
@Override
public MethodLookupResult internalDescribeLookupMethod(
MethodLookupResult previous, DexMethod context) {
- assert originalMethodSignatures == null;
DexMethod bridge = methodMap.get(previous.getReference());
if (bridge == null) {
return previous;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java b/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java
index c11c8bf..48002cc 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java
@@ -28,9 +28,9 @@
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.MethodSignatureEquivalence;
import com.android.tools.r8.utils.Timing;
+import com.android.tools.r8.utils.collections.BidirectionalOneToOneHashMap;
import com.google.common.base.Equivalence.Wrapper;
import com.google.common.collect.BiMap;
-import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
@@ -54,7 +54,7 @@
private final Map<DexMethod, ArgumentInfoCollection> removedArgumentsInfoPerMethod;
UninstantiatedTypeOptimizationGraphLens(
- BiMap<DexMethod, DexMethod> methodMap,
+ BidirectionalOneToOneHashMap<DexMethod, DexMethod> methodMap,
Map<DexMethod, ArgumentInfoCollection> removedArgumentsInfoPerMethod,
AppView<?> appView) {
super(
@@ -62,7 +62,7 @@
methodMap,
ImmutableMap.of(),
null,
- methodMap.inverse(),
+ methodMap.getInverseOneToOneMap(),
appView.graphLens(),
appView.dexItemFactory());
this.appView = appView;
@@ -129,7 +129,8 @@
}
Map<Wrapper<DexMethod>, Set<DexType>> changedVirtualMethods = new HashMap<>();
- BiMap<DexMethod, DexMethod> methodMapping = HashBiMap.create();
+ BidirectionalOneToOneHashMap<DexMethod, DexMethod> methodMapping =
+ new BidirectionalOneToOneHashMap<>();
Map<DexMethod, ArgumentInfoCollection> removedArgumentsInfoPerMethod = new IdentityHashMap<>();
TopDownClassHierarchyTraversal.forProgramClasses(appView)
@@ -139,7 +140,7 @@
processClass(
clazz,
changedVirtualMethods,
- methodMapping,
+ methodMapping.getForwardBacking(),
methodPoolCollection,
removedArgumentsInfoPerMethod));
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/UnusedArgumentsCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/UnusedArgumentsCollector.java
index 492685a..16fb558 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/UnusedArgumentsCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/UnusedArgumentsCollector.java
@@ -26,9 +26,9 @@
import com.android.tools.r8.utils.SymbolGenerationUtils.MixedCasing;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
+import com.android.tools.r8.utils.collections.BidirectionalOneToOneHashMap;
import com.google.common.base.Equivalence.Wrapper;
import com.google.common.collect.BiMap;
-import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Streams;
@@ -48,7 +48,8 @@
private final AppView<AppInfoWithLiveness> appView;
private final MethodPoolCollection methodPoolCollection;
- private final BiMap<DexMethod, DexMethod> methodMapping = HashBiMap.create();
+ private final BidirectionalOneToOneHashMap<DexMethod, DexMethod> methodMapping =
+ new BidirectionalOneToOneHashMap<>();
private final Map<DexMethod, ArgumentInfoCollection> removedArguments = new IdentityHashMap<>();
public static class UnusedArgumentsGraphLens extends NestedGraphLens {
@@ -60,7 +61,7 @@
Map<DexMethod, DexMethod> methodMap,
Map<DexField, DexField> fieldMap,
BiMap<DexField, DexField> originalFieldSignatures,
- BiMap<DexMethod, DexMethod> originalMethodSignatures,
+ BidirectionalOneToOneHashMap<DexMethod, DexMethod> originalMethodSignatures,
GraphLens previousLens,
DexItemFactory dexItemFactory,
Map<DexMethod, ArgumentInfoCollection> removedArguments) {
@@ -111,7 +112,7 @@
methodMapping,
ImmutableMap.of(),
ImmutableBiMap.of(),
- methodMapping.inverse(),
+ methodMapping.getInverseOneToOneMap(),
appView.graphLens(),
appView.dexItemFactory(),
removedArguments);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingLens.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingLens.java
index d99bf3e..b6660fc 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingLens.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingLens.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.graph.RewrittenPrototypeDescription;
import com.android.tools.r8.ir.code.Invoke;
import com.android.tools.r8.utils.BooleanUtils;
+import com.android.tools.r8.utils.collections.BidirectionalOneToOneHashMap;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableMap;
@@ -30,7 +31,7 @@
Map<DexMethod, DexMethod> methodMap,
Map<DexField, DexField> fieldMap,
BiMap<DexField, DexField> originalFieldSignatures,
- BiMap<DexMethod, DexMethod> originalMethodSignatures,
+ BidirectionalOneToOneHashMap<DexMethod, DexMethod> originalMethodSignatures,
GraphLens previousLens,
DexItemFactory dexItemFactory,
Map<DexMethod, RewrittenPrototypeDescription> prototypeChangesPerMethod,
@@ -76,7 +77,8 @@
protected final Map<DexType, DexType> typeMap = new IdentityHashMap<>();
protected final BiMap<DexField, DexField> originalFieldSignatures = HashBiMap.create();
- protected final BiMap<DexMethod, DexMethod> originalMethodSignatures = HashBiMap.create();
+ protected final BidirectionalOneToOneHashMap<DexMethod, DexMethod> originalMethodSignatures =
+ new BidirectionalOneToOneHashMap<>();
private Map<DexMethod, RewrittenPrototypeDescription> prototypeChangesPerMethod =
new IdentityHashMap<>();
@@ -148,7 +150,7 @@
}
return new EnumUnboxingLens(
typeMap,
- originalMethodSignatures.inverse(),
+ originalMethodSignatures.getInverseOneToOneMap(),
originalFieldSignatures.inverse(),
originalFieldSignatures,
originalMethodSignatures,
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerGraphLens.java b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerGraphLens.java
index 6eeeb46..fbc4c12 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerGraphLens.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerGraphLens.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
import com.android.tools.r8.ir.code.Invoke.Type;
+import com.android.tools.r8.utils.collections.BidirectionalOneToOneHashMap;
import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableMap;
@@ -17,13 +18,13 @@
ClassStaticizerGraphLens(
AppView<?> appView,
BiMap<DexField, DexField> fieldMapping,
- BiMap<DexMethod, DexMethod> methodMapping) {
+ BidirectionalOneToOneHashMap<DexMethod, DexMethod> methodMapping) {
super(
ImmutableMap.of(),
methodMapping,
fieldMapping,
fieldMapping.inverse(),
- methodMapping.inverse(),
+ methodMapping.getInverseOneToOneMap(),
appView.graphLens(),
appView.dexItemFactory());
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
index f776d44..2313a5a 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
@@ -45,6 +45,7 @@
import com.android.tools.r8.utils.SetUtils;
import com.android.tools.r8.utils.Timing;
import com.android.tools.r8.utils.TraversalContinuation;
+import com.android.tools.r8.utils.collections.BidirectionalOneToOneHashMap;
import com.android.tools.r8.utils.collections.LongLivedProgramMethodSetBuilder;
import com.android.tools.r8.utils.collections.ProgramMethodSet;
import com.android.tools.r8.utils.collections.SortedProgramMethodSet;
@@ -737,7 +738,8 @@
}
private ProgramMethodSet staticizeMethodSymbols() {
- BiMap<DexMethod, DexMethod> methodMapping = HashBiMap.create();
+ BidirectionalOneToOneHashMap<DexMethod, DexMethod> methodMapping =
+ new BidirectionalOneToOneHashMap<>();
BiMap<DexField, DexField> fieldMapping = HashBiMap.create();
ProgramMethodSet staticizedMethods = ProgramMethodSet.create();
@@ -801,7 +803,7 @@
DexProgramClass candidateClass,
DexType hostType,
DexProgramClass hostClass,
- BiMap<DexMethod, DexMethod> methodMapping,
+ BidirectionalOneToOneHashMap<DexMethod, DexMethod> methodMapping,
BiMap<DexField, DexField> fieldMapping) {
candidateToHostMapping.put(candidateClass.type, hostType);
@@ -856,7 +858,7 @@
// has just been migrated to the host class.
staticizedMethods.createAndAdd(hostClass, newMethod);
}
- DexMethod originalMethod = methodMapping.inverse().get(method.method);
+ DexMethod originalMethod = methodMapping.getRepresentativeKey(method.method);
if (originalMethod == null) {
methodMapping.put(method.method, newMethod.method);
} else {
diff --git a/src/main/java/com/android/tools/r8/optimize/PublicizerLens.java b/src/main/java/com/android/tools/r8/optimize/PublicizerLens.java
index 52e7b3d..bd8db04 100644
--- a/src/main/java/com/android/tools/r8/optimize/PublicizerLens.java
+++ b/src/main/java/com/android/tools/r8/optimize/PublicizerLens.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
import com.android.tools.r8.ir.code.Invoke.Type;
+import com.android.tools.r8.utils.collections.BidirectionalManyToManyRepresentativeMap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import java.util.Set;
@@ -25,7 +26,7 @@
ImmutableMap.of(),
ImmutableMap.of(),
null,
- null,
+ BidirectionalManyToManyRepresentativeMap.empty(),
appView.graphLens(),
appView.dexItemFactory());
this.appView = appView;
diff --git a/src/main/java/com/android/tools/r8/repackaging/RepackagingLens.java b/src/main/java/com/android/tools/r8/repackaging/RepackagingLens.java
index d3ceea5..b871193 100644
--- a/src/main/java/com/android/tools/r8/repackaging/RepackagingLens.java
+++ b/src/main/java/com/android/tools/r8/repackaging/RepackagingLens.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.utils.collections.BidirectionalOneToOneHashMap;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
@@ -20,11 +21,11 @@
private RepackagingLens(
AppView<AppInfoWithLiveness> appView,
BiMap<DexField, DexField> originalFieldSignatures,
- BiMap<DexMethod, DexMethod> originalMethodSignatures,
+ BidirectionalOneToOneHashMap<DexMethod, DexMethod> originalMethodSignatures,
BiMap<DexType, DexType> originalTypes) {
super(
originalTypes.inverse(),
- originalMethodSignatures.inverse(),
+ originalMethodSignatures.getInverseBacking(),
originalFieldSignatures.inverse(),
originalFieldSignatures,
originalMethodSignatures,
@@ -48,7 +49,8 @@
protected final BiMap<DexType, DexType> originalTypes = HashBiMap.create();
protected final BiMap<DexField, DexField> originalFieldSignatures = HashBiMap.create();
- protected final BiMap<DexMethod, DexMethod> originalMethodSignatures = HashBiMap.create();
+ protected final BidirectionalOneToOneHashMap<DexMethod, DexMethod> originalMethodSignatures =
+ new BidirectionalOneToOneHashMap<>();
public void recordMove(DexField from, DexField to) {
originalFieldSignatures.put(to, from);
diff --git a/src/main/java/com/android/tools/r8/shaking/StaticClassMerger.java b/src/main/java/com/android/tools/r8/shaking/StaticClassMerger.java
index 97e980c..58e85ff 100644
--- a/src/main/java/com/android/tools/r8/shaking/StaticClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/StaticClassMerger.java
@@ -23,6 +23,7 @@
import com.android.tools.r8.utils.MethodSignatureEquivalence;
import com.android.tools.r8.utils.SingletonEquivalence;
import com.android.tools.r8.utils.TraversalContinuation;
+import com.android.tools.r8.utils.collections.BidirectionalOneToOneHashMap;
import com.google.common.base.Equivalence;
import com.google.common.base.Equivalence.Wrapper;
import com.google.common.collect.BiMap;
@@ -199,7 +200,8 @@
private final Map<MergeKey, Representative> representatives = new HashMap<>();
private final BiMap<DexField, DexField> fieldMapping = HashBiMap.create();
- private final BiMap<DexMethod, DexMethod> methodMapping = HashBiMap.create();
+ private final BidirectionalOneToOneHashMap<DexMethod, DexMethod> methodMapping =
+ new BidirectionalOneToOneHashMap<>();
private int numberOfMergedClasses = 0;
@@ -234,7 +236,8 @@
private NestedGraphLens buildGraphLens() {
if (!fieldMapping.isEmpty() || !methodMapping.isEmpty()) {
BiMap<DexField, DexField> originalFieldSignatures = fieldMapping.inverse();
- BiMap<DexMethod, DexMethod> originalMethodSignatures = methodMapping.inverse();
+ BidirectionalOneToOneHashMap<DexMethod, DexMethod> originalMethodSignatures =
+ methodMapping.getInverseOneToOneMap();
return new NestedGraphLens(
ImmutableMap.of(),
methodMapping,
@@ -497,7 +500,7 @@
newMethods.add(sourceMethodAfterMove);
DexMethod originalMethod =
- methodMapping.inverse().getOrDefault(sourceMethod.method, sourceMethod.method);
+ methodMapping.getRepresentativeKeyOrDefault(sourceMethod.method, sourceMethod.method);
methodMapping.forcePut(originalMethod, sourceMethodAfterMove.method);
existingMethods.add(equivalence.wrap(sourceMethodAfterMove.method));
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLens.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLens.java
index 2bee133..f634f48 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLens.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLens.java
@@ -17,6 +17,7 @@
import com.android.tools.r8.graph.classmerging.VerticallyMergedClasses;
import com.android.tools.r8.ir.code.Invoke.Type;
import com.android.tools.r8.utils.IterableUtils;
+import com.android.tools.r8.utils.collections.BidirectionalOneToOneHashMap;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableSet;
@@ -74,7 +75,7 @@
Map<DexType, Map<DexMethod, GraphLensLookupResultProvider>>
contextualVirtualToDirectMethodMaps,
BiMap<DexField, DexField> originalFieldSignatures,
- BiMap<DexMethod, DexMethod> originalMethodSignatures,
+ BidirectionalOneToOneHashMap<DexMethod, DexMethod> originalMethodSignatures,
Map<DexMethod, DexMethod> originalMethodSignaturesForBridges,
GraphLens previousLens) {
super(
@@ -171,7 +172,8 @@
private final Map<DexType, Map<DexMethod, GraphLensLookupResultProvider>>
contextualVirtualToDirectMethodMaps = new IdentityHashMap<>();
- private final BiMap<DexMethod, DexMethod> originalMethodSignatures = HashBiMap.create();
+ private final BidirectionalOneToOneHashMap<DexMethod, DexMethod> originalMethodSignatures =
+ new BidirectionalOneToOneHashMap<>();
private final Map<DexMethod, DexMethod> originalMethodSignaturesForBridges =
new IdentityHashMap<>();
@@ -215,11 +217,12 @@
context);
}
}
- for (Map.Entry<DexMethod, DexMethod> entry : builder.originalMethodSignatures.entrySet()) {
- newBuilder.recordMove(
- entry.getValue(),
- builder.getMethodSignatureAfterClassMerging(entry.getKey(), mergedClasses));
- }
+ builder.originalMethodSignatures.forEach(
+ (renamedMethodSignature, originalMethodSignature) ->
+ newBuilder.recordMove(
+ originalMethodSignature,
+ builder.getMethodSignatureAfterClassMerging(
+ renamedMethodSignature, mergedClasses)));
for (Map.Entry<DexMethod, DexMethod> entry :
builder.originalMethodSignaturesForBridges.entrySet()) {
newBuilder.recordCreationOfBridgeMethod(
diff --git a/src/main/java/com/android/tools/r8/utils/IterableUtils.java b/src/main/java/com/android/tools/r8/utils/IterableUtils.java
index fcf2f42..aee34f6 100644
--- a/src/main/java/com/android/tools/r8/utils/IterableUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/IterableUtils.java
@@ -88,6 +88,10 @@
return Iterables.concat(Iterables.transform(iterable, val -> map.apply(val)));
}
+ public static <T> Iterable<T> empty() {
+ return Collections.emptyList();
+ }
+
public static <T> Iterable<T> emptyIf(Iterable<T> iterable, boolean condition) {
if (condition) {
return Collections.emptySet();
diff --git a/src/main/java/com/android/tools/r8/utils/collections/BidirectionalManyToManyRepresentativeMap.java b/src/main/java/com/android/tools/r8/utils/collections/BidirectionalManyToManyRepresentativeMap.java
new file mode 100644
index 0000000..a4878dc
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/utils/collections/BidirectionalManyToManyRepresentativeMap.java
@@ -0,0 +1,94 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.utils.collections;
+
+import java.util.Map;
+
+public abstract class BidirectionalManyToManyRepresentativeMap<K, V> {
+
+ public static <K, V> BidirectionalManyToManyRepresentativeMap<K, V> empty() {
+ return new EmptyBidirectionalManyToManyRepresentativeMap<>();
+ }
+
+ public abstract boolean containsKey(K key);
+
+ public abstract boolean containsValue(V value);
+
+ public abstract Map<K, V> getForwardBacking();
+
+ public abstract Map<V, K> getInverseBacking();
+
+ public final Inverse getInverseManyToManyMap() {
+ return new Inverse();
+ }
+
+ public abstract K getRepresentativeKey(V value);
+
+ public final K getRepresentativeKeyOrDefault(V value, K defaultValue) {
+ K representativeKey = getRepresentativeKey(value);
+ return representativeKey != null ? representativeKey : defaultValue;
+ }
+
+ public abstract V getRepresentativeValue(K key);
+
+ public final V getRepresentativeValueOrDefault(K key, V defaultValue) {
+ V representativeValue = getRepresentativeValue(key);
+ return representativeValue != null ? representativeValue : defaultValue;
+ }
+
+ public abstract Iterable<K> getKeys(V value);
+
+ public abstract Iterable<V> getValues(K key);
+
+ public abstract boolean isEmpty();
+
+ public class Inverse extends BidirectionalManyToManyRepresentativeMap<V, K> {
+
+ @Override
+ public boolean containsKey(V key) {
+ return BidirectionalManyToManyRepresentativeMap.this.containsValue(key);
+ }
+
+ @Override
+ public boolean containsValue(K value) {
+ return BidirectionalManyToManyRepresentativeMap.this.containsKey(value);
+ }
+
+ @Override
+ public Map<V, K> getForwardBacking() {
+ return BidirectionalManyToManyRepresentativeMap.this.getInverseBacking();
+ }
+
+ @Override
+ public Map<K, V> getInverseBacking() {
+ return BidirectionalManyToManyRepresentativeMap.this.getForwardBacking();
+ }
+
+ @Override
+ public V getRepresentativeKey(K value) {
+ return BidirectionalManyToManyRepresentativeMap.this.getRepresentativeValue(value);
+ }
+
+ @Override
+ public K getRepresentativeValue(V key) {
+ return BidirectionalManyToManyRepresentativeMap.this.getRepresentativeKey(key);
+ }
+
+ @Override
+ public Iterable<V> getKeys(K value) {
+ return BidirectionalManyToManyRepresentativeMap.this.getValues(value);
+ }
+
+ @Override
+ public Iterable<K> getValues(V key) {
+ return BidirectionalManyToManyRepresentativeMap.this.getKeys(key);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return BidirectionalManyToManyRepresentativeMap.this.isEmpty();
+ }
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/utils/collections/BidirectionalOneToOneHashMap.java b/src/main/java/com/android/tools/r8/utils/collections/BidirectionalOneToOneHashMap.java
new file mode 100644
index 0000000..0f85170
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/utils/collections/BidirectionalOneToOneHashMap.java
@@ -0,0 +1,134 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.utils.collections;
+
+import com.android.tools.r8.utils.IterableUtils;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+public class BidirectionalOneToOneHashMap<K, V>
+ extends BidirectionalManyToManyRepresentativeMap<K, V> implements Map<K, V> {
+
+ private final BiMap<K, V> backing;
+
+ public BidirectionalOneToOneHashMap() {
+ this(HashBiMap.create());
+ }
+
+ public BidirectionalOneToOneHashMap(BiMap<K, V> backing) {
+ this.backing = backing;
+ }
+
+ @Override
+ public void clear() {
+ backing.clear();
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ return backing.containsKey(key);
+ }
+
+ @Override
+ public boolean containsValue(Object value) {
+ return backing.containsValue(value);
+ }
+
+ @Override
+ public Set<Entry<K, V>> entrySet() {
+ return backing.entrySet();
+ }
+
+ public V forcePut(K key, V value) {
+ return backing.forcePut(key, value);
+ }
+
+ @Override
+ public V get(Object key) {
+ return getRepresentativeValue((K) key);
+ }
+
+ @Override
+ public BiMap<K, V> getForwardBacking() {
+ return backing;
+ }
+
+ @Override
+ public BiMap<V, K> getInverseBacking() {
+ return backing.inverse();
+ }
+
+ public BidirectionalOneToOneHashMap<V, K> getInverseOneToOneMap() {
+ return new BidirectionalOneToOneHashMap<>(backing.inverse());
+ }
+
+ @Override
+ public K getRepresentativeKey(V value) {
+ return backing.inverse().get(value);
+ }
+
+ @Override
+ public V getRepresentativeValue(K key) {
+ return backing.get(key);
+ }
+
+ @Override
+ public Iterable<K> getKeys(V value) {
+ if (containsValue(value)) {
+ return IterableUtils.singleton(getRepresentativeKey(value));
+ }
+ return IterableUtils.empty();
+ }
+
+ @Override
+ public Iterable<V> getValues(K key) {
+ if (containsKey(key)) {
+ return IterableUtils.singleton(getRepresentativeValue(key));
+ }
+ return IterableUtils.empty();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return backing.isEmpty();
+ }
+
+ @Override
+ public Set<K> keySet() {
+ return backing.keySet();
+ }
+
+ @Override
+ public V put(K key, V value) {
+ return backing.put(key, value);
+ }
+
+ public void putAll(BidirectionalOneToOneHashMap<K, V> map) {
+ putAll(map.backing);
+ }
+
+ @Override
+ public void putAll(Map<? extends K, ? extends V> map) {
+ backing.putAll(map);
+ }
+
+ @Override
+ public V remove(Object key) {
+ return backing.remove(key);
+ }
+
+ @Override
+ public int size() {
+ return backing.size();
+ }
+
+ @Override
+ public Collection<V> values() {
+ return backing.values();
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/utils/collections/EmptyBidirectionalManyToManyRepresentativeMap.java b/src/main/java/com/android/tools/r8/utils/collections/EmptyBidirectionalManyToManyRepresentativeMap.java
new file mode 100644
index 0000000..dbcb753
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/utils/collections/EmptyBidirectionalManyToManyRepresentativeMap.java
@@ -0,0 +1,58 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.utils.collections;
+
+import com.android.tools.r8.utils.IterableUtils;
+import java.util.Collections;
+import java.util.Map;
+
+public class EmptyBidirectionalManyToManyRepresentativeMap<K, V>
+ extends BidirectionalManyToManyRepresentativeMap<K, V> {
+
+ @Override
+ public boolean containsKey(K key) {
+ return false;
+ }
+
+ @Override
+ public boolean containsValue(V value) {
+ return false;
+ }
+
+ @Override
+ public Map<K, V> getForwardBacking() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Map<V, K> getInverseBacking() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public K getRepresentativeKey(V value) {
+ return null;
+ }
+
+ @Override
+ public V getRepresentativeValue(K key) {
+ return null;
+ }
+
+ @Override
+ public Iterable<K> getKeys(V value) {
+ return IterableUtils.empty();
+ }
+
+ @Override
+ public Iterable<V> getValues(K key) {
+ return IterableUtils.empty();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return true;
+ }
+}