Map context during graph lense lookup
Bug: 123012641
Change-Id: I81ed27e5f54c6edf021ac998e5ced0b7c44b952a
diff --git a/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java b/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
index f070078..df23b1c 100644
--- a/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
+++ b/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
@@ -74,22 +74,24 @@
}
public DirectMappedDexApplication rewrittenWithLense(GraphLense graphLense) {
- assert mappingIsValid(graphLense, programClasses.getAllTypes());
- assert mappingIsValid(graphLense, libraryClasses.keySet());
// As a side effect, this will rebuild the program classes and library classes maps.
- return this.builder().build().asDirect();
+ DirectMappedDexApplication rewrittenApplication = this.builder().build().asDirect();
+ assert rewrittenApplication.mappingIsValid(graphLense, programClasses.getAllTypes());
+ assert rewrittenApplication.mappingIsValid(graphLense, libraryClasses.keySet());
+ return rewrittenApplication;
}
private boolean mappingIsValid(GraphLense graphLense, Iterable<DexType> types) {
- // The lense might either map to a different type that is already present in the application
+ // The lens might either map to a different type that is already present in the application
// (e.g. relinking a type) or it might encode a type that was renamed, in which case the
// original type will point to a definition that was renamed.
for (DexType type : types) {
DexType renamed = graphLense.lookupType(type);
if (renamed != type) {
- if (definitionFor(type).type != renamed && definitionFor(renamed) == null) {
- return false;
+ if (definitionFor(type) == null && definitionFor(renamed) != null) {
+ continue;
}
+ assert definitionFor(type).type != renamed && definitionFor(renamed) == null;
}
}
return true;
diff --git a/src/main/java/com/android/tools/r8/graph/GraphLense.java b/src/main/java/com/android/tools/r8/graph/GraphLense.java
index 898afed..bc22da0 100644
--- a/src/main/java/com/android/tools/r8/graph/GraphLense.java
+++ b/src/main/java/com/android/tools/r8/graph/GraphLense.java
@@ -359,6 +359,8 @@
return new Builder();
}
+ public abstract DexType getOriginalType(DexType type);
+
public abstract DexField getOriginalFieldSignature(DexField field);
public abstract DexMethod getOriginalMethodSignature(DexMethod method);
@@ -391,7 +393,7 @@
}
public abstract GraphLenseLookupResult lookupMethod(
- DexMethod method, DexEncodedMethod context, Type type);
+ DexMethod method, DexMethod context, Type type);
public abstract RewrittenPrototypeDescription lookupPrototypeChanges(DexMethod method);
@@ -626,6 +628,11 @@
}
@Override
+ public DexType getOriginalType(DexType type) {
+ return type;
+ }
+
+ @Override
public DexField getOriginalFieldSignature(DexField field) {
return field;
}
@@ -651,8 +658,7 @@
}
@Override
- public GraphLenseLookupResult lookupMethod(
- DexMethod method, DexEncodedMethod context, Type type) {
+ public GraphLenseLookupResult lookupMethod(DexMethod method, DexMethod context, Type type) {
return new GraphLenseLookupResult(method, type);
}
@@ -673,14 +679,14 @@
}
/**
- * GraphLense implementation with a parent lense using a simple mapping for type, method and
- * field mapping.
+ * GraphLense implementation with a parent lense using a simple mapping for type, method and field
+ * mapping.
*
- * Subclasses can override the lookup methods.
+ * <p>Subclasses can override the lookup methods.
*
- * For method mapping where invocation type can change just override
- * {@link #mapInvocationType(DexMethod, DexMethod, DexEncodedMethod, Type)} if
- * the default name mapping applies, and only invocation type might need to change.
+ * <p>For method mapping where invocation type can change just override {@link
+ * #mapInvocationType(DexMethod, DexMethod, DexMethod, Type)} if the default name mapping applies,
+ * and only invocation type might need to change.
*/
public static class NestedGraphLense extends GraphLense {
@@ -715,6 +721,11 @@
}
@Override
+ public DexType getOriginalType(DexType type) {
+ return previousLense.getOriginalType(type);
+ }
+
+ @Override
public DexField getOriginalFieldSignature(DexField field) {
DexField originalField =
originalFieldSignatures != null
@@ -772,9 +783,12 @@
}
@Override
- public GraphLenseLookupResult lookupMethod(
- DexMethod method, DexEncodedMethod context, Type type) {
- GraphLenseLookupResult previous = previousLense.lookupMethod(method, context, type);
+ public GraphLenseLookupResult lookupMethod(DexMethod method, DexMethod context, Type type) {
+ DexMethod previousContext =
+ originalMethodSignatures != null
+ ? originalMethodSignatures.getOrDefault(context, context)
+ : context;
+ GraphLenseLookupResult previous = previousLense.lookupMethod(method, previousContext, type);
DexMethod newMethod = methodMap.get(previous.getMethod());
if (newMethod == null) {
return previous;
@@ -782,7 +796,7 @@
// TODO(sgjesse): Should we always do interface to virtual mapping? Is it a performance win
// that only subclasses which are known to need it actually do it?
return new GraphLenseLookupResult(
- newMethod, mapInvocationType(newMethod, method, context, previous.getType()));
+ newMethod, mapInvocationType(newMethod, method, previous.getType()));
}
@Override
@@ -793,22 +807,20 @@
/**
* Default invocation type mapping.
*
- * This is an identity mapping. If a subclass need invocation type mapping either override
- * this method or {@link #lookupMethod(DexMethod, DexEncodedMethod, Type)}
+ * <p>This is an identity mapping. If a subclass need invocation type mapping either override
+ * this method or {@link #lookupMethod(DexMethod, DexMethod, Type)}
*/
- protected Type mapInvocationType(
- DexMethod newMethod, DexMethod originalMethod, DexEncodedMethod context, Type type) {
+ protected Type mapInvocationType(DexMethod newMethod, DexMethod originalMethod, Type type) {
return type;
}
/**
* Standard mapping between interface and virtual invoke type.
*
- * Handle methods moved from interface to class or class to interface.
+ * <p>Handle methods moved from interface to class or class to interface.
*/
- final protected Type mapVirtualInterfaceInvocationTypes(
- AppInfo appInfo, DexMethod newMethod, DexMethod originalMethod,
- DexEncodedMethod context, Type type) {
+ protected final Type mapVirtualInterfaceInvocationTypes(
+ AppInfo appInfo, DexMethod newMethod, DexMethod originalMethod, Type type) {
if (type == Type.VIRTUAL || type == Type.INTERFACE) {
// Get the invoke type of the actual definition.
DexClass newTargetClass = appInfo.definitionFor(newMethod.holder);
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 d9040c5..c12ea40 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
@@ -532,7 +532,7 @@
private void processInvoke(Type type, DexMethod method) {
DexEncodedMethod source = caller.method;
- GraphLenseLookupResult result = graphLense.lookupMethod(method, source, type);
+ GraphLenseLookupResult result = graphLense.lookupMethod(method, source.method, type);
method = result.getMethod();
type = result.getType();
DexEncodedMethod definition = appInfo.lookup(type, method, source.method.holder);
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
index cf88f0f..fd968d6 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
@@ -156,7 +156,7 @@
checkInvokeDirect(method.method, invoke.asInvokeDirect());
}
GraphLenseLookupResult lenseLookup =
- graphLense.lookupMethod(invokedMethod, method, invoke.getType());
+ graphLense.lookupMethod(invokedMethod, method.method, invoke.getType());
DexMethod actualTarget = lenseLookup.getMethod();
Invoke.Type actualInvokeType = lenseLookup.getType();
if (actualInvokeType == Type.VIRTUAL) {
@@ -314,10 +314,11 @@
}
} else if (current.isMoveException()) {
MoveException moveException = current.asMoveException();
- if (moveException.hasOutValue()) {
- // Conservatively add the out-value to `newSSAValues` since the catch handler guards
- // may have been renamed as a result of class merging.
- newSSAValues.add(moveException.outValue());
+ DexType newExceptionType = graphLense.lookupType(moveException.getExceptionType());
+ if (newExceptionType != moveException.getExceptionType()) {
+ iterator.replaceCurrentInstruction(
+ new MoveException(
+ makeOutValue(moveException, code, newSSAValues), newExceptionType, options));
}
} else if (current.isNewArrayEmpty()) {
NewArrayEmpty newArrayEmpty = current.asNewArrayEmpty();
@@ -328,7 +329,7 @@
iterator.replaceCurrentInstruction(newNewArray);
}
} else if (current.isNewInstance()) {
- NewInstance newInstance= current.asNewInstance();
+ NewInstance newInstance = current.asNewInstance();
DexType newClazz = graphLense.lookupType(newInstance.clazz);
if (newClazz != newInstance.clazz) {
NewInstance newNewInstance = new NewInstance(
@@ -464,7 +465,7 @@
DexMethod invokedMethod = methodHandle.asMethod();
MethodHandleType oldType = methodHandle.type;
GraphLenseLookupResult lenseLookup =
- graphLense.lookupMethod(invokedMethod, context, oldType.toInvokeType());
+ graphLense.lookupMethod(invokedMethod, context.method, oldType.toInvokeType());
DexMethod rewrittenTarget = lenseLookup.getMethod();
DexMethod actualTarget;
MethodHandleType newType;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriterGraphLense.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriterGraphLense.java
index 26f890e..d5ceeb1 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriterGraphLense.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriterGraphLense.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.desugar;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.GraphLense;
@@ -28,13 +27,12 @@
}
@Override
- protected Type mapInvocationType(
- DexMethod newMethod, DexMethod originalMethod, DexEncodedMethod context, Type type) {
+ protected Type mapInvocationType(DexMethod newMethod, DexMethod originalMethod, Type type) {
if (methodMap.get(originalMethod) == newMethod) {
assert type == Type.VIRTUAL || type == Type.DIRECT;
return Type.STATIC;
}
- return super.mapInvocationType(newMethod, originalMethod, context, type);
+ return super.mapInvocationType(newMethod, originalMethod, type);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerGraphLense.java b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerGraphLense.java
index 9bdd55e..6613534 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerGraphLense.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerGraphLense.java
@@ -36,14 +36,12 @@
}
@Override
- protected Type mapInvocationType(
- DexMethod newMethod, DexMethod originalMethod,
- DexEncodedMethod context, Type type) {
+ protected Type mapInvocationType(DexMethod newMethod, DexMethod originalMethod, Type type) {
if (methodMap.get(originalMethod) == newMethod) {
assert type == Type.VIRTUAL || type == Type.DIRECT;
return Type.STATIC;
}
- return super.mapInvocationType(newMethod, originalMethod, context, type);
+ return super.mapInvocationType(newMethod, originalMethod, type);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/optimize/MemberRebindingLense.java b/src/main/java/com/android/tools/r8/optimize/MemberRebindingLense.java
index 98a0da4..5e19d48 100644
--- a/src/main/java/com/android/tools/r8/optimize/MemberRebindingLense.java
+++ b/src/main/java/com/android/tools/r8/optimize/MemberRebindingLense.java
@@ -5,7 +5,6 @@
package com.android.tools.r8.optimize;
import com.android.tools.r8.graph.AppInfo;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.GraphLense;
@@ -47,11 +46,8 @@
return new Builder(appInfo);
}
-
@Override
- protected Type mapInvocationType(
- DexMethod newMethod, DexMethod originalMethod, DexEncodedMethod context, Type type) {
- return super.mapVirtualInterfaceInvocationTypes(
- appInfo, newMethod, originalMethod, context, type);
+ protected Type mapInvocationType(DexMethod newMethod, DexMethod originalMethod, Type type) {
+ return super.mapVirtualInterfaceInvocationTypes(appInfo, newMethod, originalMethod, type);
}
}
diff --git a/src/main/java/com/android/tools/r8/optimize/PublicizerLense.java b/src/main/java/com/android/tools/r8/optimize/PublicizerLense.java
index 2db2dce..c685d84 100644
--- a/src/main/java/com/android/tools/r8/optimize/PublicizerLense.java
+++ b/src/main/java/com/android/tools/r8/optimize/PublicizerLense.java
@@ -15,6 +15,7 @@
import java.util.Set;
final class PublicizerLense extends NestedGraphLense {
+
private final AppView appView;
private final Set<DexMethod> publicizedMethods;
@@ -34,8 +35,7 @@
}
@Override
- public GraphLenseLookupResult lookupMethod(
- DexMethod method, DexEncodedMethod context, Type type) {
+ public GraphLenseLookupResult lookupMethod(DexMethod method, DexMethod context, Type type) {
GraphLenseLookupResult previous = previousLense.lookupMethod(method, context, type);
method = previous.getMethod();
type = previous.getType();
@@ -46,7 +46,7 @@
return super.lookupMethod(method, context, type);
}
- private boolean publicizedMethodIsPresentOnHolder(DexMethod method, DexEncodedMethod context) {
+ private boolean publicizedMethodIsPresentOnHolder(DexMethod method, DexMethod context) {
GraphLenseLookupResult lookup =
appView.graphLense().lookupMethod(method, context, Type.VIRTUAL);
DexMethod signatureInCurrentWorld = lookup.getMethod();
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
index 2d8392b..956d6bd 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -6,7 +6,6 @@
import static com.android.tools.r8.ir.code.Invoke.Type.DIRECT;
import static com.android.tools.r8.ir.code.Invoke.Type.STATIC;
-import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppInfo.ResolutionResult;
@@ -53,6 +52,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
import com.google.common.collect.Streams;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
@@ -211,13 +211,13 @@
private final Set<DexProgramClass> mergeCandidates = new LinkedHashSet<>();
// Map from source class to target class.
- private final Map<DexType, DexType> mergedClasses = new HashMap<>();
+ private final Map<DexType, DexType> mergedClasses = new IdentityHashMap<>();
// Map from target class to the super classes that have been merged into the target class.
- private final Map<DexType, Set<DexType>> mergedClassesInverse = new HashMap<>();
+ private final Map<DexType, Set<DexType>> mergedClassesInverse = new IdentityHashMap<>();
// Set of types that must not be merged into their subtype.
- private final Set<DexType> pinnedTypes = new HashSet<>();
+ private final Set<DexType> pinnedTypes = Sets.newIdentityHashSet();
// The resulting graph lense that should be used after class merging.
private final VerticalClassMergerGraphLense.Builder renamedMembersLense;
@@ -686,7 +686,7 @@
if (Log.ENABLED) {
Log.debug(getClass(), "Merged %d classes.", mergedClasses.size());
}
- return renamedMembersLense.build(graphLense, mergedClasses, synthesizedBridges, appInfo);
+ return renamedMembersLense.build(graphLense, mergedClasses, appInfo);
}
private boolean methodResolutionMayChange(DexClass source, DexClass target) {
@@ -1427,42 +1427,19 @@
for (DexProgramClass clazz : appInfo.classes()) {
clazz.setDirectMethods(substituteTypesIn(clazz.directMethods()));
clazz.setVirtualMethods(substituteTypesIn(clazz.virtualMethods()));
- clazz.setVirtualMethods(removeDupes(clazz.virtualMethods()));
clazz.setStaticFields(substituteTypesIn(clazz.staticFields()));
clazz.setInstanceFields(substituteTypesIn(clazz.instanceFields()));
}
+ for (SynthesizedBridgeCode synthesizedBridge : synthesizedBridges) {
+ synthesizedBridge.updateMethodSignatures(this::fixupMethod);
+ }
// Record type renamings so check-cast and instance-of checks are also fixed.
for (DexType type : mergedClasses.keySet()) {
- DexType fixed = fixupType(type);
- lense.map(type, fixed);
+ lense.map(type, fixupType(type));
}
return lense.build(application.dexItemFactory, graphLense);
}
- private DexEncodedMethod[] removeDupes(DexEncodedMethod[] methods) {
- if (methods == null) {
- return null;
- }
- Map<DexMethod, DexEncodedMethod> filtered = new IdentityHashMap<>();
- for (DexEncodedMethod method : methods) {
- DexEncodedMethod previous = filtered.put(method.method, method);
- if (previous != null) {
- if (!previous.accessFlags.isBridge()) {
- if (!method.accessFlags.isBridge()) {
- throw new CompilationError(
- "Class merging produced invalid result on: " + previous.toSourceString());
- } else {
- filtered.put(previous.method, previous);
- }
- }
- }
- }
- if (filtered.size() == methods.length) {
- return methods;
- }
- return filtered.values().toArray(DexEncodedMethod.EMPTY_ARRAY);
- }
-
private DexEncodedMethod[] substituteTypesIn(DexEncodedMethod[] methods) {
if (methods == null) {
return null;
@@ -1470,12 +1447,9 @@
for (int i = 0; i < methods.length; i++) {
DexEncodedMethod encodedMethod = methods[i];
DexMethod method = encodedMethod.method;
- DexProto newProto = getUpdatedProto(method.proto);
- DexType newHolder = fixupType(method.holder);
- DexMethod newMethod = application.dexItemFactory.createMethod(newHolder, newProto,
- method.name);
- if (newMethod != encodedMethod.method) {
- lense.move(encodedMethod.method, newMethod);
+ DexMethod newMethod = fixupMethod(method);
+ if (newMethod != method) {
+ lense.move(method, newMethod);
methods[i] = encodedMethod.toTypeSubstitutedMethod(newMethod);
}
}
@@ -1500,7 +1474,12 @@
return fields;
}
- private DexProto getUpdatedProto(DexProto proto) {
+ private DexMethod fixupMethod(DexMethod method) {
+ return application.dexItemFactory.createMethod(
+ fixupType(method.holder), fixupProto(method.proto), method.name);
+ }
+
+ private DexProto fixupProto(DexProto proto) {
DexProto result = protoFixupCache.get(proto);
if (result == null) {
DexType returnType = fixupType(proto.returnType);
@@ -1517,12 +1496,13 @@
DexType fixed = fixupType(base);
if (base == fixed) {
return type;
- } else {
- return type.replaceBaseType(fixed, application.dexItemFactory);
}
+ return type.replaceBaseType(fixed, application.dexItemFactory);
}
- while (mergedClasses.containsKey(type)) {
- type = mergedClasses.get(type);
+ if (type.isClassType()) {
+ while (mergedClasses.containsKey(type)) {
+ type = mergedClasses.get(type);
+ }
}
return type;
}
@@ -1675,6 +1655,11 @@
}
@Override
+ public DexType getOriginalType(DexType type) {
+ throw new Unreachable();
+ }
+
+ @Override
public DexField getOriginalFieldSignature(DexField field) {
throw new Unreachable();
}
@@ -1700,8 +1685,7 @@
}
@Override
- public GraphLenseLookupResult lookupMethod(
- DexMethod method, DexEncodedMethod context, Type type) {
+ public GraphLenseLookupResult lookupMethod(DexMethod method, DexMethod context, Type type) {
// First look up the method using the existing graph lense (for example, the type will have
// changed if the method was publicized by ClassAndMemberPublicizer).
GraphLenseLookupResult lookup = graphLense.lookupMethod(method, context, type);
@@ -1745,7 +1729,7 @@
public static class IllegalAccessDetector extends UseRegistry {
private boolean foundIllegalAccess = false;
- private DexEncodedMethod context = null;
+ private DexMethod context = null;
private final AppView<? extends AppInfo> appView;
private final DexClass source;
@@ -1761,7 +1745,7 @@
}
public void setContext(DexEncodedMethod context) {
- this.context = context;
+ this.context = context.method;
}
private boolean checkFieldReference(DexField field) {
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLense.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLense.java
index 20a05ab..6576433 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLense.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLense.java
@@ -5,7 +5,6 @@
package com.android.tools.r8.shaking;
import com.android.tools.r8.graph.AppInfo;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
@@ -14,17 +13,14 @@
import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.graph.GraphLense.NestedGraphLense;
import com.android.tools.r8.ir.code.Invoke.Type;
-import com.android.tools.r8.shaking.VerticalClassMerger.SynthesizedBridgeCode;
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 java.util.HashMap;
import java.util.IdentityHashMap;
-import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.function.Function;
// This graph lense is instantiated during vertical class merging. The graph lense is context
// sensitive in the enclosing class of a given invoke *and* the type of the invoke (e.g., invoke-
@@ -55,7 +51,7 @@
private final Map<DexType, Map<DexMethod, GraphLenseLookupResult>>
contextualVirtualToDirectMethodMaps;
- private final Set<DexMethod> mergedMethods;
+ private Set<DexMethod> mergedMethods;
private final Map<DexMethod, DexMethod> originalMethodSignaturesForBridges;
public VerticalClassMergerGraphLense(
@@ -83,19 +79,29 @@
}
@Override
+ public DexType getOriginalType(DexType type) {
+ return previousLense.getOriginalType(type);
+ }
+
+ @Override
public DexMethod getOriginalMethodSignature(DexMethod method) {
return super.getOriginalMethodSignature(
originalMethodSignaturesForBridges.getOrDefault(method, method));
}
@Override
- public GraphLenseLookupResult lookupMethod(
- DexMethod method, DexEncodedMethod context, Type type) {
+ public GraphLenseLookupResult lookupMethod(DexMethod method, DexMethod context, Type type) {
assert isContextFreeForMethod(method) || (context != null && type != null);
- GraphLenseLookupResult previous = previousLense.lookupMethod(method, context, type);
- if (previous.getType() == Type.SUPER && !mergedMethods.contains(context.method)) {
+ DexMethod previousContext =
+ originalMethodSignaturesForBridges.containsKey(context)
+ ? originalMethodSignaturesForBridges.get(context)
+ : originalMethodSignatures != null
+ ? originalMethodSignatures.getOrDefault(context, context)
+ : context;
+ GraphLenseLookupResult previous = previousLense.lookupMethod(method, previousContext, type);
+ if (previous.getType() == Type.SUPER && !mergedMethods.contains(context)) {
Map<DexMethod, GraphLenseLookupResult> virtualToDirectMethodMap =
- contextualVirtualToDirectMethodMaps.get(context.method.holder);
+ contextualVirtualToDirectMethodMaps.get(context.holder);
if (virtualToDirectMethodMap != null) {
GraphLenseLookupResult lookup = virtualToDirectMethodMap.get(previous.getMethod());
if (lookup != null) {
@@ -113,10 +119,8 @@
}
@Override
- protected Type mapInvocationType(
- DexMethod newMethod, DexMethod originalMethod, DexEncodedMethod context, Type type) {
- return super.mapVirtualInterfaceInvocationTypes(
- appInfo, newMethod, originalMethod, context, type);
+ protected Type mapInvocationType(DexMethod newMethod, DexMethod originalMethod, Type type) {
+ return super.mapVirtualInterfaceInvocationTypes(appInfo, newMethod, originalMethod, type);
}
@Override
@@ -170,7 +174,6 @@
public GraphLense build(
GraphLense previousLense,
Map<DexType, DexType> mergedClasses,
- List<SynthesizedBridgeCode> synthesizedBridges,
AppInfo appInfo) {
if (fieldMap.isEmpty()
&& methodMap.isEmpty()
@@ -179,14 +182,6 @@
}
Map<DexProto, DexProto> cache = new HashMap<>();
BiMap<DexField, DexField> originalFieldSignatures = fieldMap.inverse();
- // Update all synthesized bridges.
- Function<DexMethod, DexMethod> synthesizedBridgeTransformer =
- method ->
- getMethodSignatureAfterClassMerging(
- method, mergedClasses, appInfo.dexItemFactory, cache);
- for (SynthesizedBridgeCode synthesizedBridge : synthesizedBridges) {
- synthesizedBridge.updateMethodSignatures(synthesizedBridgeTransformer);
- }
// Build new graph lense.
return new VerticalClassMergerGraphLense(
appInfo,
diff --git a/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java b/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
index ec12f82..c9be1b8 100644
--- a/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
+++ b/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
@@ -28,6 +28,7 @@
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.naming.ClassNameMapper;
@@ -150,16 +151,17 @@
// At this point we don't know if we really need to add this class to the builder.
// It depends on whether any methods/fields are renamed or some methods contain positions.
// Create a supplier which creates a new, cached ClassNaming.Builder on-demand.
+ DexType originalType = graphLense.getOriginalType(clazz.type);
DexString renamedClassName = namingLens.lookupDescriptor(clazz.getType());
Supplier<ClassNaming.Builder> onDemandClassNamingBuilder =
Suppliers.memoize(
() ->
classNameMapperBuilder.classNamingBuilder(
DescriptorUtils.descriptorToJavaType(renamedClassName.toString()),
- clazz.toString()));
+ originalType.toSourceString()));
// If the class is renamed add it to the classNamingBuilder.
- addClassToClassNaming(clazz, renamedClassName, onDemandClassNamingBuilder);
+ addClassToClassNaming(originalType, renamedClassName, onDemandClassNamingBuilder);
// First transfer renamed fields to classNamingBuilder.
addFieldsToClassNaming(graphLense, namingLens, clazz, onDemandClassNamingBuilder);
@@ -306,10 +308,12 @@
}
@SuppressWarnings("ReturnValueIgnored")
- private static void addClassToClassNaming(DexProgramClass clazz, DexString renamedClassName,
+ private static void addClassToClassNaming(
+ DexType originalType,
+ DexString renamedClassName,
Supplier<Builder> onDemandClassNamingBuilder) {
// We do know we need to create a ClassNaming.Builder if the class itself had been renamed.
- if (!clazz.toString().equals(renamedClassName.toString())) {
+ if (originalType.descriptor != renamedClassName) {
// Not using return value, it's registered in classNameMapperBuilder
onDemandClassNamingBuilder.get();
}
diff --git a/src/test/java/com/android/tools/r8/classmerging/VerticalClassMergerTest.java b/src/test/java/com/android/tools/r8/classmerging/VerticalClassMergerTest.java
index bb89443..1836a29 100644
--- a/src/test/java/com/android/tools/r8/classmerging/VerticalClassMergerTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/VerticalClassMergerTest.java
@@ -86,16 +86,13 @@
private void runR8(Path proguardConfig, Consumer<InternalOptions> optionsConsumer)
throws IOException, ExecutionException, CompilationFailedException {
- ToolHelper.runR8(
- R8Command.builder()
- .setOutput(Paths.get(temp.getRoot().getCanonicalPath()), OutputMode.DexIndexed)
+ inspector =
+ testForR8(Backend.DEX)
.addProgramFiles(EXAMPLE_JAR)
- .addProguardConfigurationFiles(proguardConfig)
- .setDisableMinification(true)
- .build(),
- optionsConsumer);
- inspector = new CodeInspector(
- Paths.get(temp.getRoot().getCanonicalPath()).resolve("classes.dex"));
+ .addKeepRuleFiles(proguardConfig)
+ .addOptionsModification(optionsConsumer)
+ .compile()
+ .inspector();
}
private CodeInspector inspector;
diff --git a/src/test/java/com/android/tools/r8/proguard/printmapping/PrintMappingTest.java b/src/test/java/com/android/tools/r8/proguard/printmapping/PrintMappingTest.java
index e9bf581..378cf0e 100644
--- a/src/test/java/com/android/tools/r8/proguard/printmapping/PrintMappingTest.java
+++ b/src/test/java/com/android/tools/r8/proguard/printmapping/PrintMappingTest.java
@@ -27,14 +27,11 @@
private void test(Path mapping) throws Exception {
testForR8(Backend.DEX)
.addInnerClasses(PrintMappingTest.class)
- .addKeepMainRule(TestClass.class)
+ .addKeepRules("-keep,allowobfuscation class " + TestClass.class.getTypeName())
.addKeepRules("-printmapping " + mapping)
.compile();
assertTrue(mapping.toFile().exists());
}
- static class TestClass {
-
- public static void main(String[] args) {}
- }
+ static class TestClass {}
}
diff --git a/src/test/java/com/android/tools/r8/resource/KeepDirectoriesTest.java b/src/test/java/com/android/tools/r8/resource/KeepDirectoriesTest.java
index 1c28054..5b7a11e 100644
--- a/src/test/java/com/android/tools/r8/resource/KeepDirectoriesTest.java
+++ b/src/test/java/com/android/tools/r8/resource/KeepDirectoriesTest.java
@@ -15,6 +15,7 @@
import com.android.tools.r8.DataResourceConsumer;
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.R8Command;
+import com.android.tools.r8.StringResource;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.naming.ClassNameMapper;
@@ -65,10 +66,15 @@
// Return the package name in the app for this package.
private String pathForThisPackage(AndroidApp app) throws Exception {
- ClassNameMapper mapper =
- ClassNameMapper.mapperFromString(app.getProguardMapOutputData().getString());
- String x = mapper.getObfuscatedToOriginalMapping().inverse.get(Main.class.getCanonicalName());
- return x.substring(0, x.lastIndexOf('.')).replace('.', '/');
+ String name;
+ if (app.getProguardMapOutputData() != null) {
+ ClassNameMapper mapper =
+ ClassNameMapper.mapperFromString(app.getProguardMapOutputData().getString());
+ name = mapper.getObfuscatedToOriginalMapping().inverse.get(Main.class.getCanonicalName());
+ } else {
+ name = Main.class.getTypeName();
+ }
+ return name.substring(0, name.lastIndexOf('.')).replace('.', '/');
}
private void checkResourceNames(Set<String> resourceNames, String expectedPackageName) {
diff --git a/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java b/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java
index b302615..0b246a5 100644
--- a/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java
@@ -260,9 +260,8 @@
}
if (inspection != null) {
- CodeInspector inspector = new CodeInspector(out,
- minify.isMinify() ? proguardMap.toString()
- : null);
+ CodeInspector inspector =
+ new CodeInspector(out, minify.isMinify() ? proguardMap.toString() : null);
inspection.accept(inspector);
}
}
diff --git a/src/test/java/com/android/tools/r8/shaking/examples/TreeShaking11Test.java b/src/test/java/com/android/tools/r8/shaking/examples/TreeShaking11Test.java
index f65c1d4..3833645 100644
--- a/src/test/java/com/android/tools/r8/shaking/examples/TreeShaking11Test.java
+++ b/src/test/java/com/android/tools/r8/shaking/examples/TreeShaking11Test.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking.examples;
-import com.android.tools.r8.TestBase.MinifyMode;
import com.android.tools.r8.shaking.TreeShakingTest;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableList;
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
index 9983320..a9058ff 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
@@ -45,6 +45,7 @@
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.lang.reflect.Method;
+import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
@@ -82,13 +83,14 @@
public CodeInspector(
List<Path> files, String mappingFile, Consumer<InternalOptions> optionsConsumer)
throws IOException, ExecutionException {
- if (mappingFile != null) {
- this.mapping = ClassNameMapper.mapperFromFile(Paths.get(mappingFile));
- BiMapContainer<String, String> nameMapping = this.mapping.getObfuscatedToOriginalMapping();
+ Path mappingPath = mappingFile != null ? Paths.get(mappingFile) : null;
+ if (mappingPath != null && Files.exists(mappingPath)) {
+ mapping = ClassNameMapper.mapperFromFile(mappingPath);
+ BiMapContainer<String, String> nameMapping = mapping.getObfuscatedToOriginalMapping();
obfuscatedToOriginalMapping = nameMapping.original;
originalToObfuscatedMapping = nameMapping.inverse;
} else {
- this.mapping = null;
+ mapping = null;
originalToObfuscatedMapping = null;
obfuscatedToOriginalMapping = null;
}