Desugared lib: refactoring
- compute in a single place retargetCoreLibMember
Bug: 145908214
Change-Id: I2b45a831e8b5ffee5445a6aee298a65092a09be5
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
index 939d33a..f990694 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
@@ -134,16 +134,12 @@
.appInfo()
.lookupSuperTarget(invoke.getInvokedMethod(), code.method.method.holder);
if (!dexEncodedMethod.isFinal()) { // Final methods can be rewritten as a normal invoke.
- Map<DexString, Map<DexType, DexType>> retargetCoreLibMember =
- appView.options().desugaredLibraryConfiguration.getRetargetCoreLibMember();
- Map<DexType, DexType> typeMap = retargetCoreLibMember.get(dexEncodedMethod.method.name);
- if (typeMap != null && typeMap.containsKey(dexEncodedMethod.method.holder)) {
- DexMethod retargetMethod =
- factory.createMethod(
- typeMap.get(dexEncodedMethod.method.holder),
- factory.prependTypeToProto(
- dexEncodedMethod.method.holder, dexEncodedMethod.method.proto),
- dexEncodedMethod.method.name);
+ DexMethod retargetMethod =
+ appView
+ .options()
+ .desugaredLibraryConfiguration
+ .retargetMethod(dexEncodedMethod.method, appView);
+ if (retargetMethod != null) {
iterator.replaceCurrentInstruction(
new InvokeStatic(retargetMethod, invoke.outValue(), invoke.arguments()));
}
@@ -318,7 +314,9 @@
// NOTE: Never add a forwarding method to methods of classes unknown or coming from android.jar
// even if this results in invalid code, these classes are never desugared.
// In desugared library, emulated interface methods can be overridden by retarget lib members.
- DexMethod forwardMethod = ClassProcessor.retargetMethod(appView, target);
+ DexMethod forwardMethod =
+ appView.options().desugaredLibraryConfiguration.retargetMethod(target, appView);
+ assert forwardMethod != null && forwardMethod != target;
// New method will have the same name, proto, and also all the flags of the
// default method, including bridge flag.
DexMethod newMethod =
@@ -433,20 +431,16 @@
// }
// We do not deal with complex cases (multiple retargeting of the same signature in the
// same inheritance tree, etc., since they do not happen in the most common desugared library.
- DexItemFactory factory = appView.dexItemFactory();
- DexProto newProto =
- factory.prependTypeToProto(emulatedDispatchMethod.holder, emulatedDispatchMethod.proto);
- DexMethod newMethod =
- factory.createMethod(dispatchHolder, newProto, emulatedDispatchMethod.name);
- DexType desugarType =
+ DexMethod desugarMethod =
appView
.options()
.desugaredLibraryConfiguration
- .getRetargetCoreLibMember()
- .get(emulatedDispatchMethod.name)
- .get(emulatedDispatchMethod.holder);
- DexMethod desugarMethod =
- factory.createMethod(desugarType, newProto, emulatedDispatchMethod.name);
+ .retargetMethod(emulatedDispatchMethod, appView);
+ assert desugarMethod != null; // This method is reached only for retarget core lib members.
+ DexMethod newMethod =
+ appView
+ .dexItemFactory()
+ .createMethod(dispatchHolder, desugarMethod.proto, emulatedDispatchMethod.name);
return DexEncodedMethod.toEmulateDispatchLibraryMethod(
emulatedDispatchMethod.holder,
newMethod,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
index c2f5ae9..5626ef4 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
@@ -12,7 +12,6 @@
import com.android.tools.r8.graph.DexLibraryClass;
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.MethodAccessFlags;
import com.android.tools.r8.graph.ParameterAnnotationsList;
@@ -50,6 +49,7 @@
// Collection for method signatures that may cause forwarding methods to be created.
private static class MethodSignatures {
+
static final MethodSignatures EMPTY = new MethodSignatures(Collections.emptySet());
static MethodSignatures create(Set<Wrapper<DexMethod>> signatures) {
@@ -125,6 +125,7 @@
// Helper to keep track of the direct active subclass and nearest program subclass for reporting.
private static class ReportingContext {
+
final DexClass directSubClass;
final DexProgramClass closestProgramSubClass;
@@ -156,6 +157,7 @@
// Specialized context to disable reporting when traversing the library strucure.
private static class LibraryReportingContext extends ReportingContext {
+
static final LibraryReportingContext LIBRARY_CONTEXT = new LibraryReportingContext();
LibraryReportingContext() {
@@ -340,13 +342,8 @@
if (method.isFinal()) {
return false;
}
- Map<DexType, DexType> typeMap =
- appView
- .options()
- .desugaredLibraryConfiguration
- .getRetargetCoreLibMember()
- .get(method.method.name);
- return typeMap != null && typeMap.containsKey(holder.type);
+ return appView.options().desugaredLibraryConfiguration.retargetMethod(method.method, appView)
+ != null;
}
private boolean dontRewrite(DexClass clazz, DexEncodedMethod method) {
@@ -391,7 +388,8 @@
DexMethod forwardMethod =
targetHolder.isInterface()
? rewriter.defaultAsMethodOfCompanionClass(method)
- : retargetMethod(appView, method);
+ : appView.options().desugaredLibraryConfiguration.retargetMethod(method, appView);
+ assert forwardMethod != null;
// New method will have the same name, proto, and also all the flags of the
// default method, including bridge flag.
DexMethod newMethod = dexItemFactory.createMethod(clazz.type, method.proto, method.name);
@@ -415,20 +413,6 @@
addSyntheticMethod(clazz.asProgramClass(), newEncodedMethod);
}
- static DexMethod retargetMethod(AppView<?> appView, DexMethod method) {
- Map<DexString, Map<DexType, DexType>> retargetCoreLibMember =
- appView.options().desugaredLibraryConfiguration.getRetargetCoreLibMember();
- Map<DexType, DexType> typeMap = retargetCoreLibMember.get(method.name);
- assert typeMap != null;
- assert typeMap.get(method.holder) != null;
- return appView
- .dexItemFactory()
- .createMethod(
- typeMap.get(method.holder),
- appView.dexItemFactory().prependTypeToProto(method.holder, method.proto),
- method.name);
- }
-
// Topological order traversal and its helpers.
private DexClass definitionOrNull(DexType type, ReportingContext context) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryConfiguration.java b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryConfiguration.java
index fd954e5..3d0a59c 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryConfiguration.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryConfiguration.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.desugar.PrefixRewritingMapper.DesugarPrefixRewritingMapper;
@@ -126,6 +127,20 @@
return emulateLibraryInterface;
}
+ // If the method is retargeted, answers the retargeted method, else null.
+ public DexMethod retargetMethod(DexMethod method, AppView<?> appView) {
+ Map<DexType, DexType> typeMap = retargetCoreLibMember.get(method.name);
+ if (typeMap != null && typeMap.containsKey(method.holder)) {
+ return appView
+ .dexItemFactory()
+ .createMethod(
+ typeMap.get(method.holder),
+ appView.dexItemFactory().prependTypeToProto(method.holder, method.proto),
+ method.name);
+ }
+ return null;
+ }
+
public Map<DexString, Map<DexType, DexType>> getRetargetCoreLibMember() {
return retargetCoreLibMember;
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
index 679f927..b044b37 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
@@ -288,11 +288,10 @@
// Rewriting is required because the super invoke resolves into a missing
// method (method is on desugared library). Find out if it needs to be
// retarget or if it just calls a companion class method and rewrite.
- Map<DexString, Map<DexType, DexType>> retargetCoreLibMember =
- options.desugaredLibraryConfiguration.getRetargetCoreLibMember();
- Map<DexType, DexType> typeMap =
- retargetCoreLibMember.get(dexEncodedMethod.method.name);
- if (typeMap == null || !typeMap.containsKey(dexEncodedMethod.method.holder)) {
+ DexMethod retargetMethod =
+ options.desugaredLibraryConfiguration.retargetMethod(
+ dexEncodedMethod.method, appView);
+ if (retargetMethod == null) {
DexMethod originalCompanionMethod =
instanceAsMethodOfCompanionClass(
dexEncodedMethod.method, DEFAULT_METHOD_PREFIX, factory);
@@ -306,12 +305,6 @@
new InvokeStatic(
companionMethod, invokeSuper.outValue(), invokeSuper.arguments()));
} else {
- DexMethod retargetMethod =
- factory.createMethod(
- typeMap.get(dexEncodedMethod.method.holder),
- factory.prependTypeToProto(
- dexEncodedMethod.method.holder, dexEncodedMethod.method.proto),
- dexEncodedMethod.method.name);
instructions.replaceCurrentInstruction(
new InvokeStatic(
retargetMethod, invokeSuper.outValue(), invokeSuper.arguments()));