Extend profile rewriting to default interface method desugaring
Bug: b/265729283
Change-Id: I2eb2795acab72f9e1cfd4519d70f0511d45b5142
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 761298d..d7a47a1 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -1224,12 +1224,11 @@
}
public static DexEncodedMethod createDesugaringForwardingMethod(
- DexEncodedMethod target, DexClass clazz, DexMethod forwardMethod, DexItemFactory factory) {
- DexMethod method = target.getReference();
+ DexClassAndMethod target, DexClass clazz, DexMethod forwardMethod, DexItemFactory factory) {
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 = factory.createMethod(clazz.type, method.proto, method.name);
+ DexMethod newMethod = target.getReference().withHolder(clazz, factory);
MethodAccessFlags newFlags = target.getAccessFlags().copy();
// Some debuggers (like IntelliJ) automatically skip synthetic methods on single step.
newFlags.setSynthetic();
@@ -1246,8 +1245,8 @@
.setNonStaticSource(newMethod)
.setStaticTarget(forwardMethod, isInterfaceMethodReference)
.build())
- .setApiLevelForDefinition(target.getApiLevelForDefinition())
- .setApiLevelForCode(target.getApiLevelForCode())
+ .setApiLevelForDefinition(target.getDefinition().getApiLevelForDefinition())
+ .setApiLevelForCode(target.getDefinition().getApiLevelForCode())
.build();
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java
index f96680f..0d37795 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.ir.desugar;
import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexClasspathClass;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
@@ -13,6 +14,8 @@
import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.DesugaredLibraryRetargeterSynthesizerEventConsumer.DesugaredLibraryRetargeterPostProcessingEventConsumer;
import com.android.tools.r8.ir.desugar.itf.InterfaceDesugaringSyntheticHelper;
import com.android.tools.r8.ir.desugar.itf.InterfaceProcessingDesugaringEventConsumer;
+import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
+import com.android.tools.r8.profile.art.rewriting.ArtProfileRewritingCfPostProcessingDesugaringEventConsumer;
import com.android.tools.r8.shaking.Enqueuer.SyntheticAdditions;
import com.android.tools.r8.utils.collections.ProgramMethodSet;
import java.util.concurrent.ExecutionException;
@@ -33,11 +36,15 @@
return new D8CfPostProcessingDesugaringEventConsumer(methodProcessor, instructionDesugaring);
}
- public static R8PostProcessingDesugaringEventConsumer createForR8(
+ public static CfPostProcessingDesugaringEventConsumer createForR8(
SyntheticAdditions additions,
+ ArtProfileCollectionAdditions artProfileCollectionAdditions,
CfInstructionDesugaringCollection desugaring,
BiConsumer<DexProgramClass, DexType> missingClassConsumer) {
- return new R8PostProcessingDesugaringEventConsumer(additions, desugaring, missingClassConsumer);
+ CfPostProcessingDesugaringEventConsumer eventConsumer =
+ new R8PostProcessingDesugaringEventConsumer(additions, desugaring, missingClassConsumer);
+ return ArtProfileRewritingCfPostProcessingDesugaringEventConsumer.attach(
+ artProfileCollectionAdditions, eventConsumer);
}
public abstract void finalizeDesugaring() throws ExecutionException;
@@ -92,7 +99,18 @@
}
@Override
- public void acceptForwardingMethod(ProgramMethod method) {
+ public void acceptDesugaredLibraryRetargeterForwardingMethod(ProgramMethod method) {
+ addMethodToReprocess(method);
+ }
+
+ @Override
+ public void acceptInterfaceMethodDesugaringForwardingMethod(
+ ProgramMethod method, DexClassAndMethod baseMethod) {
+ addMethodToReprocess(method);
+ }
+
+ @Override
+ public void acceptThrowingMethod(ProgramMethod method, DexType errorType) {
addMethodToReprocess(method);
}
@@ -180,7 +198,18 @@
}
@Override
- public void acceptForwardingMethod(ProgramMethod method) {
+ public void acceptDesugaredLibraryRetargeterForwardingMethod(ProgramMethod method) {
+ additions.addLiveMethod(method);
+ }
+
+ @Override
+ public void acceptInterfaceMethodDesugaringForwardingMethod(
+ ProgramMethod method, DexClassAndMethod baseMethod) {
+ additions.addLiveMethod(method);
+ }
+
+ @Override
+ public void acceptThrowingMethod(ProgramMethod method, DexType errorType) {
additions.addLiveMethod(method);
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterPostProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterPostProcessor.java
index 53b8207..cc5abfd 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterPostProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterPostProcessor.java
@@ -5,6 +5,7 @@
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.DexLibraryClass;
import com.android.tools.r8.graph.DexMethod;
@@ -136,7 +137,8 @@
if (clazz.lookupVirtualMethod(method) == null) {
DexEncodedMethod newMethod = createForwardingMethod(itfMethod, descriptor, clazz);
clazz.addVirtualMethod(newMethod);
- eventConsumer.acceptForwardingMethod(new ProgramMethod(clazz, newMethod));
+ eventConsumer.acceptDesugaredLibraryRetargeterForwardingMethod(
+ new ProgramMethod(clazz, newMethod));
}
}
}
@@ -148,8 +150,8 @@
// In desugared library, emulated interface methods can be overridden by retarget lib members.
DexMethod forwardMethod = syntheticHelper.forwardingMethod(descriptor);
assert forwardMethod != null && forwardMethod != target;
- DexEncodedMethod resolvedMethod =
- appView.appInfoForDesugaring().resolveMethodLegacy(target, true).getResolvedMethod();
+ DexClassAndMethod resolvedMethod =
+ appView.appInfoForDesugaring().resolveMethodLegacy(target, true).getResolutionPair();
assert resolvedMethod != null;
DexEncodedMethod desugaringForwardingMethod =
DexEncodedMethod.createDesugaringForwardingMethod(
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterSynthesizerEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterSynthesizerEventConsumer.java
index 7e86c5b..63dcba2 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterSynthesizerEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterSynthesizerEventConsumer.java
@@ -25,6 +25,6 @@
extends DesugaredLibraryRetargeterInstructionEventConsumer {
void acceptInterfaceInjection(DexProgramClass clazz, DexClass newInterface);
- void acceptForwardingMethod(ProgramMethod method);
+ void acceptDesugaredLibraryRetargeterForwardingMethod(ProgramMethod method);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/ClassProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/ClassProcessor.java
index 3f3d045..0c5ed70 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/ClassProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/ClassProcessor.java
@@ -18,6 +18,7 @@
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexClassAndMember;
import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.DexEncodedMember;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexLibraryClass;
@@ -39,8 +40,8 @@
import com.android.tools.r8.utils.IterableUtils;
import com.android.tools.r8.utils.MethodSignatureEquivalence;
import com.android.tools.r8.utils.OptionalBool;
+import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.WorkList;
-import com.android.tools.r8.utils.collections.ProgramMethodSet;
import com.google.common.base.Equivalence.Wrapper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
@@ -55,6 +56,8 @@
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -71,6 +74,74 @@
*/
final class ClassProcessor {
+ private abstract static class SyntheticMethodInfo {
+
+ private final ProgramMethod method;
+
+ SyntheticMethodInfo(ProgramMethod method) {
+ this.method = method;
+ }
+
+ ProgramMethod getMethod() {
+ return method;
+ }
+
+ boolean isForwardingMethodInfo() {
+ return false;
+ }
+
+ SyntheticForwardingMethodInfo asForwardingMethodInfo() {
+ return null;
+ }
+
+ SyntheticThrowingMethodInfo asThrowingMethodInfo() {
+ return null;
+ }
+ }
+
+ private static class SyntheticForwardingMethodInfo extends SyntheticMethodInfo {
+
+ private final DexClassAndMethod baseMethod;
+
+ SyntheticForwardingMethodInfo(ProgramMethod method, DexClassAndMethod baseMethod) {
+ super(method);
+ this.baseMethod = baseMethod;
+ }
+
+ DexClassAndMethod getBaseMethod() {
+ return baseMethod;
+ }
+
+ @Override
+ boolean isForwardingMethodInfo() {
+ return true;
+ }
+
+ @Override
+ SyntheticForwardingMethodInfo asForwardingMethodInfo() {
+ return this;
+ }
+ }
+
+ private static class SyntheticThrowingMethodInfo extends SyntheticMethodInfo {
+
+ private final DexType errorType;
+
+ SyntheticThrowingMethodInfo(ProgramMethod method, DexType errorType) {
+ super(method);
+ this.errorType = errorType;
+ }
+
+ DexType getErrorType() {
+ return errorType;
+ }
+
+ @Override
+ SyntheticThrowingMethodInfo asThrowingMethodInfo() {
+ return this;
+ }
+ }
+
// Collection for method signatures that may cause forwarding methods to be created.
private static class MethodSignatures {
@@ -370,7 +441,7 @@
private final Map<DexClass, SignaturesInfo> interfaceInfo = new ConcurrentHashMap<>();
// Mapping from actual program classes to the synthesized forwarding methods to be created.
- private final Map<DexProgramClass, ProgramMethodSet> newSyntheticMethods =
+ private final Map<DexProgramClass, Map<DexMethod, SyntheticMethodInfo>> newSyntheticMethods =
new ConcurrentHashMap<>();
// Mapping from actual program classes to the extra interfaces needed for emulated dispatch.
@@ -422,16 +493,30 @@
// We introduce forwarding methods only once all desugaring has been performed to avoid
// confusing the look-up with inserted forwarding methods.
- public void finalizeProcessing(InterfaceProcessingDesugaringEventConsumer eventConsumer) {
- newSyntheticMethods.forEach(
- (clazz, newForwardingMethods) -> {
- List<ProgramMethod> sorted = new ArrayList<>(newForwardingMethods.toCollection());
- sorted.sort(Comparator.comparing(ProgramMethod::getReference));
- for (ProgramMethod method : sorted) {
- clazz.addVirtualMethod(method.getDefinition());
- eventConsumer.acceptForwardingMethod(method);
+ public void finalizeProcessing(
+ InterfaceProcessingDesugaringEventConsumer eventConsumer, ExecutorService executorService)
+ throws ExecutionException {
+ ThreadUtils.processMap(
+ newSyntheticMethods,
+ (clazz, infos) -> {
+ List<DexEncodedMethod> sortedDefinitions = new ArrayList<>(infos.size());
+ for (SyntheticMethodInfo info : infos.values()) {
+ sortedDefinitions.add(info.getMethod().getDefinition());
}
- });
+ sortedDefinitions.sort(Comparator.comparing(DexEncodedMember::getReference));
+ clazz.addVirtualMethods(sortedDefinitions);
+ for (DexEncodedMethod definition : sortedDefinitions) {
+ SyntheticMethodInfo info = infos.get(definition.getReference());
+ if (info.isForwardingMethodInfo()) {
+ eventConsumer.acceptInterfaceMethodDesugaringForwardingMethod(
+ info.getMethod(), info.asForwardingMethodInfo().getBaseMethod());
+ } else {
+ eventConsumer.acceptThrowingMethod(
+ info.getMethod(), info.asThrowingMethodInfo().getErrorType());
+ }
+ }
+ },
+ executorService);
newExtraInterfaceSignatures.forEach(
(clazz, extraInterfaceSignatures) -> {
if (!extraInterfaceSignatures.isEmpty()) {
@@ -826,11 +911,20 @@
}
}
- // Construction of actual forwarding methods.
- private void addSyntheticMethod(DexProgramClass clazz, DexEncodedMethod method) {
- newSyntheticMethods
- .computeIfAbsent(clazz, key -> ProgramMethodSet.create())
- .createAndAdd(clazz, method);
+ private void addSyntheticForwardingMethod(ProgramMethod method, DexClassAndMethod baseMethod) {
+ SyntheticMethodInfo existingMethodInfo =
+ newSyntheticMethods
+ .computeIfAbsent(method.getHolder(), key -> new ConcurrentHashMap<>())
+ .put(method.getReference(), new SyntheticForwardingMethodInfo(method, baseMethod));
+ assert existingMethodInfo == null;
+ }
+
+ private void addSyntheticThrowingMethod(ProgramMethod method, DexType errorType) {
+ SyntheticMethodInfo existingMethodInfo =
+ newSyntheticMethods
+ .computeIfAbsent(method.getHolder(), key -> new ConcurrentHashMap<>())
+ .put(method.getReference(), new SyntheticThrowingMethodInfo(method, errorType));
+ assert existingMethodInfo == null;
}
private void addICCEThrowingMethod(DexMethod method, DexClass clazz) {
@@ -859,7 +953,7 @@
createExceptionThrowingCfCode(newMethod, accessFlags, errorType, dexItemFactory))
.disableAndroidApiLevelCheck()
.build();
- addSyntheticMethod(clazz.asProgramClass(), newEncodedMethod);
+ addSyntheticThrowingMethod(newEncodedMethod.asProgramMethod(clazz.asProgramClass()), errorType);
}
private static CfCode createExceptionThrowingCfCode(
@@ -907,12 +1001,12 @@
// In desugared library, emulated interface methods can be overridden by retarget lib members.
DexEncodedMethod desugaringForwardingMethod =
DexEncodedMethod.createDesugaringForwardingMethod(
- target.getDefinition(), clazz, forwardMethod, dexItemFactory);
- if (!target.isProgramDefinition()
- || target.getDefinition().isLibraryMethodOverride().isTrue()) {
+ target, clazz, forwardMethod, dexItemFactory);
+ if (!target.isProgramMethod() || target.getDefinition().isLibraryMethodOverride().isTrue()) {
desugaringForwardingMethod.setLibraryMethodOverride(OptionalBool.TRUE);
}
- addSyntheticMethod(clazz.asProgramClass(), desugaringForwardingMethod);
+ addSyntheticForwardingMethod(
+ desugaringForwardingMethod.asProgramMethod(clazz.asProgramClass()), target);
}
// Topological order traversal and its helpers.
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodProcessorFacade.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodProcessorFacade.java
index a5ec16a..c92c9ce 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodProcessorFacade.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodProcessorFacade.java
@@ -54,7 +54,7 @@
Iterables.filter(programClasses, (DexProgramClass clazz) -> shouldProcess(clazz, flavour)),
clazz -> classProcessor.process(clazz, eventConsumer),
executorService);
- classProcessor.finalizeProcessing(eventConsumer);
+ classProcessor.finalizeProcessing(eventConsumer, executorService);
interfaceProcessor.finalizeProcessing();
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessingDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessingDesugaringEventConsumer.java
index 8115626..dde1382 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessingDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessingDesugaringEventConsumer.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.ir.desugar.itf;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexClasspathClass;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
@@ -11,11 +12,14 @@
public interface InterfaceProcessingDesugaringEventConsumer {
- void acceptForwardingMethod(ProgramMethod method);
+ void acceptInterfaceMethodDesugaringForwardingMethod(
+ ProgramMethod method, DexClassAndMethod baseMethod);
void acceptEmulatedInterfaceMarkerInterface(
DexProgramClass clazz, DexClasspathClass newInterface);
+ void acceptThrowingMethod(ProgramMethod method, DexType errorType);
+
void warnMissingInterface(
DexProgramClass context, DexType missing, InterfaceDesugaringSyntheticHelper helper);
}
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileAdditions.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileAdditions.java
index 297e443..428f970 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileAdditions.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileAdditions.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.profile.art.rewriting;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
@@ -32,7 +33,7 @@
this.artProfile = artProfile;
}
- void addRulesIfContextIsInProfile(ProgramMethod context, ProgramDefinition... definitions) {
+ void addRulesIfContextIsInProfile(DexClassAndMethod context, ProgramDefinition... definitions) {
ArtProfileMethodRule contextMethodRule = artProfile.getMethodRule(context.getReference());
if (contextMethodRule != null) {
for (ProgramDefinition definition : definitions) {
@@ -42,7 +43,7 @@
}
// Specialization of the above method to avoid redundant varargs array creation.
- void addRulesIfContextIsInProfile(ProgramMethod context, ProgramDefinition definition) {
+ void addRulesIfContextIsInProfile(DexClassAndMethod context, ProgramDefinition definition) {
ArtProfileMethodRule contextMethodRule = artProfile.getMethodRule(context.getReference());
if (contextMethodRule != null) {
addRuleFromContext(definition, contextMethodRule, MethodRuleAdditionConfig.getDefault());
@@ -82,9 +83,11 @@
methodReference -> ArtProfileMethodRule.builder().setMethod(method.getReference()));
// Setup the rule.
- methodRuleBuilder.acceptMethodRuleInfoBuilder(
- methodRuleInfoBuilder ->
- config.configureMethodRuleInfo(methodRuleInfoBuilder, contextMethodRule));
+ synchronized (methodRuleBuilder) {
+ methodRuleBuilder.acceptMethodRuleInfoBuilder(
+ methodRuleInfoBuilder ->
+ config.configureMethodRuleInfo(methodRuleInfoBuilder, contextMethodRule));
+ }
}
ArtProfile createNewArtProfile() {
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfInstructionDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfInstructionDesugaringEventConsumer.java
index 5c9ffa5..3f04e4c 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfInstructionDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfInstructionDesugaringEventConsumer.java
@@ -82,6 +82,8 @@
@Override
public void acceptDefaultAsCompanionMethod(ProgramMethod method, ProgramMethod companionMethod) {
+ additionsCollection.addRulesIfContextIsInProfile(
+ method, companionMethod, companionMethod.getHolder());
parent.acceptDefaultAsCompanionMethod(method, companionMethod);
}
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfPostProcessingDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfPostProcessingDesugaringEventConsumer.java
new file mode 100644
index 0000000..cc234c8
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfPostProcessingDesugaringEventConsumer.java
@@ -0,0 +1,113 @@
+// Copyright (c) 2023, 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.profile.art.rewriting;
+
+import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.DexClasspathClass;
+import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer;
+import com.android.tools.r8.ir.desugar.itf.InterfaceDesugaringSyntheticHelper;
+import java.util.concurrent.ExecutionException;
+
+public class ArtProfileRewritingCfPostProcessingDesugaringEventConsumer
+ extends CfPostProcessingDesugaringEventConsumer {
+
+ private final ConcreteArtProfileCollectionAdditions additionsCollection;
+ private final CfPostProcessingDesugaringEventConsumer parent;
+
+ private ArtProfileRewritingCfPostProcessingDesugaringEventConsumer(
+ ConcreteArtProfileCollectionAdditions additionsCollection,
+ CfPostProcessingDesugaringEventConsumer parent) {
+ this.additionsCollection = additionsCollection;
+ this.parent = parent;
+ }
+
+ public static CfPostProcessingDesugaringEventConsumer attach(
+ ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ CfPostProcessingDesugaringEventConsumer eventConsumer) {
+ if (artProfileCollectionAdditions.isNop()) {
+ return eventConsumer;
+ }
+ return new ArtProfileRewritingCfPostProcessingDesugaringEventConsumer(
+ artProfileCollectionAdditions.asConcrete(), eventConsumer);
+ }
+
+ @Override
+ public void acceptAPIConversionCallback(ProgramMethod method) {
+ parent.acceptAPIConversionCallback(method);
+ }
+
+ @Override
+ public void acceptCollectionConversion(ProgramMethod arrayConversion) {
+ parent.acceptCollectionConversion(arrayConversion);
+ }
+
+ @Override
+ public void acceptCovariantRetargetMethod(ProgramMethod method) {
+ parent.acceptCovariantRetargetMethod(method);
+ }
+
+ @Override
+ public void acceptDesugaredLibraryRetargeterDispatchClasspathClass(DexClasspathClass clazz) {
+ parent.acceptDesugaredLibraryRetargeterDispatchClasspathClass(clazz);
+ }
+
+ @Override
+ public void acceptDesugaredLibraryRetargeterForwardingMethod(ProgramMethod method) {
+ parent.acceptDesugaredLibraryRetargeterForwardingMethod(method);
+ }
+
+ @Override
+ public void acceptEmulatedInterfaceMarkerInterface(
+ DexProgramClass clazz, DexClasspathClass newInterface) {
+ parent.acceptEmulatedInterfaceMarkerInterface(clazz, newInterface);
+ }
+
+ @Override
+ public void acceptEnumConversionClasspathClass(DexClasspathClass clazz) {
+ parent.acceptEnumConversionClasspathClass(clazz);
+ }
+
+ @Override
+ public void acceptGenericApiConversionStub(DexClasspathClass dexClasspathClass) {
+ parent.acceptGenericApiConversionStub(dexClasspathClass);
+ }
+
+ @Override
+ public void acceptInterfaceInjection(DexProgramClass clazz, DexClass newInterface) {
+ parent.acceptInterfaceInjection(clazz, newInterface);
+ }
+
+ @Override
+ public void acceptInterfaceMethodDesugaringForwardingMethod(
+ ProgramMethod method, DexClassAndMethod baseMethod) {
+ additionsCollection.addRulesIfContextIsInProfile(baseMethod, method);
+ parent.acceptInterfaceMethodDesugaringForwardingMethod(method, baseMethod);
+ }
+
+ @Override
+ public void acceptThrowingMethod(ProgramMethod method, DexType errorType) {
+ parent.acceptThrowingMethod(method, errorType);
+ }
+
+ @Override
+ public void acceptWrapperClasspathClass(DexClasspathClass clazz) {
+ parent.acceptWrapperClasspathClass(clazz);
+ }
+
+ @Override
+ public void finalizeDesugaring() throws ExecutionException {
+ parent.finalizeDesugaring();
+ }
+
+ @Override
+ public void warnMissingInterface(
+ DexProgramClass context, DexType missing, InterfaceDesugaringSyntheticHelper helper) {
+ parent.warnMissingInterface(context, missing, helper);
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ConcreteArtProfileCollectionAdditions.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ConcreteArtProfileCollectionAdditions.java
index b66c5f1..1d0c199 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ConcreteArtProfileCollectionAdditions.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ConcreteArtProfileCollectionAdditions.java
@@ -5,8 +5,8 @@
package com.android.tools.r8.profile.art.rewriting;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.ProgramDefinition;
-import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.profile.art.ArtProfile;
import com.android.tools.r8.profile.art.ArtProfileCollection;
import com.android.tools.r8.profile.art.NonEmptyArtProfileCollection;
@@ -25,14 +25,14 @@
assert !additionsCollection.isEmpty();
}
- void addRulesIfContextIsInProfile(ProgramMethod context, ProgramDefinition... definitions) {
+ void addRulesIfContextIsInProfile(DexClassAndMethod context, ProgramDefinition... definitions) {
for (ArtProfileAdditions artProfileAdditions : additionsCollection) {
artProfileAdditions.addRulesIfContextIsInProfile(context, definitions);
}
}
// Specialization of the above method to avoid redundant varargs array creation.
- void addRulesIfContextIsInProfile(ProgramMethod context, ProgramDefinition definition) {
+ void addRulesIfContextIsInProfile(DexClassAndMethod context, ProgramDefinition definition) {
for (ArtProfileAdditions artProfileAdditions : additionsCollection) {
artProfileAdditions.addRulesIfContextIsInProfile(context, definition);
}
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index ca0f9b5..06db3b7 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -113,7 +113,6 @@
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringCollection;
import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer;
-import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer.R8PostProcessingDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.LambdaClass;
import com.android.tools.r8.ir.desugar.LambdaDescriptor;
import com.android.tools.r8.ir.desugar.ProgramAdditions;
@@ -4562,9 +4561,10 @@
assert workList.isEmpty();
- R8PostProcessingDesugaringEventConsumer eventConsumer =
+ CfPostProcessingDesugaringEventConsumer eventConsumer =
CfPostProcessingDesugaringEventConsumer.createForR8(
syntheticAdditions,
+ artProfileCollectionAdditions,
desugaring,
(context, missing) ->
missingClassesBuilder.addNewMissingClassWithDesugarDiagnostic(
diff --git a/src/test/java/com/android/tools/r8/profile/art/completeness/DefaultInterfaceMethodProfileRewritingTest.java b/src/test/java/com/android/tools/r8/profile/art/completeness/DefaultInterfaceMethodProfileRewritingTest.java
index 4e59b75..211d4bb 100644
--- a/src/test/java/com/android/tools/r8/profile/art/completeness/DefaultInterfaceMethodProfileRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/profile/art/completeness/DefaultInterfaceMethodProfileRewritingTest.java
@@ -73,6 +73,9 @@
ClassSubject aClassSubject = inspector.clazz(A.class);
assertThat(aClassSubject, isPresent());
+ ClassSubject bClassSubject = inspector.clazz(B.class);
+ assertThat(bClassSubject, isPresent());
+
ClassSubject companionClassSubject =
inspector.clazz(SyntheticItemsTestUtils.syntheticCompanionClass(I.class));
assertThat(companionClassSubject, isPresent());
@@ -80,15 +83,24 @@
MethodSubject interfaceMethodSubject = iClassSubject.uniqueMethodWithOriginalName("m");
assertThat(interfaceMethodSubject, isPresent());
- MethodSubject implementationMethodSubject =
+ MethodSubject aForwardingMethodSubject =
aClassSubject.method(interfaceMethodSubject.getFinalReference());
- assertThat(implementationMethodSubject, isPresent());
+ assertThat(aForwardingMethodSubject, isPresent());
+
+ MethodSubject bForwardingMethodSubject =
+ bClassSubject.method(interfaceMethodSubject.getFinalReference());
+ assertThat(bForwardingMethodSubject, isPresent());
MethodSubject movedMethodSubject = companionClassSubject.uniqueMethod();
assertThat(movedMethodSubject, isPresent());
- // TODO(b/265729283): Should also include the two methods from desugaring.
- profileInspector.assertContainsMethodRule(interfaceMethodSubject);
+ profileInspector
+ .assertContainsClassRule(companionClassSubject)
+ .assertContainsMethodRules(
+ interfaceMethodSubject,
+ aForwardingMethodSubject,
+ bForwardingMethodSubject,
+ movedMethodSubject);
}
profileInspector.assertContainsNoOtherRules();