Revert "Stub retargeter"
This reverts commit e83d09622b71ae8183106c925c997a364ed71c4d.
Reason for revert: break bots
Change-Id: Idaebe22da56a772c56a5914459b15ebcf82c58dc
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 5a95c61..85c05f6 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -49,6 +49,7 @@
import com.android.tools.r8.ir.desugar.BackportedMethodRewriter;
import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaringCollection;
import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaringEventConsumer;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.DesugaredLibraryRetargeterLibraryTypeSynthesizer;
import com.android.tools.r8.ir.desugar.itf.InterfaceMethodRewriter;
import com.android.tools.r8.ir.desugar.records.RecordDesugaring;
import com.android.tools.r8.ir.desugar.records.RecordFieldValuesRewriter;
@@ -310,6 +311,10 @@
if (!options.mainDexKeepRules.isEmpty()) {
MainDexListBuilder.checkForAssumedLibraryTypes(appView.appInfo());
}
+ if (options.machineDesugaredLibrarySpecification.hasRetargeting()) {
+ DesugaredLibraryRetargeterLibraryTypeSynthesizer.checkForAssumedLibraryTypes(appView);
+ DesugaredLibraryRetargeterLibraryTypeSynthesizer.amendLibraryWithRetargetedMembers(appView);
+ }
InterfaceMethodRewriter.checkForAssumedLibraryTypes(appView.appInfo(), options);
BackportedMethodRewriter.registerAssumedLibraryTypes(options);
if (options.enableEnumUnboxing) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java
index 064e614..5fcf037 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java
@@ -11,11 +11,10 @@
import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexClassAndMethod;
+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.MethodAccessFlags;
import com.android.tools.r8.graph.MethodResolutionResult;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaring;
@@ -25,7 +24,6 @@
import com.android.tools.r8.ir.desugar.LocalStackAllocator;
import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.EmulatedDispatchMethodDescriptor;
import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.DesugaredLibraryRetargeterSynthesizerEventConsumer.DesugaredLibraryRetargeterInstructionEventConsumer;
-import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
@@ -89,41 +87,6 @@
return computeNewInvokeTarget(instruction, context).hasNewInvokeTarget();
}
- private void ensureRetargetMethod(
- DexMethod retarget, DesugaredLibraryRetargeterInstructionEventConsumer eventConsumer) {
- DexClass holderClass = appView.definitionFor(retarget.getHolderType());
- if (holderClass != null && holderClass.isProgramClass()) {
- assert holderClass.lookupMethod(retarget) != null;
- return;
- }
- appView
- .getSyntheticItems()
- .ensureFixedClasspathMethodFromType(
- retarget.getName(),
- retarget.getProto(),
- SyntheticKind.RETARGET_STUB,
- retarget.getHolderType(),
- appView,
- ignored -> {},
- eventConsumer::acceptDesugaredLibraryRetargeterDispatchClasspathClass,
- methodBuilder ->
- methodBuilder
- .setAccessFlags(MethodAccessFlags.createPublicStaticSynthetic())
- .setCode(null));
- }
-
- InvokeRetargetingResult ensureInvokeRetargetingResult(DexMethod retarget) {
- if (retarget == null) {
- return NO_REWRITING;
- }
- return new InvokeRetargetingResult(
- true,
- eventConsumer -> {
- ensureRetargetMethod(retarget, eventConsumer);
- return retarget;
- });
- }
-
static class InvokeRetargetingResult {
static InvokeRetargetingResult NO_REWRITING =
@@ -185,33 +148,44 @@
assert singleTarget != null;
if (cfInvoke.isInvokeStatic()) {
DexMethod retarget = staticRetarget.get(singleTarget);
- return retarget == null ? NO_REWRITING : ensureInvokeRetargetingResult(retarget);
+ return retarget == null
+ ? NO_REWRITING
+ : InvokeRetargetingResult.createInvokeRetargetingResult(retarget);
}
- InvokeRetargetingResult retarget = computeNonStaticRetarget(singleTarget, false);
+ InvokeRetargetingResult retarget = computeNonStaticRetarget(singleTarget);
if (!retarget.hasNewInvokeTarget()) {
return NO_REWRITING;
}
if (cfInvoke.isInvokeSuper(context.getHolderType())) {
DexClassAndMethod superTarget = appInfo.lookupSuperTarget(invokedMethod, context);
if (superTarget != null) {
- assert !superTarget.getDefinition().isStatic();
- return computeNonStaticRetarget(superTarget.getReference(), true);
+ return computeSuperRetarget(superTarget.getDefinition());
}
}
return retarget;
}
- private InvokeRetargetingResult computeNonStaticRetarget(
- DexMethod singleTarget, boolean superInvoke) {
+ private InvokeRetargetingResult computeNonStaticRetarget(DexMethod singleTarget) {
EmulatedDispatchMethodDescriptor descriptor = emulatedVirtualRetarget.get(singleTarget);
if (descriptor != null) {
return new InvokeRetargetingResult(
true,
eventConsumer ->
- superInvoke
- ? syntheticHelper.ensureForwardingMethod(descriptor)
- : syntheticHelper.ensureEmulatedHolderDispatchMethod(descriptor, eventConsumer));
+ syntheticHelper.ensureEmulatedHolderDispatchMethod(descriptor, eventConsumer));
}
- return ensureInvokeRetargetingResult(nonEmulatedVirtualRetarget.get(singleTarget));
+ return InvokeRetargetingResult.createInvokeRetargetingResult(
+ nonEmulatedVirtualRetarget.get(singleTarget));
+ }
+
+ private InvokeRetargetingResult computeSuperRetarget(DexEncodedMethod singleTarget) {
+ assert !singleTarget.isStatic();
+ DexMethod reference = singleTarget.getReference();
+ EmulatedDispatchMethodDescriptor descriptor = emulatedVirtualRetarget.get(reference);
+ if (descriptor != null) {
+ return InvokeRetargetingResult.createInvokeRetargetingResult(
+ syntheticHelper.ensureForwardingMethod(descriptor));
+ }
+ return InvokeRetargetingResult.createInvokeRetargetingResult(
+ nonEmulatedVirtualRetarget.get(reference));
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterLibraryTypeSynthesizer.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterLibraryTypeSynthesizer.java
new file mode 100644
index 0000000..bfb423a
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterLibraryTypeSynthesizer.java
@@ -0,0 +1,163 @@
+// Copyright (c) 2021, 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.ir.desugar.desugaredlibrary.retargeter;
+
+import com.android.tools.r8.ProgramResource.Kind;
+import com.android.tools.r8.dex.Constants;
+import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.ClassAccessFlags;
+import com.android.tools.r8.graph.DexAnnotationSet;
+import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexEncodedField;
+import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexLibraryClass;
+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.graph.DexTypeList;
+import com.android.tools.r8.graph.DirectMappedDexApplication;
+import com.android.tools.r8.graph.EnclosingMethodAttribute;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
+import com.android.tools.r8.graph.InnerClassAttribute;
+import com.android.tools.r8.graph.MethodAccessFlags;
+import com.android.tools.r8.graph.NestHostClassAttribute;
+import com.android.tools.r8.graph.NestMemberClassAttribute;
+import com.android.tools.r8.origin.SynthesizedOrigin;
+import com.android.tools.r8.utils.StringDiagnostic;
+import java.util.Comparator;
+import java.util.IdentityHashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeSet;
+
+public class DesugaredLibraryRetargeterLibraryTypeSynthesizer {
+
+ public static void checkForAssumedLibraryTypes(AppView<?> appView) {
+ appView
+ .options()
+ .machineDesugaredLibrarySpecification
+ .forEachRetargetHolder(
+ inType -> {
+ DexClass typeClass = appView.definitionFor(inType);
+ if (typeClass == null) {
+ warnMissingRetargetCoreLibraryMember(inType, appView);
+ }
+ });
+ }
+
+ public static void amendLibraryWithRetargetedMembers(AppView<AppInfoWithClassHierarchy> appView) {
+ Map<DexString, Map<DexType, DexType>> retargetCoreLibMember =
+ appView.options().desugaredLibrarySpecification.getRetargetCoreLibMember();
+ Map<DexType, DexLibraryClass> synthesizedLibraryClasses =
+ synthesizeLibraryClassesForRetargetedMembers(appView, retargetCoreLibMember);
+ Map<DexLibraryClass, Set<DexEncodedMethod>> synthesizedLibraryMethods =
+ synthesizedMembersForRetargetClasses(
+ appView, retargetCoreLibMember, synthesizedLibraryClasses);
+ synthesizedLibraryMethods.forEach(DexLibraryClass::addDirectMethods);
+ DirectMappedDexApplication newApplication =
+ appView
+ .appInfo()
+ .app()
+ .asDirect()
+ .builder()
+ .addLibraryClasses(synthesizedLibraryClasses.values())
+ .build();
+ appView.setAppInfo(appView.appInfo().rebuildWithClassHierarchy(app -> newApplication));
+ }
+
+ private static Map<DexType, DexLibraryClass> synthesizeLibraryClassesForRetargetedMembers(
+ AppView<AppInfoWithClassHierarchy> appView,
+ Map<DexString, Map<DexType, DexType>> retargetCoreLibMember) {
+ DexItemFactory dexItemFactory = appView.dexItemFactory();
+ Map<DexType, DexLibraryClass> synthesizedLibraryClasses = new LinkedHashMap<>();
+ for (Map<DexType, DexType> oldToNewTypeMap : retargetCoreLibMember.values()) {
+ for (DexType newType : oldToNewTypeMap.values()) {
+ if (appView.definitionFor(newType) == null) {
+ synthesizedLibraryClasses.computeIfAbsent(
+ newType,
+ type ->
+ // Synthesize a library class with the given name. Note that this is assuming that
+ // the library class inherits directly from java.lang.Object, does not implement
+ // any interfaces, etc.
+ new DexLibraryClass(
+ type,
+ Kind.CF,
+ new SynthesizedOrigin(
+ "Desugared library retargeter", DesugaredLibraryRetargeter.class),
+ ClassAccessFlags.fromCfAccessFlags(Constants.ACC_PUBLIC),
+ dexItemFactory.objectType,
+ DexTypeList.empty(),
+ dexItemFactory.createString("DesugaredLibraryRetargeter"),
+ NestHostClassAttribute.none(),
+ NestMemberClassAttribute.emptyList(),
+ EnclosingMethodAttribute.none(),
+ InnerClassAttribute.emptyList(),
+ ClassSignature.noSignature(),
+ DexAnnotationSet.empty(),
+ DexEncodedField.EMPTY_ARRAY,
+ DexEncodedField.EMPTY_ARRAY,
+ DexEncodedMethod.EMPTY_ARRAY,
+ DexEncodedMethod.EMPTY_ARRAY,
+ dexItemFactory.getSkipNameValidationForTesting()));
+ }
+ }
+ }
+ return synthesizedLibraryClasses;
+ }
+
+ private static Map<DexLibraryClass, Set<DexEncodedMethod>> synthesizedMembersForRetargetClasses(
+ AppView<AppInfoWithClassHierarchy> appView,
+ Map<DexString, Map<DexType, DexType>> retargetCoreLibMember,
+ Map<DexType, DexLibraryClass> synthesizedLibraryClasses) {
+ DexItemFactory dexItemFactory = appView.dexItemFactory();
+ Map<DexLibraryClass, Set<DexEncodedMethod>> synthesizedMembers = new IdentityHashMap<>();
+ for (Entry<DexString, Map<DexType, DexType>> entry : retargetCoreLibMember.entrySet()) {
+ DexString methodName = entry.getKey();
+ Map<DexType, DexType> types = entry.getValue();
+ types.forEach(
+ (oldType, newType) -> {
+ DexClass oldClass = appView.definitionFor(oldType);
+ DexLibraryClass newClass = synthesizedLibraryClasses.get(newType);
+ if (oldClass == null || newClass == null) {
+ return;
+ }
+ for (DexEncodedMethod method :
+ oldClass.methods(method -> method.getName() == methodName)) {
+ DexMethod retargetMethod = method.getReference().withHolder(newType, dexItemFactory);
+ if (!method.isStatic()) {
+ retargetMethod = retargetMethod.withExtraArgumentPrepended(oldType, dexItemFactory);
+ }
+ synthesizedMembers
+ .computeIfAbsent(
+ newClass,
+ ignore -> new TreeSet<>(Comparator.comparing(DexEncodedMethod::getReference)))
+ .add(
+ DexEncodedMethod.syntheticBuilder()
+ .setMethod(retargetMethod)
+ .setAccessFlags(
+ MethodAccessFlags.fromCfAccessFlags(
+ Constants.ACC_PUBLIC | Constants.ACC_STATIC, false))
+ .setCode(null)
+ .setApiLevelForDefinition(method.getApiLevelForDefinition())
+ .build());
+ }
+ });
+ }
+ return synthesizedMembers;
+ }
+
+ private static void warnMissingRetargetCoreLibraryMember(DexType type, AppView<?> appView) {
+ StringDiagnostic warning =
+ new StringDiagnostic(
+ "Cannot retarget core library member "
+ + type.getName()
+ + " because the class is missing.");
+ appView.options().reporter.warning(warning);
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
index 7c3303b..cb4a537 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
@@ -171,8 +171,7 @@
SyntheticKind.EMULATED_INTERFACE_MARKER_CLASS,
type,
appView,
- SyntheticClassBuilder::setInterface,
- ignored -> {});
+ SyntheticClassBuilder::setInterface);
}
DexClassAndMethod lookupMaximallySpecificIncludingSelf(
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
index 9b67476..6d45ee1 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
@@ -10,7 +10,6 @@
import com.android.tools.r8.features.ClassToFeatureSplitMap;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.ClasspathMethod;
import com.android.tools.r8.graph.ClasspathOrLibraryClass;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexClass;
@@ -650,11 +649,10 @@
SyntheticKind kind,
DexType contextType,
AppView<?> appView,
- Consumer<SyntheticClasspathClassBuilder> classConsumer,
- Consumer<DexClasspathClass> onCreationConsumer) {
+ Consumer<SyntheticClasspathClassBuilder> classConsumer) {
SynthesizingContext outerContext = SynthesizingContext.fromType(contextType);
return internalEnsureFixedClasspathClass(
- kind, classConsumer, onCreationConsumer, outerContext, appView);
+ kind, classConsumer, ignored -> {}, outerContext, appView);
}
public DexClasspathClass ensureFixedClasspathClass(
@@ -670,23 +668,7 @@
kind, classConsumer, onCreationConsumer, outerContext, appView);
}
- public ClasspathMethod ensureFixedClasspathMethodFromType(
- DexString methodName,
- DexProto methodProto,
- SyntheticKind kind,
- DexType contextType,
- AppView<?> appView,
- Consumer<SyntheticClasspathClassBuilder> classConsumer,
- Consumer<DexClasspathClass> onCreationConsumer,
- Consumer<SyntheticMethodBuilder> buildMethodCallback) {
- DexClasspathClass clazz =
- ensureFixedClasspathClassFromType(
- kind, contextType, appView, classConsumer, onCreationConsumer);
- return internalEnsureFixedClasspathMethod(
- methodName, methodProto, kind, appView, buildMethodCallback, clazz);
- }
-
- public ClasspathMethod ensureFixedClasspathClassMethod(
+ public DexClassAndMethod ensureFixedClasspathClassMethod(
DexString methodName,
DexProto methodProto,
SyntheticKind kind,
@@ -698,17 +680,6 @@
DexClasspathClass clazz =
ensureFixedClasspathClass(
kind, context, appView, buildClassCallback, onClassCreationCallback);
- return internalEnsureFixedClasspathMethod(
- methodName, methodProto, kind, appView, buildMethodCallback, clazz);
- }
-
- private ClasspathMethod internalEnsureFixedClasspathMethod(
- DexString methodName,
- DexProto methodProto,
- SyntheticKind kind,
- AppView<?> appView,
- Consumer<SyntheticMethodBuilder> buildMethodCallback,
- DexClasspathClass clazz) {
DexMethod methodReference =
appView.dexItemFactory().createMethod(clazz.getType(), methodProto, methodName);
DexEncodedMethod methodDefinition =
@@ -723,7 +694,7 @@
buildMethodCallback.accept(methodBuilder.disableAndroidApiLevelCheck());
},
emptyConsumer());
- return new ClasspathMethod(clazz, methodDefinition);
+ return DexClassAndMethod.create(clazz, methodDefinition);
}
@SuppressWarnings("unchecked")
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
index 6568eaa..62c7c6f 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
@@ -31,7 +31,6 @@
COMPANION_CLASS("$-CC", 2, false, true),
EMULATED_INTERFACE_CLASS("$-EL", 3, false, true),
RETARGET_CLASS("RetargetClass", 20, false, true),
- RETARGET_STUB("RetargetStub", 36, false, true),
RETARGET_INTERFACE("RetargetInterface", 21, false, true),
WRAPPER("$Wrapper", 22, false, true),
VIVIFIED_WRAPPER("$VivifiedWrapper", 23, false, true),