Complete rewriting of art profiles
Bug: b/265729283
Change-Id: Ie604a5f7673ab8d8f2f966ccbf06a8490f2fe0ce
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index e9b73d4..55438d2 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -436,7 +436,7 @@
return finalDexApp.build();
}
- static class ConvertedCfFiles implements DexIndexedConsumer, ProgramResourceProvider {
+ public static class ConvertedCfFiles implements DexIndexedConsumer, ProgramResourceProvider {
private final List<ProgramResource> resources = new ArrayList<>();
diff --git a/src/main/java/com/android/tools/r8/GenerateMainDexList.java b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
index 7d1c9bd..3c17174 100644
--- a/src/main/java/com/android/tools/r8/GenerateMainDexList.java
+++ b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
@@ -15,6 +15,7 @@
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.SubtypingInfo;
+import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
import com.android.tools.r8.shaking.Enqueuer;
import com.android.tools.r8.shaking.EnqueuerFactory;
import com.android.tools.r8.shaking.MainDexInfo;
@@ -65,8 +66,12 @@
SubtypingInfo subtypingInfo = SubtypingInfo.create(appView);
+ ArtProfileCollectionAdditions artProfileCollectionAdditions =
+ ArtProfileCollectionAdditions.nop();
MainDexRootSet mainDexRootSet =
- MainDexRootSet.builder(appView, subtypingInfo, options.mainDexKeepRules).build(executor);
+ MainDexRootSet.builder(
+ appView, artProfileCollectionAdditions, subtypingInfo, options.mainDexKeepRules)
+ .build(executor);
appView.setMainDexRootSet(mainDexRootSet);
GraphConsumer graphConsumer = options.mainDexKeptGraphConsumer;
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index c227e1c..fc7bb85 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -73,6 +73,7 @@
import com.android.tools.r8.optimize.proto.ProtoNormalizer;
import com.android.tools.r8.origin.CommandLineOrigin;
import com.android.tools.r8.profile.art.ArtProfileCompletenessChecker;
+import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
import com.android.tools.r8.repackaging.Repackaging;
import com.android.tools.r8.repackaging.RepackagingLens;
import com.android.tools.r8.shaking.AbstractMethodRemover;
@@ -330,11 +331,14 @@
options.itemFactory, options.getMinApiLevel()));
}
}
+ ArtProfileCollectionAdditions artProfileCollectionAdditions =
+ ArtProfileCollectionAdditions.create(appView);
AssumeInfoCollection.Builder assumeInfoCollectionBuilder = AssumeInfoCollection.builder();
SubtypingInfo subtypingInfo = SubtypingInfo.create(appView);
appView.setRootSet(
RootSet.builder(
appView,
+ artProfileCollectionAdditions,
subtypingInfo,
Iterables.concat(
options.getProguardConfiguration().getRules(), synthesizedProguardRules))
@@ -348,7 +352,11 @@
assert appView.graphLens().isIdentityLens();
// Find classes which may have code executed before secondary dex files installation.
MainDexRootSet mainDexRootSet =
- MainDexRootSet.builder(appView, subtypingInfo, options.mainDexKeepRules)
+ MainDexRootSet.builder(
+ appView,
+ artProfileCollectionAdditions,
+ subtypingInfo,
+ options.mainDexKeepRules)
.build(executorService);
appView.setMainDexRootSet(mainDexRootSet);
appView.appInfo().unsetObsolete();
@@ -363,6 +371,7 @@
annotationRemoverBuilder,
executorService,
appView,
+ artProfileCollectionAdditions,
subtypingInfo,
classMergingEnqueuerExtensionBuilder);
timing.end();
@@ -958,12 +967,14 @@
AnnotationRemover.Builder annotationRemoverBuilder,
ExecutorService executorService,
AppView<AppInfoWithClassHierarchy> appView,
+ ArtProfileCollectionAdditions artProfileCollectionAdditions,
SubtypingInfo subtypingInfo,
RuntimeTypeCheckInfo.Builder classMergingEnqueuerExtensionBuilder)
throws ExecutionException {
timing.begin("Set up enqueuer");
Enqueuer enqueuer =
- EnqueuerFactory.createForInitialTreeShaking(appView, executorService, subtypingInfo);
+ EnqueuerFactory.createForInitialTreeShaking(
+ appView, artProfileCollectionAdditions, executorService, subtypingInfo);
enqueuer.setAnnotationRemoverBuilder(annotationRemoverBuilder);
if (appView.options().enableInitializedClassesInInstanceMethodsAnalysis) {
enqueuer.registerAnalysis(new InitializedClassesInInstanceMethodsAnalysis(appView));
@@ -983,6 +994,7 @@
timing.begin("Trace application");
EnqueuerResult enqueuerResult =
enqueuer.traceApplication(appView.rootSet(), executorService, timing);
+ assert artProfileCollectionAdditions.verifyIsCommitted();
timing.end();
timing.begin("Finalize enqueuer result");
AppView<AppInfoWithLiveness> appViewWithLiveness =
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
index 4300df0..99cb304 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.ByteBufferProvider;
import com.android.tools.r8.ByteDataView;
+import com.android.tools.r8.D8.ConvertedCfFiles;
import com.android.tools.r8.DataDirectoryResource;
import com.android.tools.r8.DataEntryResource;
import com.android.tools.r8.DataResourceConsumer;
@@ -432,7 +433,9 @@
// Fail if there are pending errors, e.g., the program consumers may have reported errors.
options.reporter.failIfPendingErrors();
// Supply info to all additional resource consumers.
- supplyAdditionalConsumers(appView);
+ if (!(programConsumer instanceof ConvertedCfFiles)) {
+ supplyAdditionalConsumers(appView);
+ }
} finally {
timing.end();
}
diff --git a/src/main/java/com/android/tools/r8/graph/AppView.java b/src/main/java/com/android/tools/r8/graph/AppView.java
index fb288a7..9560129 100644
--- a/src/main/java/com/android/tools/r8/graph/AppView.java
+++ b/src/main/java/com/android/tools/r8/graph/AppView.java
@@ -916,6 +916,15 @@
appView
.withLiveness()
.setAppInfo(appView.appInfoWithLiveness().rewrittenWithLens(application, lens));
+ } else {
+ assert appView.hasClassHierarchy();
+ AppView<AppInfoWithClassHierarchy> appViewWithClassHierarchy =
+ appView.withClassHierarchy();
+ AppInfoWithClassHierarchy appInfo = appViewWithClassHierarchy.appInfo();
+ MainDexInfo rewrittenMainDexInfo =
+ appInfo.getMainDexInfo().rewrittenWithLens(appView.getSyntheticItems(), lens);
+ appViewWithClassHierarchy.setAppInfo(
+ appInfo.rebuildWithMainDexInfo(rewrittenMainDexInfo));
}
appView.setAppServices(appView.appServices().rewrittenWithLens(lens));
appView.setArtProfileCollection(
diff --git a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
index 22d3978..01fa0e0 100644
--- a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
@@ -265,6 +265,10 @@
forEachStaticField(field -> consumer.accept(new ProgramField(this, field)));
}
+ public void forEachProgramStaticMethod(Consumer<? super ProgramMethod> consumer) {
+ forEachProgramDirectMethodMatching(DexEncodedMethod::isStatic, consumer);
+ }
+
public void forEachProgramMember(Consumer<? super ProgramMember<?, ?>> consumer) {
forEachProgramField(consumer);
forEachProgramMethod(consumer);
@@ -310,7 +314,7 @@
}
public void forEachProgramDirectMethodMatching(
- Predicate<DexEncodedMethod> predicate, Consumer<ProgramMethod> consumer) {
+ Predicate<DexEncodedMethod> predicate, Consumer<? super ProgramMethod> consumer) {
methodCollection.forEachDirectMethodMatching(
predicate, method -> consumer.accept(new ProgramMethod(this, method)));
}
diff --git a/src/main/java/com/android/tools/r8/graph/MethodResolutionResult.java b/src/main/java/com/android/tools/r8/graph/MethodResolutionResult.java
index 8c949fe..ef0d7ff 100644
--- a/src/main/java/com/android/tools/r8/graph/MethodResolutionResult.java
+++ b/src/main/java/com/android/tools/r8/graph/MethodResolutionResult.java
@@ -1213,6 +1213,10 @@
super(typesCausingError);
}
+ public static NoSuchMethodResult getEmptyNoSuchMethodResult() {
+ return INSTANCE;
+ }
+
@Override
public boolean isNoSuchMethodErrorResult(DexClass context, AppInfoWithClassHierarchy appInfo) {
return true;
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
index b84809e..b8782e2 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
@@ -154,7 +154,12 @@
appView.setHorizontallyMergedClasses(mergedClasses, mode);
HorizontalClassMergerGraphLens horizontalClassMergerGraphLens =
- createLens(mergedClasses, lensBuilder, mode, syntheticArgumentClass);
+ createLens(
+ mergedClasses,
+ lensBuilder,
+ mode,
+ artProfileCollectionAdditions,
+ syntheticArgumentClass);
artProfileCollectionAdditions =
artProfileCollectionAdditions.rewriteMethodReferences(
horizontalClassMergerGraphLens::getNextMethodToInvoke);
@@ -185,7 +190,7 @@
.appInfo()
.getMainDexInfo()
.rewrittenWithLens(syntheticItems, horizontalClassMergerGraphLens)));
- appView.setGraphLens(horizontalClassMergerGraphLens);
+ appView.rewriteWithD8Lens(horizontalClassMergerGraphLens);
}
codeProvider.setGraphLens(horizontalClassMergerGraphLens);
@@ -391,8 +396,15 @@
HorizontallyMergedClasses mergedClasses,
HorizontalClassMergerGraphLens.Builder lensBuilder,
Mode mode,
+ ArtProfileCollectionAdditions artProfileCollectionAdditions,
SyntheticArgumentClass syntheticArgumentClass) {
- return new TreeFixer(appView, mergedClasses, lensBuilder, mode, syntheticArgumentClass)
+ return new TreeFixer(
+ appView,
+ mergedClasses,
+ lensBuilder,
+ mode,
+ artProfileCollectionAdditions,
+ syntheticArgumentClass)
.fixupTypeReferences();
}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMergerGraphLens.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMergerGraphLens.java
index 51b4939..53f08a6 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMergerGraphLens.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMergerGraphLens.java
@@ -99,7 +99,7 @@
private final MutableBidirectionalManyToOneRepresentativeMap<DexField, DexField>
newFieldSignatures = BidirectionalManyToOneRepresentativeHashMap.newIdentityHashMap();
- private final MutableBidirectionalManyToOneMap<DexMethod, DexMethod> methodMap =
+ final MutableBidirectionalManyToOneMap<DexMethod, DexMethod> methodMap =
BidirectionalManyToOneHashMap.newIdentityHashMap();
private final MutableBidirectionalManyToOneRepresentativeMap<DexMethod, DexMethod>
newMethodSignatures = BidirectionalManyToOneRepresentativeHashMap.newIdentityHashMap();
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/TreeFixer.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/TreeFixer.java
index 31753bf..a4b8ae0 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/TreeFixer.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/TreeFixer.java
@@ -21,8 +21,10 @@
import com.android.tools.r8.graph.TreeFixerBase;
import com.android.tools.r8.horizontalclassmerging.HorizontalClassMerger.Mode;
import com.android.tools.r8.ir.conversion.ExtraUnusedNullParameter;
+import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
import com.android.tools.r8.shaking.AnnotationFixer;
import com.android.tools.r8.utils.ArrayUtils;
+import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.OptionalBool;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
@@ -47,6 +49,7 @@
private final Mode mode;
private final HorizontalClassMergerGraphLens.Builder lensBuilder;
private final DexItemFactory dexItemFactory;
+ private final ArtProfileCollectionAdditions artProfileCollectionAdditions;
private final SyntheticArgumentClass syntheticArgumentClass;
private final Map<DexProgramClass, DexType> originalSuperTypes = new IdentityHashMap<>();
@@ -58,12 +61,14 @@
HorizontallyMergedClasses mergedClasses,
HorizontalClassMergerGraphLens.Builder lensBuilder,
Mode mode,
+ ArtProfileCollectionAdditions artProfileCollectionAdditions,
SyntheticArgumentClass syntheticArgumentClass) {
super(appView);
this.appView = appView;
this.mergedClasses = mergedClasses;
this.mode = mode;
this.lensBuilder = lensBuilder;
+ this.artProfileCollectionAdditions = artProfileCollectionAdditions;
this.syntheticArgumentClass = syntheticArgumentClass;
this.dexItemFactory = appView.dexItemFactory();
}
@@ -289,15 +294,36 @@
if (method.isInstanceInitializer()) {
// If the method is an instance initializer, then add extra nulls.
+ Box<Set<DexType>> usedSyntheticArgumentClasses = new Box<>();
newMethodReference =
dexItemFactory.createInstanceInitializerWithFreshProto(
newMethodReference,
syntheticArgumentClass.getArgumentClasses(),
- tryMethod -> !newMethods.contains(tryMethod.getSignature()));
+ tryMethod -> !newMethods.contains(tryMethod.getSignature()),
+ usedSyntheticArgumentClasses::set);
lensBuilder.addExtraParameters(
originalMethodReference,
ExtraUnusedNullParameter.computeExtraUnusedNullParameters(
originalMethodReference, newMethodReference));
+
+ // Amend the art profile collection.
+ if (usedSyntheticArgumentClasses.isSet()) {
+ Set<DexMethod> previousMethodReferences =
+ lensBuilder.methodMap.getKeys(originalMethodReference);
+ if (previousMethodReferences.isEmpty()) {
+ artProfileCollectionAdditions.applyIfContextIsInProfile(
+ originalMethodReference,
+ additionsBuilder ->
+ usedSyntheticArgumentClasses.get().forEach(additionsBuilder::addRule));
+ } else {
+ for (DexMethod previousMethodReference : previousMethodReferences) {
+ artProfileCollectionAdditions.applyIfContextIsInProfile(
+ previousMethodReference,
+ additionsBuilder ->
+ usedSyntheticArgumentClasses.get().forEach(additionsBuilder::addRule));
+ }
+ }
+ }
} else {
newMethodReference =
dexItemFactory.createFreshMethodNameWithoutHolder(
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/PrimaryD8L8IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/PrimaryD8L8IRConverter.java
index 0092f10..9d03bb5 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/PrimaryD8L8IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/PrimaryD8L8IRConverter.java
@@ -309,6 +309,7 @@
throws ExecutionException {
CfPostProcessingDesugaringEventConsumer eventConsumer =
CfPostProcessingDesugaringEventConsumer.createForD8(
+ appView,
methodProcessor.getArtProfileCollectionAdditions(),
methodProcessor,
instructionDesugaring);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfClassSynthesizerDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/CfClassSynthesizerDesugaringEventConsumer.java
index 4e7a473..49a7dd8 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfClassSynthesizerDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfClassSynthesizerDesugaringEventConsumer.java
@@ -101,7 +101,7 @@
}
@Override
- public void acceptCollectionConversion(ProgramMethod arrayConversion) {
+ public void acceptCollectionConversion(ProgramMethod arrayConversion, ProgramMethod context) {
synthesizedClasses.add(arrayConversion.getHolder());
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
index 09cc827..7290623 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
@@ -163,12 +163,12 @@
}
@Override
- public void acceptCollectionConversion(ProgramMethod arrayConversion) {
+ public void acceptCollectionConversion(ProgramMethod arrayConversion, ProgramMethod context) {
methodProcessor.scheduleMethodForProcessing(arrayConversion, outermostEventConsumer);
}
@Override
- public void acceptCovariantRetargetMethod(ProgramMethod method) {
+ public void acceptCovariantRetargetMethod(ProgramMethod method, ProgramMethod context) {
methodProcessor.scheduleMethodForProcessing(method, outermostEventConsumer);
}
@@ -354,7 +354,7 @@
}
@Override
- public void acceptAPIConversion(ProgramMethod method) {
+ public void acceptAPIConversionOutline(ProgramMethod method, ProgramMethod context) {
methodProcessor.scheduleDesugaredMethodForProcessing(method);
}
@@ -522,7 +522,7 @@
}
@Override
- public void acceptCollectionConversion(ProgramMethod arrayConversion) {
+ public void acceptCollectionConversion(ProgramMethod arrayConversion, ProgramMethod context) {
// Intentionally empty. The method will be hit by tracing if required.
}
@@ -548,7 +548,7 @@
}
@Override
- public void acceptCovariantRetargetMethod(ProgramMethod method) {
+ public void acceptCovariantRetargetMethod(ProgramMethod method, ProgramMethod context) {
// Intentionally empty. The method will be hit by tracing if required.
}
@@ -614,7 +614,7 @@
}
@Override
- public void acceptAPIConversion(ProgramMethod method) {
+ public void acceptAPIConversionOutline(ProgramMethod method, ProgramMethod context) {
// Intentionally empty. The method will be hit by tracing if required.
}
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 33ff0b4..7a38cf1 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
@@ -3,15 +3,18 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.desugar;
+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.DexClasspathClass;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.MethodResolutionResult.FailedResolutionResult;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.conversion.D8MethodProcessor;
import com.android.tools.r8.ir.desugar.desugaredlibrary.apiconversion.DesugaredLibraryWrapperSynthesizerEventConsumer.DesugaredLibraryAPICallbackSynthesizorEventConsumer;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.EmulatedDispatchMethodDescriptor;
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;
@@ -35,16 +38,18 @@
DesugaredLibraryAPICallbackSynthesizorEventConsumer {
public static CfPostProcessingDesugaringEventConsumer createForD8(
+ AppView<?> appView,
ArtProfileCollectionAdditions artProfileCollectionAdditions,
D8MethodProcessor methodProcessor,
CfInstructionDesugaringCollection instructionDesugaring) {
CfPostProcessingDesugaringEventConsumer eventConsumer =
new D8CfPostProcessingDesugaringEventConsumer(methodProcessor, instructionDesugaring);
return ArtProfileRewritingCfPostProcessingDesugaringEventConsumer.attach(
- artProfileCollectionAdditions, eventConsumer);
+ appView, artProfileCollectionAdditions, eventConsumer);
}
public static CfPostProcessingDesugaringEventConsumer createForR8(
+ AppView<?> appView,
SyntheticAdditions additions,
ArtProfileCollectionAdditions artProfileCollectionAdditions,
CfInstructionDesugaringCollection desugaring,
@@ -52,7 +57,7 @@
CfPostProcessingDesugaringEventConsumer eventConsumer =
new R8PostProcessingDesugaringEventConsumer(additions, desugaring, missingClassConsumer);
return ArtProfileRewritingCfPostProcessingDesugaringEventConsumer.attach(
- artProfileCollectionAdditions, eventConsumer);
+ appView, artProfileCollectionAdditions, eventConsumer);
}
public abstract Set<DexMethod> getNewlyLiveMethods();
@@ -93,7 +98,7 @@
}
@Override
- public void acceptCovariantRetargetMethod(ProgramMethod method) {
+ public void acceptCovariantRetargetMethod(ProgramMethod method, ProgramMethod context) {
addMethodToReprocess(method);
}
@@ -109,7 +114,8 @@
}
@Override
- public void acceptDesugaredLibraryRetargeterForwardingMethod(ProgramMethod method) {
+ public void acceptDesugaredLibraryRetargeterForwardingMethod(
+ ProgramMethod method, EmulatedDispatchMethodDescriptor descriptor) {
addMethodToReprocess(method);
}
@@ -120,12 +126,13 @@
}
@Override
- public void acceptThrowingMethod(ProgramMethod method, DexType errorType) {
+ public void acceptThrowingMethod(
+ ProgramMethod method, DexType errorType, FailedResolutionResult resolutionResult) {
addMethodToReprocess(method);
}
@Override
- public void acceptCollectionConversion(ProgramMethod method) {
+ public void acceptCollectionConversion(ProgramMethod method, ProgramMethod context) {
addMethodToReprocess(method);
}
@@ -216,12 +223,13 @@
}
@Override
- public void acceptCovariantRetargetMethod(ProgramMethod method) {
+ public void acceptCovariantRetargetMethod(ProgramMethod method, ProgramMethod context) {
additions.addLiveMethod(method);
}
@Override
- public void acceptDesugaredLibraryRetargeterForwardingMethod(ProgramMethod method) {
+ public void acceptDesugaredLibraryRetargeterForwardingMethod(
+ ProgramMethod method, EmulatedDispatchMethodDescriptor descriptor) {
additions.addLiveMethod(method);
}
@@ -232,12 +240,13 @@
}
@Override
- public void acceptThrowingMethod(ProgramMethod method, DexType errorType) {
+ public void acceptThrowingMethod(
+ ProgramMethod method, DexType errorType, FailedResolutionResult resolutionResult) {
additions.addLiveMethod(method);
}
@Override
- public void acceptCollectionConversion(ProgramMethod method) {
+ public void acceptCollectionConversion(ProgramMethod method, ProgramMethod context) {
additions.addLiveMethod(method);
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryConversionCfProvider.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryConversionCfProvider.java
index c4ce708..9a75734 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryConversionCfProvider.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryConversionCfProvider.java
@@ -260,7 +260,7 @@
parameterConversions,
invoke.getOpcode())
.generateCfCode()));
- eventConsumer.acceptAPIConversion(outline);
+ eventConsumer.acceptAPIConversionOutline(outline, context);
return outline;
}
@@ -362,7 +362,8 @@
methodSignature ->
computeParameterConversionCfCode(
methodSignature.holder, invokedMethod, parameterConversions)));
- eventConsumer.acceptAPIConversion(parameterConversion);
+ eventConsumer.acceptAPIConversionOutline(
+ parameterConversion, methodProcessingContext.getMethodContext());
cfInstructions.add(
new CfInvoke(Opcodes.INVOKESTATIC, parameterConversion.getReference(), false));
int arrayLocal = freshLocalProvider.getFreshLocal(ValueType.OBJECT.requiredRegisters());
@@ -461,6 +462,7 @@
destIsVivified,
apiConversionCollection,
eventConsumer,
+ context,
contextSupplier),
context);
}
@@ -479,6 +481,7 @@
destIsVivified,
apiConversionCollection,
eventConsumer,
+ context,
contextSupplier),
context);
}
@@ -507,7 +510,12 @@
wrapperSynthesizer,
(argType, apiGenericTypesConversion) ->
wrapperSynthesizer.ensureConversionMethod(
- argType, destIsVivified, apiGenericTypesConversion, eventConsumer, contextSupplier),
+ argType,
+ destIsVivified,
+ apiGenericTypesConversion,
+ eventConsumer,
+ context,
+ contextSupplier),
context);
}
@@ -522,7 +530,12 @@
wrapperSynthesizer,
(argType, apiGenericTypesConversion) ->
wrapperSynthesizer.getExistingProgramConversionMethod(
- argType, destIsVivified, apiGenericTypesConversion, eventConsumer, contextSupplier),
+ argType,
+ destIsVivified,
+ apiGenericTypesConversion,
+ eventConsumer,
+ context,
+ contextSupplier),
context);
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryWrapperSynthesizer.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryWrapperSynthesizer.java
index 40f9d67..cc5d7d6 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryWrapperSynthesizer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryWrapperSynthesizer.java
@@ -197,6 +197,7 @@
boolean destIsVivified,
DexMethod apiGenericTypesConversion,
DesugaredLibraryClasspathWrapperSynthesizeEventConsumer eventConsumer,
+ ProgramMethod context,
Supplier<UniqueContext> contextSupplier) {
if (apiGenericTypesConversion != null) {
assert !type.isArrayType();
@@ -205,7 +206,8 @@
DexType srcType = destIsVivified ? type : vivifiedTypeFor(type);
DexType destType = destIsVivified ? vivifiedTypeFor(type) : type;
if (type.isArrayType()) {
- return ensureArrayConversionMethod(type, srcType, destType, eventConsumer, contextSupplier);
+ return ensureArrayConversionMethod(
+ type, srcType, destType, eventConsumer, context, contextSupplier);
}
DexMethod customConversion = getCustomConversion(type, srcType, destType);
if (customConversion != null) {
@@ -231,6 +233,7 @@
DexType srcType,
DexType destType,
DesugaredLibraryClasspathWrapperSynthesizeEventConsumer eventConsumer,
+ ProgramMethod context,
Supplier<UniqueContext> contextSupplier) {
DexMethod conversion =
ensureConversionMethod(
@@ -238,9 +241,10 @@
srcType == type,
null,
eventConsumer,
+ context,
contextSupplier);
return ensureArrayConversionMethod(
- srcType, destType, eventConsumer, contextSupplier, conversion);
+ srcType, destType, eventConsumer, context, contextSupplier, conversion);
}
private DexMethod ensureArrayConversionMethodFromExistingBaseConversion(
@@ -248,6 +252,7 @@
DexType srcType,
DexType destType,
DesugaredLibraryL8ProgramWrapperSynthesizerEventConsumer eventConsumer,
+ ProgramMethod context,
Supplier<UniqueContext> contextSupplier) {
DexMethod conversion =
getExistingProgramConversionMethod(
@@ -255,15 +260,17 @@
srcType == type,
null,
eventConsumer,
+ context,
contextSupplier);
return ensureArrayConversionMethod(
- srcType, destType, eventConsumer, contextSupplier, conversion);
+ srcType, destType, eventConsumer, context, contextSupplier, conversion);
}
private DexMethod ensureArrayConversionMethod(
DexType srcType,
DexType destType,
DesugaredLibraryWrapperSynthesizerEventConsumer eventConsumer,
+ ProgramMethod context,
Supplier<UniqueContext> contextSupplier,
DexMethod conversion) {
ProgramMethod arrayConversion =
@@ -286,7 +293,7 @@
destType,
conversion)
.generateCfCode()));
- eventConsumer.acceptCollectionConversion(arrayConversion);
+ eventConsumer.acceptCollectionConversion(arrayConversion, context);
return arrayConversion.getReference();
}
@@ -295,6 +302,7 @@
boolean destIsVivified,
DexMethod apiGenericTypesConversion,
DesugaredLibraryL8ProgramWrapperSynthesizerEventConsumer eventConsumer,
+ ProgramMethod context,
Supplier<UniqueContext> contextSupplier) {
if (apiGenericTypesConversion != null) {
assert !type.isArrayType();
@@ -304,7 +312,7 @@
DexType destType = destIsVivified ? vivifiedTypeFor(type) : type;
if (type.isArrayType()) {
return ensureArrayConversionMethodFromExistingBaseConversion(
- type, srcType, destType, eventConsumer, contextSupplier);
+ type, srcType, destType, eventConsumer, context, contextSupplier);
}
DexMethod customConversion = getCustomConversion(type, srcType, destType);
if (customConversion != null) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryWrapperSynthesizerEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryWrapperSynthesizerEventConsumer.java
index 161247c..9a57f6b 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryWrapperSynthesizerEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryWrapperSynthesizerEventConsumer.java
@@ -10,7 +10,7 @@
public interface DesugaredLibraryWrapperSynthesizerEventConsumer {
- void acceptCollectionConversion(ProgramMethod arrayConversion);
+ void acceptCollectionConversion(ProgramMethod arrayConversion, ProgramMethod context);
interface DesugaredLibraryL8ProgramWrapperSynthesizerEventConsumer
extends DesugaredLibraryWrapperSynthesizerEventConsumer {
@@ -33,7 +33,7 @@
interface DesugaredLibraryAPIConverterEventConsumer
extends DesugaredLibraryClasspathWrapperSynthesizeEventConsumer {
- void acceptAPIConversion(ProgramMethod method);
+ void acceptAPIConversionOutline(ProgramMethod method, ProgramMethod context);
}
interface DesugaredLibraryAPICallbackSynthesizorEventConsumer
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/SupportedClasses.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/SupportedClasses.java
index 3c1cfd6..32f1bf9 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/SupportedClasses.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/SupportedClasses.java
@@ -11,6 +11,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSortedMap;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.IdentityHashMap;
@@ -83,26 +84,26 @@
private final DexClass clazz;
private ClassAnnotation classAnnotation;
- private final List<DexEncodedMethod> supportedMethods = new ArrayList<>();
+ private final Map<DexMethod, DexEncodedMethod> supportedMethods = new IdentityHashMap<>();
private final Map<DexMethod, MethodAnnotation> methodAnnotations = new HashMap<>();
private Builder(DexClass clazz) {
this.clazz = clazz;
}
- void forEachMethods(BiConsumer<DexClass, List<DexEncodedMethod>> biConsumer) {
- biConsumer.accept(clazz, supportedMethods);
+ void forEachMethods(BiConsumer<DexClass, Collection<DexEncodedMethod>> biConsumer) {
+ biConsumer.accept(clazz, supportedMethods.values());
}
void forEachMethod(BiConsumer<DexClass, DexEncodedMethod> biConsumer) {
- for (DexEncodedMethod dexEncodedMethod : supportedMethods) {
+ for (DexEncodedMethod dexEncodedMethod : supportedMethods.values()) {
biConsumer.accept(clazz, dexEncodedMethod);
}
}
void addSupportedMethod(DexEncodedMethod method) {
assert method.getHolderType() == clazz.type;
- supportedMethods.add(method);
+ supportedMethods.put(method.getReference(), method);
}
void annotateClass(ClassAnnotation annotation) {
@@ -123,9 +124,13 @@
}
SupportedClass build() {
- supportedMethods.sort(Comparator.comparing(DexEncodedMethod::getReference));
+ List<DexEncodedMethod> supportedMethodsSorted = new ArrayList<>(supportedMethods.values());
+ supportedMethodsSorted.sort(Comparator.comparing(DexEncodedMethod::getReference));
return new SupportedClass(
- clazz, classAnnotation, ImmutableList.copyOf(supportedMethods), methodAnnotations);
+ clazz,
+ classAnnotation,
+ ImmutableList.copyOf(supportedMethodsSorted),
+ methodAnnotations);
}
}
}
@@ -138,7 +143,7 @@
Map<DexType, SupportedClass.Builder> supportedClassBuilders = new IdentityHashMap<>();
- void forEachClassAndMethods(BiConsumer<DexClass, List<DexEncodedMethod>> biConsumer) {
+ void forEachClassAndMethods(BiConsumer<DexClass, Collection<DexEncodedMethod>> biConsumer) {
supportedClassBuilders
.values()
.forEach(classBuilder -> classBuilder.forEachMethods(biConsumer));
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 cc5abfd..dcf5c0a 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
@@ -138,7 +138,7 @@
DexEncodedMethod newMethod = createForwardingMethod(itfMethod, descriptor, clazz);
clazz.addVirtualMethod(newMethod);
eventConsumer.acceptDesugaredLibraryRetargeterForwardingMethod(
- new ProgramMethod(clazz, newMethod));
+ new ProgramMethod(clazz, newMethod), descriptor);
}
}
}
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 63dcba2..6e491ff 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
@@ -8,6 +8,7 @@
import com.android.tools.r8.graph.DexClasspathClass;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.EmulatedDispatchMethodDescriptor;
public interface DesugaredLibraryRetargeterSynthesizerEventConsumer {
@@ -18,13 +19,14 @@
interface DesugaredLibraryRetargeterInstructionEventConsumer {
void acceptDesugaredLibraryRetargeterDispatchClasspathClass(DexClasspathClass clazz);
- void acceptCovariantRetargetMethod(ProgramMethod method);
+ void acceptCovariantRetargetMethod(ProgramMethod method, ProgramMethod context);
}
interface DesugaredLibraryRetargeterPostProcessingEventConsumer
extends DesugaredLibraryRetargeterInstructionEventConsumer {
void acceptInterfaceInjection(DexProgramClass clazz, DexClass newInterface);
- void acceptDesugaredLibraryRetargeterForwardingMethod(ProgramMethod method);
+ void acceptDesugaredLibraryRetargeterForwardingMethod(
+ ProgramMethod method, EmulatedDispatchMethodDescriptor descriptor);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterSyntheticHelper.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterSyntheticHelper.java
index ae5814a..52fa933 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterSyntheticHelper.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterSyntheticHelper.java
@@ -57,7 +57,7 @@
.setNonStaticSource(target)
.setCastResult()
.build()));
- eventConsumer.acceptCovariantRetargetMethod(method);
+ eventConsumer.acceptCovariantRetargetMethod(method, methodProcessingContext.getMethodContext());
return method.getReference();
}
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 32e2c37..6a74cf3 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
@@ -30,6 +30,8 @@
import com.android.tools.r8.graph.LookupMethodTarget;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.MethodResolutionResult;
+import com.android.tools.r8.graph.MethodResolutionResult.FailedResolutionResult;
+import com.android.tools.r8.graph.MethodResolutionResult.NoSuchMethodResult;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.DerivedMethod;
import com.android.tools.r8.ir.desugar.itf.InterfaceDesugaringSyntheticHelper.InterfaceMethodDesugaringMode;
@@ -126,16 +128,23 @@
private static class SyntheticThrowingMethodInfo extends SyntheticMethodInfo {
private final DexType errorType;
+ private final FailedResolutionResult resolutionResult;
- SyntheticThrowingMethodInfo(ProgramMethod method, DexType errorType) {
+ SyntheticThrowingMethodInfo(
+ ProgramMethod method, DexType errorType, FailedResolutionResult resolutionResult) {
super(method);
this.errorType = errorType;
+ this.resolutionResult = resolutionResult;
}
DexType getErrorType() {
return errorType;
}
+ FailedResolutionResult getResolutionResult() {
+ return resolutionResult;
+ }
+
@Override
SyntheticThrowingMethodInfo asThrowingMethodInfo() {
return this;
@@ -511,8 +520,11 @@
eventConsumer.acceptInterfaceMethodDesugaringForwardingMethod(
info.getMethod(), info.asForwardingMethodInfo().getBaseMethod());
} else {
+ SyntheticThrowingMethodInfo throwingMethodInfo = info.asThrowingMethodInfo();
eventConsumer.acceptThrowingMethod(
- info.getMethod(), info.asThrowingMethodInfo().getErrorType());
+ info.getMethod(),
+ throwingMethodInfo.getErrorType(),
+ throwingMethodInfo.getResolutionResult());
}
}
},
@@ -842,15 +854,15 @@
}
if (resolutionResult.isFailedResolution()) {
if (resolutionResult.isIncompatibleClassChangeErrorResult()) {
- addICCEThrowingMethod(method, clazz);
+ addICCEThrowingMethod(method, clazz, resolutionResult.asFailedResolution());
return;
}
if (resolutionResult.isNoSuchMethodErrorResult(clazz, appInfo)) {
- addNoSuchMethodErrorThrowingMethod(method, clazz);
+ addNoSuchMethodErrorThrowingMethod(method, clazz, resolutionResult.asFailedResolution());
return;
}
assert resolutionResult.isIllegalAccessErrorResult(clazz, appInfo);
- addIllegalAccessErrorThrowingMethod(method, clazz);
+ addIllegalAccessErrorThrowingMethod(method, clazz, resolutionResult.asFailedResolution());
return;
}
}
@@ -878,7 +890,8 @@
+ "). Please report this issue in the D8/R8 bug tracker at"
+ " https://issuetracker.google.com/issues/237507594.");
// To be able to resume compilation we add a NoSuchMethodErrorThrowingMethod.
- addNoSuchMethodErrorThrowingMethod(method, clazz);
+ addNoSuchMethodErrorThrowingMethod(
+ method, clazz, NoSuchMethodResult.getEmptyNoSuchMethodResult());
return;
}
DexClassAndMethod virtualDispatchTarget = lookupMethodTarget.getTarget();
@@ -919,27 +932,37 @@
assert existingMethodInfo == null;
}
- private void addSyntheticThrowingMethod(ProgramMethod method, DexType errorType) {
+ private void addSyntheticThrowingMethod(
+ ProgramMethod method, DexType errorType, FailedResolutionResult resolutionResult) {
SyntheticMethodInfo existingMethodInfo =
newSyntheticMethods
.computeIfAbsent(method.getHolder(), key -> new ConcurrentHashMap<>())
- .put(method.getReference(), new SyntheticThrowingMethodInfo(method, errorType));
+ .put(
+ method.getReference(),
+ new SyntheticThrowingMethodInfo(method, errorType, resolutionResult));
assert existingMethodInfo == null;
}
- private void addICCEThrowingMethod(DexMethod method, DexClass clazz) {
- addThrowingMethod(method, clazz, dexItemFactory.icceType);
+ private void addICCEThrowingMethod(
+ DexMethod method, DexClass clazz, FailedResolutionResult resolutionResult) {
+ addThrowingMethod(method, clazz, dexItemFactory.icceType, resolutionResult);
}
- private void addIllegalAccessErrorThrowingMethod(DexMethod method, DexClass clazz) {
- addThrowingMethod(method, clazz, dexItemFactory.illegalAccessErrorType);
+ private void addIllegalAccessErrorThrowingMethod(
+ DexMethod method, DexClass clazz, FailedResolutionResult resolutionResult) {
+ addThrowingMethod(method, clazz, dexItemFactory.illegalAccessErrorType, resolutionResult);
}
- private void addNoSuchMethodErrorThrowingMethod(DexMethod method, DexClass clazz) {
- addThrowingMethod(method, clazz, dexItemFactory.noSuchMethodErrorType);
+ private void addNoSuchMethodErrorThrowingMethod(
+ DexMethod method, DexClass clazz, FailedResolutionResult resolutionResult) {
+ addThrowingMethod(method, clazz, dexItemFactory.noSuchMethodErrorType, resolutionResult);
}
- private void addThrowingMethod(DexMethod method, DexClass clazz, DexType errorType) {
+ private void addThrowingMethod(
+ DexMethod method,
+ DexClass clazz,
+ DexType errorType,
+ FailedResolutionResult resolutionResult) {
if (!clazz.isProgramClass()) {
return;
}
@@ -953,7 +976,8 @@
createExceptionThrowingCfCode(newMethod, accessFlags, errorType, dexItemFactory))
.disableAndroidApiLevelCheck()
.build();
- addSyntheticThrowingMethod(newEncodedMethod.asProgramMethod(clazz.asProgramClass()), errorType);
+ addSyntheticThrowingMethod(
+ newEncodedMethod.asProgramMethod(clazz.asProgramClass()), errorType, resolutionResult);
}
private static CfCode createExceptionThrowingCfCode(
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 dde1382..a918d81 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
@@ -8,6 +8,7 @@
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.MethodResolutionResult.FailedResolutionResult;
import com.android.tools.r8.graph.ProgramMethod;
public interface InterfaceProcessingDesugaringEventConsumer {
@@ -18,7 +19,8 @@
void acceptEmulatedInterfaceMarkerInterface(
DexProgramClass clazz, DexClasspathClass newInterface);
- void acceptThrowingMethod(ProgramMethod method, DexType errorType);
+ void acceptThrowingMethod(
+ ProgramMethod method, DexType errorType, FailedResolutionResult resolutionResult);
void warnMissingInterface(
DexProgramClass context, DexType missing, InterfaceDesugaringSyntheticHelper helper);
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileOptions.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileOptions.java
index 534f5d9..0e2a3f4 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileOptions.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileOptions.java
@@ -28,7 +28,10 @@
}
public boolean isCompletenessCheckForTestingEnabled() {
- return enableCompletenessCheckForTesting && !options.isDesugaredLibraryCompilation();
+ return enableCompletenessCheckForTesting
+ && !options.isDesugaredLibraryCompilation()
+ && !options.getStartupOptions().isStartupCompletenessCheckForTestingEnabled()
+ && !options.getStartupInstrumentationOptions().isStartupInstrumentationEnabled();
}
public boolean isIncludingApiReferenceStubs() {
@@ -38,11 +41,29 @@
return enableCompletenessCheckForTesting;
}
+ public boolean isIncludingBackportedClasses() {
+ // Similar to isIncludingVarHandleClasses().
+ return enableCompletenessCheckForTesting;
+ }
+
public boolean isIncludingConstantDynamicClass() {
// Similar to isIncludingVarHandleClasses().
return enableCompletenessCheckForTesting;
}
+ public boolean isIncludingDesugaredLibraryRetargeterForwardingMethodsUnconditionally() {
+ // TODO(b/265729283): If we get as input the profile for the desugared library, maybe we can
+ // tell if the method targeted by the forwarding method is in the profile, e.g.:
+ // java.time.Instant java.util.DesugarDate.toInstant(java.util.Date).
+ return enableCompletenessCheckForTesting;
+ }
+
+ public boolean isIncludingThrowingMethods() {
+ // The throw methods we insert should generally be dead a runtime, so no need for them to be
+ // optimized.
+ return enableCompletenessCheckForTesting;
+ }
+
public boolean isIncludingVarHandleClasses() {
// We only include var handle classes in the residual ART profiles for completeness testing,
// since the classes synthesized by var handle desugaring are fairly large and may not be that
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 b1e72d9..f4400c7 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,7 +4,6 @@
package com.android.tools.r8.profile.art.rewriting;
-import static com.android.tools.r8.utils.ConsumerUtils.emptyConsumer;
import static com.android.tools.r8.utils.MapUtils.ignoreKey;
import com.android.tools.r8.graph.DexClass;
@@ -123,7 +122,10 @@
@Override
public ArtProfileAdditionsBuilder addMethodRule(DexMethod method) {
- ArtProfileAdditions.this.addMethodRuleFromContext(method, emptyConsumer());
+ ArtProfileMethodRule.Builder contextRuleBuilder = methodRuleAdditions.get(context);
+ ArtProfileAdditions.this.addMethodRuleFromContext(
+ method,
+ methodRuleInfoBuilder -> methodRuleInfoBuilder.joinFlags(contextRuleBuilder));
nestedMethodRuleAdditionsGraph.recordMethodRuleInfoFlagsLargerThan(method, context);
return this;
}
@@ -199,7 +201,20 @@
artProfile.forEachRule(
artProfileBuilder::addRule,
methodRule -> {
- if (!methodRuleRemovals.contains(methodRule.getMethod())) {
+ if (methodRuleRemovals.contains(methodRule.getMethod())) {
+ return;
+ }
+ ArtProfileMethodRule.Builder methodRuleBuilder =
+ methodRuleAdditions.remove(methodRule.getReference());
+ if (methodRuleBuilder != null) {
+ ArtProfileMethodRule newMethodRule =
+ methodRuleBuilder
+ .acceptMethodRuleInfoBuilder(
+ methodRuleInfoBuilder ->
+ methodRuleInfoBuilder.joinFlags(methodRule.getMethodRuleInfo()))
+ .build();
+ artProfileBuilder.addRule(newMethodRule);
+ } else {
artProfileBuilder.addRule(methodRule);
}
});
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileCollectionAdditions.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileCollectionAdditions.java
index 49d99c4..5198d05 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileCollectionAdditions.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileCollectionAdditions.java
@@ -55,4 +55,6 @@
public abstract ArtProfileCollectionAdditions setArtProfileCollection(
ArtProfileCollection artProfileCollection);
+
+ public abstract boolean verifyIsCommitted();
}
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfClassSynthesizerDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfClassSynthesizerDesugaringEventConsumer.java
index fc09831..ebc4799 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfClassSynthesizerDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfClassSynthesizerDesugaringEventConsumer.java
@@ -50,8 +50,9 @@
}
@Override
- public void acceptCollectionConversion(ProgramMethod arrayConversion) {
- parent.acceptCollectionConversion(arrayConversion);
+ public void acceptCollectionConversion(ProgramMethod arrayConversion, ProgramMethod context) {
+ additionsCollection.addMethodAndHolderIfContextIsInProfile(arrayConversion, context);
+ parent.acceptCollectionConversion(arrayConversion, context);
}
@Override
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 0f40e39..3ac8a23 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
@@ -55,12 +55,21 @@
}
@Override
- public void acceptAPIConversion(ProgramMethod method) {
- parent.acceptAPIConversion(method);
+ public void acceptAPIConversionOutline(ProgramMethod method, ProgramMethod context) {
+ additionsCollection.addMethodAndHolderIfContextIsInProfile(method, context);
+ parent.acceptAPIConversionOutline(method, context);
}
@Override
public void acceptBackportedClass(DexProgramClass backportedClass, ProgramMethod context) {
+ if (appView.options().getArtProfileOptions().isIncludingBackportedClasses()) {
+ additionsCollection.applyIfContextIsInProfile(
+ context,
+ additionsBuilder -> {
+ additionsBuilder.addRule(backportedClass);
+ backportedClass.forEachProgramMethod(additionsBuilder::addRule);
+ });
+ }
parent.acceptBackportedClass(backportedClass, context);
}
@@ -76,8 +85,9 @@
}
@Override
- public void acceptCollectionConversion(ProgramMethod arrayConversion) {
- parent.acceptCollectionConversion(arrayConversion);
+ public void acceptCollectionConversion(ProgramMethod arrayConversion, ProgramMethod context) {
+ additionsCollection.addMethodAndHolderIfContextIsInProfile(arrayConversion, context);
+ parent.acceptCollectionConversion(arrayConversion, context);
}
@Override
@@ -113,13 +123,19 @@
}
@Override
- public void acceptCovariantRetargetMethod(ProgramMethod method) {
- parent.acceptCovariantRetargetMethod(method);
+ public void acceptCovariantRetargetMethod(ProgramMethod method, ProgramMethod context) {
+ additionsCollection.addMethodAndHolderIfContextIsInProfile(method, context);
+ parent.acceptCovariantRetargetMethod(method, context);
}
@Override
public void acceptDefaultAsCompanionMethod(ProgramMethod method, ProgramMethod companionMethod) {
- additionsCollection.addMethodAndHolderIfContextIsInProfile(companionMethod, method);
+ additionsCollection.applyIfContextIsInProfile(
+ method,
+ additionsBuilder -> {
+ additionsBuilder.addRule(companionMethod).addRule(companionMethod.getHolder());
+ companionMethod.getHolder().acceptProgramClassInitializer(additionsBuilder::addRule);
+ });
parent.acceptDefaultAsCompanionMethod(method, companionMethod);
}
@@ -148,6 +164,7 @@
@Override
public void acceptInvokeStaticInterfaceOutliningMethod(
ProgramMethod method, ProgramMethod context) {
+ additionsCollection.addMethodAndHolderIfContextIsInProfile(method, context);
parent.acceptInvokeStaticInterfaceOutliningMethod(method, context);
}
@@ -169,6 +186,9 @@
additionsBuilder.addRule(lambdaProgramClass.getProgramClassInitializer());
}
lambdaProgramClass.forEachProgramInstanceInitializer(additionsBuilder::addRule);
+ if (appView.options().testing.alwaysGenerateLambdaFactoryMethods) {
+ lambdaProgramClass.forEachProgramStaticMethod(additionsBuilder::addRule);
+ }
});
}
@@ -216,7 +236,7 @@
.appInfoWithClassHierarchy()
.resolveMethod(target.getImplementationMethod(), target.isInterface())
.getResolutionPair();
- if (resolutionResult == null || resolutionResult.isProgramMethod()) {
+ if (resolutionResult != null && resolutionResult.isProgramMethod()) {
// Direct call to other method in the app. Only add virtual methods if the callee is in the
// profile.
return false;
@@ -272,11 +292,13 @@
public void acceptPrivateAsCompanionMethod(ProgramMethod method, ProgramMethod companionMethod) {
additionsCollection.applyIfContextIsInProfile(
method,
- additionsBuilder ->
- additionsBuilder
- .addRule(companionMethod)
- .addRule(companionMethod.getHolder())
- .removeMovedMethodRule(method, companionMethod));
+ additionsBuilder -> {
+ additionsBuilder
+ .addRule(companionMethod)
+ .addRule(companionMethod.getHolder())
+ .removeMovedMethodRule(method, companionMethod);
+ companionMethod.getHolder().acceptProgramClassInitializer(additionsBuilder::addRule);
+ });
parent.acceptPrivateAsCompanionMethod(method, companionMethod);
}
@@ -319,11 +341,13 @@
public void acceptStaticAsCompanionMethod(ProgramMethod method, ProgramMethod companionMethod) {
additionsCollection.applyIfContextIsInProfile(
method,
- additionsBuilder ->
- additionsBuilder
- .addRule(companionMethod)
- .addRule(companionMethod.getHolder())
- .removeMovedMethodRule(method, companionMethod));
+ additionsBuilder -> {
+ additionsBuilder
+ .addRule(companionMethod)
+ .addRule(companionMethod.getHolder())
+ .removeMovedMethodRule(method, companionMethod);
+ companionMethod.getHolder().acceptProgramClassInitializer(additionsBuilder::addRule);
+ });
parent.acceptStaticAsCompanionMethod(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
index a317c8d..568efcc 100644
--- 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
@@ -6,15 +6,20 @@
import static com.android.tools.r8.utils.ConsumerUtils.emptyConsumer;
+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.DexClasspathClass;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.MethodResolutionResult.FailedResolutionResult;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.EmulatedDispatchMethodDescriptor;
import com.android.tools.r8.ir.desugar.itf.InterfaceDesugaringSyntheticHelper;
+import com.android.tools.r8.profile.art.ArtProfileOptions;
+import com.android.tools.r8.utils.BooleanBox;
import java.util.Set;
import java.util.concurrent.ExecutionException;
@@ -22,23 +27,29 @@
extends CfPostProcessingDesugaringEventConsumer {
private final ConcreteArtProfileCollectionAdditions additionsCollection;
+ private final ArtProfileOptions options;
private final CfPostProcessingDesugaringEventConsumer parent;
private ArtProfileRewritingCfPostProcessingDesugaringEventConsumer(
ConcreteArtProfileCollectionAdditions additionsCollection,
+ ArtProfileOptions options,
CfPostProcessingDesugaringEventConsumer parent) {
this.additionsCollection = additionsCollection;
+ this.options = options;
this.parent = parent;
}
public static CfPostProcessingDesugaringEventConsumer attach(
+ AppView<?> appView,
ArtProfileCollectionAdditions artProfileCollectionAdditions,
CfPostProcessingDesugaringEventConsumer eventConsumer) {
if (artProfileCollectionAdditions.isNop()) {
return eventConsumer;
}
return new ArtProfileRewritingCfPostProcessingDesugaringEventConsumer(
- artProfileCollectionAdditions.asConcrete(), eventConsumer);
+ artProfileCollectionAdditions.asConcrete(),
+ appView.options().getArtProfileOptions(),
+ eventConsumer);
}
@Override
@@ -49,13 +60,15 @@
}
@Override
- public void acceptCollectionConversion(ProgramMethod arrayConversion) {
- parent.acceptCollectionConversion(arrayConversion);
+ public void acceptCollectionConversion(ProgramMethod arrayConversion, ProgramMethod context) {
+ additionsCollection.addMethodAndHolderIfContextIsInProfile(arrayConversion, context);
+ parent.acceptCollectionConversion(arrayConversion, context);
}
@Override
- public void acceptCovariantRetargetMethod(ProgramMethod method) {
- parent.acceptCovariantRetargetMethod(method);
+ public void acceptCovariantRetargetMethod(ProgramMethod method, ProgramMethod context) {
+ additionsCollection.addMethodAndHolderIfContextIsInProfile(context, method);
+ parent.acceptCovariantRetargetMethod(method, context);
}
@Override
@@ -64,8 +77,12 @@
}
@Override
- public void acceptDesugaredLibraryRetargeterForwardingMethod(ProgramMethod method) {
- parent.acceptDesugaredLibraryRetargeterForwardingMethod(method);
+ public void acceptDesugaredLibraryRetargeterForwardingMethod(
+ ProgramMethod method, EmulatedDispatchMethodDescriptor descriptor) {
+ if (options.isIncludingDesugaredLibraryRetargeterForwardingMethodsUnconditionally()) {
+ additionsCollection.apply(additions -> additions.addMethodRule(method, emptyConsumer()));
+ }
+ parent.acceptDesugaredLibraryRetargeterForwardingMethod(method, descriptor);
}
@Override
@@ -97,8 +114,24 @@
}
@Override
- public void acceptThrowingMethod(ProgramMethod method, DexType errorType) {
- parent.acceptThrowingMethod(method, errorType);
+ public void acceptThrowingMethod(
+ ProgramMethod method, DexType errorType, FailedResolutionResult resolutionResult) {
+ if (options.isIncludingThrowingMethods()) {
+ BooleanBox seenMethodCausingError = new BooleanBox();
+ resolutionResult.forEachFailureDependency(
+ emptyConsumer(),
+ methodCausingError -> {
+ additionsCollection.applyIfContextIsInProfile(
+ methodCausingError.getReference(),
+ additionsBuilder -> additionsBuilder.addRule(method));
+ seenMethodCausingError.set();
+ });
+ if (seenMethodCausingError.isFalse()) {
+ additionsCollection.applyIfContextIsInProfile(
+ method.getHolder(), additions -> additions.addMethodRule(method, emptyConsumer()));
+ }
+ }
+ parent.acceptThrowingMethod(method, errorType, resolutionResult);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingMethodProcessorEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingMethodProcessorEventConsumer.java
index 8363e62..dea3841 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingMethodProcessorEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingMethodProcessorEventConsumer.java
@@ -51,7 +51,7 @@
@Override
public void acceptEnumUnboxerCheckNotZeroContext(ProgramMethod method, ProgramMethod context) {
additionsCollection.applyIfContextIsInProfile(
- context, additionsBuilder -> additionsBuilder.addRule(method));
+ context, additionsBuilder -> additionsBuilder.addRule(method).addRule(method.getHolder()));
parent.acceptEnumUnboxerCheckNotZeroContext(method, context);
}
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingRootSetBuilderEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingRootSetBuilderEventConsumer.java
index 9a61ea9..005c33c 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingRootSetBuilderEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingRootSetBuilderEventConsumer.java
@@ -4,11 +4,8 @@
package com.android.tools.r8.profile.art.rewriting;
-import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
-import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.shaking.RootSetBuilderEventConsumer;
-import com.android.tools.r8.shaking.RootSetUtils.RootSet;
public class ArtProfileRewritingRootSetBuilderEventConsumer implements RootSetBuilderEventConsumer {
@@ -23,10 +20,8 @@
}
public static RootSetBuilderEventConsumer attach(
- AppView<? extends AppInfoWithClassHierarchy> appView,
+ ArtProfileCollectionAdditions additionsCollection,
RootSetBuilderEventConsumer eventConsumer) {
- ArtProfileCollectionAdditions additionsCollection =
- ArtProfileCollectionAdditions.create(appView);
if (additionsCollection.isNop()) {
return eventConsumer;
}
@@ -68,9 +63,4 @@
.removeMovedMethodRule(method, companionMethod));
parent.acceptStaticAsCompanionMethod(method, companionMethod);
}
-
- @Override
- public void finished(AppView<? extends AppInfoWithClassHierarchy> appView, RootSet rootSet) {
- additionsCollection.commit(appView);
- }
}
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 4cfd694..1d1a897 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
@@ -155,4 +155,10 @@
}
return this;
}
+
+ @Override
+ public boolean verifyIsCommitted() {
+ assert committed;
+ return true;
+ }
}
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/NopArtProfileCollectionAdditions.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/NopArtProfileCollectionAdditions.java
index fe61aaa..8bfd4a6 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/NopArtProfileCollectionAdditions.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/NopArtProfileCollectionAdditions.java
@@ -57,4 +57,10 @@
// Intentionally empty.
return this;
}
+
+ @Override
+ public boolean verifyIsCommitted() {
+ // Nothing to commit.
+ return true;
+ }
}
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 13e0528..15781741 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -473,6 +473,7 @@
Enqueuer(
AppView<? extends AppInfoWithClassHierarchy> appView,
+ ArtProfileCollectionAdditions artProfileCollectionAdditions,
ExecutorService executorService,
SubtypingInfo subtypingInfo,
GraphConsumer keptGraphConsumer,
@@ -481,7 +482,7 @@
InternalOptions options = appView.options();
this.appInfo = appView.appInfo();
this.appView = appView.withClassHierarchy();
- this.artProfileCollectionAdditions = ArtProfileCollectionAdditions.create(appView);
+ this.artProfileCollectionAdditions = artProfileCollectionAdditions;
this.deferredTracing = EnqueuerDeferredTracing.create(appView, this, mode);
this.executorService = executorService;
this.subtypingInfo = subtypingInfo;
@@ -531,6 +532,10 @@
return appView.appInfo();
}
+ public ArtProfileCollectionAdditions getArtProfileCollectionAdditions() {
+ return artProfileCollectionAdditions;
+ }
+
public Mode getMode() {
return mode;
}
@@ -4475,7 +4480,7 @@
}
}
ConsequentRootSetBuilder consequentSetBuilder =
- ConsequentRootSet.builder(appView, subtypingInfo, this);
+ ConsequentRootSet.builder(appView, this, subtypingInfo);
IfRuleEvaluator ifRuleEvaluator =
new IfRuleEvaluator(
appView,
@@ -4569,6 +4574,7 @@
CfPostProcessingDesugaringEventConsumer eventConsumer =
CfPostProcessingDesugaringEventConsumer.createForR8(
+ appView,
syntheticAdditions,
artProfileCollectionAdditions,
desugaring,
@@ -4635,7 +4641,7 @@
}
private ConsequentRootSet computeDelayedInterfaceMethodSyntheticBridges() {
- RootSetBuilder builder = RootSet.builder(appView, subtypingInfo);
+ RootSetBuilder builder = RootSet.builder(appView, this, subtypingInfo);
for (DelayedRootSetActionItem delayedRootSetActionItem : rootSet.delayedRootSetActionItems) {
if (delayedRootSetActionItem.isInterfaceMethodSyntheticBridgeAction()) {
handleInterfaceMethodSyntheticBridgeAction(
diff --git a/src/main/java/com/android/tools/r8/shaking/EnqueuerFactory.java b/src/main/java/com/android/tools/r8/shaking/EnqueuerFactory.java
index cfce371..e1d0124 100644
--- a/src/main/java/com/android/tools/r8/shaking/EnqueuerFactory.java
+++ b/src/main/java/com/android/tools/r8/shaking/EnqueuerFactory.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.SubtypingInfo;
+import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
import com.android.tools.r8.shaking.Enqueuer.Mode;
import java.util.Set;
import java.util.concurrent.ExecutorService;
@@ -17,9 +18,16 @@
public static Enqueuer createForInitialTreeShaking(
AppView<? extends AppInfoWithClassHierarchy> appView,
+ ArtProfileCollectionAdditions artProfileCollectionAdditions,
ExecutorService executorService,
SubtypingInfo subtypingInfo) {
- return new Enqueuer(appView, executorService, subtypingInfo, null, Mode.INITIAL_TREE_SHAKING);
+ return new Enqueuer(
+ appView,
+ artProfileCollectionAdditions,
+ executorService,
+ subtypingInfo,
+ null,
+ Mode.INITIAL_TREE_SHAKING);
}
public static Enqueuer createForFinalTreeShaking(
@@ -28,9 +36,16 @@
SubtypingInfo subtypingInfo,
GraphConsumer keptGraphConsumer,
Set<DexType> initialPrunedTypes) {
+ ArtProfileCollectionAdditions artProfileCollectionAdditions =
+ ArtProfileCollectionAdditions.create(appView);
Enqueuer enqueuer =
new Enqueuer(
- appView, executorService, subtypingInfo, keptGraphConsumer, Mode.FINAL_TREE_SHAKING);
+ appView,
+ artProfileCollectionAdditions,
+ executorService,
+ subtypingInfo,
+ keptGraphConsumer,
+ Mode.FINAL_TREE_SHAKING);
appView.withProtoShrinker(
shrinker -> enqueuer.setInitialDeadProtoTypes(shrinker.getDeadProtoTypes()));
enqueuer.setInitialPrunedTypes(initialPrunedTypes);
@@ -41,8 +56,15 @@
AppView<? extends AppInfoWithClassHierarchy> appView,
ExecutorService executorService,
SubtypingInfo subtypingInfo) {
+ ArtProfileCollectionAdditions artProfileCollectionAdditions =
+ ArtProfileCollectionAdditions.create(appView);
return new Enqueuer(
- appView, executorService, subtypingInfo, null, Mode.INITIAL_MAIN_DEX_TRACING);
+ appView,
+ artProfileCollectionAdditions,
+ executorService,
+ subtypingInfo,
+ null,
+ Mode.INITIAL_MAIN_DEX_TRACING);
}
public static Enqueuer createForFinalMainDexTracing(
@@ -50,8 +72,15 @@
ExecutorService executorService,
SubtypingInfo subtypingInfo,
GraphConsumer keptGraphConsumer) {
+ ArtProfileCollectionAdditions artProfileCollectionAdditions =
+ ArtProfileCollectionAdditions.create(appView);
return new Enqueuer(
- appView, executorService, subtypingInfo, keptGraphConsumer, Mode.FINAL_MAIN_DEX_TRACING);
+ appView,
+ artProfileCollectionAdditions,
+ executorService,
+ subtypingInfo,
+ keptGraphConsumer,
+ Mode.FINAL_MAIN_DEX_TRACING);
}
public static Enqueuer createForGenerateMainDexList(
@@ -59,8 +88,15 @@
ExecutorService executorService,
SubtypingInfo subtypingInfo,
GraphConsumer keptGraphConsumer) {
+ ArtProfileCollectionAdditions artProfileCollectionAdditions =
+ ArtProfileCollectionAdditions.create(appView);
return new Enqueuer(
- appView, executorService, subtypingInfo, keptGraphConsumer, Mode.GENERATE_MAIN_DEX_LIST);
+ appView,
+ artProfileCollectionAdditions,
+ executorService,
+ subtypingInfo,
+ keptGraphConsumer,
+ Mode.GENERATE_MAIN_DEX_LIST);
}
public static Enqueuer createForWhyAreYouKeeping(
@@ -68,7 +104,14 @@
ExecutorService executorService,
SubtypingInfo subtypingInfo,
GraphConsumer keptGraphConsumer) {
+ ArtProfileCollectionAdditions artProfileCollectionAdditions =
+ ArtProfileCollectionAdditions.create(appView);
return new Enqueuer(
- appView, executorService, subtypingInfo, keptGraphConsumer, Mode.WHY_ARE_YOU_KEEPING);
+ appView,
+ artProfileCollectionAdditions,
+ executorService,
+ subtypingInfo,
+ keptGraphConsumer,
+ Mode.WHY_ARE_YOU_KEEPING);
}
}
diff --git a/src/main/java/com/android/tools/r8/shaking/RootSetBuilderEventConsumer.java b/src/main/java/com/android/tools/r8/shaking/RootSetBuilderEventConsumer.java
index b49a15d..9378b76 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetBuilderEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetBuilderEventConsumer.java
@@ -4,25 +4,23 @@
package com.android.tools.r8.shaking;
-import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
-import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.desugar.itf.InterfaceMethodDesugaringBaseEventConsumer;
+import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
import com.android.tools.r8.profile.art.rewriting.ArtProfileRewritingRootSetBuilderEventConsumer;
-import com.android.tools.r8.shaking.RootSetUtils.RootSet;
public interface RootSetBuilderEventConsumer extends InterfaceMethodDesugaringBaseEventConsumer {
- static RootSetBuilderEventConsumer create(AppView<? extends AppInfoWithClassHierarchy> appView) {
- return ArtProfileRewritingRootSetBuilderEventConsumer.attach(appView, empty());
+ static RootSetBuilderEventConsumer create(
+ ArtProfileCollectionAdditions artProfileCollectionAdditions) {
+ return ArtProfileRewritingRootSetBuilderEventConsumer.attach(
+ artProfileCollectionAdditions, empty());
}
static EmptyRootSetBuilderEventConsumer empty() {
return EmptyRootSetBuilderEventConsumer.getInstance();
}
- default void finished(AppView<? extends AppInfoWithClassHierarchy> appView, RootSet rootSet) {}
-
class EmptyRootSetBuilderEventConsumer implements RootSetBuilderEventConsumer {
private static final EmptyRootSetBuilderEventConsumer INSTANCE =
diff --git a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
index bda1564..b5810f2 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
@@ -53,6 +53,7 @@
import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple;
import com.android.tools.r8.ir.optimize.membervaluepropagation.assume.AssumeInfo;
import com.android.tools.r8.logging.Log;
+import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
import com.android.tools.r8.repackaging.RepackagingUtils;
import com.android.tools.r8.shaking.AnnotationMatchResult.AnnotationsIgnoredMatchResult;
import com.android.tools.r8.shaking.AnnotationMatchResult.ConcreteAnnotationMatchResult;
@@ -156,10 +157,11 @@
private RootSetBuilder(
AppView<? extends AppInfoWithClassHierarchy> appView,
+ RootSetBuilderEventConsumer eventConsumer,
SubtypingInfo subtypingInfo,
Iterable<? extends ProguardConfigurationRule> rules) {
this.appView = appView;
- this.eventConsumer = RootSetBuilderEventConsumer.create(appView);
+ this.eventConsumer = eventConsumer;
this.subtypingInfo = subtypingInfo;
this.application = appView.appInfo().app().asDirect();
this.rules = rules;
@@ -171,8 +173,14 @@
}
private RootSetBuilder(
- AppView<? extends AppInfoWithClassHierarchy> appView, SubtypingInfo subtypingInfo) {
- this(appView, subtypingInfo, null);
+ AppView<? extends AppInfoWithClassHierarchy> appView,
+ Enqueuer enqueuer,
+ SubtypingInfo subtypingInfo) {
+ this(
+ appView,
+ RootSetBuilderEventConsumer.create(enqueuer.getArtProfileCollectionAdditions()),
+ subtypingInfo,
+ null);
}
boolean isMainDexRootSetBuilder() {
@@ -386,30 +394,27 @@
alwaysInline,
bypassClinitforInlining);
}
- RootSet rootSet =
- new RootSet(
- dependentMinimumKeepInfo,
- ImmutableList.copyOf(reasonAsked.values()),
- alwaysInline,
- neverInlineDueToSingleCaller,
- bypassClinitforInlining,
- whyAreYouNotInlining,
- reprocess,
- neverReprocess,
- alwaysClassInline,
- neverClassInline,
- noUnusedInterfaceRemoval,
- noVerticalClassMerging,
- noHorizontalClassMerging,
- neverPropagateValue,
- mayHaveSideEffects,
- dependentKeepClassCompatRule,
- identifierNameStrings,
- ifRules,
- Lists.newArrayList(delayedRootSetActionItems),
- pendingMethodMoveInverse);
- eventConsumer.finished(appView, rootSet);
- return rootSet;
+ return new RootSet(
+ dependentMinimumKeepInfo,
+ ImmutableList.copyOf(reasonAsked.values()),
+ alwaysInline,
+ neverInlineDueToSingleCaller,
+ bypassClinitforInlining,
+ whyAreYouNotInlining,
+ reprocess,
+ neverReprocess,
+ alwaysClassInline,
+ neverClassInline,
+ noUnusedInterfaceRemoval,
+ noVerticalClassMerging,
+ noHorizontalClassMerging,
+ neverPropagateValue,
+ mayHaveSideEffects,
+ dependentKeepClassCompatRule,
+ identifierNameStrings,
+ ifRules,
+ Lists.newArrayList(delayedRootSetActionItems),
+ pendingMethodMoveInverse);
}
private void propagateAssumeRules(DexClass clazz) {
@@ -2158,15 +2163,22 @@
}
public static RootSetBuilder builder(
- AppView<? extends AppInfoWithClassHierarchy> appView, SubtypingInfo subtypingInfo) {
- return new RootSetBuilder(appView, subtypingInfo);
+ AppView<? extends AppInfoWithClassHierarchy> appView,
+ Enqueuer enqueuer,
+ SubtypingInfo subtypingInfo) {
+ return new RootSetBuilder(appView, enqueuer, subtypingInfo);
}
public static RootSetBuilder builder(
AppView<? extends AppInfoWithClassHierarchy> appView,
+ ArtProfileCollectionAdditions artProfileCollectionAdditions,
SubtypingInfo subtypingInfo,
Iterable<? extends ProguardConfigurationRule> rules) {
- return new RootSetBuilder(appView, subtypingInfo, rules);
+ return new RootSetBuilder(
+ appView,
+ RootSetBuilderEventConsumer.create(artProfileCollectionAdditions),
+ subtypingInfo,
+ rules);
}
}
@@ -2176,9 +2188,13 @@
private ConsequentRootSetBuilder(
AppView<? extends AppInfoWithClassHierarchy> appView,
- SubtypingInfo subtypingInfo,
- Enqueuer enqueuer) {
- super(appView, subtypingInfo, null);
+ Enqueuer enqueuer,
+ SubtypingInfo subtypingInfo) {
+ super(
+ appView,
+ RootSetBuilderEventConsumer.create(enqueuer.getArtProfileCollectionAdditions()),
+ subtypingInfo,
+ null);
this.enqueuer = enqueuer;
}
@@ -2214,9 +2230,9 @@
static ConsequentRootSetBuilder builder(
AppView<? extends AppInfoWithClassHierarchy> appView,
- SubtypingInfo subtypingInfo,
- Enqueuer enqueuer) {
- return new ConsequentRootSetBuilder(appView, subtypingInfo, enqueuer);
+ Enqueuer enqueuer,
+ SubtypingInfo subtypingInfo) {
+ return new ConsequentRootSetBuilder(appView, enqueuer, subtypingInfo);
}
}
@@ -2224,9 +2240,14 @@
private MainDexRootSetBuilder(
AppView<? extends AppInfoWithClassHierarchy> appView,
+ ArtProfileCollectionAdditions artProfileCollectionAdditions,
SubtypingInfo subtypingInfo,
Iterable<? extends ProguardConfigurationRule> rules) {
- super(appView, subtypingInfo, rules);
+ super(
+ appView,
+ RootSetBuilderEventConsumer.create(artProfileCollectionAdditions),
+ subtypingInfo,
+ rules);
}
@Override
@@ -2278,9 +2299,11 @@
public static MainDexRootSetBuilder builder(
AppView<? extends AppInfoWithClassHierarchy> appView,
+ ArtProfileCollectionAdditions artProfileCollectionAdditions,
SubtypingInfo subtypingInfo,
Iterable<? extends ProguardConfigurationRule> rules) {
- return new MainDexRootSetBuilder(appView, subtypingInfo, rules);
+ return new MainDexRootSetBuilder(
+ appView, artProfileCollectionAdditions, subtypingInfo, rules);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
index 8214303..8cf1e77 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
@@ -197,15 +197,7 @@
appView.setAppInfo(appView.appInfo().rebuildWithClassHierarchy(result.commit));
appView.setAppInfo(appView.appInfo().rebuildWithMainDexInfo(result.mainDexInfo));
if (result.lens != null) {
- appView.setGraphLens(result.lens);
- appView.setAppInfo(
- appView
- .appInfo()
- .rebuildWithMainDexInfo(
- appView
- .appInfo()
- .getMainDexInfo()
- .rewrittenWithLens(appView.getSyntheticItems(), result.lens)));
+ appView.rewriteWithLens(result.lens);
}
appView.pruneItems(result.prunedItems, executorService);
}
diff --git a/src/test/java/com/android/tools/r8/TestBase.java b/src/test/java/com/android/tools/r8/TestBase.java
index 74620e9..d4123d3 100644
--- a/src/test/java/com/android/tools/r8/TestBase.java
+++ b/src/test/java/com/android/tools/r8/TestBase.java
@@ -46,6 +46,7 @@
import com.android.tools.r8.jasmin.JasminBuilder;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
+import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.FieldReference;
import com.android.tools.r8.references.MethodReference;
@@ -856,14 +857,20 @@
computeAppViewWithClassHierarchy(app, keepConfig, optionsConsumer);
// Run the tree shaker to compute an instance of AppInfoWithLiveness.
ExecutorService executor = Executors.newSingleThreadExecutor();
+ ArtProfileCollectionAdditions artProfileCollectionAdditions =
+ ArtProfileCollectionAdditions.nop();
SubtypingInfo subtypingInfo = SubtypingInfo.create(appView);
RootSet rootSet =
RootSet.builder(
- appView, subtypingInfo, appView.options().getProguardConfiguration().getRules())
+ appView,
+ artProfileCollectionAdditions,
+ subtypingInfo,
+ appView.options().getProguardConfiguration().getRules())
.build(executor);
appView.setRootSet(rootSet);
EnqueuerResult enqueuerResult =
- EnqueuerFactory.createForInitialTreeShaking(appView, executor, subtypingInfo)
+ EnqueuerFactory.createForInitialTreeShaking(
+ appView, artProfileCollectionAdditions, executor, subtypingInfo)
.traceApplication(rootSet, executor, Timing.empty());
executor.shutdown();
// We do not run the tree pruner to ensure that the hierarchy is as designed and not modified
diff --git a/src/test/java/com/android/tools/r8/ir/InlineTest.java b/src/test/java/com/android/tools/r8/ir/InlineTest.java
index be71b20..037bb82 100644
--- a/src/test/java/com/android/tools/r8/ir/InlineTest.java
+++ b/src/test/java/com/android/tools/r8/ir/InlineTest.java
@@ -23,6 +23,7 @@
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionListIterator;
import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
import com.android.tools.r8.shaking.Enqueuer;
import com.android.tools.r8.shaking.EnqueuerFactory;
import com.android.tools.r8.shaking.EnqueuerResult;
@@ -73,17 +74,21 @@
throws ExecutionException {
AppView<AppInfoWithClassHierarchy> appView = AppView.createForR8(application.asDirect());
appView.setAppServices(AppServices.builder(appView).build());
+ ArtProfileCollectionAdditions artProfileCollectionAdditions =
+ ArtProfileCollectionAdditions.nop();
ExecutorService executorService = ThreadUtils.getExecutorService(options);
SubtypingInfo subtypingInfo = SubtypingInfo.create(appView);
appView.setRootSet(
RootSet.builder(
appView,
+ artProfileCollectionAdditions,
subtypingInfo,
ImmutableList.of(ProguardKeepRule.defaultKeepAllRule(unused -> {})))
.build(executorService));
Timing timing = Timing.empty();
Enqueuer enqueuer =
- EnqueuerFactory.createForInitialTreeShaking(appView, executorService, subtypingInfo);
+ EnqueuerFactory.createForInitialTreeShaking(
+ appView, artProfileCollectionAdditions, executorService, subtypingInfo);
EnqueuerResult enqueuerResult =
enqueuer.traceApplication(appView.rootSet(), executorService, timing);
appView.setAppInfo(enqueuerResult.getAppInfo());
diff --git a/src/test/java/com/android/tools/r8/profile/art/completeness/MovedStaticInterfaceMethodProfileRewritingTest.java b/src/test/java/com/android/tools/r8/profile/art/completeness/MovedStaticInterfaceMethodProfileRewritingTest.java
index 6e7ab5b..009966f 100644
--- a/src/test/java/com/android/tools/r8/profile/art/completeness/MovedStaticInterfaceMethodProfileRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/profile/art/completeness/MovedStaticInterfaceMethodProfileRewritingTest.java
@@ -4,6 +4,8 @@
package com.android.tools.r8.profile.art.completeness;
+import static com.android.tools.r8.synthesis.SyntheticItemsTestUtils.syntheticCompanionClass;
+import static com.android.tools.r8.synthesis.SyntheticItemsTestUtils.syntheticStaticInterfaceMethodAsCompanionMethod;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -14,7 +16,6 @@
import com.android.tools.r8.profile.art.model.ExternalArtProfile;
import com.android.tools.r8.profile.art.utils.ArtProfileInspector;
import com.android.tools.r8.references.Reference;
-import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
@@ -48,6 +49,20 @@
}
@Test
+ public void testD8FromProfileAfterDesugaring() throws Exception {
+ testForD8(parameters.getBackend())
+ .addInnerClasses(getClass())
+ .addArtProfileForRewriting(
+ getArtProfileAfterDesugaring(
+ parameters.canUseDefaultAndStaticInterfaceMethodsWhenDesugaring()))
+ .setMinApi(parameters.getApiLevel())
+ .compile()
+ .inspectResidualArtProfile(this::inspectD8)
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines("Hello, world!");
+ }
+
+ @Test
public void testR8() throws Exception {
parameters.assumeR8TestParameters();
testForR8(parameters.getBackend())
@@ -62,12 +77,42 @@
.assertSuccessWithOutputLines("Hello, world!");
}
+ @Test
+ public void testR8FromProfileAfterDesugaring() throws Exception {
+ parameters.assumeR8TestParameters();
+ testForR8(parameters.getBackend())
+ .addInnerClasses(getClass())
+ .addKeepMainRule(Main.class)
+ .addArtProfileForRewriting(
+ getArtProfileAfterDesugaring(
+ parameters.isCfRuntime() || parameters.canUseDefaultAndStaticInterfaceMethods()))
+ .enableInliningAnnotations()
+ .setMinApi(parameters.getApiLevel())
+ .compile()
+ .inspectResidualArtProfile(this::inspectR8)
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines("Hello, world!");
+ }
+
private ExternalArtProfile getArtProfile() throws Exception {
return ExternalArtProfile.builder()
.addMethodRule(Reference.methodFromMethod(I.class.getDeclaredMethod("m")))
.build();
}
+ private ExternalArtProfile getArtProfileAfterDesugaring(
+ boolean canUseDefaultAndStaticInterfaceMethods) throws Exception {
+ if (canUseDefaultAndStaticInterfaceMethods) {
+ return getArtProfile();
+ } else {
+ return ExternalArtProfile.builder()
+ .addClassRule(syntheticCompanionClass(I.class))
+ .addMethodRule(
+ syntheticStaticInterfaceMethodAsCompanionMethod(I.class.getDeclaredMethod("m")))
+ .build();
+ }
+ }
+
private void inspectD8(ArtProfileInspector profileInspector, CodeInspector inspector)
throws Exception {
inspect(
@@ -100,8 +145,7 @@
.assertContainsMethodRule(staticInterfaceMethodSubject)
.assertContainsNoOtherRules();
} else {
- ClassSubject companionClassSubject =
- inspector.clazz(SyntheticItemsTestUtils.syntheticCompanionClass(I.class));
+ ClassSubject companionClassSubject = inspector.clazz(syntheticCompanionClass(I.class));
assertThat(companionClassSubject, isPresent());
MethodSubject staticInterfaceMethodSubject =
diff --git a/src/test/java/com/android/tools/r8/synthesis/SyntheticItemsTestUtils.java b/src/test/java/com/android/tools/r8/synthesis/SyntheticItemsTestUtils.java
index 478af32..e69bb0f 100644
--- a/src/test/java/com/android/tools/r8/synthesis/SyntheticItemsTestUtils.java
+++ b/src/test/java/com/android/tools/r8/synthesis/SyntheticItemsTestUtils.java
@@ -228,6 +228,14 @@
originalMethod.getMethodDescriptor());
}
+ public static MethodReference syntheticStaticInterfaceMethodAsCompanionMethod(Method method) {
+ MethodReference originalMethod = Reference.methodFromMethod(method);
+ ClassReference companionClassReference =
+ syntheticCompanionClass(originalMethod.getHolderClass());
+ return Reference.methodFromDescriptor(
+ companionClassReference, method.getName(), originalMethod.getMethodDescriptor());
+ }
+
public static ClassReference syntheticEnumUnboxingLocalUtilityClass(Class<?> clazz) {
return Reference.classFromTypeName(
clazz.getTypeName() + naming.ENUM_UNBOXING_LOCAL_UTILITY_CLASS.getDescriptor());