Fix DesugarDescription for DesugaredLibraryRetargeter
Bug: b/270144318
Change-Id: I3e1981c757b5921c44583a04dc12cac829bb527e
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 11f9c1b..fd30618 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
@@ -4,8 +4,6 @@
package com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter;
-import static com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.DesugaredLibraryRetargeter.InvokeRetargetingResult.NO_REWRITING;
-
import com.android.tools.r8.cf.code.CfFieldInstruction;
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfInvoke;
@@ -15,21 +13,15 @@
import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexField;
-import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.MethodResolutionResult;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaring;
-import com.android.tools.r8.ir.desugar.CfInstructionDesugaringCollection;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
-import com.android.tools.r8.ir.desugar.FreshLocalProvider;
-import com.android.tools.r8.ir.desugar.LocalStackAllocator;
+import com.android.tools.r8.ir.desugar.DesugarDescription;
import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.EmulatedDispatchMethodDescriptor;
import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineDesugaredLibrarySpecification;
-import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.DesugaredLibraryRetargeterSynthesizerEventConsumer.DesugaredLibraryRetargeterInstructionEventConsumer;
-import java.util.Collection;
import java.util.Collections;
-import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Consumer;
@@ -66,53 +58,89 @@
}
@Override
- public Collection<CfInstruction> desugarInstruction(
- CfInstruction instruction,
- FreshLocalProvider freshLocalProvider,
- LocalStackAllocator localStackAllocator,
- CfInstructionDesugaringEventConsumer eventConsumer,
- ProgramMethod context,
- MethodProcessingContext methodProcessingContext,
- CfInstructionDesugaringCollection desugaringCollection,
- DexItemFactory dexItemFactory) {
- if (instruction.isStaticFieldGet() && needsDesugaring(instruction, context)) {
- return desugarFieldInstruction(instruction.asFieldInstruction(), context);
- } else if (instruction.isInvoke() && needsDesugaring(instruction, context)) {
- return desugarInvoke(instruction.asInvoke(), eventConsumer, context, methodProcessingContext);
- }
- return null;
- }
-
- private Collection<CfInstruction> desugarFieldInstruction(
- CfFieldInstruction fieldInstruction, ProgramMethod context) {
- DexField fieldRetarget = fieldRetarget(fieldInstruction, context);
- assert fieldRetarget != null;
- assert fieldInstruction.isStaticFieldGet();
- return Collections.singletonList(fieldInstruction.createWithField(fieldRetarget));
- }
-
- private List<CfInstruction> desugarInvoke(
- CfInvoke invoke,
- CfInstructionDesugaringEventConsumer eventConsumer,
- ProgramMethod context,
- MethodProcessingContext methodProcessingContext) {
- InvokeRetargetingResult invokeRetargetingResult = computeNewInvokeTarget(invoke, context);
- assert invokeRetargetingResult.hasNewInvokeTarget();
- DexMethod newInvokeTarget =
- invokeRetargetingResult.getNewInvokeTarget(eventConsumer, methodProcessingContext);
- assert appView.definitionFor(newInvokeTarget.getHolderType()) != null;
- assert !appView.definitionFor(newInvokeTarget.getHolderType()).isInterface();
- return Collections.singletonList(new CfInvoke(Opcodes.INVOKESTATIC, newInvokeTarget, false));
- }
-
- @Override
- public boolean needsDesugaring(CfInstruction instruction, ProgramMethod context) {
+ public DesugarDescription compute(CfInstruction instruction, ProgramMethod context) {
if (instruction.isStaticFieldGet()) {
- return fieldRetarget(instruction.asFieldInstruction(), context) != null;
- } else if (instruction.isInvoke()) {
- return computeNewInvokeTarget(instruction.asInvoke(), context).hasNewInvokeTarget();
+ return computeStaticFieldGetDescription(instruction, context);
}
- return false;
+ if (instruction.isInvoke()) {
+ return computeInvokeDescription(instruction, context);
+ }
+ return DesugarDescription.nothing();
+ }
+
+ private DesugarDescription computeInvokeDescription(
+ CfInstruction instruction, ProgramMethod context) {
+ if (appView.dexItemFactory().multiDexTypes.contains(context.getContextType())) {
+ return DesugarDescription.nothing();
+ }
+ CfInvoke cfInvoke = instruction.asInvoke();
+ DexMethod invokedMethod = cfInvoke.getMethod();
+ AppInfoWithClassHierarchy appInfo = appView.appInfoForDesugaring();
+ MethodResolutionResult resolutionResult =
+ appInfo.resolveMethodLegacy(invokedMethod, cfInvoke.isInterface());
+ if (!resolutionResult.isSingleResolution()) {
+ return DesugarDescription.nothing();
+ }
+ assert resolutionResult.getSingleTarget() != null;
+ DexMethod singleTarget = resolutionResult.getSingleTarget().getReference();
+ if (cfInvoke.isInvokeStatic()) {
+ DexMethod retarget = staticRetarget.get(singleTarget);
+ return ensureInvokeRetargetingResult(retarget);
+ }
+ DesugarDescription retarget = computeNonStaticRetarget(singleTarget, false);
+ if (!retarget.needsDesugaring()) {
+ return DesugarDescription.nothing();
+ }
+ if (cfInvoke.isInvokeSuper(context.getHolderType())) {
+ DexClassAndMethod superTarget = appInfo.lookupSuperTarget(invokedMethod, context);
+ if (superTarget != null) {
+ assert !superTarget.getDefinition().isStatic();
+ return computeNonStaticRetarget(superTarget.getReference(), true);
+ }
+ }
+ return retarget;
+ }
+
+ private DesugarDescription createWithTarget(
+ BiFunction<CfInstructionDesugaringEventConsumer, MethodProcessingContext, DexMethod>
+ methodProvider) {
+ return DesugarDescription.builder()
+ .setDesugarRewrite(
+ (freshLocalProvider,
+ localStackAllocator,
+ eventConsumer,
+ context,
+ methodProcessingContext,
+ desugarings,
+ dexItemFactory) -> {
+ DexMethod newInvokeTarget =
+ methodProvider.apply(eventConsumer, methodProcessingContext);
+ assert appView.definitionFor(newInvokeTarget.getHolderType()) != null;
+ assert !appView.definitionFor(newInvokeTarget.getHolderType()).isInterface();
+ return Collections.singletonList(
+ new CfInvoke(Opcodes.INVOKESTATIC, newInvokeTarget, false));
+ })
+ .build();
+ }
+
+ private DesugarDescription computeStaticFieldGetDescription(
+ CfInstruction instruction, ProgramMethod context) {
+ CfFieldInstruction fieldInstruction = instruction.asFieldInstruction();
+ DexField fieldRetarget = fieldRetarget(fieldInstruction, context);
+ if (fieldRetarget == null) {
+ return DesugarDescription.nothing();
+ }
+ return DesugarDescription.builder()
+ .setDesugarRewrite(
+ (freshLocalProvider,
+ localStackAllocator,
+ eventConsumer,
+ context1,
+ methodProcessingContext,
+ desugarings,
+ dexItemFactory) ->
+ Collections.singletonList(fieldInstruction.createWithField(fieldRetarget)))
+ .build();
}
private DexField fieldRetarget(CfFieldInstruction fieldInstruction, ProgramMethod context) {
@@ -129,98 +157,26 @@
return null;
}
- InvokeRetargetingResult ensureInvokeRetargetingResult(DexMethod retarget) {
+ DesugarDescription ensureInvokeRetargetingResult(DexMethod retarget) {
if (retarget == null) {
- return NO_REWRITING;
+ return DesugarDescription.nothing();
}
- return new InvokeRetargetingResult(
- true,
- (eventConsumer, methodProcessingContext) -> {
- syntheticHelper.ensureRetargetMethod(retarget, eventConsumer);
- return retarget;
- });
+ return createWithTarget(
+ (eventConsumer, methodProcessingContext) ->
+ syntheticHelper.ensureRetargetMethod(retarget, eventConsumer));
}
- static class InvokeRetargetingResult {
-
- static InvokeRetargetingResult NO_REWRITING =
- new InvokeRetargetingResult(false, (ignored, alsoIgnored) -> null);
-
- private final boolean hasNewInvokeTarget;
- private final BiFunction<
- DesugaredLibraryRetargeterInstructionEventConsumer, MethodProcessingContext, DexMethod>
- newInvokeTargetSupplier;
-
- private InvokeRetargetingResult(
- boolean hasNewInvokeTarget,
- BiFunction<
- DesugaredLibraryRetargeterInstructionEventConsumer,
- MethodProcessingContext,
- DexMethod>
- newInvokeTargetSupplier) {
- this.hasNewInvokeTarget = hasNewInvokeTarget;
- this.newInvokeTargetSupplier = newInvokeTargetSupplier;
- }
-
- public boolean hasNewInvokeTarget() {
- return hasNewInvokeTarget;
- }
-
- public DexMethod getNewInvokeTarget(
- DesugaredLibraryRetargeterInstructionEventConsumer eventConsumer,
- MethodProcessingContext methodProcessingContext) {
- assert hasNewInvokeTarget();
- return newInvokeTargetSupplier.apply(eventConsumer, methodProcessingContext);
- }
- }
-
- private InvokeRetargetingResult computeNewInvokeTarget(
- CfInvoke instruction, ProgramMethod context) {
- if (appView.dexItemFactory().multiDexTypes.contains(context.getContextType())) {
- return NO_REWRITING;
- }
- CfInvoke cfInvoke = instruction.asInvoke();
- DexMethod invokedMethod = cfInvoke.getMethod();
- AppInfoWithClassHierarchy appInfo = appView.appInfoForDesugaring();
- MethodResolutionResult resolutionResult =
- appInfo.resolveMethodLegacy(invokedMethod, cfInvoke.isInterface());
- if (!resolutionResult.isSingleResolution()) {
- return NO_REWRITING;
- }
- assert resolutionResult.getSingleTarget() != null;
- DexMethod singleTarget = resolutionResult.getSingleTarget().getReference();
- if (cfInvoke.isInvokeStatic()) {
- DexMethod retarget = staticRetarget.get(singleTarget);
- return retarget == null ? NO_REWRITING : ensureInvokeRetargetingResult(retarget);
- }
- InvokeRetargetingResult retarget = computeNonStaticRetarget(singleTarget, false);
- 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 retarget;
- }
-
- private InvokeRetargetingResult computeNonStaticRetarget(
- DexMethod singleTarget, boolean superInvoke) {
+ private DesugarDescription computeNonStaticRetarget(DexMethod singleTarget, boolean superInvoke) {
EmulatedDispatchMethodDescriptor descriptor = emulatedVirtualRetarget.get(singleTarget);
if (descriptor != null) {
- return new InvokeRetargetingResult(
- true,
+ return createWithTarget(
(eventConsumer, methodProcessingContext) ->
superInvoke
? syntheticHelper.ensureForwardingMethod(descriptor, eventConsumer)
: syntheticHelper.ensureEmulatedHolderDispatchMethod(descriptor, eventConsumer));
}
if (covariantRetarget.containsKey(singleTarget)) {
- return new InvokeRetargetingResult(
- true,
+ return createWithTarget(
(eventConsumer, methodProcessingContext) ->
syntheticHelper.ensureCovariantRetargetMethod(
singleTarget,