Merge commit 'fa84c4d76daf331833bad01f14133cb4a6484425' into dev-release
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index 52735a5..abf8844 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -311,6 +311,7 @@
appView.setArtProfileCollection(
appView.getArtProfileCollection().withoutMissingItems(appView));
+ assert appView.getStartupProfile().isEmpty();
finalizeApplication(appView, executor, timing);
diff --git a/src/main/java/com/android/tools/r8/GenerateMainDexList.java b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
index 3c17174..14677cc 100644
--- a/src/main/java/com/android/tools/r8/GenerateMainDexList.java
+++ b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
@@ -15,7 +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.profile.art.rewriting.ProfileCollectionAdditions;
import com.android.tools.r8.shaking.Enqueuer;
import com.android.tools.r8.shaking.EnqueuerFactory;
import com.android.tools.r8.shaking.MainDexInfo;
@@ -66,11 +66,10 @@
SubtypingInfo subtypingInfo = SubtypingInfo.create(appView);
- ArtProfileCollectionAdditions artProfileCollectionAdditions =
- ArtProfileCollectionAdditions.nop();
+ ProfileCollectionAdditions profileCollectionAdditions = ProfileCollectionAdditions.nop();
MainDexRootSet mainDexRootSet =
MainDexRootSet.builder(
- appView, artProfileCollectionAdditions, subtypingInfo, options.mainDexKeepRules)
+ appView, profileCollectionAdditions, subtypingInfo, options.mainDexKeepRules)
.build(executor);
appView.setMainDexRootSet(mainDexRootSet);
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 9e8e260..41ea658 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -73,7 +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.profile.art.rewriting.ProfileCollectionAdditions;
import com.android.tools.r8.repackaging.Repackaging;
import com.android.tools.r8.repackaging.RepackagingLens;
import com.android.tools.r8.shaking.AbstractMethodRemover;
@@ -331,14 +331,14 @@
options.itemFactory, options.getMinApiLevel()));
}
}
- ArtProfileCollectionAdditions artProfileCollectionAdditions =
- ArtProfileCollectionAdditions.create(appView);
+ ProfileCollectionAdditions profileCollectionAdditions =
+ ProfileCollectionAdditions.create(appView);
AssumeInfoCollection.Builder assumeInfoCollectionBuilder = AssumeInfoCollection.builder();
SubtypingInfo subtypingInfo = SubtypingInfo.create(appView);
appView.setRootSet(
RootSet.builder(
appView,
- artProfileCollectionAdditions,
+ profileCollectionAdditions,
subtypingInfo,
Iterables.concat(
options.getProguardConfiguration().getRules(), synthesizedProguardRules))
@@ -353,10 +353,7 @@
// Find classes which may have code executed before secondary dex files installation.
MainDexRootSet mainDexRootSet =
MainDexRootSet.builder(
- appView,
- artProfileCollectionAdditions,
- subtypingInfo,
- options.mainDexKeepRules)
+ appView, profileCollectionAdditions, subtypingInfo, options.mainDexKeepRules)
.build(executorService);
appView.setMainDexRootSet(mainDexRootSet);
appView.appInfo().unsetObsolete();
@@ -371,7 +368,7 @@
annotationRemoverBuilder,
executorService,
appView,
- artProfileCollectionAdditions,
+ profileCollectionAdditions,
subtypingInfo,
classMergingEnqueuerExtensionBuilder);
timing.end();
@@ -702,6 +699,7 @@
appView.setArtProfileCollection(
appView.getArtProfileCollection().withoutMissingItems(appView));
+ appView.setStartupProfile(appView.getStartupProfile().withoutMissingItems(appView));
if (appView.appInfo().hasLiveness()) {
SyntheticFinalization.finalizeWithLiveness(appView.withLiveness(), executorService, timing);
@@ -970,14 +968,14 @@
AnnotationRemover.Builder annotationRemoverBuilder,
ExecutorService executorService,
AppView<AppInfoWithClassHierarchy> appView,
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
SubtypingInfo subtypingInfo,
RuntimeTypeCheckInfo.Builder classMergingEnqueuerExtensionBuilder)
throws ExecutionException {
timing.begin("Set up enqueuer");
Enqueuer enqueuer =
EnqueuerFactory.createForInitialTreeShaking(
- appView, artProfileCollectionAdditions, executorService, subtypingInfo);
+ appView, profileCollectionAdditions, executorService, subtypingInfo);
enqueuer.setAnnotationRemoverBuilder(annotationRemoverBuilder);
if (appView.options().enableInitializedClassesInInstanceMethodsAnalysis) {
enqueuer.registerAnalysis(new InitializedClassesInInstanceMethodsAnalysis(appView));
@@ -997,7 +995,7 @@
timing.begin("Trace application");
EnqueuerResult enqueuerResult =
enqueuer.traceApplication(appView.rootSet(), executorService, timing);
- assert artProfileCollectionAdditions.verifyIsCommitted();
+ assert profileCollectionAdditions.verifyIsCommitted();
timing.end();
timing.begin("Finalize enqueuer result");
AppView<AppInfoWithLiveness> appViewWithLiveness =
diff --git a/src/main/java/com/android/tools/r8/androidapi/ApiReferenceStubber.java b/src/main/java/com/android/tools/r8/androidapi/ApiReferenceStubber.java
index c1af115..261497d 100644
--- a/src/main/java/com/android/tools/r8/androidapi/ApiReferenceStubber.java
+++ b/src/main/java/com/android/tools/r8/androidapi/ApiReferenceStubber.java
@@ -23,6 +23,7 @@
import com.android.tools.r8.graph.ThrowExceptionCode;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.synthesis.CommittedItems;
+import com.android.tools.r8.synthesis.SyntheticItems;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.WorkList;
import com.google.common.collect.Sets;
@@ -89,10 +90,15 @@
eventConsumer.finished(appView);
}
+ private boolean isAlreadyOutlined(DexProgramClass clazz) {
+ SyntheticItems syntheticItems = appView.getSyntheticItems();
+ return syntheticItems.isSyntheticOfKind(clazz.getType(), kinds -> kinds.API_MODEL_OUTLINE)
+ || syntheticItems.isSyntheticOfKind(
+ clazz.getType(), kinds -> kinds.API_MODEL_OUTLINE_WITHOUT_GLOBAL_MERGING);
+ }
+
public void processClass(DexProgramClass clazz) {
- if (appView
- .getSyntheticItems()
- .isSyntheticOfKind(clazz.getType(), kinds -> kinds.API_MODEL_OUTLINE)) {
+ if (isAlreadyOutlined(clazz)) {
return;
}
// We cannot reliably create a stub that will have the same throwing behavior for all VMs.
diff --git a/src/main/java/com/android/tools/r8/androidapi/ApiReferenceStubberEventConsumer.java b/src/main/java/com/android/tools/r8/androidapi/ApiReferenceStubberEventConsumer.java
index 7c42536..47b5efb 100644
--- a/src/main/java/com/android/tools/r8/androidapi/ApiReferenceStubberEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/androidapi/ApiReferenceStubberEventConsumer.java
@@ -7,7 +7,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexLibraryClass;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileRewritingApiReferenceStubberEventConsumer;
+import com.android.tools.r8.profile.art.rewriting.ProfileRewritingApiReferenceStubberEventConsumer;
public interface ApiReferenceStubberEventConsumer {
@@ -21,7 +21,7 @@
boolean isEmpty();
static ApiReferenceStubberEventConsumer create(AppView<?> appView) {
- return ArtProfileRewritingApiReferenceStubberEventConsumer.attach(appView, empty());
+ return ProfileRewritingApiReferenceStubberEventConsumer.attach(appView, empty());
}
static EmptyApiReferenceStubberEventConsumer empty() {
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 99cb304..08b14b8 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -25,7 +25,7 @@
import com.android.tools.r8.dex.VirtualFile.ItemUseInfo;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.experimental.startup.StartupCompleteness;
-import com.android.tools.r8.experimental.startup.StartupOrder;
+import com.android.tools.r8.experimental.startup.StartupProfile;
import com.android.tools.r8.features.FeatureSplitConfiguration.DataResourceProvidersAndConsumer;
import com.android.tools.r8.graph.AppServices;
import com.android.tools.r8.graph.AppView;
@@ -241,13 +241,13 @@
// Retrieve the startup order for writing the app. In R8, the startup order is created
// up-front to guide optimizations through-out the compilation. In D8, the startup
// order is only used for writing the app, so we create it here for the first time.
- StartupOrder startupOrder =
+ StartupProfile startupProfile =
appView.appInfo().hasClassHierarchy()
- ? appView.appInfoWithClassHierarchy().getStartupOrder()
- : StartupOrder.createInitialStartupOrderForD8(appView);
+ ? appView.getStartupProfile()
+ : StartupProfile.createInitialStartupProfileForD8(appView);
distributor =
new VirtualFile.FillFilesDistributor(
- this, classes, options, executorService, startupOrder);
+ this, classes, options, executorService, startupProfile);
}
List<VirtualFile> virtualFiles = distributor.run();
diff --git a/src/main/java/com/android/tools/r8/dex/MixedSectionLayoutStrategy.java b/src/main/java/com/android/tools/r8/dex/MixedSectionLayoutStrategy.java
index 13a4a2c..60055c9 100644
--- a/src/main/java/com/android/tools/r8/dex/MixedSectionLayoutStrategy.java
+++ b/src/main/java/com/android/tools/r8/dex/MixedSectionLayoutStrategy.java
@@ -5,7 +5,7 @@
package com.android.tools.r8.dex;
import com.android.tools.r8.dex.FileWriter.MixedSectionOffsets;
-import com.android.tools.r8.experimental.startup.StartupOrder;
+import com.android.tools.r8.experimental.startup.StartupProfile;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationDirectory;
@@ -22,21 +22,21 @@
public static MixedSectionLayoutStrategy create(
AppView<?> appView, MixedSectionOffsets mixedSectionOffsets, VirtualFile virtualFile) {
- StartupOrder startupOrderForWriting;
- if (virtualFile.getStartupOrder().isEmpty()) {
- startupOrderForWriting = StartupOrder.empty();
+ StartupProfile startupProfileForWriting;
+ if (virtualFile.getStartupProfile().isEmpty()) {
+ startupProfileForWriting = StartupProfile.empty();
} else {
assert virtualFile.getId() == 0;
- startupOrderForWriting =
+ startupProfileForWriting =
appView.options().getStartupOptions().isStartupLayoutOptimizationsEnabled()
- ? virtualFile.getStartupOrder().toStartupOrderForWriting(appView)
- : StartupOrder.empty();
+ ? virtualFile.getStartupProfile().toStartupProfileForWriting(appView)
+ : StartupProfile.empty();
}
MixedSectionLayoutStrategy mixedSectionLayoutStrategy =
- startupOrderForWriting.isEmpty()
+ startupProfileForWriting.isEmpty()
? new DefaultMixedSectionLayoutStrategy(appView, mixedSectionOffsets)
: new StartupMixedSectionLayoutStrategy(
- appView, mixedSectionOffsets, startupOrderForWriting, virtualFile);
+ appView, mixedSectionOffsets, startupProfileForWriting, virtualFile);
return wrapForTesting(appView, mixedSectionLayoutStrategy, virtualFile);
}
diff --git a/src/main/java/com/android/tools/r8/dex/StartupMixedSectionLayoutStrategy.java b/src/main/java/com/android/tools/r8/dex/StartupMixedSectionLayoutStrategy.java
index 0833358..e848e3b 100644
--- a/src/main/java/com/android/tools/r8/dex/StartupMixedSectionLayoutStrategy.java
+++ b/src/main/java/com/android/tools/r8/dex/StartupMixedSectionLayoutStrategy.java
@@ -5,10 +5,10 @@
package com.android.tools.r8.dex;
import com.android.tools.r8.dex.FileWriter.MixedSectionOffsets;
-import com.android.tools.r8.experimental.startup.StartupOrder;
-import com.android.tools.r8.experimental.startup.profile.StartupClass;
-import com.android.tools.r8.experimental.startup.profile.StartupItem;
-import com.android.tools.r8.experimental.startup.profile.StartupMethod;
+import com.android.tools.r8.experimental.startup.StartupProfile;
+import com.android.tools.r8.experimental.startup.profile.StartupProfileClassRule;
+import com.android.tools.r8.experimental.startup.profile.StartupProfileMethodRule;
+import com.android.tools.r8.experimental.startup.profile.StartupProfileRule;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationDirectory;
@@ -36,7 +36,7 @@
public class StartupMixedSectionLayoutStrategy extends DefaultMixedSectionLayoutStrategy {
- private final StartupOrder startupOrderForWriting;
+ private final StartupProfile startupProfileForWriting;
private final LinkedHashSet<DexAnnotation> annotationLayout;
private final LinkedHashSet<DexAnnotationDirectory> annotationDirectoryLayout;
@@ -51,10 +51,10 @@
public StartupMixedSectionLayoutStrategy(
AppView<?> appView,
MixedSectionOffsets mixedSectionOffsets,
- StartupOrder startupOrderForWriting,
+ StartupProfile startupProfileForWriting,
VirtualFile virtualFile) {
super(appView, mixedSectionOffsets);
- this.startupOrderForWriting = startupOrderForWriting;
+ this.startupProfileForWriting = startupProfileForWriting;
// Initialize startup layouts.
this.annotationLayout = new LinkedHashSet<>(mixedSectionOffsets.getAnnotations().size());
@@ -82,23 +82,18 @@
virtualFile.classes().size());
LensCodeRewriterUtils rewriter = new LensCodeRewriterUtils(appView, true);
StartupIndexedItemCollection indexedItemCollection = new StartupIndexedItemCollection();
- for (StartupItem startupItem : startupOrderForWriting.getItems()) {
+ for (StartupProfileRule startupItem : startupProfileForWriting.getRules()) {
startupItem.accept(
startupClass ->
collectStartupItems(startupClass, indexedItemCollection, virtualFileDefinitions),
startupMethod ->
collectStartupItems(
- startupMethod, indexedItemCollection, virtualFileDefinitions, rewriter),
- syntheticStartupMethod -> {
- // All synthetic startup items should be removed after calling
- // StartupOrder#toStartupOrderForWriting.
- assert false;
- });
+ startupMethod, indexedItemCollection, virtualFileDefinitions, rewriter));
}
}
private void collectStartupItems(
- StartupClass startupClass,
+ StartupProfileClassRule startupClass,
StartupIndexedItemCollection indexedItemCollection,
Map<DexType, DexProgramClass> virtualFileDefinitions) {
DexProgramClass definition = virtualFileDefinitions.get(startupClass.getReference());
@@ -121,7 +116,7 @@
}
private void collectStartupItems(
- StartupMethod startupMethod,
+ StartupProfileMethodRule startupMethod,
StartupIndexedItemCollection indexedItemCollection,
Map<DexType, DexProgramClass> virtualFileDefinitions,
LensCodeRewriterUtils rewriter) {
diff --git a/src/main/java/com/android/tools/r8/dex/VirtualFile.java b/src/main/java/com/android/tools/r8/dex/VirtualFile.java
index 692192d..270fcf2 100644
--- a/src/main/java/com/android/tools/r8/dex/VirtualFile.java
+++ b/src/main/java/com/android/tools/r8/dex/VirtualFile.java
@@ -9,7 +9,7 @@
import com.android.tools.r8.debuginfo.DebugRepresentation;
import com.android.tools.r8.errors.DexFileOverflowDiagnostic;
import com.android.tools.r8.errors.InternalCompilerError;
-import com.android.tools.r8.experimental.startup.StartupOrder;
+import com.android.tools.r8.experimental.startup.StartupProfile;
import com.android.tools.r8.features.ClassToFeatureSplitMap;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
@@ -30,7 +30,6 @@
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.MainDexInfo;
-import com.android.tools.r8.synthesis.SyntheticItems;
import com.android.tools.r8.synthesis.SyntheticNaming;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.FileUtils;
@@ -69,28 +68,28 @@
public final VirtualFileIndexedItemCollection indexedItems;
private final IndexedItemTransaction transaction;
private final FeatureSplit featureSplit;
- private final StartupOrder startupOrder;
+ private final StartupProfile startupProfile;
private final DexString primaryClassDescriptor;
private final DexString primaryClassSynthesizingContextDescriptor;
private DebugRepresentation debugRepresentation;
VirtualFile(int id, AppView<?> appView) {
- this(id, appView, null, null, StartupOrder.empty());
+ this(id, appView, null, null, StartupProfile.empty());
}
VirtualFile(
int id,
AppView<?> appView,
FeatureSplit featureSplit) {
- this(id, appView, null, featureSplit, StartupOrder.empty());
+ this(id, appView, null, featureSplit, StartupProfile.empty());
}
private VirtualFile(
int id,
AppView<?> appView,
DexProgramClass primaryClass) {
- this(id, appView, primaryClass, null, StartupOrder.empty());
+ this(id, appView, primaryClass, null, StartupProfile.empty());
}
private VirtualFile(
@@ -98,12 +97,12 @@
AppView<?> appView,
DexProgramClass primaryClass,
FeatureSplit featureSplit,
- StartupOrder startupOrder) {
+ StartupProfile startupProfile) {
this.id = id;
this.indexedItems = new VirtualFileIndexedItemCollection(appView);
this.transaction = new IndexedItemTransaction(indexedItems, appView);
this.featureSplit = featureSplit;
- this.startupOrder = startupOrder;
+ this.startupProfile = startupProfile;
if (primaryClass == null) {
primaryClassDescriptor = null;
primaryClassSynthesizingContextDescriptor = null;
@@ -138,8 +137,8 @@
return featureSplit;
}
- public StartupOrder getStartupOrder() {
- return startupOrder;
+ public StartupProfile getStartupProfile() {
+ return startupProfile;
}
public String getPrimaryClassDescriptor() {
@@ -380,14 +379,14 @@
ApplicationWriter writer,
Collection<DexProgramClass> classes,
InternalOptions options,
- StartupOrder startupOrder) {
+ StartupProfile startupProfile) {
super(writer);
this.options = options;
this.classes = SetUtils.newIdentityHashSet(classes);
// Create the primary dex file. The distribution will add more if needed. We use the startup
// order (if any) to guide the layout of the primary dex file.
- mainDexFile = new VirtualFile(0, appView, null, null, startupOrder);
+ mainDexFile = new VirtualFile(0, appView, null, null, startupProfile);
assert virtualFiles.isEmpty();
virtualFiles.add(mainDexFile);
addMarkers(mainDexFile);
@@ -450,7 +449,8 @@
}
protected void addFeatureSplitFiles(
- Map<FeatureSplit, Set<DexProgramClass>> featureSplitClasses, StartupOrder startupOrder) {
+ Map<FeatureSplit, Set<DexProgramClass>> featureSplitClasses,
+ StartupProfile startupProfile) {
if (featureSplitClasses.isEmpty()) {
return;
}
@@ -473,7 +473,7 @@
appView,
featureSplitSetEntry.getValue(),
originalNames,
- startupOrder,
+ startupProfile,
nextFileId)
.run();
}
@@ -483,17 +483,17 @@
public static class FillFilesDistributor extends DistributorBase {
private final ExecutorService executorService;
- private final StartupOrder startupOrder;
+ private final StartupProfile startupProfile;
FillFilesDistributor(
ApplicationWriter writer,
Collection<DexProgramClass> classes,
InternalOptions options,
ExecutorService executorService,
- StartupOrder startupOrder) {
- super(writer, classes, options, startupOrder);
+ StartupProfile startupProfile) {
+ super(writer, classes, options, startupProfile);
this.executorService = executorService;
- this.startupOrder = startupOrder;
+ this.startupProfile = startupProfile;
}
@Override
@@ -539,11 +539,11 @@
appView,
classes,
originalNames,
- startupOrder,
+ startupProfile,
nextFileId)
.run();
}
- addFeatureSplitFiles(featureSplitClasses, startupOrder);
+ addFeatureSplitFiles(featureSplitClasses, startupProfile);
assert totalClassNumber == virtualFiles.stream().mapToInt(dex -> dex.classes().size()).sum();
return virtualFiles;
@@ -553,7 +553,7 @@
public static class MonoDexDistributor extends DistributorBase {
MonoDexDistributor(
ApplicationWriter writer, Collection<DexProgramClass> classes, InternalOptions options) {
- super(writer, classes, options, StartupOrder.empty());
+ super(writer, classes, options, StartupProfile.empty());
}
@Override
@@ -569,7 +569,7 @@
if (options.featureSplitConfiguration != null) {
if (!featureSplitClasses.isEmpty()) {
// TODO(141334414): Figure out if we allow multidex in features even when mono-dexing
- addFeatureSplitFiles(featureSplitClasses, StartupOrder.empty());
+ addFeatureSplitFiles(featureSplitClasses, StartupProfile.empty());
}
}
return virtualFiles;
@@ -1279,12 +1279,11 @@
public static PackageSplitClassPartioning create(
Collection<DexProgramClass> classes,
Map<DexProgramClass, String> originalNames,
- StartupOrder startupOrder,
- SyntheticItems syntheticItems) {
+ StartupProfile startupProfile) {
return create(
classes,
getClassesByPackageComparator(originalNames),
- getStartupClassPredicate(startupOrder, syntheticItems));
+ getStartupClassPredicate(startupProfile));
}
private static PackageSplitClassPartioning create(
@@ -1335,8 +1334,8 @@
}
private static Predicate<DexProgramClass> getStartupClassPredicate(
- StartupOrder startupOrder, SyntheticItems syntheticItems) {
- return clazz -> startupOrder.contains(clazz.getType(), syntheticItems);
+ StartupProfile startupProfile) {
+ return clazz -> startupProfile.containsClassRule(clazz.getType());
}
public List<DexProgramClass> getStartupClasses() {
@@ -1372,11 +1371,10 @@
AppView<?> appView,
Collection<DexProgramClass> classes,
Map<DexProgramClass, String> originalNames,
- StartupOrder startupOrder,
+ StartupProfile startupProfile,
IntBox nextFileId) {
this.classPartioning =
- PackageSplitClassPartioning.create(
- classes, originalNames, startupOrder, appView.getSyntheticItems());
+ PackageSplitClassPartioning.create(classes, originalNames, startupProfile);
this.originalNames = originalNames;
this.dexItemFactory = appView.dexItemFactory();
this.options = appView.options();
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/EmptyStartupOrder.java b/src/main/java/com/android/tools/r8/experimental/startup/EmptyStartupOrder.java
deleted file mode 100644
index 032e0b8..0000000
--- a/src/main/java/com/android/tools/r8/experimental/startup/EmptyStartupOrder.java
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2022, 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.experimental.startup;
-
-import com.android.tools.r8.experimental.startup.profile.StartupItem;
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLens;
-import com.android.tools.r8.graph.PrunedItems;
-import com.android.tools.r8.synthesis.SyntheticItems;
-import java.util.Collection;
-import java.util.Collections;
-
-public class EmptyStartupOrder extends StartupOrder {
-
- EmptyStartupOrder() {}
-
- @Override
- public boolean contains(DexMethod method, SyntheticItems syntheticItems) {
- return false;
- }
-
- @Override
- public boolean contains(DexType type, SyntheticItems syntheticItems) {
- return false;
- }
-
- @Override
- public Collection<StartupItem> getItems() {
- return Collections.emptyList();
- }
-
- @Override
- public boolean isEmpty() {
- return true;
- }
-
- @Override
- public EmptyStartupOrder rewrittenWithLens(GraphLens graphLens) {
- return this;
- }
-
- @Override
- public StartupOrder toStartupOrderForWriting(AppView<?> appView) {
- return this;
- }
-
- @Override
- public EmptyStartupOrder withoutPrunedItems(
- PrunedItems prunedItems, SyntheticItems syntheticItems) {
- return this;
- }
-}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/EmptyStartupProfile.java b/src/main/java/com/android/tools/r8/experimental/startup/EmptyStartupProfile.java
new file mode 100644
index 0000000..7f2a248
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/experimental/startup/EmptyStartupProfile.java
@@ -0,0 +1,81 @@
+// Copyright (c) 2022, 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.experimental.startup;
+
+import com.android.tools.r8.experimental.startup.profile.StartupProfileClassRule;
+import com.android.tools.r8.experimental.startup.profile.StartupProfileMethodRule;
+import com.android.tools.r8.experimental.startup.profile.StartupProfileRule;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.PrunedItems;
+import com.android.tools.r8.synthesis.SyntheticItems;
+import com.android.tools.r8.utils.ThrowingConsumer;
+import java.util.Collection;
+import java.util.Collections;
+
+public class EmptyStartupProfile extends StartupProfile {
+
+ EmptyStartupProfile() {}
+
+ @Override
+ public boolean containsClassRule(DexType type) {
+ return false;
+ }
+
+ @Override
+ public boolean containsMethodRule(DexMethod method) {
+ return false;
+ }
+
+ @Override
+ public <E1 extends Exception, E2 extends Exception> void forEachRule(
+ ThrowingConsumer<StartupProfileClassRule, E1> classRuleConsumer,
+ ThrowingConsumer<StartupProfileMethodRule, E2> methodRuleConsumer) {
+ // Intentionally empty.
+ }
+
+ @Override
+ public StartupProfileClassRule getClassRule(DexType type) {
+ return null;
+ }
+
+ @Override
+ public StartupProfileMethodRule getMethodRule(DexMethod method) {
+ return null;
+ }
+
+ @Override
+ public Collection<StartupProfileRule> getRules() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return true;
+ }
+
+ @Override
+ public EmptyStartupProfile rewrittenWithLens(GraphLens graphLens) {
+ return this;
+ }
+
+ @Override
+ public EmptyStartupProfile toStartupProfileForWriting(AppView<?> appView) {
+ return this;
+ }
+
+ @Override
+ public StartupProfile withoutMissingItems(AppView<?> appView) {
+ return this;
+ }
+
+ @Override
+ public EmptyStartupProfile withoutPrunedItems(
+ PrunedItems prunedItems, SyntheticItems syntheticItems) {
+ return this;
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/NonEmptyStartupOrder.java b/src/main/java/com/android/tools/r8/experimental/startup/NonEmptyStartupOrder.java
deleted file mode 100644
index 25188c0..0000000
--- a/src/main/java/com/android/tools/r8/experimental/startup/NonEmptyStartupOrder.java
+++ /dev/null
@@ -1,266 +0,0 @@
-// Copyright (c) 2022, 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.experimental.startup;
-
-import com.android.tools.r8.experimental.startup.profile.StartupClass;
-import com.android.tools.r8.experimental.startup.profile.StartupItem;
-import com.android.tools.r8.experimental.startup.profile.StartupMethod;
-import com.android.tools.r8.experimental.startup.profile.SyntheticStartupMethod;
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexApplication;
-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.GraphLens;
-import com.android.tools.r8.graph.PrunedItems;
-import com.android.tools.r8.synthesis.SyntheticItems;
-import com.android.tools.r8.utils.LazyBox;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-public class NonEmptyStartupOrder extends StartupOrder {
-
- private final LinkedHashSet<StartupItem> startupItems;
-
- // Sets to allow efficient querying without boxing.
- private final Set<DexType> nonSyntheticStartupClasses = Sets.newIdentityHashSet();
- private final Set<DexType> syntheticStartupClasses = Sets.newIdentityHashSet();
-
- private final Set<DexMethod> nonSyntheticStartupMethods = Sets.newIdentityHashSet();
-
- NonEmptyStartupOrder(LinkedHashSet<StartupItem> startupItems) {
- assert !startupItems.isEmpty();
- this.startupItems = startupItems;
- for (StartupItem startupItem : startupItems) {
- startupItem.accept(
- startupClass -> nonSyntheticStartupClasses.add(startupClass.getReference()),
- startupMethod -> {
- nonSyntheticStartupClasses.add(startupMethod.getReference().getHolderType());
- nonSyntheticStartupMethods.add(startupMethod.getReference());
- },
- syntheticStartupMethod ->
- syntheticStartupClasses.add(syntheticStartupMethod.getSyntheticContextType()));
- }
- }
-
- @Override
- public boolean contains(DexMethod method, SyntheticItems syntheticItems) {
- if (nonSyntheticStartupMethods.contains(method)) {
- return true;
- }
- if (syntheticItems.isSyntheticClass(method.getHolderType())) {
- return containsSyntheticClass(method.getHolderType(), syntheticItems);
- }
- return false;
- }
-
- @Override
- public boolean contains(DexType type, SyntheticItems syntheticItems) {
- return syntheticItems.isSyntheticClass(type)
- ? containsSyntheticClass(type, syntheticItems)
- : containsNonSyntheticClass(type);
- }
-
- private boolean containsNonSyntheticClass(DexType type) {
- return nonSyntheticStartupClasses.contains(type);
- }
-
- private boolean containsSyntheticClass(DexType type, SyntheticItems syntheticItems) {
- assert syntheticItems.isSyntheticClass(type);
- return Iterables.any(
- syntheticItems.getSynthesizingContextTypes(type),
- this::containsSyntheticClassesSynthesizedFrom);
- }
-
- private boolean containsSyntheticClassesSynthesizedFrom(DexType synthesizingContextType) {
- return syntheticStartupClasses.contains(synthesizingContextType);
- }
-
- @Override
- public Collection<StartupItem> getItems() {
- return startupItems;
- }
-
- @Override
- public boolean isEmpty() {
- return false;
- }
-
- @Override
- public StartupOrder rewrittenWithLens(GraphLens graphLens) {
- LinkedHashSet<StartupItem> rewrittenStartupItems = new LinkedHashSet<>(startupItems.size());
- for (StartupItem startupItem : startupItems) {
- // TODO(b/238173796): This should account for one-to-many mappings. e.g., when a bridge is
- // created.
- startupItem.apply(
- startupClass ->
- rewrittenStartupItems.add(
- StartupClass.builder()
- .setClassReference(graphLens.lookupType(startupClass.getReference()))
- .build()),
- startupMethod ->
- rewrittenStartupItems.add(
- StartupMethod.builder()
- .setMethodReference(
- graphLens.getRenamedMethodSignature(startupMethod.getReference()))
- .build()),
- syntheticStartupMethod ->
- rewrittenStartupItems.add(
- SyntheticStartupMethod.builder()
- .setSyntheticContextReference(
- graphLens.lookupType(syntheticStartupMethod.getSyntheticContextType()))
- .build()));
- }
- return createNonEmpty(rewrittenStartupItems);
- }
-
- /**
- * This is called to process the startup order before computing the startup layouts.
- *
- * <p>This processing makes two key changes to the startup order:
- *
- * <ul>
- * <li>Synthetic startup classes on the form "SLcom/example/SyntheticContext;" represents that
- * any method of any synthetic class that have been synthesized from SyntheticContext has
- * been executed. This pass removes such entries from the startup order, and replaces them
- * by all the methods from all of the synthetics that have been synthesized from
- * SyntheticContext.
- * <li>Moreover, this inserts a StartupClass event for all supertypes of a given class next to
- * the class in the startup order. This ensures that the classes from the super hierarchy
- * will be laid out close to their subclasses, at the point where the subclasses are used
- * during startup.
- * <p>Note that this normally follows from the trace already, except that the class
- * initializers of interfaces are not executed when a subclass is used.
- * </ul>
- */
- @Override
- public StartupOrder toStartupOrderForWriting(AppView<?> appView) {
- LinkedHashSet<StartupItem> rewrittenStartupItems = new LinkedHashSet<>(startupItems.size());
- Map<DexType, List<DexProgramClass>> syntheticContextsToSyntheticClasses =
- appView.getSyntheticItems().computeSyntheticContextsToSyntheticClasses(appView);
- for (StartupItem startupItem : startupItems) {
- addStartupItem(
- startupItem, rewrittenStartupItems, syntheticContextsToSyntheticClasses, appView);
- }
- assert rewrittenStartupItems.stream().noneMatch(StartupItem::isSyntheticStartupMethod);
- return createNonEmpty(rewrittenStartupItems);
- }
-
- private static void addStartupItem(
- StartupItem startupItem,
- LinkedHashSet<StartupItem> rewrittenStartupItems,
- Map<DexType, List<DexProgramClass>> syntheticContextsToSyntheticClasses,
- AppView<?> appView) {
- if (startupItem.isSyntheticStartupMethod()) {
- SyntheticStartupMethod syntheticStartupMethod = startupItem.asSyntheticStartupMethod();
- List<DexProgramClass> syntheticClassesForContext =
- syntheticContextsToSyntheticClasses.getOrDefault(
- syntheticStartupMethod.getSyntheticContextType(), Collections.emptyList());
- for (DexProgramClass clazz : syntheticClassesForContext) {
- addClassAndParentClasses(clazz, rewrittenStartupItems, appView);
- addAllMethods(clazz, rewrittenStartupItems);
- }
- } else {
- if (startupItem.isStartupClass()) {
- addClassAndParentClasses(
- startupItem.asStartupClass().getReference(), rewrittenStartupItems, appView);
- } else {
- rewrittenStartupItems.add(startupItem);
- }
- }
- }
-
- private static boolean addClass(
- DexProgramClass clazz, LinkedHashSet<StartupItem> rewrittenStartupItems) {
- return rewrittenStartupItems.add(
- StartupClass.builder().setClassReference(clazz.getType()).build());
- }
-
- private static void addClassAndParentClasses(
- DexType type, LinkedHashSet<StartupItem> rewrittenStartupItems, AppView<?> appView) {
- DexProgramClass definition = appView.app().programDefinitionFor(type);
- if (definition != null) {
- addClassAndParentClasses(definition, rewrittenStartupItems, appView);
- }
- }
-
- private static void addClassAndParentClasses(
- DexProgramClass clazz, LinkedHashSet<StartupItem> rewrittenStartupItems, AppView<?> appView) {
- if (addClass(clazz, rewrittenStartupItems)) {
- addParentClasses(clazz, rewrittenStartupItems, appView);
- }
- }
-
- private static void addParentClasses(
- DexProgramClass clazz, LinkedHashSet<StartupItem> rewrittenStartupItems, AppView<?> appView) {
- clazz.forEachImmediateSupertype(
- supertype -> addClassAndParentClasses(supertype, rewrittenStartupItems, appView));
- }
-
- private static void addAllMethods(
- DexProgramClass clazz, LinkedHashSet<StartupItem> rewrittenStartupItems) {
- clazz.forEachProgramMethod(
- method ->
- rewrittenStartupItems.add(
- StartupMethod.builder().setMethodReference(method.getReference()).build()));
- }
-
- @Override
- public StartupOrder withoutPrunedItems(PrunedItems prunedItems, SyntheticItems syntheticItems) {
- LinkedHashSet<StartupItem> rewrittenStartupItems = new LinkedHashSet<>(startupItems.size());
- LazyBox<Set<DexType>> contextsOfLiveSynthetics =
- new LazyBox<>(
- () -> computeContextsOfLiveSynthetics(prunedItems.getPrunedApp(), syntheticItems));
- for (StartupItem startupItem : startupItems) {
- // Only prune non-synthetic classes, since the pruning of a class does not imply that all
- // classes synthesized from it have been pruned.
- startupItem.accept(
- startupClass -> {
- if (!prunedItems.isRemoved(startupClass.getReference())) {
- rewrittenStartupItems.add(startupItem);
- }
- },
- startupMethod -> {
- if (!prunedItems.isRemoved(startupMethod.getReference())) {
- rewrittenStartupItems.add(startupItem);
- }
- },
- syntheticStartupMethod -> {
- if (contextsOfLiveSynthetics
- .computeIfAbsent()
- .contains(syntheticStartupMethod.getSyntheticContextType())) {
- rewrittenStartupItems.add(syntheticStartupMethod);
- }
- });
- }
- return createNonEmpty(rewrittenStartupItems);
- }
-
- private Set<DexType> computeContextsOfLiveSynthetics(
- DexApplication app, SyntheticItems syntheticItems) {
- Set<DexType> contextsOfLiveSynthetics = Sets.newIdentityHashSet();
- for (DexProgramClass clazz : app.classes()) {
- if (syntheticItems.isSyntheticClass(clazz)) {
- contextsOfLiveSynthetics.addAll(
- syntheticItems.getSynthesizingContextTypes(clazz.getType()));
- }
- }
- return contextsOfLiveSynthetics;
- }
-
- private StartupOrder createNonEmpty(LinkedHashSet<StartupItem> startupItems) {
- if (startupItems.isEmpty()) {
- assert false;
- return empty();
- }
- return new NonEmptyStartupOrder(startupItems);
- }
-}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/StartupCompleteness.java b/src/main/java/com/android/tools/r8/experimental/startup/StartupCompleteness.java
index 6ef463d..e3699f7 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/StartupCompleteness.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/StartupCompleteness.java
@@ -4,40 +4,32 @@
package com.android.tools.r8.experimental.startup;
-import com.android.tools.r8.experimental.startup.profile.StartupItem;
+import com.android.tools.r8.experimental.startup.profile.StartupProfileRule;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexReference;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.ThrowNullCode;
-import com.android.tools.r8.profile.art.ArtProfileBuilderUtils.SyntheticToSyntheticContextGeneralization;
+import com.android.tools.r8.startup.diagnostic.MissingStartupProfileItemsDiagnostic;
import com.android.tools.r8.utils.InternalOptions;
import com.google.common.collect.Sets;
import it.unimi.dsi.fastutil.ints.Int2ReferenceMaps;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
import java.util.Set;
public class StartupCompleteness {
private final AppView<?> appView;
- private final StartupOrder startupOrder;
+ private final StartupProfile startupProfile;
private StartupCompleteness(AppView<?> appView) {
- SyntheticToSyntheticContextGeneralization syntheticToSyntheticContextGeneralization =
- appView.enableWholeProgramOptimizations()
- ? SyntheticToSyntheticContextGeneralization.createForR8()
- : SyntheticToSyntheticContextGeneralization.createForD8();
this.appView = appView;
- this.startupOrder =
+ this.startupProfile =
appView.hasClassHierarchy()
- ? appView.appInfoWithClassHierarchy().getStartupOrder()
- : StartupOrder.createInitialStartupOrder(
- appView.options(), null, syntheticToSyntheticContextGeneralization);
+ ? appView.getStartupProfile()
+ : StartupProfile.createInitialStartupProfile(
+ appView.options(), origin -> MissingStartupProfileItemsDiagnostic.Builder.nop());
}
/**
@@ -82,22 +74,10 @@
private Set<DexReference> computeStartupItems() {
Set<DexReference> startupItems = Sets.newIdentityHashSet();
- Map<DexType, List<DexProgramClass>> syntheticContextsToSyntheticClasses =
- appView.getSyntheticItems().computeSyntheticContextsToSyntheticClasses(appView);
- for (StartupItem startupItem : startupOrder.getItems()) {
+ for (StartupProfileRule startupItem : startupProfile.getRules()) {
startupItem.accept(
startupClass -> startupItems.add(startupClass.getReference()),
- startupMethod -> startupItems.add(startupMethod.getReference()),
- syntheticStartupMethod -> {
- List<DexProgramClass> syntheticClasses =
- syntheticContextsToSyntheticClasses.getOrDefault(
- syntheticStartupMethod.getSyntheticContextType(), Collections.emptyList());
- for (DexProgramClass syntheticClass : syntheticClasses) {
- startupItems.add(syntheticClass.getType());
- syntheticClass.forEachProgramMethod(
- method -> startupItems.add(method.getReference()));
- }
- });
+ startupMethod -> startupItems.add(startupMethod.getReference()));
}
return startupItems;
}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/StartupOrder.java b/src/main/java/com/android/tools/r8/experimental/startup/StartupOrder.java
deleted file mode 100644
index b369a94..0000000
--- a/src/main/java/com/android/tools/r8/experimental/startup/StartupOrder.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2022, 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.experimental.startup;
-
-import com.android.tools.r8.experimental.startup.profile.StartupItem;
-import com.android.tools.r8.experimental.startup.profile.StartupProfile;
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexApplication;
-import com.android.tools.r8.graph.DexDefinitionSupplier;
-import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLens;
-import com.android.tools.r8.graph.PrunedItems;
-import com.android.tools.r8.profile.art.ArtProfileBuilderUtils.SyntheticToSyntheticContextGeneralization;
-import com.android.tools.r8.synthesis.SyntheticItems;
-import com.android.tools.r8.utils.InternalOptions;
-import java.util.Collection;
-import java.util.LinkedHashSet;
-
-public abstract class StartupOrder {
-
- StartupOrder() {}
-
- public static StartupOrder createInitialStartupOrder(
- InternalOptions options,
- DexDefinitionSupplier definitions,
- SyntheticToSyntheticContextGeneralization syntheticToSyntheticContextGeneralization) {
- StartupProfile startupProfile =
- StartupProfile.parseStartupProfile(
- options, definitions, syntheticToSyntheticContextGeneralization);
- if (startupProfile == null || startupProfile.getStartupItems().isEmpty()) {
- return empty();
- }
- return new NonEmptyStartupOrder(new LinkedHashSet<>(startupProfile.getStartupItems()));
- }
-
- public static StartupOrder createInitialStartupOrderForD8(AppView<?> appView) {
- return createInitialStartupOrder(
- appView.options(), appView, SyntheticToSyntheticContextGeneralization.createForD8());
- }
-
- public static StartupOrder createInitialStartupOrderForR8(DexApplication application) {
- return createInitialStartupOrder(
- application.options, application, SyntheticToSyntheticContextGeneralization.createForR8());
- }
-
- public static StartupOrder empty() {
- return new EmptyStartupOrder();
- }
-
- public abstract boolean contains(DexMethod method, SyntheticItems syntheticItems);
-
- public abstract boolean contains(DexType type, SyntheticItems syntheticItems);
-
- public abstract Collection<StartupItem> getItems();
-
- public abstract boolean isEmpty();
-
- public abstract StartupOrder rewrittenWithLens(GraphLens graphLens);
-
- public abstract StartupOrder toStartupOrderForWriting(AppView<?> appView);
-
- public abstract StartupOrder withoutPrunedItems(
- PrunedItems prunedItems, SyntheticItems syntheticItems);
-}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/StartupProfile.java b/src/main/java/com/android/tools/r8/experimental/startup/StartupProfile.java
new file mode 100644
index 0000000..b85dbaa
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/experimental/startup/StartupProfile.java
@@ -0,0 +1,271 @@
+// Copyright (c) 2022, 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.experimental.startup;
+
+import com.android.tools.r8.TextInputStream;
+import com.android.tools.r8.experimental.startup.profile.NonEmptyStartupProfile;
+import com.android.tools.r8.experimental.startup.profile.StartupProfileClassRule;
+import com.android.tools.r8.experimental.startup.profile.StartupProfileMethodRule;
+import com.android.tools.r8.experimental.startup.profile.StartupProfileRule;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexApplication;
+import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexReference;
+import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.PrunedItems;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.profile.AbstractProfile;
+import com.android.tools.r8.profile.AbstractProfileRule;
+import com.android.tools.r8.profile.art.ArtProfileBuilderUtils;
+import com.android.tools.r8.profile.art.HumanReadableArtProfileParser;
+import com.android.tools.r8.profile.art.HumanReadableArtProfileParserBuilder;
+import com.android.tools.r8.startup.StartupClassBuilder;
+import com.android.tools.r8.startup.StartupMethodBuilder;
+import com.android.tools.r8.startup.StartupProfileBuilder;
+import com.android.tools.r8.startup.StartupProfileProvider;
+import com.android.tools.r8.startup.diagnostic.MissingStartupProfileItemsDiagnostic;
+import com.android.tools.r8.synthesis.SyntheticItems;
+import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.Reporter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+public abstract class StartupProfile
+ implements AbstractProfile<StartupProfileClassRule, StartupProfileMethodRule> {
+
+ protected StartupProfile() {}
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static Builder builderWithCapacity(int capacity) {
+ return new Builder(capacity);
+ }
+
+ public static Builder builder(
+ InternalOptions options,
+ MissingStartupProfileItemsDiagnostic.Builder missingItemsDiagnosticBuilder,
+ StartupProfileProvider startupProfileProvider) {
+ return new Builder(options, missingItemsDiagnosticBuilder, startupProfileProvider);
+ }
+
+ public static StartupProfile createInitialStartupProfile(
+ InternalOptions options,
+ Function<Origin, MissingStartupProfileItemsDiagnostic.Builder>
+ missingItemsDiagnosticBuilderFactory) {
+ StartupProfile startupProfile =
+ StartupProfile.parseStartupProfile(options, missingItemsDiagnosticBuilderFactory);
+ return startupProfile != null ? startupProfile : empty();
+ }
+
+ public static StartupProfile createInitialStartupProfileForD8(AppView<?> appView) {
+ return createInitialStartupProfile(
+ appView.options(),
+ origin -> new MissingStartupProfileItemsDiagnostic.Builder(appView).setOrigin(origin));
+ }
+
+ public static StartupProfile createInitialStartupProfileForR8(DexApplication application) {
+ // In R8 we expect a startup profile that matches the input app. Since profiles gathered from
+ // running on ART will include synthetics, and these synthetics are not in the input app, we do
+ // not raise warnings if some rules in the profile do not match anything.
+ return createInitialStartupProfile(
+ application.options, origin -> MissingStartupProfileItemsDiagnostic.Builder.nop());
+ }
+
+ public static StartupProfile empty() {
+ return new EmptyStartupProfile();
+ }
+
+ public static StartupProfile merge(Collection<StartupProfile> startupProfiles) {
+ Builder builder = builder();
+ for (StartupProfile startupProfile : startupProfiles) {
+ startupProfile.getRules().forEach(builder::addStartupItem);
+ }
+ return builder.build();
+ }
+
+ /**
+ * Parses the supplied startup configuration, if any. The startup configuration is a list of class
+ * and method descriptors.
+ *
+ * <p>Example:
+ *
+ * <pre>
+ * Landroidx/compose/runtime/ComposerImpl;->updateValue(Ljava/lang/Object;)V
+ * Landroidx/compose/runtime/ComposerImpl;->updatedNodeCount(I)I
+ * Landroidx/compose/runtime/ComposerImpl;->validateNodeExpected()V
+ * Landroidx/compose/runtime/CompositionImpl;->applyChanges()V
+ * Landroidx/compose/runtime/ComposerKt;->findLocation(Ljava/util/List;I)I
+ * Landroidx/compose/runtime/ComposerImpl;
+ * </pre>
+ */
+ public static StartupProfile parseStartupProfile(
+ InternalOptions options,
+ Function<Origin, MissingStartupProfileItemsDiagnostic.Builder>
+ missingItemsDiagnosticBuilderFactory) {
+ if (!options.getStartupOptions().hasStartupProfileProviders()) {
+ return null;
+ }
+ Collection<StartupProfileProvider> startupProfileProviders =
+ options.getStartupOptions().getStartupProfileProviders();
+ List<StartupProfile> startupProfiles = new ArrayList<>(startupProfileProviders.size());
+ for (StartupProfileProvider startupProfileProvider : startupProfileProviders) {
+ MissingStartupProfileItemsDiagnostic.Builder missingItemsDiagnosticBuilder =
+ missingItemsDiagnosticBuilderFactory.apply(startupProfileProvider.getOrigin());
+ StartupProfile.Builder startupProfileBuilder =
+ StartupProfile.builder(options, missingItemsDiagnosticBuilder, startupProfileProvider);
+ startupProfileProvider.getStartupProfile(startupProfileBuilder);
+ startupProfiles.add(startupProfileBuilder.build());
+ if (missingItemsDiagnosticBuilder.hasMissingStartupItems()) {
+ options.reporter.warning(missingItemsDiagnosticBuilder.build());
+ }
+ }
+ return StartupProfile.merge(startupProfiles);
+ }
+
+ public abstract Collection<StartupProfileRule> getRules();
+
+ public abstract boolean isEmpty();
+
+ public abstract StartupProfile rewrittenWithLens(GraphLens graphLens);
+
+ public abstract StartupProfile toStartupProfileForWriting(AppView<?> appView);
+
+ public abstract StartupProfile withoutMissingItems(AppView<?> appView);
+
+ public abstract StartupProfile withoutPrunedItems(
+ PrunedItems prunedItems, SyntheticItems syntheticItems);
+
+ public static class Builder
+ implements AbstractProfile.Builder<
+ StartupProfileClassRule, StartupProfileMethodRule, StartupProfile, Builder>,
+ StartupProfileBuilder {
+
+ private final DexItemFactory dexItemFactory;
+ private final MissingStartupProfileItemsDiagnostic.Builder missingItemsDiagnosticBuilder;
+ private Reporter reporter;
+ private final StartupProfileProvider startupProfileProvider;
+
+ private final LinkedHashMap<DexReference, StartupProfileRule> startupItems;
+
+ Builder() {
+ this.dexItemFactory = null;
+ this.missingItemsDiagnosticBuilder = null;
+ this.reporter = null;
+ this.startupItems = new LinkedHashMap<>();
+ this.startupProfileProvider = null;
+ }
+
+ Builder(int capacity) {
+ this.dexItemFactory = null;
+ this.missingItemsDiagnosticBuilder = null;
+ this.reporter = null;
+ this.startupItems = new LinkedHashMap<>(capacity);
+ this.startupProfileProvider = null;
+ }
+
+ Builder(
+ InternalOptions options,
+ MissingStartupProfileItemsDiagnostic.Builder missingItemsDiagnosticBuilder,
+ StartupProfileProvider startupProfileProvider) {
+ this.dexItemFactory = options.dexItemFactory();
+ this.missingItemsDiagnosticBuilder = missingItemsDiagnosticBuilder;
+ this.reporter = options.reporter;
+ this.startupItems = new LinkedHashMap<>();
+ this.startupProfileProvider = startupProfileProvider;
+ }
+
+ @Override
+ public Builder addRule(AbstractProfileRule rule) {
+ return addStartupItem(rule.asStartupProfileRule());
+ }
+
+ @Override
+ public Builder addClassRule(StartupProfileClassRule classRule) {
+ return addStartupItem(classRule);
+ }
+
+ @Override
+ public Builder addMethodRule(StartupProfileMethodRule methodRule) {
+ return addStartupItem(methodRule);
+ }
+
+ @Override
+ public Builder addStartupClass(Consumer<StartupClassBuilder> startupClassBuilderConsumer) {
+ StartupProfileClassRule.Builder startupClassBuilder =
+ StartupProfileClassRule.builder(dexItemFactory);
+ startupClassBuilderConsumer.accept(startupClassBuilder);
+ StartupProfileClassRule startupClass = startupClassBuilder.build();
+ if (missingItemsDiagnosticBuilder.registerStartupClass(startupClass)) {
+ return this;
+ }
+ return addStartupItem(startupClass);
+ }
+
+ @Override
+ public Builder addStartupMethod(Consumer<StartupMethodBuilder> startupMethodBuilderConsumer) {
+ StartupProfileMethodRule.Builder startupMethodBuilder =
+ StartupProfileMethodRule.builder(dexItemFactory);
+ startupMethodBuilderConsumer.accept(startupMethodBuilder);
+ StartupProfileMethodRule startupMethod = startupMethodBuilder.build();
+ if (missingItemsDiagnosticBuilder.registerStartupMethod(startupMethod)) {
+ return this;
+ }
+ return addStartupItem(startupMethod);
+ }
+
+ @Override
+ public StartupProfileBuilder addHumanReadableArtProfile(
+ TextInputStream textInputStream,
+ Consumer<HumanReadableArtProfileParserBuilder> parserBuilderConsumer) {
+ HumanReadableArtProfileParser.Builder parserBuilder =
+ HumanReadableArtProfileParser.builder()
+ .setReporter(reporter)
+ .setProfileBuilder(
+ ArtProfileBuilderUtils.createBuilderForArtProfileToStartupProfileConversion(
+ this));
+ parserBuilderConsumer.accept(parserBuilder);
+ HumanReadableArtProfileParser parser = parserBuilder.build();
+ parser.parse(textInputStream, startupProfileProvider.getOrigin());
+ return this;
+ }
+
+ public Builder addStartupItem(StartupProfileRule startupItem) {
+ startupItems.put(startupItem.getReference(), startupItem);
+ return this;
+ }
+
+ public Builder apply(Consumer<Builder> consumer) {
+ consumer.accept(this);
+ return this;
+ }
+
+ public Builder setIgnoreWarnings() {
+ return setReporter(null);
+ }
+
+ public Builder setReporter(Reporter reporter) {
+ this.reporter = reporter;
+ return this;
+ }
+
+ public int size() {
+ return startupItems.size();
+ }
+
+ @Override
+ public StartupProfile build() {
+ if (startupItems.isEmpty()) {
+ return empty();
+ }
+ return new NonEmptyStartupProfile(startupItems);
+ }
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/StartupProfileProviderUtils.java b/src/main/java/com/android/tools/r8/experimental/startup/StartupProfileProviderUtils.java
index a4b0f5e..e5b6b58 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/StartupProfileProviderUtils.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/StartupProfileProviderUtils.java
@@ -6,11 +6,9 @@
import static com.android.tools.r8.utils.ConsumerUtils.emptyConsumer;
-import com.android.tools.r8.experimental.startup.profile.StartupItem;
-import com.android.tools.r8.experimental.startup.profile.StartupProfile;
+import com.android.tools.r8.experimental.startup.profile.StartupProfileRule;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
-import com.android.tools.r8.profile.art.ArtProfileBuilderUtils.SyntheticToSyntheticContextGeneralization;
import com.android.tools.r8.profile.art.HumanReadableArtProfileParserBuilder;
import com.android.tools.r8.startup.StartupProfileBuilder;
import com.android.tools.r8.startup.StartupProfileProvider;
@@ -51,27 +49,21 @@
/** Serialize the given {@param startupProfileProvider} to a string for writing it to a dump. */
public static String serializeToString(
- InternalOptions options, StartupProfileProvider startupProfileProvider) {
+ InternalOptions options, StartupProfileProvider startupProfileProvider) throws IOException {
// Do not report missing items.
MissingStartupProfileItemsDiagnostic.Builder missingItemsDiagnosticBuilder =
MissingStartupProfileItemsDiagnostic.Builder.nop();
- // Do not generalize synthetic items to their synthetic context.
- SyntheticToSyntheticContextGeneralization syntheticToSyntheticContextGeneralization =
- SyntheticToSyntheticContextGeneralization.createForD8();
StartupProfile.Builder startupProfileBuilder =
- StartupProfile.builder(
- options,
- missingItemsDiagnosticBuilder,
- startupProfileProvider,
- syntheticToSyntheticContextGeneralization);
+ StartupProfile.builder(options, missingItemsDiagnosticBuilder, startupProfileProvider);
// Do not report warnings for lines that cannot be parsed.
startupProfileBuilder.setIgnoreWarnings();
// Populate the startup profile builder.
startupProfileProvider.getStartupProfile(startupProfileBuilder);
// Serialize the startup items.
StringBuilder resultBuilder = new StringBuilder();
- for (StartupItem startupItem : startupProfileBuilder.build().getStartupItems()) {
- resultBuilder.append(startupItem.serializeToString()).append('\n');
+ for (StartupProfileRule startupItem : startupProfileBuilder.build().getRules()) {
+ startupItem.write(resultBuilder);
+ resultBuilder.append('\n');
}
return resultBuilder.toString();
}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/profile/NonEmptyStartupProfile.java b/src/main/java/com/android/tools/r8/experimental/startup/profile/NonEmptyStartupProfile.java
new file mode 100644
index 0000000..ab251a8
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/experimental/startup/profile/NonEmptyStartupProfile.java
@@ -0,0 +1,185 @@
+// Copyright (c) 2022, 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.experimental.startup.profile;
+
+import com.android.tools.r8.experimental.startup.StartupProfile;
+import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.DexReference;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.PrunedItems;
+import com.android.tools.r8.synthesis.SyntheticItems;
+import com.android.tools.r8.utils.ThrowingConsumer;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.function.BiConsumer;
+
+public class NonEmptyStartupProfile extends StartupProfile {
+
+ private final LinkedHashMap<DexReference, StartupProfileRule> startupItems;
+
+ public NonEmptyStartupProfile(LinkedHashMap<DexReference, StartupProfileRule> startupItems) {
+ assert !startupItems.isEmpty();
+ this.startupItems = startupItems;
+ }
+
+ @Override
+ public boolean containsMethodRule(DexMethod method) {
+ return startupItems.containsKey(method);
+ }
+
+ @Override
+ public boolean containsClassRule(DexType type) {
+ return startupItems.containsKey(type);
+ }
+
+ @Override
+ public <E1 extends Exception, E2 extends Exception> void forEachRule(
+ ThrowingConsumer<StartupProfileClassRule, E1> classRuleConsumer,
+ ThrowingConsumer<StartupProfileMethodRule, E2> methodRuleConsumer)
+ throws E1, E2 {
+ for (StartupProfileRule rule : getRules()) {
+ rule.accept(classRuleConsumer, methodRuleConsumer);
+ }
+ }
+
+ @Override
+ public StartupProfileClassRule getClassRule(DexType type) {
+ return (StartupProfileClassRule) startupItems.get(type);
+ }
+
+ @Override
+ public StartupProfileMethodRule getMethodRule(DexMethod method) {
+ return (StartupProfileMethodRule) startupItems.get(method);
+ }
+
+ @Override
+ public Collection<StartupProfileRule> getRules() {
+ return startupItems.values();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
+
+ @Override
+ public StartupProfile rewrittenWithLens(GraphLens graphLens) {
+ return transform(
+ (classRule, builder) ->
+ builder.addClassRule(
+ StartupProfileClassRule.builder()
+ .setClassReference(graphLens.lookupType(classRule.getReference()))
+ .build()),
+ (methodRule, builder) ->
+ builder.addMethodRule(
+ StartupProfileMethodRule.builder()
+ .setMethod(graphLens.getRenamedMethodSignature(methodRule.getReference()))
+ .build()));
+ }
+
+ public int size() {
+ return startupItems.size();
+ }
+
+ /**
+ * This is called to process the startup profile before computing the startup layouts.
+ *
+ * <p>This processing makes the following key change to the startup profile: A {@link
+ * StartupProfileClassRule} is inserted for all supertypes of a given class next to the class in
+ * the startup profile. This ensures that the classes from the super hierarchy will be laid out
+ * close to their subclasses, at the point where the subclasses are used during startup.
+ *
+ * <p>This normally follows from the trace already, except that the class initializers of
+ * interfaces are not executed when a subclass is used.
+ */
+ @Override
+ public StartupProfile toStartupProfileForWriting(AppView<?> appView) {
+ return transform(
+ (classRule, builder) -> addStartupItem(classRule, builder, appView),
+ (methodRule, builder) -> addStartupItem(methodRule, builder, appView));
+ }
+
+ private static void addStartupItem(
+ StartupProfileRule startupItem, Builder builder, AppView<?> appView) {
+ startupItem.accept(
+ classRule -> addClassAndParentClasses(classRule.getReference(), builder, appView),
+ builder::addMethodRule);
+ }
+
+ private static boolean addClass(DexProgramClass clazz, Builder builder) {
+ int oldSize = builder.size();
+ builder.addClassRule(
+ StartupProfileClassRule.builder().setClassReference(clazz.getType()).build());
+ return builder.size() > oldSize;
+ }
+
+ private static void addClassAndParentClasses(DexType type, Builder builder, AppView<?> appView) {
+ DexProgramClass definition = appView.app().programDefinitionFor(type);
+ if (definition != null) {
+ addClassAndParentClasses(definition, builder, appView);
+ }
+ }
+
+ private static void addClassAndParentClasses(
+ DexProgramClass clazz, Builder builder, AppView<?> appView) {
+ if (addClass(clazz, builder)) {
+ addParentClasses(clazz, builder, appView);
+ }
+ }
+
+ private static void addParentClasses(DexProgramClass clazz, Builder builder, AppView<?> appView) {
+ clazz.forEachImmediateSupertype(
+ supertype -> addClassAndParentClasses(supertype, builder, appView));
+ }
+
+ @Override
+ public StartupProfile withoutMissingItems(AppView<?> appView) {
+ AppInfo appInfo = appView.appInfo();
+ return transform(
+ (classRule, builder) -> {
+ if (appInfo.hasDefinitionForWithoutExistenceAssert(classRule.getReference())) {
+ builder.addClassRule(classRule);
+ }
+ },
+ (methodRule, builder) -> {
+ DexClass clazz =
+ appInfo.definitionForWithoutExistenceAssert(
+ methodRule.getReference().getHolderType());
+ if (methodRule.getReference().isDefinedOnClass(clazz)) {
+ builder.addMethodRule(methodRule);
+ }
+ });
+ }
+
+ @Override
+ public StartupProfile withoutPrunedItems(PrunedItems prunedItems, SyntheticItems syntheticItems) {
+ return transform(
+ (classRule, builder) -> {
+ if (!prunedItems.isRemoved(classRule.getReference())) {
+ builder.addClassRule(classRule);
+ }
+ },
+ (methodRule, builder) -> {
+ if (!prunedItems.isRemoved(methodRule.getReference())) {
+ builder.addMethodRule(methodRule);
+ }
+ });
+ }
+
+ private StartupProfile transform(
+ BiConsumer<StartupProfileClassRule, Builder> classRuleTransformer,
+ BiConsumer<StartupProfileMethodRule, Builder> methodRuleTransformer) {
+ Builder builder = builderWithCapacity(startupItems.size());
+ forEachRule(
+ classRule -> classRuleTransformer.accept(classRule, builder),
+ methodRule -> methodRuleTransformer.accept(methodRule, builder));
+ return builder.build();
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupItem.java b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupItem.java
deleted file mode 100644
index b7e6f1c..0000000
--- a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupItem.java
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2022, 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.experimental.startup.profile;
-
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-public abstract class StartupItem {
-
- public abstract void accept(
- Consumer<StartupClass> classConsumer,
- Consumer<StartupMethod> methodConsumer,
- Consumer<SyntheticStartupMethod> syntheticMethodConsumer);
-
- public abstract <T> T apply(
- Function<StartupClass, T> classFunction,
- Function<StartupMethod, T> methodFunction,
- Function<SyntheticStartupMethod, T> syntheticMethodFunction);
-
- public boolean isStartupClass() {
- return false;
- }
-
- public StartupClass asStartupClass() {
- assert false;
- return null;
- }
-
- public boolean isStartupMethod() {
- return false;
- }
-
- public StartupMethod asStartupMethod() {
- assert false;
- return null;
- }
-
- public boolean isSyntheticStartupMethod() {
- return false;
- }
-
- public SyntheticStartupMethod asSyntheticStartupMethod() {
- assert false;
- return null;
- }
-
- public abstract String serializeToString();
-}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupMethod.java b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupMethod.java
deleted file mode 100644
index 18045ef..0000000
--- a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupMethod.java
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2022, 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.experimental.startup.profile;
-
-import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.references.MethodReference;
-import com.android.tools.r8.startup.StartupMethodBuilder;
-import com.android.tools.r8.utils.MethodReferenceUtils;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-public class StartupMethod extends StartupItem {
-
- private final DexMethod method;
-
- StartupMethod(DexMethod method) {
- this.method = method;
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static Builder builder(DexItemFactory dexItemFactory) {
- return new Builder(dexItemFactory);
- }
-
- @Override
- public void accept(
- Consumer<StartupClass> classConsumer,
- Consumer<StartupMethod> methodConsumer,
- Consumer<SyntheticStartupMethod> syntheticMethodConsumer) {
- methodConsumer.accept(this);
- }
-
- @Override
- public <T> T apply(
- Function<StartupClass, T> classFunction,
- Function<StartupMethod, T> methodFunction,
- Function<SyntheticStartupMethod, T> syntheticMethodFunction) {
- return methodFunction.apply(this);
- }
-
- public DexMethod getReference() {
- return method;
- }
-
- @Override
- public boolean isStartupMethod() {
- return true;
- }
-
- @Override
- public StartupMethod asStartupMethod() {
- return this;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- StartupMethod that = (StartupMethod) o;
- return method == that.method;
- }
-
- @Override
- public int hashCode() {
- return method.hashCode();
- }
-
- @Override
- public String serializeToString() {
- return method.toSmaliString();
- }
-
- public static class Builder implements StartupMethodBuilder {
-
- private final DexItemFactory dexItemFactory;
-
- private DexMethod method;
-
- Builder() {
- this(null);
- }
-
- Builder(DexItemFactory dexItemFactory) {
- this.dexItemFactory = dexItemFactory;
- }
-
- @Override
- public Builder setMethodReference(MethodReference classReference) {
- assert dexItemFactory != null;
- return setMethodReference(MethodReferenceUtils.toDexMethod(classReference, dexItemFactory));
- }
-
- public Builder setMethodReference(DexMethod method) {
- this.method = method;
- return this;
- }
-
- public StartupMethod build() {
- return new StartupMethod(method);
- }
- }
-}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfile.java b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfile.java
deleted file mode 100644
index 3a63098..0000000
--- a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfile.java
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright (c) 2022, 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.experimental.startup.profile;
-
-import com.android.tools.r8.TextInputStream;
-import com.android.tools.r8.graph.DexDefinitionSupplier;
-import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.profile.art.ArtProfileBuilderUtils;
-import com.android.tools.r8.profile.art.ArtProfileBuilderUtils.SyntheticToSyntheticContextGeneralization;
-import com.android.tools.r8.profile.art.HumanReadableArtProfileParser;
-import com.android.tools.r8.profile.art.HumanReadableArtProfileParserBuilder;
-import com.android.tools.r8.startup.StartupClassBuilder;
-import com.android.tools.r8.startup.StartupMethodBuilder;
-import com.android.tools.r8.startup.StartupProfileBuilder;
-import com.android.tools.r8.startup.StartupProfileProvider;
-import com.android.tools.r8.startup.SyntheticStartupMethodBuilder;
-import com.android.tools.r8.startup.diagnostic.MissingStartupProfileItemsDiagnostic;
-import com.android.tools.r8.utils.InternalOptions;
-import com.android.tools.r8.utils.Reporter;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.function.Consumer;
-
-public class StartupProfile {
-
- private final LinkedHashSet<StartupItem> startupItems;
-
- StartupProfile(LinkedHashSet<StartupItem> startupItems) {
- this.startupItems = startupItems;
- }
-
- public static Builder builder(
- InternalOptions options,
- MissingStartupProfileItemsDiagnostic.Builder missingItemsDiagnosticBuilder,
- StartupProfileProvider startupProfileProvider,
- SyntheticToSyntheticContextGeneralization syntheticToSyntheticContextGeneralization) {
- return new Builder(
- options,
- missingItemsDiagnosticBuilder,
- startupProfileProvider,
- syntheticToSyntheticContextGeneralization);
- }
-
- public static StartupProfile merge(Collection<StartupProfile> startupProfiles) {
- LinkedHashSet<StartupItem> mergedStartupItems = new LinkedHashSet<>();
- for (StartupProfile startupProfile : startupProfiles) {
- mergedStartupItems.addAll(startupProfile.getStartupItems());
- }
- return new StartupProfile(mergedStartupItems);
- }
-
- /**
- * Parses the supplied startup configuration, if any. The startup configuration is a list of class
- * and method descriptors.
- *
- * <p>Example:
- *
- * <pre>
- * Landroidx/compose/runtime/ComposerImpl;->updateValue(Ljava/lang/Object;)V
- * Landroidx/compose/runtime/ComposerImpl;->updatedNodeCount(I)I
- * Landroidx/compose/runtime/ComposerImpl;->validateNodeExpected()V
- * Landroidx/compose/runtime/CompositionImpl;->applyChanges()V
- * Landroidx/compose/runtime/ComposerKt;->findLocation(Ljava/util/List;I)I
- * Landroidx/compose/runtime/ComposerImpl;
- * </pre>
- */
- public static StartupProfile parseStartupProfile(
- InternalOptions options,
- DexDefinitionSupplier definitions,
- SyntheticToSyntheticContextGeneralization syntheticToSyntheticContextGeneralization) {
- if (!options.getStartupOptions().hasStartupProfileProviders()) {
- return null;
- }
- Collection<StartupProfileProvider> startupProfileProviders =
- options.getStartupOptions().getStartupProfileProviders();
- List<StartupProfile> startupProfiles = new ArrayList<>(startupProfileProviders.size());
- for (StartupProfileProvider startupProfileProvider : startupProfileProviders) {
- MissingStartupProfileItemsDiagnostic.Builder missingItemsDiagnosticBuilder =
- new MissingStartupProfileItemsDiagnostic.Builder(definitions)
- .setOrigin(startupProfileProvider.getOrigin());
- StartupProfile.Builder startupProfileBuilder =
- StartupProfile.builder(
- options,
- missingItemsDiagnosticBuilder,
- startupProfileProvider,
- syntheticToSyntheticContextGeneralization);
- startupProfileProvider.getStartupProfile(startupProfileBuilder);
- startupProfiles.add(startupProfileBuilder.build());
- if (missingItemsDiagnosticBuilder.hasMissingStartupItems()) {
- options.reporter.warning(missingItemsDiagnosticBuilder.build());
- }
- }
- return StartupProfile.merge(startupProfiles);
- }
-
- public Collection<StartupItem> getStartupItems() {
- return startupItems;
- }
-
- public static class Builder implements StartupProfileBuilder {
-
- private final DexItemFactory dexItemFactory;
- private final MissingStartupProfileItemsDiagnostic.Builder missingItemsDiagnosticBuilder;
- private Reporter reporter;
- private final StartupProfileProvider startupProfileProvider;
- private final SyntheticToSyntheticContextGeneralization
- syntheticToSyntheticContextGeneralization;
-
- private final LinkedHashSet<StartupItem> startupItems = new LinkedHashSet<>();
-
- Builder(
- InternalOptions options,
- MissingStartupProfileItemsDiagnostic.Builder missingItemsDiagnosticBuilder,
- StartupProfileProvider startupProfileProvider,
- SyntheticToSyntheticContextGeneralization syntheticToSyntheticContextGeneralization) {
- this.dexItemFactory = options.dexItemFactory();
- this.missingItemsDiagnosticBuilder = missingItemsDiagnosticBuilder;
- this.reporter = options.reporter;
- this.startupProfileProvider = startupProfileProvider;
- this.syntheticToSyntheticContextGeneralization = syntheticToSyntheticContextGeneralization;
- }
-
- @Override
- public Builder addStartupClass(Consumer<StartupClassBuilder> startupClassBuilderConsumer) {
- StartupClass.Builder startupClassBuilder = StartupClass.builder(dexItemFactory);
- startupClassBuilderConsumer.accept(startupClassBuilder);
- StartupClass startupClass = startupClassBuilder.build();
- if (missingItemsDiagnosticBuilder.registerStartupClass(startupClass)) {
- return this;
- }
- return addStartupItem(startupClass);
- }
-
- @Override
- public Builder addStartupMethod(Consumer<StartupMethodBuilder> startupMethodBuilderConsumer) {
- StartupMethod.Builder startupMethodBuilder = StartupMethod.builder(dexItemFactory);
- startupMethodBuilderConsumer.accept(startupMethodBuilder);
- StartupMethod startupMethod = startupMethodBuilder.build();
- if (missingItemsDiagnosticBuilder.registerStartupMethod(startupMethod)) {
- return this;
- }
- return addStartupItem(startupMethod);
- }
-
- @Override
- public StartupProfileBuilder addSyntheticStartupMethod(
- Consumer<SyntheticStartupMethodBuilder> syntheticStartupMethodBuilderConsumer) {
- SyntheticStartupMethod.Builder syntheticStartupMethodBuilder =
- SyntheticStartupMethod.builder(dexItemFactory);
- syntheticStartupMethodBuilderConsumer.accept(syntheticStartupMethodBuilder);
- SyntheticStartupMethod syntheticStartupMethod = syntheticStartupMethodBuilder.build();
- if (missingItemsDiagnosticBuilder.registerSyntheticStartupMethod(syntheticStartupMethod)) {
- return this;
- }
- return addStartupItem(syntheticStartupMethod);
- }
-
- @Override
- public StartupProfileBuilder addHumanReadableArtProfile(
- TextInputStream textInputStream,
- Consumer<HumanReadableArtProfileParserBuilder> parserBuilderConsumer) {
- HumanReadableArtProfileParser.Builder parserBuilder =
- HumanReadableArtProfileParser.builder()
- .setReporter(reporter)
- .setProfileBuilder(
- ArtProfileBuilderUtils.createBuilderForArtProfileToStartupProfileConversion(
- this, syntheticToSyntheticContextGeneralization));
- parserBuilderConsumer.accept(parserBuilder);
- HumanReadableArtProfileParser parser = parserBuilder.build();
- parser.parse(textInputStream, startupProfileProvider.getOrigin());
- return this;
- }
-
- private Builder addStartupItem(StartupItem startupItem) {
- this.startupItems.add(startupItem);
- return this;
- }
-
- public Builder apply(Consumer<Builder> consumer) {
- consumer.accept(this);
- return this;
- }
-
- public Builder setIgnoreWarnings() {
- return setReporter(null);
- }
-
- public Builder setReporter(Reporter reporter) {
- this.reporter = reporter;
- return this;
- }
-
- public StartupProfile build() {
- return new StartupProfile(startupItems);
- }
- }
-}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupClass.java b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileClassRule.java
similarity index 63%
rename from src/main/java/com/android/tools/r8/experimental/startup/profile/StartupClass.java
rename to src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileClassRule.java
index d281a65..c474ff2 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupClass.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileClassRule.java
@@ -6,17 +6,20 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.profile.AbstractProfileClassRule;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.startup.StartupClassBuilder;
import com.android.tools.r8.utils.ClassReferenceUtils;
-import java.util.function.Consumer;
+import com.android.tools.r8.utils.ThrowingConsumer;
+import java.io.IOException;
import java.util.function.Function;
-public class StartupClass extends StartupItem {
+public class StartupProfileClassRule extends StartupProfileRule
+ implements AbstractProfileClassRule {
private final DexType type;
- StartupClass(DexType type) {
+ StartupProfileClassRule(DexType type) {
this.type = type;
}
@@ -29,36 +32,26 @@
}
@Override
- public void accept(
- Consumer<StartupClass> classConsumer,
- Consumer<StartupMethod> methodConsumer,
- Consumer<SyntheticStartupMethod> syntheticMethodConsumer) {
+ public <E1 extends Exception, E2 extends Exception> void accept(
+ ThrowingConsumer<StartupProfileClassRule, E1> classConsumer,
+ ThrowingConsumer<StartupProfileMethodRule, E2> methodConsumer)
+ throws E1 {
classConsumer.accept(this);
}
@Override
public <T> T apply(
- Function<StartupClass, T> classFunction,
- Function<StartupMethod, T> methodFunction,
- Function<SyntheticStartupMethod, T> syntheticMethodFunction) {
+ Function<StartupProfileClassRule, T> classFunction,
+ Function<StartupProfileMethodRule, T> methodFunction) {
return classFunction.apply(this);
}
+ @Override
public DexType getReference() {
return type;
}
@Override
- public boolean isStartupClass() {
- return true;
- }
-
- @Override
- public StartupClass asStartupClass() {
- return this;
- }
-
- @Override
public boolean equals(Object o) {
if (this == o) {
return true;
@@ -66,7 +59,7 @@
if (o == null || getClass() != o.getClass()) {
return false;
}
- StartupClass that = (StartupClass) o;
+ StartupProfileClassRule that = (StartupProfileClassRule) o;
return type == that.type;
}
@@ -76,11 +69,12 @@
}
@Override
- public String serializeToString() {
- return getReference().toDescriptorString();
+ public void write(Appendable appendable) throws IOException {
+ appendable.append(getReference().toDescriptorString());
}
- public static class Builder implements StartupClassBuilder {
+ public static class Builder
+ implements AbstractProfileClassRule.Builder<StartupProfileClassRule>, StartupClassBuilder {
private final DexItemFactory dexItemFactory;
@@ -105,8 +99,9 @@
return this;
}
- public StartupClass build() {
- return new StartupClass(type);
+ @Override
+ public StartupProfileClassRule build() {
+ return new StartupProfileClassRule(type);
}
}
}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileMethodRule.java b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileMethodRule.java
new file mode 100644
index 0000000..0a3a36a
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileMethodRule.java
@@ -0,0 +1,124 @@
+// Copyright (c) 2022, 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.experimental.startup.profile;
+
+import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.profile.AbstractProfileMethodRule;
+import com.android.tools.r8.references.MethodReference;
+import com.android.tools.r8.startup.StartupMethodBuilder;
+import com.android.tools.r8.utils.MethodReferenceUtils;
+import com.android.tools.r8.utils.ThrowingConsumer;
+import java.io.IOException;
+import java.util.function.Function;
+
+public class StartupProfileMethodRule extends StartupProfileRule
+ implements AbstractProfileMethodRule {
+
+ private final DexMethod method;
+
+ StartupProfileMethodRule(DexMethod method) {
+ this.method = method;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static Builder builder(DexItemFactory dexItemFactory) {
+ return new Builder(dexItemFactory);
+ }
+
+ @Override
+ public <E1 extends Exception, E2 extends Exception> void accept(
+ ThrowingConsumer<StartupProfileClassRule, E1> classConsumer,
+ ThrowingConsumer<StartupProfileMethodRule, E2> methodConsumer)
+ throws E2 {
+ methodConsumer.accept(this);
+ }
+
+ @Override
+ public <T> T apply(
+ Function<StartupProfileClassRule, T> classFunction,
+ Function<StartupProfileMethodRule, T> methodFunction) {
+ return methodFunction.apply(this);
+ }
+
+ @Override
+ public DexMethod getReference() {
+ return method;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ StartupProfileMethodRule that = (StartupProfileMethodRule) o;
+ return method == that.method;
+ }
+
+ @Override
+ public int hashCode() {
+ return method.hashCode();
+ }
+
+ @Override
+ public void write(Appendable appendable) throws IOException {
+ appendable.append(method.toSmaliString());
+ }
+
+ public static class Builder
+ implements AbstractProfileMethodRule.Builder<StartupProfileMethodRule, Builder>,
+ StartupMethodBuilder {
+
+ private final DexItemFactory dexItemFactory;
+
+ private DexMethod method;
+
+ Builder() {
+ this(null);
+ }
+
+ Builder(DexItemFactory dexItemFactory) {
+ this.dexItemFactory = dexItemFactory;
+ }
+
+ @Override
+ public boolean isGreaterThanOrEqualTo(Builder builder) {
+ return true;
+ }
+
+ @Override
+ public Builder join(Builder builder) {
+ return this;
+ }
+
+ @Override
+ public Builder join(StartupProfileMethodRule methodRule) {
+ return this;
+ }
+
+ @Override
+ public Builder setMethod(DexMethod method) {
+ this.method = method;
+ return this;
+ }
+
+ @Override
+ public Builder setMethodReference(MethodReference classReference) {
+ assert dexItemFactory != null;
+ return setMethod(MethodReferenceUtils.toDexMethod(classReference, dexItemFactory));
+ }
+
+ @Override
+ public StartupProfileMethodRule build() {
+ return new StartupProfileMethodRule(method);
+ }
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileRule.java b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileRule.java
new file mode 100644
index 0000000..200d364
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileRule.java
@@ -0,0 +1,33 @@
+// Copyright (c) 2022, 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.experimental.startup.profile;
+
+import com.android.tools.r8.graph.DexReference;
+import com.android.tools.r8.profile.AbstractProfileRule;
+import com.android.tools.r8.utils.ThrowingConsumer;
+import java.io.IOException;
+import java.util.function.Function;
+
+public abstract class StartupProfileRule
+ implements AbstractProfileRule, Comparable<StartupProfileRule> {
+
+ public abstract <E1 extends Exception, E2 extends Exception> void accept(
+ ThrowingConsumer<StartupProfileClassRule, E1> classConsumer,
+ ThrowingConsumer<StartupProfileMethodRule, E2> methodConsumer)
+ throws E1, E2;
+
+ public abstract <T> T apply(
+ Function<StartupProfileClassRule, T> classFunction,
+ Function<StartupProfileMethodRule, T> methodFunction);
+
+ @Override
+ public final int compareTo(StartupProfileRule rule) {
+ return getReference().compareTo(rule.getReference());
+ }
+
+ public abstract DexReference getReference();
+
+ public abstract void write(Appendable appendable) throws IOException;
+}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/profile/SyntheticStartupMethod.java b/src/main/java/com/android/tools/r8/experimental/startup/profile/SyntheticStartupMethod.java
deleted file mode 100644
index c68a198..0000000
--- a/src/main/java/com/android/tools/r8/experimental/startup/profile/SyntheticStartupMethod.java
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (c) 2022, 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.experimental.startup.profile;
-
-import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.startup.SyntheticStartupMethodBuilder;
-import com.android.tools.r8.utils.ClassReferenceUtils;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-public class SyntheticStartupMethod extends StartupItem {
-
- private final DexType syntheticContextType;
-
- SyntheticStartupMethod(DexType syntheticContextType) {
- this.syntheticContextType = syntheticContextType;
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static Builder builder(DexItemFactory dexItemFactory) {
- return new Builder(dexItemFactory);
- }
-
- @Override
- public void accept(
- Consumer<StartupClass> classConsumer,
- Consumer<StartupMethod> methodConsumer,
- Consumer<SyntheticStartupMethod> syntheticMethodConsumer) {
- syntheticMethodConsumer.accept(this);
- }
-
- @Override
- public <T> T apply(
- Function<StartupClass, T> classFunction,
- Function<StartupMethod, T> methodFunction,
- Function<SyntheticStartupMethod, T> syntheticMethodFunction) {
- return syntheticMethodFunction.apply(this);
- }
-
- public DexType getSyntheticContextType() {
- return syntheticContextType;
- }
-
- @Override
- public boolean isSyntheticStartupMethod() {
- return true;
- }
-
- @Override
- public SyntheticStartupMethod asSyntheticStartupMethod() {
- return this;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- SyntheticStartupMethod that = (SyntheticStartupMethod) o;
- return syntheticContextType == that.syntheticContextType;
- }
-
- @Override
- public int hashCode() {
- return syntheticContextType.hashCode();
- }
-
- @Override
- public String serializeToString() {
- return 'S' + syntheticContextType.toDescriptorString();
- }
-
- public static class Builder implements SyntheticStartupMethodBuilder {
-
- private final DexItemFactory dexItemFactory;
-
- private DexType syntheticContextReference;
-
- Builder() {
- this(null);
- }
-
- Builder(DexItemFactory dexItemFactory) {
- this.dexItemFactory = dexItemFactory;
- }
-
- @Override
- public Builder setSyntheticContextReference(ClassReference syntheticContextReference) {
- assert dexItemFactory != null;
- return setSyntheticContextReference(
- ClassReferenceUtils.toDexType(syntheticContextReference, dexItemFactory));
- }
-
- public Builder setSyntheticContextReference(DexType syntheticContextReference) {
- this.syntheticContextReference = syntheticContextReference;
- return this;
- }
-
- public SyntheticStartupMethod build() {
- return new SyntheticStartupMethod(syntheticContextReference);
- }
- }
-}
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/rewriting/StartupProfileAdditions.java b/src/main/java/com/android/tools/r8/experimental/startup/rewriting/StartupProfileAdditions.java
new file mode 100644
index 0000000..2522234
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/experimental/startup/rewriting/StartupProfileAdditions.java
@@ -0,0 +1,61 @@
+// 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.experimental.startup.rewriting;
+
+import com.android.tools.r8.experimental.startup.StartupProfile;
+import com.android.tools.r8.experimental.startup.profile.StartupProfileClassRule;
+import com.android.tools.r8.experimental.startup.profile.StartupProfileMethodRule;
+import com.android.tools.r8.experimental.startup.profile.StartupProfileRule;
+import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.profile.AbstractProfileRule;
+import com.android.tools.r8.profile.art.rewriting.ProfileAdditions;
+import java.util.Comparator;
+
+public class StartupProfileAdditions
+ extends ProfileAdditions<
+ StartupProfileAdditions,
+ StartupProfileClassRule,
+ StartupProfileClassRule.Builder,
+ StartupProfileMethodRule,
+ StartupProfileMethodRule.Builder,
+ StartupProfileRule,
+ StartupProfile,
+ StartupProfile.Builder> {
+
+ public StartupProfileAdditions(StartupProfile profile) {
+ super(profile);
+ }
+
+ @Override
+ public StartupProfileAdditions create() {
+ return new StartupProfileAdditions(profile);
+ }
+
+ @Override
+ public StartupProfileClassRule.Builder createClassRuleBuilder(DexType type) {
+ return StartupProfileClassRule.builder().setClassReference(type);
+ }
+
+ @Override
+ public StartupProfileMethodRule.Builder createMethodRuleBuilder(DexMethod method) {
+ return StartupProfileMethodRule.builder().setMethod(method);
+ }
+
+ @Override
+ public StartupProfile.Builder createProfileBuilder() {
+ return StartupProfile.builder();
+ }
+
+ @Override
+ public Comparator<AbstractProfileRule> getRuleComparator() {
+ return Comparator.comparing(AbstractProfileRule::asStartupProfileRule);
+ }
+
+ @Override
+ public StartupProfileAdditions self() {
+ return this;
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/features/ClassToFeatureSplitMap.java b/src/main/java/com/android/tools/r8/features/ClassToFeatureSplitMap.java
index fd710bb..dc33db7 100644
--- a/src/main/java/com/android/tools/r8/features/ClassToFeatureSplitMap.java
+++ b/src/main/java/com/android/tools/r8/features/ClassToFeatureSplitMap.java
@@ -8,7 +8,7 @@
import com.android.tools.r8.ProgramResource;
import com.android.tools.r8.ProgramResourceProvider;
import com.android.tools.r8.ResourceException;
-import com.android.tools.r8.experimental.startup.StartupOrder;
+import com.android.tools.r8.experimental.startup.StartupProfile;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexItemFactory;
@@ -106,20 +106,17 @@
public Map<FeatureSplit, Set<DexProgramClass>> getFeatureSplitClasses(
Set<DexProgramClass> classes, AppView<? extends AppInfoWithClassHierarchy> appView) {
return getFeatureSplitClasses(
- classes,
- appView.options(),
- appView.appInfo().getStartupOrder(),
- appView.getSyntheticItems());
+ classes, appView.options(), appView.getStartupProfile(), appView.getSyntheticItems());
}
public Map<FeatureSplit, Set<DexProgramClass>> getFeatureSplitClasses(
Set<DexProgramClass> classes,
InternalOptions options,
- StartupOrder startupOrder,
+ StartupProfile startupProfile,
SyntheticItems syntheticItems) {
Map<FeatureSplit, Set<DexProgramClass>> result = new IdentityHashMap<>();
for (DexProgramClass clazz : classes) {
- FeatureSplit featureSplit = getFeatureSplit(clazz, options, startupOrder, syntheticItems);
+ FeatureSplit featureSplit = getFeatureSplit(clazz, options, startupProfile, syntheticItems);
if (featureSplit != null && !featureSplit.isBase()) {
result.computeIfAbsent(featureSplit, ignore -> Sets.newIdentityHashSet()).add(clazz);
}
@@ -130,34 +127,31 @@
public FeatureSplit getFeatureSplit(
ProgramDefinition definition, AppView<? extends AppInfoWithClassHierarchy> appView) {
return getFeatureSplit(
- definition,
- appView.options(),
- appView.appInfo().getStartupOrder(),
- appView.getSyntheticItems());
+ definition, appView.options(), appView.getStartupProfile(), appView.getSyntheticItems());
}
public FeatureSplit getFeatureSplit(
ProgramDefinition definition,
InternalOptions options,
- StartupOrder startupOrder,
+ StartupProfile startupProfile,
SyntheticItems syntheticItems) {
- return getFeatureSplit(definition.getContextType(), options, startupOrder, syntheticItems);
+ return getFeatureSplit(definition.getContextType(), options, startupProfile, syntheticItems);
}
public FeatureSplit getFeatureSplit(
DexType type, AppView<? extends AppInfoWithClassHierarchy> appView) {
return getFeatureSplit(
- type, appView.options(), appView.appInfo().getStartupOrder(), appView.getSyntheticItems());
+ type, appView.options(), appView.getStartupProfile(), appView.getSyntheticItems());
}
public FeatureSplit getFeatureSplit(
DexType type,
InternalOptions options,
- StartupOrder startupOrder,
+ StartupProfile startupProfile,
SyntheticItems syntheticItems) {
if (syntheticItems == null) {
// Called from AndroidApp.dumpProgramResources().
- assert startupOrder.isEmpty();
+ assert startupProfile.isEmpty();
return classToFeatureSplitMap.getOrDefault(type, FeatureSplit.BASE);
}
FeatureSplit feature;
@@ -168,7 +162,7 @@
// the shared utility class in case it is used during startup. The use of base startup
// allows for merging startup classes with the shared utility class, however, which could be
// bad for startup if the shared utility class is not used during startup.
- return startupOrder.isEmpty()
+ return startupProfile.isEmpty()
|| options.getStartupOptions().isStartupBoundaryOptimizationsEnabled()
? FeatureSplit.BASE
: FeatureSplit.BASE_STARTUP;
@@ -181,7 +175,7 @@
feature = classToFeatureSplitMap.getOrDefault(type, FeatureSplit.BASE);
}
if (feature.isBase()) {
- return !startupOrder.contains(type, syntheticItems)
+ return !startupProfile.containsClassRule(type)
|| options.getStartupOptions().isStartupBoundaryOptimizationsEnabled()
? FeatureSplit.BASE
: FeatureSplit.BASE_STARTUP;
@@ -199,15 +193,15 @@
public boolean isInBase(
DexProgramClass clazz, AppView<? extends AppInfoWithClassHierarchy> appView) {
return isInBase(
- clazz, appView.options(), appView.appInfo().getStartupOrder(), appView.getSyntheticItems());
+ clazz, appView.options(), appView.getStartupProfile(), appView.getSyntheticItems());
}
public boolean isInBase(
DexProgramClass clazz,
InternalOptions options,
- StartupOrder startupOrder,
+ StartupProfile startupProfile,
SyntheticItems syntheticItems) {
- return getFeatureSplit(clazz, options, startupOrder, syntheticItems).isBase();
+ return getFeatureSplit(clazz, options, startupProfile, syntheticItems).isBase();
}
public boolean isInBaseOrSameFeatureAs(
@@ -218,7 +212,7 @@
clazz,
context,
appView.options(),
- appView.appInfo().getStartupOrder(),
+ appView.getStartupProfile(),
appView.getSyntheticItems());
}
@@ -226,10 +220,10 @@
DexProgramClass clazz,
ProgramDefinition context,
InternalOptions options,
- StartupOrder startupOrder,
+ StartupProfile startupProfile,
SyntheticItems syntheticItems) {
return isInBaseOrSameFeatureAs(
- clazz.getContextType(), context, options, startupOrder, syntheticItems);
+ clazz.getContextType(), context, options, startupProfile, syntheticItems);
}
public boolean isInBaseOrSameFeatureAs(
@@ -240,7 +234,7 @@
clazz,
context,
appView.options(),
- appView.appInfo().getStartupOrder(),
+ appView.getStartupProfile(),
appView.getSyntheticItems());
}
@@ -248,51 +242,51 @@
DexType clazz,
ProgramDefinition context,
InternalOptions options,
- StartupOrder startupOrder,
+ StartupProfile startupProfile,
SyntheticItems syntheticItems) {
- FeatureSplit split = getFeatureSplit(clazz, options, startupOrder, syntheticItems);
+ FeatureSplit split = getFeatureSplit(clazz, options, startupProfile, syntheticItems);
return split.isBase()
- || split == getFeatureSplit(context, options, startupOrder, syntheticItems);
+ || split == getFeatureSplit(context, options, startupProfile, syntheticItems);
}
public boolean isInFeature(
DexProgramClass clazz,
InternalOptions options,
- StartupOrder startupOrder,
+ StartupProfile startupProfile,
SyntheticItems syntheticItems) {
- return !isInBase(clazz, options, startupOrder, syntheticItems);
+ return !isInBase(clazz, options, startupProfile, syntheticItems);
}
public boolean isInSameFeatureOrBothInSameBase(
ProgramMethod a, ProgramMethod b, AppView<? extends AppInfoWithClassHierarchy> appView) {
return isInSameFeatureOrBothInSameBase(
- a, b, appView.options(), appView.appInfo().getStartupOrder(), appView.getSyntheticItems());
+ a, b, appView.options(), appView.getStartupProfile(), appView.getSyntheticItems());
}
public boolean isInSameFeatureOrBothInSameBase(
ProgramMethod a,
ProgramMethod b,
InternalOptions options,
- StartupOrder startupOrder,
+ StartupProfile startupProfile,
SyntheticItems syntheticItems) {
return isInSameFeatureOrBothInSameBase(
- a.getHolder(), b.getHolder(), options, startupOrder, syntheticItems);
+ a.getHolder(), b.getHolder(), options, startupProfile, syntheticItems);
}
public boolean isInSameFeatureOrBothInSameBase(
DexProgramClass a, DexProgramClass b, AppView<? extends AppInfoWithClassHierarchy> appView) {
return isInSameFeatureOrBothInSameBase(
- a, b, appView.options(), appView.appInfo().getStartupOrder(), appView.getSyntheticItems());
+ a, b, appView.options(), appView.getStartupProfile(), appView.getSyntheticItems());
}
public boolean isInSameFeatureOrBothInSameBase(
DexProgramClass a,
DexProgramClass b,
InternalOptions options,
- StartupOrder startupOrder,
+ StartupProfile startupProfile,
SyntheticItems syntheticItems) {
- return getFeatureSplit(a, options, startupOrder, syntheticItems)
- == getFeatureSplit(b, options, startupOrder, syntheticItems);
+ return getFeatureSplit(a, options, startupProfile, syntheticItems)
+ == getFeatureSplit(b, options, startupProfile, syntheticItems);
}
public ClassToFeatureSplitMap rewrittenWithLens(GraphLens lens) {
@@ -335,9 +329,6 @@
DexProgramClass clazz, AppView<? extends AppInfoWithClassHierarchy> appView) {
return getMap(appView)
.isInFeature(
- clazz,
- appView.options(),
- appView.appInfo().getStartupOrder(),
- appView.getSyntheticItems());
+ clazz, appView.options(), appView.getStartupProfile(), appView.getSyntheticItems());
}
}
diff --git a/src/main/java/com/android/tools/r8/features/FeatureSplitBoundaryOptimizationUtils.java b/src/main/java/com/android/tools/r8/features/FeatureSplitBoundaryOptimizationUtils.java
index 8e2fbb4..37f1494 100644
--- a/src/main/java/com/android/tools/r8/features/FeatureSplitBoundaryOptimizationUtils.java
+++ b/src/main/java/com/android/tools/r8/features/FeatureSplitBoundaryOptimizationUtils.java
@@ -5,7 +5,7 @@
package com.android.tools.r8.features;
import com.android.tools.r8.FeatureSplit;
-import com.android.tools.r8.experimental.startup.StartupOrder;
+import com.android.tools.r8.experimental.startup.StartupProfile;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedMember;
@@ -44,10 +44,10 @@
ProgramDefinition accessor,
ClassToFeatureSplitMap classToFeatureSplitMap,
InternalOptions options,
- StartupOrder startupOrder,
+ StartupProfile startupProfile,
SyntheticItems syntheticItems) {
return classToFeatureSplitMap.isInBaseOrSameFeatureAs(
- accessedClass, accessor, options, startupOrder, syntheticItems);
+ accessedClass, accessor, options, startupProfile, syntheticItems);
}
public static boolean isSafeForInlining(
@@ -66,34 +66,32 @@
}
// Next perform startup checks.
- StartupOrder startupOrder = appView.appInfo().getStartupOrder();
- SyntheticItems syntheticItems = appView.getSyntheticItems();
- OptionalBool callerIsStartupMethod = isStartupMethod(caller, startupOrder, syntheticItems);
+ StartupProfile startupProfile = appView.getStartupProfile();
+ OptionalBool callerIsStartupMethod = isStartupMethod(caller, startupProfile);
if (callerIsStartupMethod.isTrue()) {
// If the caller is a startup method, then only allow inlining if the callee is also a startup
// method.
- if (isStartupMethod(callee, startupOrder, syntheticItems).isFalse()) {
+ if (isStartupMethod(callee, startupProfile).isFalse()) {
return false;
}
} else if (callerIsStartupMethod.isFalse()) {
// If the caller is not a startup method, then only allow inlining if the caller is not a
// startup class or the callee is a startup class.
- if (startupOrder.contains(caller.getHolderType(), syntheticItems)
- && !startupOrder.contains(callee.getHolderType(), syntheticItems)) {
+ if (startupProfile.containsClassRule(caller.getHolderType())
+ && !startupProfile.containsClassRule(callee.getHolderType())) {
return false;
}
}
return true;
}
- private static OptionalBool isStartupMethod(
- ProgramMethod method, StartupOrder startupOrder, SyntheticItems syntheticItems) {
+ private static OptionalBool isStartupMethod(ProgramMethod method, StartupProfile startupProfile) {
if (method.getDefinition().isD8R8Synthesized()) {
// Due to inadequate rewriting of the startup list during desugaring, we do not give an
// accurate result in this case.
return OptionalBool.unknown();
}
- return OptionalBool.of(startupOrder.contains(method.getReference(), syntheticItems));
+ return OptionalBool.of(startupProfile.containsMethodRule(method.getReference()));
}
public static boolean isSafeForVerticalClassMerging(
@@ -115,10 +113,9 @@
// If the source class is a startup class then require that the target class is also a startup
// class.
- StartupOrder startupOrder = appView.appInfo().getStartupOrder();
- SyntheticItems syntheticItems = appView.getSyntheticItems();
- if (startupOrder.contains(sourceClass.getType(), syntheticItems)
- && !startupOrder.contains(targetClass.getType(), syntheticItems)) {
+ StartupProfile startupProfile = appView.getStartupProfile();
+ if (startupProfile.containsClassRule(sourceClass.getType())
+ && !startupProfile.containsClassRule(targetClass.getType())) {
return false;
}
return true;
diff --git a/src/main/java/com/android/tools/r8/graph/AccessControl.java b/src/main/java/com/android/tools/r8/graph/AccessControl.java
index 9211db6..ecb16404 100644
--- a/src/main/java/com/android/tools/r8/graph/AccessControl.java
+++ b/src/main/java/com/android/tools/r8/graph/AccessControl.java
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.graph;
-import com.android.tools.r8.experimental.startup.StartupOrder;
+import com.android.tools.r8.experimental.startup.StartupProfile;
import com.android.tools.r8.features.ClassToFeatureSplitMap;
import com.android.tools.r8.features.FeatureSplitBoundaryOptimizationUtils;
import com.android.tools.r8.synthesis.SyntheticItems;
@@ -27,7 +27,7 @@
context,
appView.appInfo().getClassToFeatureSplitMap(),
appView.options(),
- appView.appInfo().getStartupOrder(),
+ appView.getStartupProfile(),
appView.getSyntheticItems());
}
@@ -36,7 +36,7 @@
Definition context,
ClassToFeatureSplitMap classToFeatureSplitMap,
InternalOptions options,
- StartupOrder startupOrder,
+ StartupProfile startupProfile,
SyntheticItems syntheticItems) {
if (!clazz.isPublic() && !clazz.getType().isSamePackage(context.getContextType())) {
return OptionalBool.FALSE;
@@ -48,7 +48,7 @@
context.asProgramDefinition(),
classToFeatureSplitMap,
options,
- startupOrder,
+ startupProfile,
syntheticItems)) {
return OptionalBool.UNKNOWN;
}
@@ -58,37 +58,40 @@
/** Intentionally package-private, use {@link MemberResolutionResult#isAccessibleFrom}. */
static OptionalBool isMemberAccessible(
SuccessfulMemberResolutionResult<?, ?> resolutionResult,
- ProgramDefinition context,
+ Definition context,
+ AppView<?> appView,
AppInfoWithClassHierarchy appInfo) {
return isMemberAccessible(
resolutionResult.getResolutionPair(),
resolutionResult.getInitialResolutionHolder(),
- context.getContextClass(),
+ context,
+ appView,
appInfo);
}
public static OptionalBool isMemberAccessible(
DexClassAndMember<?, ?> member,
- DexClass initialResolutionHolder,
- ProgramDefinition context,
+ Definition initialResolutionContext,
+ Definition context,
AppView<? extends AppInfoWithClassHierarchy> appView) {
return isMemberAccessible(
- member, initialResolutionHolder, context.getContextClass(), appView.appInfo());
+ member, initialResolutionContext, context, appView, appView.appInfo());
}
static OptionalBool isMemberAccessible(
DexClassAndMember<?, ?> member,
- DexClass initialResolutionHolder,
- DexClass context,
+ Definition initialResolutionContext,
+ Definition context,
+ AppView<?> appView,
AppInfoWithClassHierarchy appInfo) {
AccessFlags<?> memberFlags = member.getDefinition().getAccessFlags();
OptionalBool classAccessibility =
isClassAccessible(
- initialResolutionHolder,
+ initialResolutionContext.getContextClass(),
context,
appInfo.getClassToFeatureSplitMap(),
appInfo.options(),
- appInfo.getStartupOrder(),
+ appView.getStartupProfile(),
appInfo.getSyntheticItems());
if (classAccessibility.isFalse()) {
return OptionalBool.FALSE;
@@ -97,15 +100,16 @@
return classAccessibility;
}
if (memberFlags.isPrivate()) {
- if (!isNestMate(member.getHolder(), context)) {
+ if (!isNestMate(member.getHolder(), context.getContextClass())) {
return OptionalBool.FALSE;
}
return classAccessibility;
}
- if (member.getHolderType().isSamePackage(context.getType())) {
+ if (member.getHolderType().isSamePackage(context.getContextType())) {
return classAccessibility;
}
- if (memberFlags.isProtected() && appInfo.isSubtype(context.getType(), member.getHolderType())) {
+ if (memberFlags.isProtected()
+ && appInfo.isSubtype(context.getContextType(), member.getHolderType())) {
return classAccessibility;
}
return OptionalBool.FALSE;
diff --git a/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java b/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java
index 1536cd8..e834153 100644
--- a/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java
+++ b/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java
@@ -7,7 +7,6 @@
import static com.android.tools.r8.utils.TraversalContinuation.doBreak;
import static com.android.tools.r8.utils.TraversalContinuation.doContinue;
-import com.android.tools.r8.experimental.startup.StartupOrder;
import com.android.tools.r8.features.ClassToFeatureSplitMap;
import com.android.tools.r8.ir.analysis.type.InterfaceCollection;
import com.android.tools.r8.ir.analysis.type.InterfaceCollection.Builder;
@@ -50,18 +49,15 @@
DexApplication application,
ClassToFeatureSplitMap classToFeatureSplitMap,
MainDexInfo mainDexInfo,
- GlobalSyntheticsStrategy globalSyntheticsStrategy,
- StartupOrder startupOrder) {
+ GlobalSyntheticsStrategy globalSyntheticsStrategy) {
return new AppInfoWithClassHierarchy(
SyntheticItems.createInitialSyntheticItems(application, globalSyntheticsStrategy),
classToFeatureSplitMap,
mainDexInfo,
- MissingClasses.empty(),
- startupOrder);
+ MissingClasses.empty());
}
private final ClassToFeatureSplitMap classToFeatureSplitMap;
- private final StartupOrder startupOrder;
/** Set of types that are mentioned in the program, but for which no definition exists. */
// TODO(b/175659048): Consider hoisting to AppInfo to allow using MissingClasses in D8 desugar.
@@ -72,12 +68,10 @@
CommittedItems committedItems,
ClassToFeatureSplitMap classToFeatureSplitMap,
MainDexInfo mainDexInfo,
- MissingClasses missingClasses,
- StartupOrder startupOrder) {
+ MissingClasses missingClasses) {
super(committedItems, mainDexInfo);
this.classToFeatureSplitMap = classToFeatureSplitMap;
this.missingClasses = missingClasses;
- this.startupOrder = startupOrder;
}
// For desugaring.
@@ -87,7 +81,6 @@
// TODO(b/175659048): Migrate the reporting of missing classes in D8 desugar to MissingClasses,
// and use the missing classes from AppInfo instead of MissingClasses.empty().
this.missingClasses = MissingClasses.empty();
- this.startupOrder = StartupOrder.empty();
}
public static AppInfoWithClassHierarchy createForDesugaring(AppInfo appInfo) {
@@ -97,11 +90,7 @@
public final AppInfoWithClassHierarchy rebuildWithClassHierarchy(CommittedItems commit) {
return new AppInfoWithClassHierarchy(
- commit,
- getClassToFeatureSplitMap(),
- getMainDexInfo(),
- getMissingClasses(),
- getStartupOrder());
+ commit, getClassToFeatureSplitMap(), getMainDexInfo(), getMissingClasses());
}
public AppInfoWithClassHierarchy rebuildWithClassHierarchy(
@@ -111,8 +100,7 @@
getSyntheticItems().commit(fn.apply(app())),
getClassToFeatureSplitMap(),
getMainDexInfo(),
- getMissingClasses(),
- getStartupOrder());
+ getMissingClasses());
}
@Override
@@ -123,8 +111,7 @@
getSyntheticItems().commit(app()),
getClassToFeatureSplitMap(),
mainDexInfo,
- getMissingClasses(),
- getStartupOrder());
+ getMissingClasses());
}
@Override
@@ -140,8 +127,7 @@
getSyntheticItems().commitPrunedItems(prunedItems),
getClassToFeatureSplitMap().withoutPrunedItems(prunedItems),
getMainDexInfo().withoutPrunedItems(prunedItems),
- getMissingClasses(),
- getStartupOrder().withoutPrunedItems(prunedItems, getSyntheticItems()));
+ getMissingClasses());
}
public ClassToFeatureSplitMap getClassToFeatureSplitMap() {
@@ -152,10 +138,6 @@
return missingClasses;
}
- public StartupOrder getStartupOrder() {
- return startupOrder;
- }
-
@Override
public boolean hasClassHierarchy() {
assert checkIfObsolete();
@@ -621,14 +603,37 @@
* @return The actual target for {@code method} or {@code null} if none found.
*/
// TODO(b/155968472): This should take a parameter `boolean isInterface` and use resolveMethod().
- public DexEncodedMethod lookupStaticTarget(DexMethod method, DexProgramClass context) {
+ public DexEncodedMethod lookupStaticTarget(
+ DexMethod method,
+ DexProgramClass context,
+ AppView<? extends AppInfoWithClassHierarchy> appView) {
+ return lookupStaticTarget(method, context, appView, appView.appInfo());
+ }
+
+ public DexEncodedMethod lookupStaticTarget(
+ DexMethod method,
+ DexProgramClass context,
+ AppView<?> appView,
+ AppInfoWithClassHierarchy appInfo) {
assert checkIfObsolete();
- return unsafeResolveMethodDueToDexFormatLegacy(method).lookupInvokeStaticTarget(context, this);
+ return unsafeResolveMethodDueToDexFormatLegacy(method)
+ .lookupInvokeStaticTarget(context, appView, appInfo);
}
// TODO(b/155968472): This should take a parameter `boolean isInterface` and use resolveMethod().
- public DexEncodedMethod lookupStaticTarget(DexMethod method, ProgramMethod context) {
- return lookupStaticTarget(method, context.getHolder());
+ public DexEncodedMethod lookupStaticTarget(
+ DexMethod method,
+ ProgramMethod context,
+ AppView<? extends AppInfoWithClassHierarchy> appView) {
+ return lookupStaticTarget(method, context.getHolder(), appView);
+ }
+
+ public DexEncodedMethod lookupStaticTarget(
+ DexMethod method,
+ ProgramMethod context,
+ AppView<?> appView,
+ AppInfoWithClassHierarchy appInfo) {
+ return lookupStaticTarget(method, context.getHolder(), appView, appInfo);
}
/**
@@ -642,14 +647,37 @@
* @return The actual target for {@code method} or {@code null} if none found.
*/
// TODO(b/155968472): This should take a parameter `boolean isInterface` and use resolveMethod().
- public DexClassAndMethod lookupSuperTarget(DexMethod method, DexProgramClass context) {
+ public DexClassAndMethod lookupSuperTarget(
+ DexMethod method,
+ DexProgramClass context,
+ AppView<? extends AppInfoWithClassHierarchy> appView) {
+ return lookupSuperTarget(method, context, appView, appView.appInfo());
+ }
+
+ public DexClassAndMethod lookupSuperTarget(
+ DexMethod method,
+ DexProgramClass context,
+ AppView<?> appView,
+ AppInfoWithClassHierarchy appInfo) {
assert checkIfObsolete();
- return unsafeResolveMethodDueToDexFormatLegacy(method).lookupInvokeSuperTarget(context, this);
+ return unsafeResolveMethodDueToDexFormatLegacy(method)
+ .lookupInvokeSuperTarget(context, appView, appInfo);
}
// TODO(b/155968472): This should take a parameter `boolean isInterface` and use resolveMethod().
- public DexClassAndMethod lookupSuperTarget(DexMethod method, ProgramMethod context) {
- return lookupSuperTarget(method, context.getHolder());
+ public final DexClassAndMethod lookupSuperTarget(
+ DexMethod method,
+ ProgramMethod context,
+ AppView<? extends AppInfoWithClassHierarchy> appView) {
+ return lookupSuperTarget(method, context, appView, appView.appInfo());
+ }
+
+ public final DexClassAndMethod lookupSuperTarget(
+ DexMethod method,
+ ProgramMethod context,
+ AppView<?> appView,
+ AppInfoWithClassHierarchy appInfo) {
+ return lookupSuperTarget(method, context.getHolder(), appView, appInfo);
}
/**
@@ -661,14 +689,37 @@
* @return The actual target for {@code method} or {@code null} if none found.
*/
// TODO(b/155968472): This should take a parameter `boolean isInterface` and use resolveMethod().
- public DexEncodedMethod lookupDirectTarget(DexMethod method, DexProgramClass context) {
+ public DexEncodedMethod lookupDirectTarget(
+ DexMethod method,
+ DexProgramClass context,
+ AppView<? extends AppInfoWithClassHierarchy> appView) {
+ return lookupDirectTarget(method, context, appView, appView.appInfo());
+ }
+
+ public DexEncodedMethod lookupDirectTarget(
+ DexMethod method,
+ DexProgramClass context,
+ AppView<?> appView,
+ AppInfoWithClassHierarchy appInfo) {
assert checkIfObsolete();
- return unsafeResolveMethodDueToDexFormatLegacy(method).lookupInvokeDirectTarget(context, this);
+ return unsafeResolveMethodDueToDexFormatLegacy(method)
+ .lookupInvokeDirectTarget(context, appView, appInfo);
}
// TODO(b/155968472): This should take a parameter `boolean isInterface` and use resolveMethod().
- public DexEncodedMethod lookupDirectTarget(DexMethod method, ProgramMethod context) {
- return lookupDirectTarget(method, context.getHolder());
+ public DexEncodedMethod lookupDirectTarget(
+ DexMethod method,
+ ProgramMethod context,
+ AppView<? extends AppInfoWithClassHierarchy> appView) {
+ return lookupDirectTarget(method, context, appView, appView.appInfo());
+ }
+
+ public DexEncodedMethod lookupDirectTarget(
+ DexMethod method,
+ ProgramMethod context,
+ AppView<?> appView,
+ AppInfoWithClassHierarchy appInfo) {
+ return lookupDirectTarget(method, context.getHolder(), appView, appInfo);
}
/**
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 9560129..92848aa 100644
--- a/src/main/java/com/android/tools/r8/graph/AppView.java
+++ b/src/main/java/com/android/tools/r8/graph/AppView.java
@@ -9,7 +9,7 @@
import com.android.tools.r8.contexts.CompilationContext;
import com.android.tools.r8.contexts.CompilationContext.ProcessorContext;
import com.android.tools.r8.errors.dontwarn.DontWarnConfiguration;
-import com.android.tools.r8.experimental.startup.StartupOrder;
+import com.android.tools.r8.experimental.startup.StartupProfile;
import com.android.tools.r8.features.ClassToFeatureSplitMap;
import com.android.tools.r8.graph.DexValue.DexValueString;
import com.android.tools.r8.graph.GraphLens.NonIdentityGraphLens;
@@ -87,6 +87,8 @@
private ProguardCompatibilityActions proguardCompatibilityActions;
private RootSet rootSet;
private MainDexRootSet mainDexRootSet = null;
+ private StartupProfile startupProfile;
+
// This should preferably always be obtained via AppInfoWithLiveness.
// Currently however the liveness may be downgraded thus loosing the computed keep info.
private KeepInfoCollection keepInfo = null;
@@ -138,14 +140,22 @@
private AppView(
T appInfo,
ArtProfileCollection artProfileCollection,
+ StartupProfile startupProfile,
WholeProgramOptimizations wholeProgramOptimizations,
TypeRewriter mapper) {
- this(appInfo, artProfileCollection, wholeProgramOptimizations, mapper, Timing.empty());
+ this(
+ appInfo,
+ artProfileCollection,
+ startupProfile,
+ wholeProgramOptimizations,
+ mapper,
+ Timing.empty());
}
private AppView(
T appInfo,
ArtProfileCollection artProfileCollection,
+ StartupProfile startupProfile,
WholeProgramOptimizations wholeProgramOptimizations,
TypeRewriter mapper,
Timing timing) {
@@ -155,6 +165,7 @@
timing.time(
"Compilation context", () -> CompilationContext.createInitialContext(options()));
this.artProfileCollection = artProfileCollection;
+ this.startupProfile = startupProfile;
this.dontWarnConfiguration =
timing.time(
"Dont warn config",
@@ -200,6 +211,7 @@
return new AppView<>(
appInfo,
ArtProfileCollection.createInitialArtProfileCollection(appInfo, appInfo.options()),
+ StartupProfile.empty(),
WholeProgramOptimizations.OFF,
defaultTypeRewriter(appInfo));
}
@@ -208,6 +220,7 @@
return new AppView<>(
appInfo,
ArtProfileCollection.empty(),
+ StartupProfile.empty(),
WholeProgramOptimizations.OFF,
defaultTypeRewriter(appInfo));
}
@@ -217,6 +230,7 @@
return new AppView<>(
appInfo,
ArtProfileCollection.createInitialArtProfileCollection(appInfo, appInfo.options()),
+ StartupProfile.empty(),
WholeProgramOptimizations.OFF,
mapper,
timing);
@@ -230,17 +244,16 @@
DexApplication application, MainDexInfo mainDexInfo) {
ClassToFeatureSplitMap classToFeatureSplitMap =
ClassToFeatureSplitMap.createInitialClassToFeatureSplitMap(application.options);
- StartupOrder startupOrder = StartupOrder.createInitialStartupOrderForR8(application);
AppInfoWithClassHierarchy appInfo =
AppInfoWithClassHierarchy.createInitialAppInfoWithClassHierarchy(
application,
classToFeatureSplitMap,
mainDexInfo,
- GlobalSyntheticsStrategy.forSingleOutputMode(),
- startupOrder);
+ GlobalSyntheticsStrategy.forSingleOutputMode());
return new AppView<>(
appInfo,
ArtProfileCollection.createInitialArtProfileCollection(appInfo, appInfo.options()),
+ StartupProfile.createInitialStartupProfileForR8(application),
WholeProgramOptimizations.ON,
defaultTypeRewriter(appInfo));
}
@@ -249,6 +262,7 @@
return new AppView<>(
appInfo,
ArtProfileCollection.createInitialArtProfileCollection(appInfo, appInfo.options()),
+ StartupProfile.empty(),
WholeProgramOptimizations.OFF,
mapper);
}
@@ -257,6 +271,7 @@
return new AppView<>(
appInfo,
ArtProfileCollection.empty(),
+ StartupProfile.empty(),
WholeProgramOptimizations.OFF,
defaultTypeRewriter(appInfo));
}
@@ -266,6 +281,7 @@
return new AppView<>(
appInfo,
ArtProfileCollection.empty(),
+ StartupProfile.empty(),
WholeProgramOptimizations.ON,
defaultTypeRewriter(appInfo));
}
@@ -361,6 +377,14 @@
this.artProfileCollection = artProfileCollection;
}
+ public StartupProfile getStartupProfile() {
+ return startupProfile;
+ }
+
+ public void setStartupProfile(StartupProfile startupProfile) {
+ this.startupProfile = startupProfile;
+ }
+
public AssumeInfoCollection getAssumeInfoCollection() {
return assumeInfoCollection;
}
@@ -827,6 +851,7 @@
if (hasRootSet()) {
rootSet.pruneItems(prunedItems);
}
+ setStartupProfile(getStartupProfile().withoutPrunedItems(prunedItems, getSyntheticItems()));
if (hasMainDexRootSet()) {
setMainDexRootSet(mainDexRootSet.withoutPrunedItems(prunedItems));
}
@@ -946,6 +971,7 @@
if (appView.hasRootSet()) {
appView.setRootSet(appView.rootSet().rewrittenWithLens(lens));
}
+ appView.setStartupProfile(appView.getStartupProfile().rewrittenWithLens(lens));
});
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexAnnotation.java b/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
index e24a22c..f72877a 100644
--- a/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
+++ b/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
@@ -62,7 +62,7 @@
private static final int UNKNOWN_API_LEVEL = -1;
private static final int NOT_SET_API_LEVEL = -2;
- private static void specify(StructuralSpecification<DexAnnotation, ?> spec) {
+ protected static void specify(StructuralSpecification<DexAnnotation, ?> spec) {
spec.withItem(a -> a.annotation).withInt(a -> a.visibility);
}
@@ -71,6 +71,14 @@
this.annotation = annotation;
}
+ public boolean isTypeAnnotation() {
+ return false;
+ }
+
+ public DexTypeAnnotation asTypeAnnotation() {
+ return null;
+ }
+
@Override
public DexAnnotation self() {
return this;
diff --git a/src/main/java/com/android/tools/r8/graph/DexAnnotationSet.java b/src/main/java/com/android/tools/r8/graph/DexAnnotationSet.java
index bcddd66..1cd2f4b 100644
--- a/src/main/java/com/android/tools/r8/graph/DexAnnotationSet.java
+++ b/src/main/java/com/android/tools/r8/graph/DexAnnotationSet.java
@@ -81,6 +81,8 @@
public static DexType findDuplicateEntryType(List<DexAnnotation> annotations) {
Set<DexType> seenTypes = Sets.newIdentityHashSet();
for (DexAnnotation annotation : annotations) {
+ // This is only reachable from DEX where type annotations are not supported.
+ assert !annotation.isTypeAnnotation();
if (!seenTypes.add(annotation.annotation.type)) {
return annotation.annotation.type;
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexTypeAnnotation.java b/src/main/java/com/android/tools/r8/graph/DexTypeAnnotation.java
new file mode 100644
index 0000000..99dadb8
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/graph/DexTypeAnnotation.java
@@ -0,0 +1,70 @@
+// 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.graph;
+
+import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.dex.MixedSectionCollection;
+import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.utils.structural.StructuralMapping;
+import org.objectweb.asm.TypePath;
+
+public class DexTypeAnnotation extends DexAnnotation {
+
+ private final int typeRef;
+ private final TypePath typePath;
+
+ public DexTypeAnnotation(
+ int visibility, DexEncodedAnnotation annotation, int typeRef, TypePath typePath) {
+ super(visibility, annotation);
+ this.typeRef = typeRef;
+ this.typePath = typePath;
+ }
+
+ @Override
+ public boolean isTypeAnnotation() {
+ return true;
+ }
+
+ @Override
+ public DexTypeAnnotation asTypeAnnotation() {
+ return this;
+ }
+
+ @Override
+ public void collectIndexedItems(AppView<?> appView, IndexedItemCollection indexedItems) {
+ throw new Unreachable("Should not collect type annotation in DEX");
+ }
+
+ @Override
+ void collectMixedSectionItems(MixedSectionCollection mixedItems) {
+ throw new Unreachable("Should not collect type annotation in DEX");
+ }
+
+ public int getTypeRef() {
+ return typeRef;
+ }
+
+ public TypePath getTypePath() {
+ return typePath;
+ }
+
+ @Override
+ public StructuralMapping<DexAnnotation> getStructuralMapping() {
+ return spec ->
+ spec.withInt(t -> typeRef)
+ .withIntArray(
+ annotation -> {
+ int totalCount = typePath.getLength() * 2;
+ int[] serializedArr = new int[totalCount];
+ for (int i = 0; i < totalCount; i++) {
+ int startIndex = i * 2;
+ serializedArr[startIndex] = typePath.getStep(i);
+ serializedArr[startIndex + 1] = typePath.getStepArgument(i);
+ }
+ return serializedArr;
+ })
+ .withSpec(DexAnnotation::specify);
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/graph/FieldResolutionResult.java b/src/main/java/com/android/tools/r8/graph/FieldResolutionResult.java
index 196864a..9a6d7cb 100644
--- a/src/main/java/com/android/tools/r8/graph/FieldResolutionResult.java
+++ b/src/main/java/com/android/tools/r8/graph/FieldResolutionResult.java
@@ -197,8 +197,8 @@
@Override
public OptionalBool isAccessibleFrom(
- ProgramDefinition context, AppInfoWithClassHierarchy appInfo) {
- return AccessControl.isMemberAccessible(this, context, appInfo);
+ ProgramDefinition context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
+ return AccessControl.isMemberAccessible(this, context, appView, appInfo);
}
@Override
@@ -382,7 +382,7 @@
@Override
public OptionalBool isAccessibleFrom(
- ProgramDefinition context, AppInfoWithClassHierarchy appInfo) {
+ ProgramDefinition context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
throw new Unimplemented("Should not be called on MultipleFieldResolutionResult");
}
@@ -456,7 +456,7 @@
@Override
public OptionalBool isAccessibleFrom(
- ProgramDefinition context, AppInfoWithClassHierarchy appInfo) {
+ ProgramDefinition context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
return OptionalBool.FALSE;
}
diff --git a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
index 76ca9ac..368ffea 100644
--- a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
+++ b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
@@ -56,6 +56,7 @@
import java.util.Objects;
import java.util.Set;
import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.zip.CRC32;
import org.objectweb.asm.AnnotationVisitor;
@@ -175,22 +176,46 @@
return MethodAccessFlags.fromCfAccessFlags(cleanAccessFlags(access), isConstructor);
}
- private static AnnotationVisitor createAnnotationVisitor(String desc, boolean visible,
+ private static AnnotationVisitor createAnnotationVisitor(
+ String desc,
+ boolean visible,
List<DexAnnotation> annotations,
- JarApplicationReader application) {
- assert annotations != null;
+ JarApplicationReader application,
+ BiFunction<Integer, DexEncodedAnnotation, DexAnnotation> newAnnotationConstructor) {
+ assert newAnnotationConstructor != null;
if (visible || retainCompileTimeAnnotation(desc, application)) {
- int visiblity = visible ? DexAnnotation.VISIBILITY_RUNTIME : DexAnnotation.VISIBILITY_BUILD;
+ int visibility = visible ? DexAnnotation.VISIBILITY_RUNTIME : DexAnnotation.VISIBILITY_BUILD;
return new CreateAnnotationVisitor(
application,
(names, values) ->
annotations.add(
- new DexAnnotation(
- visiblity, createEncodedAnnotation(desc, names, values, application))));
+ newAnnotationConstructor.apply(
+ visibility, createEncodedAnnotation(desc, names, values, application))));
}
return null;
}
+ private static AnnotationVisitor createTypeAnnotationVisitor(
+ String desc,
+ boolean visible,
+ List<DexAnnotation> annotations,
+ JarApplicationReader application,
+ int typeRef,
+ TypePath typePath) {
+ assert annotations != null;
+ // Java 8 type annotations are not supported by Dex. Ignore them.
+ if (!application.options.isGeneratingClassFiles()) {
+ return null;
+ }
+ return createAnnotationVisitor(
+ desc,
+ visible,
+ annotations,
+ application,
+ (visibility, annotation) ->
+ new DexTypeAnnotation(visibility, annotation, typeRef, typePath));
+ }
+
private static boolean retainCompileTimeAnnotation(
String desc, JarApplicationReader application) {
return DexAnnotation.retainCompileTimeAnnotation(
@@ -446,14 +471,15 @@
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
- return createAnnotationVisitor(desc, visible, getAnnotations(), application);
+ return createAnnotationVisitor(
+ desc, visible, getAnnotations(), application, DexAnnotation::new);
}
@Override
public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc,
boolean visible) {
- // Java 8 type annotations are not supported by Dex, thus ignore them.
- return null;
+ return createTypeAnnotationVisitor(
+ desc, visible, getAnnotations(), application, typeRef, typePath);
}
@Override
@@ -674,14 +700,15 @@
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
- return createAnnotationVisitor(desc, visible, getAnnotations(), parent.application);
+ return createAnnotationVisitor(
+ desc, visible, getAnnotations(), parent.application, DexAnnotation::new);
}
@Override
public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc,
boolean visible) {
- // Java 8 type annotations are not supported by Dex, thus ignore them.
- return null;
+ return createTypeAnnotationVisitor(
+ desc, visible, getAnnotations(), parent.application, typeRef, typePath);
}
@Override
@@ -815,7 +842,8 @@
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
- return createAnnotationVisitor(desc, visible, getAnnotations(), parent.application);
+ return createAnnotationVisitor(
+ desc, visible, getAnnotations(), parent.application, DexAnnotation::new);
}
@Override
@@ -827,13 +855,6 @@
}
@Override
- public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc,
- boolean visible) {
- // Java 8 type annotations are not supported by Dex, thus ignore them.
- return null;
- }
-
- @Override
public void visitAnnotableParameterCount(int parameterCount, boolean visible) {
if (annotableParameterCount != -1) {
// TODO(113565942): We assume that the runtime visible and runtime invisible parameter
@@ -856,28 +877,42 @@
}
}
assert mv == null;
- return createAnnotationVisitor(desc, visible,
- parameterAnnotationsLists.get(parameter), parent.application);
+ return createAnnotationVisitor(
+ desc,
+ visible,
+ parameterAnnotationsLists.get(parameter),
+ parent.application,
+ DexAnnotation::new);
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ int typeRef, TypePath typePath, String desc, boolean visible) {
+ return createTypeAnnotationVisitor(
+ desc, visible, getAnnotations(), parent.application, typeRef, typePath);
}
@Override
public AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String desc,
boolean visible) {
- // Java 8 type annotations are not supported by Dex, thus ignore them.
+ // We do not support code type annotations since that would require us to maintain these
+ // through IR where we may as well invalidate any assumptions made on the code.
return null;
}
@Override
public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, TypePath typePath,
Label[] start, Label[] end, int[] index, String desc, boolean visible) {
- // Java 8 type annotations are not supported by Dex, thus ignore them.
+ // We do not support code type annotations since that would require us to maintain these
+ // through IR where we may as well invalidate any assumptions made on the code.
return null;
}
@Override
public AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath, String desc,
boolean visible) {
- // Java 8 type annotations are not supported by Dex, thus ignore them.
+ // We do not support code type annotations since that would require us to maintain these
+ // through IR where we may as well invalidate any assumptions made on the code.
return null;
}
diff --git a/src/main/java/com/android/tools/r8/graph/MemberResolutionResult.java b/src/main/java/com/android/tools/r8/graph/MemberResolutionResult.java
index e5467ff..47f8a33 100644
--- a/src/main/java/com/android/tools/r8/graph/MemberResolutionResult.java
+++ b/src/main/java/com/android/tools/r8/graph/MemberResolutionResult.java
@@ -17,14 +17,14 @@
public abstract SuccessfulMemberResolutionResult<D, R> asSuccessfulMemberResolutionResult();
- public abstract OptionalBool isAccessibleFrom(
- ProgramDefinition context, AppInfoWithClassHierarchy appInfo);
-
public final OptionalBool isAccessibleFrom(
ProgramDefinition context, AppView<? extends AppInfoWithClassHierarchy> appView) {
- return isAccessibleFrom(context, appView.appInfo());
+ return isAccessibleFrom(context, appView, appView.appInfo());
}
+ public abstract OptionalBool isAccessibleFrom(
+ ProgramDefinition context, AppView<?> appView, AppInfoWithClassHierarchy appInfo);
+
/**
* Returns true if resolution failed.
*
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 ef0d7ff..f2a07b1 100644
--- a/src/main/java/com/android/tools/r8/graph/MethodResolutionResult.java
+++ b/src/main/java/com/android/tools/r8/graph/MethodResolutionResult.java
@@ -75,7 +75,13 @@
return false;
}
- public boolean isNoSuchMethodErrorResult(DexClass context, AppInfoWithClassHierarchy appInfo) {
+ public final boolean isNoSuchMethodErrorResult(
+ DexClass context, AppView<? extends AppInfoWithClassHierarchy> appView) {
+ return isNoSuchMethodErrorResult(context, appView, appView.appInfo());
+ }
+
+ public boolean isNoSuchMethodErrorResult(
+ DexClass context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
return false;
}
@@ -83,7 +89,13 @@
return false;
}
- public boolean isIllegalAccessErrorResult(DexClass context, AppInfoWithClassHierarchy appInfo) {
+ public final boolean isIllegalAccessErrorResult(
+ DexClass context, AppView<? extends AppInfoWithClassHierarchy> appView) {
+ return isIllegalAccessErrorResult(context, appView, appView.appInfo());
+ }
+
+ public boolean isIllegalAccessErrorResult(
+ DexClass context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
return false;
}
@@ -139,41 +151,57 @@
}
public abstract OptionalBool isAccessibleForVirtualDispatchFrom(
- ProgramDefinition context, AppInfoWithClassHierarchy appInfo);
+ ProgramDefinition context, AppView<? extends AppInfoWithClassHierarchy> appView);
public abstract boolean isVirtualTarget();
/** Lookup the single target of an invoke-special on this resolution result if possible. */
public abstract DexClassAndMethod lookupInvokeSpecialTarget(
- DexProgramClass context, AppInfoWithClassHierarchy appInfo);
+ DexProgramClass context, AppView<? extends AppInfoWithClassHierarchy> appView);
+
+ public final DexClassAndMethod lookupInvokeSuperTarget(
+ DexProgramClass context, AppView<? extends AppInfoWithClassHierarchy> appView) {
+ return lookupInvokeSuperTarget(context, appView, appView.appInfo());
+ }
/** Lookup the single target of an invoke-super on this resolution result if possible. */
public abstract DexClassAndMethod lookupInvokeSuperTarget(
- DexProgramClass context, AppInfoWithClassHierarchy appInfo);
+ DexProgramClass context, AppView<?> appView, AppInfoWithClassHierarchy appInfo);
/** Lookup the single target of an invoke-direct on this resolution result if possible. */
+ public final DexEncodedMethod lookupInvokeDirectTarget(
+ DexProgramClass context, AppView<? extends AppInfoWithClassHierarchy> appView) {
+ return lookupInvokeDirectTarget(context, appView, appView.appInfo());
+ }
+
public abstract DexEncodedMethod lookupInvokeDirectTarget(
- DexProgramClass context, AppInfoWithClassHierarchy appInfo);
+ DexProgramClass context, AppView<?> appView, AppInfoWithClassHierarchy appInfo);
/** Lookup the single target of an invoke-static on this resolution result if possible. */
+ public final DexEncodedMethod lookupInvokeStaticTarget(
+ DexProgramClass context, AppView<? extends AppInfoWithClassHierarchy> appView) {
+ return lookupInvokeStaticTarget(context, appView, appView.appInfo());
+ }
+
public abstract DexEncodedMethod lookupInvokeStaticTarget(
- DexProgramClass context, AppInfoWithClassHierarchy appInfo);
+ DexProgramClass context, AppView<?> appView, AppInfoWithClassHierarchy appInfo);
public abstract LookupResult lookupVirtualDispatchTargets(
DexProgramClass context,
- AppInfoWithClassHierarchy appInfo,
+ AppView<? extends AppInfoWithClassHierarchy> appView,
InstantiatedSubTypeInfo instantiatedInfo,
PinnedPredicate pinnedPredicate);
public final LookupResult lookupVirtualDispatchTargets(
- DexProgramClass context, AppInfoWithLiveness appInfo) {
+ DexProgramClass context, AppView<AppInfoWithLiveness> appView) {
+ AppInfoWithLiveness appInfo = appView.appInfo();
return lookupVirtualDispatchTargets(
- context, appInfo, appInfo, appInfo::isPinnedNotProgramOrLibraryOverride);
+ context, appView, appInfo, appInfo::isPinnedNotProgramOrLibraryOverride);
}
public abstract LookupResult lookupVirtualDispatchTargets(
DexProgramClass context,
- AppInfoWithLiveness appInfo,
+ AppView<AppInfoWithLiveness> appView,
DexProgramClass refinedReceiverUpperBound,
DexProgramClass refinedReceiverLowerBound);
@@ -309,15 +337,15 @@
@Override
public OptionalBool isAccessibleFrom(
- ProgramDefinition context, AppInfoWithClassHierarchy appInfo) {
- return AccessControl.isMemberAccessible(this, context, appInfo);
+ ProgramDefinition context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
+ return AccessControl.isMemberAccessible(this, context, appView, appInfo);
}
@Override
public OptionalBool isAccessibleForVirtualDispatchFrom(
- ProgramDefinition context, AppInfoWithClassHierarchy appInfo) {
+ ProgramDefinition context, AppView<? extends AppInfoWithClassHierarchy> appView) {
if (resolvedMethod.isVirtualMethod()) {
- return isAccessibleFrom(context, appInfo);
+ return isAccessibleFrom(context, appView, appView.appInfo());
}
return OptionalBool.FALSE;
}
@@ -335,9 +363,10 @@
*/
@Override
public DexClassAndMethod lookupInvokeSpecialTarget(
- DexProgramClass context, AppInfoWithClassHierarchy appInfo) {
+ DexProgramClass context, AppView<? extends AppInfoWithClassHierarchy> appView) {
// If the resolution is non-accessible then no target exists.
- if (isAccessibleFrom(context, appInfo).isPossiblyTrue()) {
+ AppInfoWithClassHierarchy appInfo = appView.appInfo();
+ if (isAccessibleFrom(context, appView).isPossiblyTrue()) {
return internalInvokeSpecialOrSuper(
context, appInfo, (sup, sub) -> isSuperclass(sup, sub, appInfo));
}
@@ -372,14 +401,14 @@
*/
@Override
public DexClassAndMethod lookupInvokeSuperTarget(
- DexProgramClass context, AppInfoWithClassHierarchy appInfo) {
+ DexProgramClass context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
if (resolvedMethod.isInstanceInitializer()
|| (initialResolutionHolder != context
&& !isSuperclass(initialResolutionHolder, context, appInfo))) {
// If the target is <init> or not on a super class then the call is invalid.
return null;
}
- if (isAccessibleFrom(context, appInfo).isPossiblyTrue()) {
+ if (isAccessibleFrom(context, appView, appInfo).isPossiblyTrue()) {
return internalInvokeSpecialOrSuper(context, appInfo, (sup, sub) -> true);
}
return null;
@@ -397,8 +426,8 @@
*/
@Override
public DexEncodedMethod lookupInvokeStaticTarget(
- DexProgramClass context, AppInfoWithClassHierarchy appInfo) {
- if (isAccessibleFrom(context, appInfo).isFalse()) {
+ DexProgramClass context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
+ if (isAccessibleFrom(context, appView, appInfo).isFalse()) {
return null;
}
if (resolvedMethod.isStatic()) {
@@ -418,8 +447,8 @@
*/
@Override
public DexEncodedMethod lookupInvokeDirectTarget(
- DexProgramClass context, AppInfoWithClassHierarchy appInfo) {
- if (isAccessibleFrom(context, appInfo).isFalse()) {
+ DexProgramClass context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
+ if (isAccessibleFrom(context, appView, appInfo).isFalse()) {
return null;
}
if (resolvedMethod.isDirectMethod()) {
@@ -513,13 +542,14 @@
@Override
public LookupResult lookupVirtualDispatchTargets(
DexProgramClass context,
- AppInfoWithClassHierarchy appInfo,
+ AppView<? extends AppInfoWithClassHierarchy> appView,
InstantiatedSubTypeInfo instantiatedInfo,
PinnedPredicate pinnedPredicate) {
// Check that the initial resolution holder is accessible from the context.
+ AppInfoWithClassHierarchy appInfo = appView.appInfo();
assert appInfo.isSubtype(initialResolutionHolder.type, resolvedHolder.type)
: initialResolutionHolder.type + " is not a subtype of " + resolvedHolder.type;
- if (context != null && isAccessibleFrom(context, appInfo).isFalse()) {
+ if (context != null && isAccessibleFrom(context, appView).isFalse()) {
return LookupResult.createFailedResult();
}
if (resolvedMethod.isPrivateMethod()) {
@@ -558,7 +588,7 @@
},
lambda -> {
assert resolvedHolder.isInterface()
- || resolvedHolder.type == appInfo.dexItemFactory().objectType;
+ || resolvedHolder.type == appView.dexItemFactory().objectType;
LookupTarget target =
lookupVirtualDispatchTarget(
lambda,
@@ -582,9 +612,10 @@
@Override
public LookupResult lookupVirtualDispatchTargets(
DexProgramClass context,
- AppInfoWithLiveness appInfo,
+ AppView<AppInfoWithLiveness> appView,
DexProgramClass refinedReceiverUpperBound,
DexProgramClass refinedReceiverLowerBound) {
+ AppInfoWithLiveness appInfo = appView.appInfo();
assert refinedReceiverUpperBound != null;
assert appInfo.isSubtype(refinedReceiverUpperBound.type, initialResolutionHolder.type);
assert refinedReceiverLowerBound == null
@@ -600,7 +631,7 @@
LookupResult lookupResult =
lookupVirtualDispatchTargets(
context,
- appInfo,
+ appView,
instantiatedSubTypeInfo,
appInfo::isPinnedNotProgramOrLibraryOverride);
if (hasInstantiatedLambdas.get() && lookupResult.isLookupResultSuccess()) {
@@ -977,32 +1008,32 @@
@Override
public final DexClassAndMethod lookupInvokeSpecialTarget(
- DexProgramClass context, AppInfoWithClassHierarchy appInfo) {
+ DexProgramClass context, AppView<? extends AppInfoWithClassHierarchy> appView) {
return null;
}
@Override
public DexClassAndMethod lookupInvokeSuperTarget(
- DexProgramClass context, AppInfoWithClassHierarchy appInfo) {
+ DexProgramClass context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
return null;
}
@Override
public DexEncodedMethod lookupInvokeStaticTarget(
- DexProgramClass context, AppInfoWithClassHierarchy appInfo) {
+ DexProgramClass context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
return null;
}
@Override
public DexEncodedMethod lookupInvokeDirectTarget(
- DexProgramClass context, AppInfoWithClassHierarchy appInfo) {
+ DexProgramClass context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
return null;
}
@Override
public LookupResult lookupVirtualDispatchTargets(
DexProgramClass context,
- AppInfoWithClassHierarchy appInfo,
+ AppView<? extends AppInfoWithClassHierarchy> appView,
InstantiatedSubTypeInfo instantiatedInfo,
PinnedPredicate pinnedPredicate) {
return LookupResult.getIncompleteEmptyResult();
@@ -1011,7 +1042,7 @@
@Override
public LookupResult lookupVirtualDispatchTargets(
DexProgramClass context,
- AppInfoWithLiveness appInfo,
+ AppView<AppInfoWithLiveness> appView,
DexProgramClass refinedReceiverUpperBound,
DexProgramClass refinedReceiverLowerBound) {
return LookupResult.getIncompleteEmptyResult();
@@ -1050,13 +1081,13 @@
@Override
public OptionalBool isAccessibleFrom(
- ProgramDefinition context, AppInfoWithClassHierarchy appInfo) {
+ ProgramDefinition context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
return OptionalBool.TRUE;
}
@Override
public OptionalBool isAccessibleForVirtualDispatchFrom(
- ProgramDefinition context, AppInfoWithClassHierarchy appInfo) {
+ ProgramDefinition context, AppView<? extends AppInfoWithClassHierarchy> appView) {
return OptionalBool.TRUE;
}
@@ -1110,13 +1141,13 @@
@Override
public OptionalBool isAccessibleFrom(
- ProgramDefinition context, AppInfoWithClassHierarchy appInfo) {
+ ProgramDefinition context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
return OptionalBool.FALSE;
}
@Override
public OptionalBool isAccessibleForVirtualDispatchFrom(
- ProgramDefinition context, AppInfoWithClassHierarchy appInfo) {
+ ProgramDefinition context, AppView<? extends AppInfoWithClassHierarchy> appView) {
return OptionalBool.FALSE;
}
@@ -1218,7 +1249,8 @@
}
@Override
- public boolean isNoSuchMethodErrorResult(DexClass context, AppInfoWithClassHierarchy appInfo) {
+ public boolean isNoSuchMethodErrorResult(
+ DexClass context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
return true;
}
@@ -1262,14 +1294,15 @@
}
@Override
- public boolean isIllegalAccessErrorResult(DexClass context, AppInfoWithClassHierarchy appInfo) {
+ public boolean isIllegalAccessErrorResult(
+ DexClass context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
if (!hasMethodsCausingError()) {
return false;
}
BooleanBox seenNoAccess = new BooleanBox(false);
forEachFailureDependency(
type ->
- appInfo
+ appView
.contextIndependentDefinitionForWithResolutionResult(type)
.forEachClassResolutionResult(
clazz ->
@@ -1278,27 +1311,28 @@
clazz,
context,
appInfo.getClassToFeatureSplitMap(),
- appInfo.options(),
- appInfo.getStartupOrder(),
- appInfo.getSyntheticItems())
+ appView.options(),
+ appView.getStartupProfile(),
+ appView.getSyntheticItems())
.isPossiblyFalse())),
method -> {
- DexClass holder = appInfo.definitionFor(method.getHolderType());
+ DexClass holder = appView.definitionFor(method.getHolderType());
DexClassAndMethod classAndMethod = DexClassAndMethod.create(holder, method);
seenNoAccess.or(
AccessControl.isMemberAccessible(
- classAndMethod, initialResolutionHolder, context, appInfo)
+ classAndMethod, initialResolutionHolder, context, appView, appInfo)
.isPossiblyFalse());
});
return seenNoAccess.get();
}
@Override
- public boolean isNoSuchMethodErrorResult(DexClass context, AppInfoWithClassHierarchy appInfo) {
+ public boolean isNoSuchMethodErrorResult(
+ DexClass context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
if (!hasMethodsCausingError()) {
return true;
}
- if (isIllegalAccessErrorResult(context, appInfo)) {
+ if (isIllegalAccessErrorResult(context, appView, appInfo)) {
return false;
}
// At this point we know we have methods causing errors but we have access to them. To be
@@ -1345,13 +1379,13 @@
@Override
public OptionalBool isAccessibleFrom(
- ProgramDefinition context, AppInfoWithClassHierarchy appInfo) {
+ ProgramDefinition context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
throw new Unreachable("Should not be called on MultipleFieldResolutionResult");
}
@Override
public OptionalBool isAccessibleForVirtualDispatchFrom(
- ProgramDefinition context, AppInfoWithClassHierarchy appInfo) {
+ ProgramDefinition context, AppView<? extends AppInfoWithClassHierarchy> appView) {
throw new Unreachable("Should not be called on MultipleFieldResolutionResult");
}
@@ -1362,32 +1396,32 @@
@Override
public DexClassAndMethod lookupInvokeSpecialTarget(
- DexProgramClass context, AppInfoWithClassHierarchy appInfo) {
+ DexProgramClass context, AppView<? extends AppInfoWithClassHierarchy> appView) {
throw new Unreachable("Should not be called on MultipleFieldResolutionResult");
}
@Override
public DexClassAndMethod lookupInvokeSuperTarget(
- DexProgramClass context, AppInfoWithClassHierarchy appInfo) {
+ DexProgramClass context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
throw new Unreachable("Should not be called on MultipleFieldResolutionResult");
}
@Override
public DexEncodedMethod lookupInvokeDirectTarget(
- DexProgramClass context, AppInfoWithClassHierarchy appInfo) {
+ DexProgramClass context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
throw new Unreachable("Should not be called on MultipleFieldResolutionResult");
}
@Override
public DexEncodedMethod lookupInvokeStaticTarget(
- DexProgramClass context, AppInfoWithClassHierarchy appInfo) {
+ DexProgramClass context, AppView<?> appView, AppInfoWithClassHierarchy appInfo) {
throw new Unreachable("Should not be called on MultipleFieldResolutionResult");
}
@Override
public LookupResult lookupVirtualDispatchTargets(
DexProgramClass context,
- AppInfoWithClassHierarchy appInfo,
+ AppView<? extends AppInfoWithClassHierarchy> appView,
InstantiatedSubTypeInfo instantiatedInfo,
PinnedPredicate pinnedPredicate) {
throw new Unreachable("Should not be called on MultipleFieldResolutionResult");
@@ -1396,7 +1430,7 @@
@Override
public LookupResult lookupVirtualDispatchTargets(
DexProgramClass context,
- AppInfoWithLiveness appInfo,
+ AppView<AppInfoWithLiveness> appView,
DexProgramClass refinedReceiverUpperBound,
DexProgramClass refinedReceiverLowerBound) {
throw new Unreachable("Should not be called on MultipleFieldResolutionResult");
diff --git a/src/main/java/com/android/tools/r8/graph/UseRegistry.java b/src/main/java/com/android/tools/r8/graph/UseRegistry.java
index f5a1aad..be1b904c06 100644
--- a/src/main/java/com/android/tools/r8/graph/UseRegistry.java
+++ b/src/main/java/com/android/tools/r8/graph/UseRegistry.java
@@ -12,7 +12,7 @@
public abstract class UseRegistry<T extends Definition> {
- private final AppView<?> appView;
+ protected final AppView<?> appView;
private final T context;
private TraversalContinuation<?, ?> continuation = TraversalContinuation.doContinue();
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java
index 96bf9a5..1cf6415 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java
@@ -29,7 +29,7 @@
import com.android.tools.r8.ir.analysis.value.NumberFromIntervalValue;
import com.android.tools.r8.ir.optimize.info.OptimizationFeedback;
import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
+import com.android.tools.r8.profile.art.rewriting.ProfileCollectionAdditions;
import com.android.tools.r8.utils.SetUtils;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
@@ -107,13 +107,11 @@
}
void mergeDirectMethods(
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
SyntheticArgumentClass syntheticArgumentClass,
SyntheticInitializerConverter.Builder syntheticInitializerConverterBuilder) {
mergeInstanceInitializers(
- artProfileCollectionAdditions,
- syntheticArgumentClass,
- syntheticInitializerConverterBuilder);
+ profileCollectionAdditions, syntheticArgumentClass, syntheticInitializerConverterBuilder);
mergeStaticClassInitializers(syntheticInitializerConverterBuilder);
group.forEach(this::mergeDirectMethods);
}
@@ -192,38 +190,36 @@
}
void mergeInstanceInitializers(
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
SyntheticArgumentClass syntheticArgumentClass,
SyntheticInitializerConverter.Builder syntheticInitializerConverterBuilder) {
instanceInitializerMergers.forEach(
merger ->
merger.merge(
- artProfileCollectionAdditions,
+ profileCollectionAdditions,
classMethodsBuilder,
syntheticArgumentClass,
syntheticInitializerConverterBuilder));
}
void mergeMethods(
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
SyntheticArgumentClass syntheticArgumentClass,
SyntheticInitializerConverter.Builder syntheticInitializerConverterBuilder,
Consumer<VirtuallyMergedMethodsKeepInfo> virtuallyMergedMethodsKeepInfoConsumer) {
- mergeVirtualMethods(artProfileCollectionAdditions, virtuallyMergedMethodsKeepInfoConsumer);
+ mergeVirtualMethods(profileCollectionAdditions, virtuallyMergedMethodsKeepInfoConsumer);
mergeDirectMethods(
- artProfileCollectionAdditions,
- syntheticArgumentClass,
- syntheticInitializerConverterBuilder);
+ profileCollectionAdditions, syntheticArgumentClass, syntheticInitializerConverterBuilder);
classMethodsBuilder.setClassMethods(group.getTarget());
}
void mergeVirtualMethods(
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
Consumer<VirtuallyMergedMethodsKeepInfo> virtuallyMergedMethodsKeepInfoConsumer) {
virtualMethodMergers.forEach(
merger ->
merger.merge(
- artProfileCollectionAdditions,
+ profileCollectionAdditions,
classMethodsBuilder,
lensBuilder,
classIdentifiers,
@@ -342,7 +338,7 @@
}
public void mergeGroup(
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
PrunedItems.Builder prunedItemsBuilder,
SyntheticArgumentClass syntheticArgumentClass,
SyntheticInitializerConverter.Builder syntheticInitializerConverterBuilder,
@@ -353,7 +349,7 @@
mergeInterfaces();
mergeFields(prunedItemsBuilder);
mergeMethods(
- artProfileCollectionAdditions,
+ profileCollectionAdditions,
syntheticArgumentClass,
syntheticInitializerConverterBuilder,
virtuallyMergedMethodsKeepInfoConsumer);
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 8fc788b..32dd38f 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
@@ -18,7 +18,7 @@
import com.android.tools.r8.horizontalclassmerging.code.SyntheticInitializerConverter;
import com.android.tools.r8.ir.code.InvokeType;
import com.android.tools.r8.profile.art.ArtProfileCompletenessChecker;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
+import com.android.tools.r8.profile.art.rewriting.ProfileCollectionAdditions;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.shaking.FieldAccessInfoCollectionModifier;
import com.android.tools.r8.shaking.KeepInfoCollection;
@@ -126,8 +126,8 @@
// Merge the classes.
List<ClassMerger> classMergers = initializeClassMergers(codeProvider, lensBuilder, groups);
- ArtProfileCollectionAdditions artProfileCollectionAdditions =
- ArtProfileCollectionAdditions.create(appView);
+ ProfileCollectionAdditions profileCollectionAdditions =
+ ProfileCollectionAdditions.create(appView);
SyntheticArgumentClass syntheticArgumentClass =
mode.isInitial()
? new SyntheticArgumentClass.Builder(appView.withLiveness()).build(groups)
@@ -138,7 +138,7 @@
PrunedItems prunedItems =
applyClassMergers(
classMergers,
- artProfileCollectionAdditions,
+ profileCollectionAdditions,
syntheticArgumentClass,
syntheticInitializerConverterBuilder,
virtuallyMergedMethodsKeepInfos::add);
@@ -155,13 +155,9 @@
HorizontalClassMergerGraphLens horizontalClassMergerGraphLens =
createLens(
- mergedClasses,
- lensBuilder,
- mode,
- artProfileCollectionAdditions,
- syntheticArgumentClass);
- artProfileCollectionAdditions =
- artProfileCollectionAdditions.rewriteMethodReferences(
+ mergedClasses, lensBuilder, mode, profileCollectionAdditions, syntheticArgumentClass);
+ profileCollectionAdditions =
+ profileCollectionAdditions.rewriteMethodReferences(
horizontalClassMergerGraphLens::getNextMethodToInvoke);
assert verifyNoCyclesInInterfaceHierarchies(appView, groups);
@@ -195,8 +191,9 @@
codeProvider.setGraphLens(horizontalClassMergerGraphLens);
// Amend art profile collection.
- artProfileCollectionAdditions
+ profileCollectionAdditions
.setArtProfileCollection(appView.getArtProfileCollection())
+ .setStartupProfile(appView.getStartupProfile())
.commit(appView);
// Record where the synthesized $r8$classId fields are read and written.
@@ -374,14 +371,14 @@
/** Merges all class groups using {@link ClassMerger}. */
private PrunedItems applyClassMergers(
Collection<ClassMerger> classMergers,
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
SyntheticArgumentClass syntheticArgumentClass,
SyntheticInitializerConverter.Builder syntheticInitializerConverterBuilder,
Consumer<VirtuallyMergedMethodsKeepInfo> virtuallyMergedMethodsKeepInfoConsumer) {
PrunedItems.Builder prunedItemsBuilder = PrunedItems.builder().setPrunedApp(appView.app());
for (ClassMerger merger : classMergers) {
merger.mergeGroup(
- artProfileCollectionAdditions,
+ profileCollectionAdditions,
prunedItemsBuilder,
syntheticArgumentClass,
syntheticInitializerConverterBuilder,
@@ -398,14 +395,14 @@
HorizontallyMergedClasses mergedClasses,
HorizontalClassMergerGraphLens.Builder lensBuilder,
Mode mode,
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
SyntheticArgumentClass syntheticArgumentClass) {
return new TreeFixer(
appView,
mergedClasses,
lensBuilder,
mode,
- artProfileCollectionAdditions,
+ profileCollectionAdditions,
syntheticArgumentClass)
.fixupTypeReferences();
}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/InstanceInitializerMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/InstanceInitializerMerger.java
index d827984..e1a6710 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/InstanceInitializerMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/InstanceInitializerMerger.java
@@ -24,7 +24,7 @@
import com.android.tools.r8.ir.conversion.ExtraConstantIntParameter;
import com.android.tools.r8.ir.conversion.ExtraParameter;
import com.android.tools.r8.ir.conversion.ExtraUnusedNullParameter;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
+import com.android.tools.r8.profile.art.rewriting.ProfileCollectionAdditions;
import com.android.tools.r8.utils.ArrayUtils;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.Box;
@@ -298,7 +298,7 @@
/** Synthesize a new method which selects the constructor based on a parameter type. */
void merge(
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
ClassMethodsBuilder classMethodsBuilder,
SyntheticArgumentClass syntheticArgumentClass,
SyntheticInitializerConverter.Builder syntheticInitializerConverterBuilder) {
@@ -324,7 +324,7 @@
// Amend the art profile collection.
if (usedSyntheticArgumentClasses.isSet()) {
for (ProgramMethod instanceInitializer : instanceInitializers) {
- artProfileCollectionAdditions.applyIfContextIsInProfile(
+ profileCollectionAdditions.applyIfContextIsInProfile(
instanceInitializer.getReference(),
additionsBuilder ->
usedSyntheticArgumentClasses.get().forEach(additionsBuilder::addRule));
@@ -353,7 +353,7 @@
instanceInitializer.getReference(), movedInstanceInitializer);
// Amend the art profile collection.
- artProfileCollectionAdditions.applyIfContextIsInProfile(
+ profileCollectionAdditions.applyIfContextIsInProfile(
instanceInitializer.getReference(),
additionsBuilder -> additionsBuilder.addRule(representative));
}
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 a4b8ae0..948c889 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/TreeFixer.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/TreeFixer.java
@@ -21,7 +21,7 @@
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.profile.art.rewriting.ProfileCollectionAdditions;
import com.android.tools.r8.shaking.AnnotationFixer;
import com.android.tools.r8.utils.ArrayUtils;
import com.android.tools.r8.utils.Box;
@@ -49,7 +49,7 @@
private final Mode mode;
private final HorizontalClassMergerGraphLens.Builder lensBuilder;
private final DexItemFactory dexItemFactory;
- private final ArtProfileCollectionAdditions artProfileCollectionAdditions;
+ private final ProfileCollectionAdditions profileCollectionAdditions;
private final SyntheticArgumentClass syntheticArgumentClass;
private final Map<DexProgramClass, DexType> originalSuperTypes = new IdentityHashMap<>();
@@ -61,14 +61,14 @@
HorizontallyMergedClasses mergedClasses,
HorizontalClassMergerGraphLens.Builder lensBuilder,
Mode mode,
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
SyntheticArgumentClass syntheticArgumentClass) {
super(appView);
this.appView = appView;
this.mergedClasses = mergedClasses;
this.mode = mode;
this.lensBuilder = lensBuilder;
- this.artProfileCollectionAdditions = artProfileCollectionAdditions;
+ this.profileCollectionAdditions = profileCollectionAdditions;
this.syntheticArgumentClass = syntheticArgumentClass;
this.dexItemFactory = appView.dexItemFactory();
}
@@ -311,13 +311,13 @@
Set<DexMethod> previousMethodReferences =
lensBuilder.methodMap.getKeys(originalMethodReference);
if (previousMethodReferences.isEmpty()) {
- artProfileCollectionAdditions.applyIfContextIsInProfile(
+ profileCollectionAdditions.applyIfContextIsInProfile(
originalMethodReference,
additionsBuilder ->
usedSyntheticArgumentClasses.get().forEach(additionsBuilder::addRule));
} else {
for (DexMethod previousMethodReference : previousMethodReferences) {
- artProfileCollectionAdditions.applyIfContextIsInProfile(
+ profileCollectionAdditions.applyIfContextIsInProfile(
previousMethodReference,
additionsBuilder ->
usedSyntheticArgumentClasses.get().forEach(additionsBuilder::addRule));
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java
index b47b947..a9dd719 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java
@@ -14,7 +14,7 @@
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.MethodResolutionResult.SingleResolutionResult;
import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
+import com.android.tools.r8.profile.art.rewriting.ProfileCollectionAdditions;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.OptionalBool;
import com.android.tools.r8.utils.structural.Ordered;
@@ -245,7 +245,7 @@
}
public void merge(
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
ClassMethodsBuilder classMethodsBuilder,
HorizontalClassMergerGraphLens.Builder lensBuilder,
Reference2IntMap<DexType> classIdentifiers,
@@ -327,9 +327,9 @@
lensBuilder.recordNewMethodSignature(bridgeMethodReference, newMethodReference);
// Amend the art profile collection.
- if (!artProfileCollectionAdditions.isNop()) {
+ if (!profileCollectionAdditions.isNop()) {
for (ProgramMethod oldMethod : methods) {
- artProfileCollectionAdditions.applyIfContextIsInProfile(
+ profileCollectionAdditions.applyIfContextIsInProfile(
oldMethod.getReference(),
additionsBuilder -> additionsBuilder.addRule(representativeMethod.getReference()));
}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoClassInitializerCycles.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoClassInitializerCycles.java
index b1ad665..2e0a307 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoClassInitializerCycles.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoClassInitializerCycles.java
@@ -106,6 +106,10 @@
this.appView = appView;
}
+ private AppView<AppInfoWithLiveness> appView() {
+ return appView;
+ }
+
// TODO(b/270398965): Replace LinkedList.
@SuppressWarnings("JdkObsolete")
@Override
@@ -407,7 +411,7 @@
class TracerUseRegistry extends UseRegistry<ProgramMethod> {
TracerUseRegistry(ProgramMethod context) {
- super(appView, context);
+ super(appView(), context);
}
private void fail() {
@@ -431,7 +435,7 @@
}
private boolean isClassAlreadyInitializedInCurrentContext(DexProgramClass clazz) {
- return appView.appInfo().isSubtype(getContext().getHolder(), clazz);
+ return appView().appInfo().isSubtype(getContext().getHolder(), clazz);
}
private void triggerClassInitializer(DexProgramClass root) {
@@ -481,7 +485,7 @@
DexMethod rewrittenMethod =
appView.graphLens().lookupInvokeDirect(method, getContext()).getReference();
MethodResolutionResult resolutionResult =
- appView.appInfo().resolveMethodOnClassHolderLegacy(rewrittenMethod);
+ appView().appInfo().resolveMethodOnClassHolderLegacy(rewrittenMethod);
if (resolutionResult.isSingleResolution()
&& resolutionResult.getResolvedHolder().isProgramClass()) {
enqueueMethod(resolutionResult.getResolvedProgramMethod());
@@ -493,7 +497,7 @@
DexMethod rewrittenMethod =
appView.graphLens().lookupInvokeInterface(method, getContext()).getReference();
DexClassAndMethod resolvedMethod =
- appView
+ appView()
.appInfo()
.resolveMethodOnInterfaceHolderLegacy(rewrittenMethod)
.getResolutionPair();
@@ -507,7 +511,7 @@
DexMethod rewrittenMethod =
appView.graphLens().lookupInvokeStatic(method, getContext()).getReference();
ProgramMethod resolvedMethod =
- appView
+ appView()
.appInfo()
.unsafeResolveMethodDueToDexFormatLegacy(rewrittenMethod)
.getResolvedProgramMethod();
@@ -523,7 +527,7 @@
appView.graphLens().lookupInvokeSuper(method, getContext()).getReference();
ProgramMethod superTarget =
asProgramMethodOrNull(
- appView.appInfo().lookupSuperTarget(rewrittenMethod, getContext()));
+ appView().appInfo().lookupSuperTarget(rewrittenMethod, getContext(), appView()));
if (superTarget != null) {
enqueueMethod(superTarget);
}
@@ -534,7 +538,10 @@
DexMethod rewrittenMethod =
appView.graphLens().lookupInvokeVirtual(method, getContext()).getReference();
DexClassAndMethod resolvedMethod =
- appView.appInfo().resolveMethodOnClassHolderLegacy(rewrittenMethod).getResolutionPair();
+ appView()
+ .appInfo()
+ .resolveMethodOnClassHolderLegacy(rewrittenMethod)
+ .getResolutionPair();
if (resolvedMethod != null) {
if (!resolvedMethod.getHolder().isEffectivelyFinal(appView)) {
fail();
@@ -569,7 +576,7 @@
@Override
public void registerCallSite(DexCallSite callSite) {
- if (isLambdaMetafactoryMethod(callSite, appView.appInfo())) {
+ if (isLambdaMetafactoryMethod(callSite, appView().appInfo())) {
// Use of lambda metafactory does not trigger any class initialization.
} else {
fail();
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/TrivialFieldAccessReprocessor.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/TrivialFieldAccessReprocessor.java
index acc6daa..4525030 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/TrivialFieldAccessReprocessor.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/TrivialFieldAccessReprocessor.java
@@ -82,6 +82,10 @@
this.postMethodProcessorBuilder = postMethodProcessorBuilder;
}
+ private AppView<AppInfoWithLiveness> appView() {
+ return appView;
+ }
+
public void run(
ExecutorService executorService, OptimizationFeedbackDelayed feedback, Timing timing)
throws ExecutionException {
@@ -312,7 +316,7 @@
class TrivialFieldAccessUseRegistry extends UseRegistry<ProgramMethod> {
TrivialFieldAccessUseRegistry(ProgramMethod method) {
- super(appView, method);
+ super(appView(), method);
}
private void registerFieldAccess(
@@ -320,7 +324,7 @@
boolean isStatic,
boolean isWrite,
BytecodeInstructionMetadata metadata) {
- FieldResolutionResult resolutionResult = appView.appInfo().resolveField(reference);
+ FieldResolutionResult resolutionResult = appView().appInfo().resolveField(reference);
if (!resolutionResult.hasProgramResult()) {
// We don't care about field accesses that may not resolve to a program field.
return;
@@ -332,8 +336,8 @@
if (definition.isStatic() != isStatic
|| appView.isCfByteCodePassThrough(getContext().getDefinition())
|| !resolutionResult.isSingleProgramFieldResolutionResult()
- || resolutionResult.isAccessibleFrom(getContext(), appView).isPossiblyFalse()
- || appView.appInfo().isNeverReprocessMethod(getContext())) {
+ || resolutionResult.isAccessibleFrom(getContext(), appView()).isPossiblyFalse()
+ || appView().appInfo().isNeverReprocessMethod(getContext())) {
recordAccessThatCannotBeOptimized(field, definition);
return;
}
@@ -355,7 +359,7 @@
}
// Record access.
- if (field.isProgramField() && appView.appInfo().mayPropagateValueFor(appView, field)) {
+ if (field.isProgramField() && appView().appInfo().mayPropagateValueFor(appView(), field)) {
if (field.getAccessFlags().isStatic() == isStatic) {
if (isWrite) {
recordFieldAccessContext(definition, writtenFields, readFields);
@@ -400,7 +404,7 @@
private void recordAccessThatCannotBeOptimized(
DexClassAndField field, DexEncodedField definition) {
constantFields.remove(definition);
- if (field.isProgramField() && appView.appInfo().mayPropagateValueFor(appView, field)) {
+ if (field.isProgramField() && appView().appInfo().mayPropagateValueFor(appView(), field)) {
destroyFieldAccessContexts(definition);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Cmp.java b/src/main/java/com/android/tools/r8/ir/code/Cmp.java
index a03637e..bc4cf73 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Cmp.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Cmp.java
@@ -19,6 +19,7 @@
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
+import com.android.tools.r8.lightir.LirBuilder;
import com.android.tools.r8.utils.LongInterval;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.StringUtils.BraceType;
@@ -236,6 +237,11 @@
}
@Override
+ public void buildLir(LirBuilder<Value, ?> builder) {
+ builder.addCmp(type, bias, leftValue(), rightValue());
+ }
+
+ @Override
public TypeElement evaluate(AppView<?> appView) {
return TypeElement.getInt();
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/FieldInstruction.java b/src/main/java/com/android/tools/r8/ir/code/FieldInstruction.java
index 3551561..86ef0d7 100644
--- a/src/main/java/com/android/tools/r8/ir/code/FieldInstruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/FieldInstruction.java
@@ -92,7 +92,7 @@
// Check if the resolution target is accessible.
if (singleFieldResolutionResult.getResolvedHolder() != context.getHolder()) {
if (singleFieldResolutionResult
- .isAccessibleFrom(context, appView.appInfo().withClassHierarchy())
+ .isAccessibleFrom(context, appView.withClassHierarchy())
.isPossiblyFalse()) {
return true;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java b/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
index d01444f..e14f898 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
@@ -32,6 +32,7 @@
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.ir.optimize.InliningConstraints;
+import com.android.tools.r8.lightir.LirBuilder;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.Set;
@@ -266,6 +267,11 @@
registry.registerInstanceFieldRead(getField());
}
+ @Override
+ public void buildLir(LirBuilder<Value, ?> builder) {
+ builder.addInstanceGet(getField(), object());
+ }
+
public static class Builder extends BuilderBase<Builder, InstanceGet> {
private DexField field;
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstancePut.java b/src/main/java/com/android/tools/r8/ir/code/InstancePut.java
index bc4d8df..acc4428 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstancePut.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstancePut.java
@@ -33,6 +33,7 @@
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.ir.optimize.InliningConstraints;
import com.android.tools.r8.ir.regalloc.RegisterAllocator;
+import com.android.tools.r8.lightir.LirBuilder;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.Arrays;
@@ -283,4 +284,9 @@
void internalRegisterUse(UseRegistry<?> registry, DexClassAndMethod context) {
registry.registerInstanceFieldWrite(getField());
}
+
+ @Override
+ public void buildLir(LirBuilder<Value, ?> builder) {
+ builder.addInstancePut(getField(), object(), value());
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeCustom.java b/src/main/java/com/android/tools/r8/ir/code/InvokeCustom.java
index 4fa5742..92ecb73 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeCustom.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeCustom.java
@@ -25,6 +25,7 @@
import com.android.tools.r8.ir.desugar.LambdaDescriptor;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.ir.optimize.InliningConstraints;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.List;
public final class InvokeCustom extends Invoke {
@@ -70,8 +71,8 @@
if (!appView.appInfo().hasLiveness()) {
return returnType;
}
- List<DexType> lambdaInterfaces =
- LambdaDescriptor.getInterfaces(callSite, appView.appInfo().withClassHierarchy());
+ AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
+ List<DexType> lambdaInterfaces = LambdaDescriptor.getInterfaces(callSite, appViewWithLiveness);
if (lambdaInterfaces == null || lambdaInterfaces.isEmpty()) {
return returnType;
}
@@ -98,7 +99,7 @@
assert verifyLambdaInterfaces(returnType, lambdaInterfaceSet, objectType);
return ClassTypeElement.create(
- objectType, Nullability.maybeNull(), appView.withClassHierarchy(), lambdaInterfaceSet);
+ objectType, Nullability.maybeNull(), appViewWithLiveness, lambdaInterfaceSet);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java b/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
index 146f61a..3891d20 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
@@ -140,9 +140,10 @@
AppView<?> appView, ProgramMethod context, DynamicType dynamicReceiverType) {
DexMethod invokedMethod = getInvokedMethod();
DexEncodedMethod result;
- if (appView.appInfo().hasLiveness()) {
- AppInfoWithLiveness appInfo = appView.appInfo().withLiveness();
- result = appInfo.lookupDirectTarget(invokedMethod, context);
+ if (appView.hasLiveness()) {
+ AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
+ AppInfoWithLiveness appInfo = appViewWithLiveness.appInfo();
+ result = appInfo.lookupDirectTarget(invokedMethod, context, appViewWithLiveness);
assert verifyD8LookupResult(
result, appView.appInfo().lookupDirectTargetOnItself(invokedMethod, context));
} else {
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeInterface.java b/src/main/java/com/android/tools/r8/ir/code/InvokeInterface.java
index 94ba6c4..2936292 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeInterface.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeInterface.java
@@ -26,6 +26,7 @@
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.ir.optimize.InliningConstraints;
+import com.android.tools.r8.lightir.LirBuilder;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.List;
@@ -165,4 +166,9 @@
void internalRegisterUse(UseRegistry<?> registry, DexClassAndMethod context) {
registry.registerInvokeInterface(getInvokedMethod());
}
+
+ @Override
+ public void buildLir(LirBuilder<Value, ?> builder) {
+ builder.addInvokeInterface(getInvokedMethod(), arguments());
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java b/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
index 7f5c809..b7a8fae 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
@@ -156,14 +156,9 @@
if (refinedReceiverUpperBound != null) {
lookupResult =
resolutionResult.lookupVirtualDispatchTargets(
- context.getHolder(),
- appView.withLiveness().appInfo(),
- refinedReceiverUpperBound,
- refinedReceiverLowerBound);
+ context.getHolder(), appView, refinedReceiverUpperBound, refinedReceiverLowerBound);
} else {
- lookupResult =
- resolutionResult.lookupVirtualDispatchTargets(
- context.getHolder(), appView.withLiveness().appInfo());
+ lookupResult = resolutionResult.lookupVirtualDispatchTargets(context.getHolder(), appView);
}
if (lookupResult.isLookupResultFailure()) {
return null;
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java b/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java
index 1bf7eb7..3acd5fc 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java
@@ -29,6 +29,7 @@
import com.android.tools.r8.ir.optimize.Inliner.Reason;
import com.android.tools.r8.ir.optimize.InliningConstraints;
import com.android.tools.r8.ir.optimize.inliner.WhyAreYouNotInliningReporter;
+import com.android.tools.r8.lightir.LirBuilder;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.List;
@@ -120,10 +121,11 @@
DexMethod invokedMethod = getInvokedMethod();
DexEncodedMethod result;
if (appView.appInfo().hasLiveness()) {
- AppInfoWithLiveness appInfo = appView.appInfo().withLiveness();
- result = appInfo.lookupStaticTarget(invokedMethod, context);
+ AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
+ AppInfoWithLiveness appInfo = appViewWithLiveness.appInfo();
+ result = appInfo.lookupStaticTarget(invokedMethod, context, appViewWithLiveness);
assert verifyD8LookupResult(
- result, appView.appInfo().lookupStaticTargetOnItself(invokedMethod, context));
+ result, appInfo.lookupStaticTargetOnItself(invokedMethod, context));
} else {
// Allow optimizing static library invokes in D8.
DexClass clazz = appView.definitionForHolder(getInvokedMethod());
@@ -216,7 +218,7 @@
// Verify that the target method is static and accessible.
if (!singleTarget.getDefinition().isStatic()
- || resolutionResult.isAccessibleFrom(context, appInfoWithLiveness).isPossiblyFalse()) {
+ || resolutionResult.isAccessibleFrom(context, appViewWithLiveness).isPossiblyFalse()) {
return true;
}
@@ -243,6 +245,11 @@
registry.registerInvokeStatic(getInvokedMethod());
}
+ @Override
+ public void buildLir(LirBuilder<Value, ?> builder) {
+ builder.addInvokeStatic(getInvokedMethod(), arguments());
+ }
+
public static class Builder extends InvokeMethod.Builder<Builder, InvokeStatic> {
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeSuper.java b/src/main/java/com/android/tools/r8/ir/code/InvokeSuper.java
index 0b7dce8..4eaae3c 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeSuper.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeSuper.java
@@ -113,7 +113,7 @@
AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
AppInfoWithLiveness appInfo = appViewWithLiveness.appInfo();
if (appInfo.isSubtype(context.getHolderType(), getInvokedMethod().holder)) {
- return appInfo.lookupSuperTarget(getInvokedMethod(), context);
+ return appInfo.lookupSuperTarget(getInvokedMethod(), context, appViewWithLiveness);
}
}
return null;
diff --git a/src/main/java/com/android/tools/r8/ir/code/NewInstance.java b/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
index 40e7d5d..0fa2583 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
@@ -29,6 +29,7 @@
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.ir.optimize.InliningConstraints;
+import com.android.tools.r8.lightir.LirBuilder;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
public class NewInstance extends Instruction {
@@ -239,6 +240,11 @@
registry.registerNewInstance(clazz);
}
+ @Override
+ public void buildLir(LirBuilder<Value, ?> builder) {
+ builder.addNewInstance(clazz);
+ }
+
public static class Builder extends BuilderBase<Builder, NewInstance> {
private DexType type;
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java
index 7cbb122..9782300 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java
@@ -13,7 +13,7 @@
import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.itf.InterfaceProcessor;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
+import com.android.tools.r8.profile.art.rewriting.ProfileCollectionAdditions;
import com.android.tools.r8.utils.MapUtils;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.collections.ImmutableDeque;
@@ -114,11 +114,10 @@
ClassConverterResult.Builder resultBuilder, ExecutorService executorService)
throws ExecutionException {
Collection<DexProgramClass> classes = appView.appInfo().classes();
- ArtProfileCollectionAdditions artProfileCollectionAdditions =
- methodProcessor.getArtProfileCollectionAdditions();
+ ProfileCollectionAdditions profileCollectionAdditions =
+ methodProcessor.getProfileCollectionAdditions();
CfClassSynthesizerDesugaringEventConsumer classSynthesizerEventConsumer =
- CfClassSynthesizerDesugaringEventConsumer.createForD8(
- appView, artProfileCollectionAdditions);
+ CfClassSynthesizerDesugaringEventConsumer.createForD8(appView, profileCollectionAdditions);
converter.classSynthesisDesugaring(executorService, classSynthesizerEventConsumer);
if (!classSynthesizerEventConsumer.getSynthesizedClasses().isEmpty()) {
classes =
@@ -130,7 +129,7 @@
CfInstructionDesugaringEventConsumer instructionDesugaringEventConsumerForPrepareStep =
CfInstructionDesugaringEventConsumer.createForD8(
- appView, artProfileCollectionAdditions, resultBuilder, methodProcessor);
+ appView, profileCollectionAdditions, resultBuilder, methodProcessor);
converter.prepareDesugaring(instructionDesugaringEventConsumerForPrepareStep, executorService);
assert instructionDesugaringEventConsumerForPrepareStep.verifyNothingToFinalize();
@@ -153,7 +152,7 @@
CfInstructionDesugaringEventConsumer instructionDesugaringEventConsumerForWave =
CfInstructionDesugaringEventConsumer.createForD8(
- appView, artProfileCollectionAdditions, resultBuilder, methodProcessor);
+ appView, profileCollectionAdditions, resultBuilder, methodProcessor);
// Process the wave and wait for all IR processing to complete.
methodProcessor.newWave();
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/D8MethodProcessor.java b/src/main/java/com/android/tools/r8/ir/conversion/D8MethodProcessor.java
index 9a81a28..fec53b0 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/D8MethodProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/D8MethodProcessor.java
@@ -12,7 +12,7 @@
import com.android.tools.r8.ir.conversion.callgraph.CallSiteInformation;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackIgnore;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
+import com.android.tools.r8.profile.art.rewriting.ProfileCollectionAdditions;
import com.android.tools.r8.utils.ThreadUtils;
import com.google.common.collect.Sets;
import java.util.ArrayList;
@@ -25,7 +25,7 @@
public class D8MethodProcessor extends MethodProcessor {
- private final ArtProfileCollectionAdditions artProfileCollectionAdditions;
+ private final ProfileCollectionAdditions profileCollectionAdditions;
private final PrimaryD8L8IRConverter converter;
private final MethodProcessorEventConsumer eventConsumer;
private final ExecutorService executorService;
@@ -44,12 +44,12 @@
private ProcessorContext processorContext;
public D8MethodProcessor(
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
PrimaryD8L8IRConverter converter,
ExecutorService executorService) {
- this.artProfileCollectionAdditions = artProfileCollectionAdditions;
+ this.profileCollectionAdditions = profileCollectionAdditions;
this.converter = converter;
- this.eventConsumer = MethodProcessorEventConsumer.createForD8(artProfileCollectionAdditions);
+ this.eventConsumer = MethodProcessorEventConsumer.createForD8(profileCollectionAdditions);
this.executorService = executorService;
this.processorContext = converter.appView.createProcessorContext();
}
@@ -68,8 +68,8 @@
return processorContext.createMethodProcessingContext(method);
}
- public ArtProfileCollectionAdditions getArtProfileCollectionAdditions() {
- return artProfileCollectionAdditions;
+ public ProfileCollectionAdditions getProfileCollectionAdditions() {
+ return profileCollectionAdditions;
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index 0050541..c2917b8 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -1056,13 +1056,15 @@
OptimizationFeedback feedback,
BytecodeMetadataProvider bytecodeMetadataProvider,
Timing timing) {
- IRCode round1 = doRoundtripWithStrategy(code, new ExternalPhisStrategy(), "indirect phis");
- IRCode round2 = doRoundtripWithStrategy(round1, new PhiInInstructionsStrategy(), "inline phis");
+ IRCode round1 =
+ doRoundtripWithStrategy(code, new ExternalPhisStrategy(), "indirect phis", timing);
+ IRCode round2 =
+ doRoundtripWithStrategy(round1, new PhiInInstructionsStrategy(), "inline phis", timing);
return round2;
}
private <EV, S extends LirStrategy<Value, EV>> IRCode doRoundtripWithStrategy(
- IRCode code, S strategy, String name) {
+ IRCode code, S strategy, String name, Timing timing) {
timing.begin("IR->LIR (" + name + ")");
LirCode<EV> lirCode =
IR2LirConverter.translate(code, strategy.getEncodingStrategy(), appView.dexItemFactory());
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/MethodProcessorEventConsumer.java b/src/main/java/com/android/tools/r8/ir/conversion/MethodProcessorEventConsumer.java
index e360a95..a14171a 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/MethodProcessorEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/MethodProcessorEventConsumer.java
@@ -12,8 +12,8 @@
import com.android.tools.r8.ir.optimize.UtilityMethodsForCodeOptimizationsEventConsumer;
import com.android.tools.r8.ir.optimize.api.InstanceInitializerOutlinerEventConsumer;
import com.android.tools.r8.ir.optimize.enums.EnumUnboxerMethodProcessorEventConsumer;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileRewritingMethodProcessorEventConsumer;
+import com.android.tools.r8.profile.art.rewriting.ProfileCollectionAdditions;
+import com.android.tools.r8.profile.art.rewriting.ProfileRewritingMethodProcessorEventConsumer;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
public abstract class MethodProcessorEventConsumer
@@ -26,14 +26,13 @@
public void finished(AppView<AppInfoWithLiveness> appView) {}
public static MethodProcessorEventConsumer createForD8(
- ArtProfileCollectionAdditions artProfileCollectionAdditions) {
- return ArtProfileRewritingMethodProcessorEventConsumer.attach(
- artProfileCollectionAdditions, empty());
+ ProfileCollectionAdditions profileCollectionAdditions) {
+ return ProfileRewritingMethodProcessorEventConsumer.attach(profileCollectionAdditions, empty());
}
public static MethodProcessorEventConsumer createForR8(
AppView<? extends AppInfoWithClassHierarchy> appView) {
- return ArtProfileRewritingMethodProcessorEventConsumer.attach(appView, empty());
+ return ProfileRewritingMethodProcessorEventConsumer.attach(appView, empty());
}
public static MethodProcessorEventConsumer empty() {
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 cf7a083..b2959f2 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
@@ -33,7 +33,7 @@
import com.android.tools.r8.ir.desugar.nest.D8NestBasedAccessDesugaring;
import com.android.tools.r8.ir.optimize.info.OptimizationFeedback;
import com.android.tools.r8.position.MethodPosition;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
+import com.android.tools.r8.profile.art.rewriting.ProfileCollectionAdditions;
import com.android.tools.r8.utils.ExceptionUtils;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.ThreadUtils;
@@ -54,10 +54,10 @@
LambdaDeserializationMethodRemover.run(appView);
workaroundAbstractMethodOnNonAbstractClassVerificationBug(executorService);
DexApplication application = appView.appInfo().app();
- ArtProfileCollectionAdditions artProfileCollectionAdditions =
- ArtProfileCollectionAdditions.create(appView);
+ ProfileCollectionAdditions profileCollectionAdditions =
+ ProfileCollectionAdditions.create(appView);
D8MethodProcessor methodProcessor =
- new D8MethodProcessor(artProfileCollectionAdditions, this, executorService);
+ new D8MethodProcessor(profileCollectionAdditions, this, executorService);
InterfaceProcessor interfaceProcessor = InterfaceProcessor.create(appView);
timing.begin("IR conversion");
@@ -90,7 +90,7 @@
new L8InnerOuterAttributeEraser(appView).run();
}
- processCovariantReturnTypeAnnotations(builder, artProfileCollectionAdditions);
+ processCovariantReturnTypeAnnotations(builder, profileCollectionAdditions);
timing.end();
@@ -100,7 +100,7 @@
appView.appInfo().getSyntheticItems().commit(application),
appView.appInfo().getMainDexInfo()));
- artProfileCollectionAdditions.commit(appView);
+ profileCollectionAdditions.commit(appView);
}
void convertMethods(
@@ -310,7 +310,7 @@
CfPostProcessingDesugaringEventConsumer eventConsumer =
CfPostProcessingDesugaringEventConsumer.createForD8(
appView,
- methodProcessor.getArtProfileCollectionAdditions(),
+ methodProcessor.getProfileCollectionAdditions(),
methodProcessor,
instructionDesugaring);
methodProcessor.newWave();
@@ -341,12 +341,11 @@
}
private void processCovariantReturnTypeAnnotations(
- Builder<?> builder, ArtProfileCollectionAdditions artProfileCollectionAdditions) {
+ Builder<?> builder, ProfileCollectionAdditions profileCollectionAdditions) {
if (covariantReturnTypeAnnotationTransformer != null) {
covariantReturnTypeAnnotationTransformer.process(
builder,
- CovariantReturnTypeAnnotationTransformerEventConsumer.create(
- artProfileCollectionAdditions));
+ CovariantReturnTypeAnnotationTransformerEventConsumer.create(profileCollectionAdditions));
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/callgraph/InvokeExtractor.java b/src/main/java/com/android/tools/r8/ir/conversion/callgraph/InvokeExtractor.java
index 3c940a6..34e00ef 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/callgraph/InvokeExtractor.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/callgraph/InvokeExtractor.java
@@ -118,7 +118,7 @@
appView.appInfo().resolveMethodLegacy(method, isInterface);
if (resolution.isVirtualTarget()) {
LookupResult lookupResult =
- resolution.lookupVirtualDispatchTargets(context.getHolder(), appView.appInfo());
+ resolution.lookupVirtualDispatchTargets(context.getHolder(), appView);
if (lookupResult.isLookupResultSuccess()) {
ProgramMethodSet targets = ProgramMethodSet.create();
lookupResult
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
index 508c314..47d762c 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
@@ -1015,6 +1015,20 @@
BackportedMethods::LongMethods_toUnsignedStringWithRadix,
"toUnsignedStringWithRadix"));
+ // Method
+ type = factory.methodType;
+
+ // int Method.getParameterCount()
+ name = factory.createString("getParameterCount");
+ proto = factory.createProto(factory.intType);
+ method = factory.createMethod(type, proto, name);
+ addProvider(
+ new StatifyingMethodGenerator(
+ method,
+ BackportedMethods::MethodMethods_getParameterCount,
+ "getParameterCount",
+ type));
+
// String
type = factory.stringType;
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 49a7dd8..0db5e13 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
@@ -14,8 +14,8 @@
import com.android.tools.r8.ir.desugar.itf.EmulatedInterfaceSynthesizerEventConsumer.L8ProgramEmulatedInterfaceSynthesizerEventConsumer;
import com.android.tools.r8.ir.desugar.records.RecordDesugaringEventConsumer.RecordClassSynthesizerDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.varhandle.VarHandleDesugaringEventConsumer;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileRewritingCfClassSynthesizerDesugaringEventConsumer;
+import com.android.tools.r8.profile.art.rewriting.ProfileCollectionAdditions;
+import com.android.tools.r8.profile.art.rewriting.ProfileRewritingCfClassSynthesizerDesugaringEventConsumer;
import com.google.common.collect.Sets;
import java.util.Set;
@@ -29,19 +29,18 @@
protected CfClassSynthesizerDesugaringEventConsumer() {}
public static CfClassSynthesizerDesugaringEventConsumer createForD8(
- AppView<?> appView, ArtProfileCollectionAdditions artProfileCollectionAdditions) {
+ AppView<?> appView, ProfileCollectionAdditions profileCollectionAdditions) {
CfClassSynthesizerDesugaringEventConsumer eventConsumer =
new D8R8CfClassSynthesizerDesugaringEventConsumer();
- return ArtProfileRewritingCfClassSynthesizerDesugaringEventConsumer.attach(
- appView, eventConsumer, artProfileCollectionAdditions);
+ return ProfileRewritingCfClassSynthesizerDesugaringEventConsumer.attach(
+ appView, eventConsumer, profileCollectionAdditions);
}
public static CfClassSynthesizerDesugaringEventConsumer createForR8(
AppView<? extends AppInfoWithClassHierarchy> appView) {
CfClassSynthesizerDesugaringEventConsumer eventConsumer =
new D8R8CfClassSynthesizerDesugaringEventConsumer();
- return ArtProfileRewritingCfClassSynthesizerDesugaringEventConsumer.attach(
- appView, eventConsumer);
+ return ProfileRewritingCfClassSynthesizerDesugaringEventConsumer.attach(appView, eventConsumer);
}
public void finished(AppView<? extends AppInfoWithClassHierarchy> appView) {}
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 7290623..509a1ff 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
@@ -32,8 +32,8 @@
import com.android.tools.r8.ir.desugar.records.RecordDesugaringEventConsumer.RecordInstructionDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.twr.TwrCloseResourceDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.varhandle.VarHandleDesugaringEventConsumer;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileRewritingCfInstructionDesugaringEventConsumer;
+import com.android.tools.r8.profile.art.rewriting.ProfileCollectionAdditions;
+import com.android.tools.r8.profile.art.rewriting.ProfileRewritingCfInstructionDesugaringEventConsumer;
import com.android.tools.r8.shaking.Enqueuer.SyntheticAdditions;
import com.android.tools.r8.shaking.KeepMethodInfo.Joiner;
import com.google.common.collect.Sets;
@@ -70,22 +70,22 @@
public static CfInstructionDesugaringEventConsumer createForD8(
AppView<?> appView,
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
ClassConverterResult.Builder classConverterResultBuilder,
D8MethodProcessor methodProcessor) {
D8CfInstructionDesugaringEventConsumer eventConsumer =
new D8CfInstructionDesugaringEventConsumer(
appView, classConverterResultBuilder, methodProcessor);
CfInstructionDesugaringEventConsumer outermostEventConsumer =
- ArtProfileRewritingCfInstructionDesugaringEventConsumer.attach(
- appView, artProfileCollectionAdditions, eventConsumer);
+ ProfileRewritingCfInstructionDesugaringEventConsumer.attach(
+ appView, profileCollectionAdditions, eventConsumer);
eventConsumer.setOutermostEventConsumer(outermostEventConsumer);
return outermostEventConsumer;
}
public static CfInstructionDesugaringEventConsumer createForR8(
AppView<? extends AppInfoWithClassHierarchy> appView,
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
BiConsumer<LambdaClass, ProgramMethod> lambdaClassConsumer,
BiConsumer<ConstantDynamicClass, ProgramMethod> constantDynamicClassConsumer,
BiConsumer<ProgramMethod, ProgramMethod> twrCloseResourceMethodConsumer,
@@ -99,8 +99,8 @@
twrCloseResourceMethodConsumer,
additions,
companionMethodConsumer);
- return ArtProfileRewritingCfInstructionDesugaringEventConsumer.attach(
- appView, artProfileCollectionAdditions, eventConsumer);
+ return ProfileRewritingCfInstructionDesugaringEventConsumer.attach(
+ appView, profileCollectionAdditions, eventConsumer);
}
public abstract List<ProgramMethod> finalizeDesugaring();
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 7a38cf1..adeecfe 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
@@ -18,8 +18,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.profile.art.rewriting.ProfileCollectionAdditions;
+import com.android.tools.r8.profile.art.rewriting.ProfileRewritingCfPostProcessingDesugaringEventConsumer;
import com.android.tools.r8.shaking.Enqueuer.SyntheticAdditions;
import com.android.tools.r8.utils.collections.ProgramMethodSet;
import java.util.Collections;
@@ -39,25 +39,25 @@
public static CfPostProcessingDesugaringEventConsumer createForD8(
AppView<?> appView,
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
D8MethodProcessor methodProcessor,
CfInstructionDesugaringCollection instructionDesugaring) {
CfPostProcessingDesugaringEventConsumer eventConsumer =
new D8CfPostProcessingDesugaringEventConsumer(methodProcessor, instructionDesugaring);
- return ArtProfileRewritingCfPostProcessingDesugaringEventConsumer.attach(
- appView, artProfileCollectionAdditions, eventConsumer);
+ return ProfileRewritingCfPostProcessingDesugaringEventConsumer.attach(
+ appView, profileCollectionAdditions, eventConsumer);
}
public static CfPostProcessingDesugaringEventConsumer createForR8(
AppView<?> appView,
SyntheticAdditions additions,
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
CfInstructionDesugaringCollection desugaring,
BiConsumer<DexProgramClass, DexType> missingClassConsumer) {
CfPostProcessingDesugaringEventConsumer eventConsumer =
new R8PostProcessingDesugaringEventConsumer(additions, desugaring, missingClassConsumer);
- return ArtProfileRewritingCfPostProcessingDesugaringEventConsumer.attach(
- appView, artProfileCollectionAdditions, eventConsumer);
+ return ProfileRewritingCfPostProcessingDesugaringEventConsumer.attach(
+ appView, profileCollectionAdditions, eventConsumer);
}
public abstract Set<DexMethod> getNewlyLiveMethods();
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformerEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformerEventConsumer.java
index dc4add0..86c74d8 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformerEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformerEventConsumer.java
@@ -5,20 +5,20 @@
package com.android.tools.r8.ir.desugar;
import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer;
+import com.android.tools.r8.profile.art.rewriting.ProfileCollectionAdditions;
+import com.android.tools.r8.profile.art.rewriting.ProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer;
public interface CovariantReturnTypeAnnotationTransformerEventConsumer {
void acceptCovariantReturnTypeBridgeMethod(ProgramMethod bridge, ProgramMethod target);
static CovariantReturnTypeAnnotationTransformerEventConsumer create(
- ArtProfileCollectionAdditions artProfileCollectionAdditions) {
- if (artProfileCollectionAdditions.isNop()) {
+ ProfileCollectionAdditions profileCollectionAdditions) {
+ if (profileCollectionAdditions.isNop()) {
return empty();
}
- return ArtProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer.attach(
- artProfileCollectionAdditions, empty());
+ return ProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer.attach(
+ profileCollectionAdditions, empty());
}
static EmptyCovariantReturnTypeAnnotationTransformerEventConsumer empty() {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java
index df7be1b..bbd4fe0 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedMethod;
@@ -68,6 +69,7 @@
}
private LambdaDescriptor(
+ AppView<?> appView,
AppInfoWithClassHierarchy appInfo,
ProgramMethod context,
DexCallSite callSite,
@@ -94,7 +96,8 @@
this.captures = captures;
this.interfaces.add(mainInterface);
- DexEncodedMethod targetMethod = context == null ? null : lookupTargetMethod(appInfo, context);
+ DexEncodedMethod targetMethod =
+ context == null ? null : lookupTargetMethod(appView, appInfo, context);
if (targetMethod != null) {
targetAccessFlags = targetMethod.accessFlags.copy();
targetHolder = targetMethod.getHolderType();
@@ -114,7 +117,7 @@
}
private DexEncodedMethod lookupTargetMethod(
- AppInfoWithClassHierarchy appInfo, ProgramMethod context) {
+ AppView<?> appView, AppInfoWithClassHierarchy appInfo, ProgramMethod context) {
assert context != null;
// Find the lambda's impl-method target.
DexMethod method = implHandle.asMethod();
@@ -126,7 +129,7 @@
.resolveMethodOnLegacy(getImplReceiverType(), method, implHandle.isInterface)
.getSingleTarget();
if (target == null) {
- target = appInfo.lookupDirectTarget(method, context);
+ target = appInfo.lookupDirectTarget(method, context, appView, appInfo);
}
assert target == null
|| (implHandle.type.isInvokeInstance() && isInstanceMethod(target))
@@ -136,13 +139,13 @@
}
case INVOKE_STATIC: {
- DexEncodedMethod target = appInfo.lookupStaticTarget(method, context);
+ DexEncodedMethod target = appInfo.lookupStaticTarget(method, context, appView, appInfo);
assert target == null || target.accessFlags.isStatic();
return target;
}
case INVOKE_CONSTRUCTOR: {
- DexEncodedMethod target = appInfo.lookupDirectTarget(method, context);
+ DexEncodedMethod target = appInfo.lookupDirectTarget(method, context, appView, appInfo);
assert target == null || target.accessFlags.isConstructor();
return target;
}
@@ -267,8 +270,11 @@
* information, or null if match failed.
*/
public static LambdaDescriptor tryInfer(
- DexCallSite callSite, AppInfoWithClassHierarchy appInfo, ProgramMethod context) {
- LambdaDescriptor descriptor = infer(callSite, appInfo, context);
+ DexCallSite callSite,
+ AppView<?> appView,
+ AppInfoWithClassHierarchy appInfo,
+ ProgramMethod context) {
+ LambdaDescriptor descriptor = infer(callSite, appView, appInfo, context);
return descriptor == MATCH_FAILED ? null : descriptor;
}
@@ -294,7 +300,10 @@
* information, or MATCH_FAILED if match failed.
*/
static LambdaDescriptor infer(
- DexCallSite callSite, AppInfoWithClassHierarchy appInfo, ProgramMethod context) {
+ DexCallSite callSite,
+ AppView<?> appView,
+ AppInfoWithClassHierarchy appInfo,
+ ProgramMethod context) {
if (!isLambdaMetafactoryMethod(callSite, appInfo)) {
return LambdaDescriptor.MATCH_FAILED;
}
@@ -337,6 +346,7 @@
// Create a match.
LambdaDescriptor match =
new LambdaDescriptor(
+ appView,
appInfo,
context,
callSite,
@@ -409,9 +419,9 @@
}
public static List<DexType> getInterfaces(
- DexCallSite callSite, AppInfoWithClassHierarchy appInfo) {
+ DexCallSite callSite, AppView<? extends AppInfoWithClassHierarchy> appView) {
// No need for the invocationContext to figure out only the interfaces.
- LambdaDescriptor descriptor = infer(callSite, appInfo, null);
+ LambdaDescriptor descriptor = infer(callSite, appView, appView.appInfo(), null);
if (descriptor == LambdaDescriptor.MATCH_FAILED) {
return null;
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java b/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java
index 40e5b9f..184dff0 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java
@@ -200,12 +200,14 @@
ProgramAdditions programAdditions) {
ensureCfCode(method);
desugarings.forEach(d -> d.prepare(method, eventConsumer, programAdditions));
+ yieldingDesugarings.forEach(d -> d.prepare(method, eventConsumer, programAdditions));
}
@Override
public void scan(ProgramMethod method, CfInstructionDesugaringEventConsumer eventConsumer) {
ensureCfCode(method);
desugarings.forEach(d -> d.scan(method, eventConsumer));
+ yieldingDesugarings.forEach(d -> d.scan(method, eventConsumer));
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/backports/BackportedMethods.java b/src/main/java/com/android/tools/r8/ir/desugar/backports/BackportedMethods.java
index 99392e1..7d65007 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/backports/BackportedMethods.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/backports/BackportedMethods.java
@@ -5773,6 +5773,30 @@
ImmutableList.of());
}
+ public static CfCode MethodMethods_getParameterCount(DexItemFactory factory, DexMethod method) {
+ CfLabel label0 = new CfLabel();
+ CfLabel label1 = new CfLabel();
+ return new CfCode(
+ method.holder,
+ 1,
+ 1,
+ ImmutableList.of(
+ label0,
+ new CfLoad(ValueType.OBJECT, 0),
+ new CfInvoke(
+ 182,
+ factory.createMethod(
+ factory.createType("Ljava/lang/reflect/Method;"),
+ factory.createProto(factory.createType("[Ljava/lang/Class;")),
+ factory.createString("getParameterTypes")),
+ false),
+ new CfArrayLength(),
+ new CfReturn(ValueType.INT),
+ label1),
+ ImmutableList.of(),
+ ImmutableList.of());
+ }
+
public static CfCode ObjectsMethods_checkFromIndexSize(DexItemFactory factory, DexMethod method) {
CfLabel label0 = new CfLabel();
CfLabel label1 = new CfLabel();
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/ConstantDynamicClass.java b/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/ConstantDynamicClass.java
index d260a73..63a6e08 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/ConstantDynamicClass.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/ConstantDynamicClass.java
@@ -157,7 +157,7 @@
// Unconditionally throw as the RI.
behaviour =
resolution.isNoSuchMethodErrorResult(
- context.getContextClass(), appView.appInfoForDesugaring())
+ context.getContextClass(), appView, appView.appInfoForDesugaring())
? THROW_NSME
: THROW_ICCE;
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryAPIConverter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryAPIConverter.java
index 292a3b3..f3e4457 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryAPIConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryAPIConverter.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfInvoke;
import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
+import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexClassAndMethod;
@@ -124,10 +125,11 @@
private DexClassAndMethod getMethodForDesugaring(CfInvoke invoke, ProgramMethod context) {
DexMethod invokedMethod = invoke.getMethod();
// TODO(b/191656218): Use lookupInvokeSpecial instead when this is all to Cf.
+ AppInfoWithClassHierarchy appInfoForDesugaring = appView.appInfoForDesugaring();
return invoke.isInvokeSuper(context.getHolderType())
- ? appView.appInfoForDesugaring().lookupSuperTarget(invokedMethod, context)
- : appView
- .appInfoForDesugaring()
+ ? appInfoForDesugaring.lookupSuperTarget(
+ invokedMethod, context, appView, appInfoForDesugaring)
+ : appInfoForDesugaring
.resolveMethodLegacy(invokedMethod, invoke.isInterface())
.getResolutionPair();
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/SupportedClassesGenerator.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/SupportedClassesGenerator.java
index b165a93..cb24e59 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/SupportedClassesGenerator.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/SupportedClassesGenerator.java
@@ -10,7 +10,6 @@
import com.android.tools.r8.androidapi.ComputedApiLevel;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.dex.Constants;
-import com.android.tools.r8.experimental.startup.StartupOrder;
import com.android.tools.r8.features.ClassToFeatureSplitMap;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.DexApplication;
@@ -148,8 +147,7 @@
dexApplication,
ClassToFeatureSplitMap.createEmptyClassToFeatureSplitMap(),
MainDexInfo.none(),
- GlobalSyntheticsStrategy.forNonSynthesizing(),
- StartupOrder.empty());
+ GlobalSyntheticsStrategy.forNonSynthesizing());
List<DexMethod> backports =
BackportedMethodRewriter.generateListOfBackportedMethods(dexApplication, options);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java
index fd30618..85154ce 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java
@@ -92,7 +92,8 @@
return DesugarDescription.nothing();
}
if (cfInvoke.isInvokeSuper(context.getHolderType())) {
- DexClassAndMethod superTarget = appInfo.lookupSuperTarget(invokedMethod, context);
+ DexClassAndMethod superTarget =
+ appInfo.lookupSuperTarget(invokedMethod, context, appView, appInfo);
if (superTarget != null) {
assert !superTarget.getDefinition().isStatic();
return computeNonStaticRetarget(superTarget.getReference(), true);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/icce/AlwaysThrowingInstructionDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/icce/AlwaysThrowingInstructionDesugaring.java
index ff3989a..ccf096e 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/icce/AlwaysThrowingInstructionDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/icce/AlwaysThrowingInstructionDesugaring.java
@@ -189,9 +189,11 @@
} else if (resolutionResult.isFailedResolution()) {
FailedResolutionResult failedResolutionResult = resolutionResult.asFailedResolution();
AppInfoWithClassHierarchy appInfo = appView.appInfoForDesugaring();
- if (failedResolutionResult.isIllegalAccessErrorResult(context.getHolder(), appInfo)) {
+ if (failedResolutionResult.isIllegalAccessErrorResult(
+ context.getHolder(), appView, appInfo)) {
return UtilityMethodsForCodeOptimizations::synthesizeThrowIllegalAccessErrorMethod;
- } else if (failedResolutionResult.isNoSuchMethodErrorResult(context.getHolder(), appInfo)) {
+ } else if (failedResolutionResult.isNoSuchMethodErrorResult(
+ context.getHolder(), appView, appInfo)) {
return UtilityMethodsForCodeOptimizations::synthesizeThrowNoSuchMethodErrorMethod;
} else if (failedResolutionResult.isIncompatibleClassChangeErrorResult()) {
return UtilityMethodsForCodeOptimizations
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 85b530e..922fd4d 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
@@ -850,11 +850,11 @@
addICCEThrowingMethod(method, clazz, resolutionResult.asFailedResolution());
return;
}
- if (resolutionResult.isNoSuchMethodErrorResult(clazz, appInfo)) {
+ if (resolutionResult.isNoSuchMethodErrorResult(clazz, appView, appInfo)) {
addNoSuchMethodErrorThrowingMethod(method, clazz, resolutionResult.asFailedResolution());
return;
}
- assert resolutionResult.isIllegalAccessErrorResult(clazz, appInfo);
+ assert resolutionResult.isIllegalAccessErrorResult(clazz, appView, appInfo);
addIllegalAccessErrorThrowingMethod(method, clazz, resolutionResult.asFailedResolution());
return;
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
index 6bc5e1d..15e9f06 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
@@ -329,7 +329,7 @@
.asSingleResolution();
if (resolution != null
&& resolution.getResolvedMethod().isPrivate()
- && resolution.isAccessibleFrom(context, appInfoForDesugaring).isTrue()) {
+ && resolution.isAccessibleFrom(context, appView, appInfoForDesugaring).isTrue()) {
return DesugarDescription.nothing();
}
if (resolution != null && resolution.getResolvedMethod().isStatic()) {
@@ -503,7 +503,7 @@
.asSingleResolution();
if (resolution != null
&& resolution.getResolvedMethod().isPrivate()
- && resolution.isAccessibleFrom(context, appInfoForDesugaring).isTrue()) {
+ && resolution.isAccessibleFrom(context, appView, appInfoForDesugaring).isTrue()) {
// TODO(b/198267586): What about the private in-accessible case?
return computeInvokeDirect(holder, invoke, context);
}
@@ -724,7 +724,9 @@
// WARNING: This may result in incorrect code on older platforms!
// Retarget call to an appropriate method of companion class.
if (resolutionResult.getResolvedMethod().isPrivateMethod()) {
- if (resolutionResult.isAccessibleFrom(context, appView.appInfoForDesugaring()).isFalse()) {
+ if (resolutionResult
+ .isAccessibleFrom(context, appView, appView.appInfoForDesugaring())
+ .isFalse()) {
// TODO(b/145775365): This should throw IAE.
return computeInvokeAsThrowRewrite(invoke, null, context);
}
@@ -803,8 +805,11 @@
private DesugarDescription computeEmulatedInterfaceInvokeSpecial(
DexClass clazz, DexMethod invokedMethod, ProgramMethod context) {
+ AppInfoWithClassHierarchy appInfoForDesugaring = appView.appInfoForDesugaring();
DexClassAndMethod superTarget =
- appView.appInfoForDesugaring().lookupSuperTarget(invokedMethod, context);
+ appView
+ .appInfoForDesugaring()
+ .lookupSuperTarget(invokedMethod, context, appView, appInfoForDesugaring);
if (clazz.isInterface()
&& clazz.isLibraryClass()
&& helper.isInDesugaredLibrary(clazz)
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/lambda/LambdaInstructionDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/lambda/LambdaInstructionDesugaring.java
index c33361a..aea4f4b 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/lambda/LambdaInstructionDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/lambda/LambdaInstructionDesugaring.java
@@ -163,7 +163,8 @@
MethodProcessingContext methodProcessingContext,
DesugarInvoke desugarInvoke) {
LambdaDescriptor descriptor =
- LambdaDescriptor.tryInfer(invoke.getCallSite(), appView.appInfoForDesugaring(), context);
+ LambdaDescriptor.tryInfer(
+ invoke.getCallSite(), appView, appView.appInfoForDesugaring(), context);
if (descriptor == null) {
return null;
}
@@ -191,6 +192,7 @@
return instruction.isInvokeDynamic()
&& LambdaDescriptor.tryInfer(
instruction.asInvokeDynamic().getCallSite(),
+ appView,
appView.appInfoForDesugaring(),
context)
!= null;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/nest/D8NestBasedAccessDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/nest/D8NestBasedAccessDesugaring.java
index c7e64b08..4e037ad 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/nest/D8NestBasedAccessDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/nest/D8NestBasedAccessDesugaring.java
@@ -18,7 +18,7 @@
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.UseRegistry;
import com.android.tools.r8.ir.conversion.D8MethodProcessor;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileRewritingNestBasedAccessDesugaringEventConsumer;
+import com.android.tools.r8.profile.art.rewriting.ProfileRewritingNestBasedAccessDesugaringEventConsumer;
import com.android.tools.r8.utils.ThreadUtils;
import com.google.common.collect.Iterables;
import java.util.ArrayList;
@@ -92,8 +92,8 @@
});
NestBasedAccessDesugaringEventConsumer eventConsumer =
- ArtProfileRewritingNestBasedAccessDesugaringEventConsumer.attach(
- methodProcessor.getArtProfileCollectionAdditions(),
+ ProfileRewritingNestBasedAccessDesugaringEventConsumer.attach(
+ methodProcessor.getProfileCollectionAdditions(),
new NestBasedAccessDesugaringEventConsumer() {
@Override
@@ -143,7 +143,7 @@
NestBasedAccessDesugaringUseRegistry(
ClasspathMethod context, NestBasedAccessDesugaringEventConsumer eventConsumer) {
- super(appView, context);
+ super(D8NestBasedAccessDesugaring.this.appView, context);
this.eventConsumer = eventConsumer;
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaring.java
index 91b7639..03304e5 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaring.java
@@ -168,7 +168,10 @@
CfInvokeDynamic cfInvokeDynamic = instruction.asInvokeDynamic();
LambdaDescriptor lambdaDescriptor =
LambdaDescriptor.tryInfer(
- cfInvokeDynamic.getCallSite(), appView.appInfoForDesugaring(), method);
+ cfInvokeDynamic.getCallSite(),
+ appView,
+ appView.appInfoForDesugaring(),
+ method);
if (lambdaDescriptor != null) {
DexMember<?, ?> member = lambdaDescriptor.implHandle.member;
if (needsDesugaring(member, method)) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java b/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
index 0db211d..a2572eb 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
@@ -180,7 +180,7 @@
}
// Abort inlining attempt if method -> target access is not right.
- if (resolutionResult.isAccessibleFrom(method, appView.appInfo()).isPossiblyFalse()) {
+ if (resolutionResult.isAccessibleFrom(method, appView).isPossiblyFalse()) {
whyAreYouNotInliningReporter.reportInaccessible();
return false;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java b/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
index 08f3912..f95b59e 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
@@ -320,7 +320,7 @@
/** This rebinds invoke-super instructions to their most specific target. */
private DexClass rebindSuperInvokeToMostSpecific(DexMethod target, ProgramMethod context) {
- DexClassAndMethod method = appView.appInfo().lookupSuperTarget(target, context);
+ DexClassAndMethod method = appView.appInfo().lookupSuperTarget(target, context, appView);
if (method == null) {
return null;
}
@@ -375,7 +375,7 @@
.asSingleResolution();
if (resolutionResult == null
|| resolutionResult
- .isAccessibleForVirtualDispatchFrom(context, appView.appInfo())
+ .isAccessibleForVirtualDispatchFrom(context, appView)
.isPossiblyFalse()) {
// Method does not resolve or is not accessible.
return target;
@@ -391,7 +391,7 @@
appView.appInfo().resolveMethodOnClassLegacy(receiverType, target).asSingleResolution();
if (newResolutionResult == null
|| newResolutionResult
- .isAccessibleForVirtualDispatchFrom(context, appView.appInfo())
+ .isAccessibleForVirtualDispatchFrom(context, appView)
.isPossiblyFalse()
|| !newResolutionResult
.getResolvedMethod()
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/IdempotentFunctionCallCanonicalizer.java b/src/main/java/com/android/tools/r8/ir/optimize/IdempotentFunctionCallCanonicalizer.java
index 900065d..7aae8a5 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/IdempotentFunctionCallCanonicalizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/IdempotentFunctionCallCanonicalizer.java
@@ -115,7 +115,7 @@
.asSingleResolution();
if (resolutionResult == null
|| resolutionResult
- .isAccessibleFrom(context, appInfoWithLiveness)
+ .isAccessibleFrom(context, appViewWithLiveness)
.isPossiblyFalse()) {
continue;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/InliningConstraints.java b/src/main/java/com/android/tools/r8/ir/optimize/InliningConstraints.java
index 59c066f..3452d98 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/InliningConstraints.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/InliningConstraints.java
@@ -227,13 +227,16 @@
MethodResolutionResult resolutionResult,
ProgramMethod context,
TriFunction<
- MethodResolutionResult, DexProgramClass, AppInfoWithClassHierarchy, DexEncodedMethod>
+ MethodResolutionResult,
+ DexProgramClass,
+ AppView<? extends AppInfoWithClassHierarchy>,
+ DexEncodedMethod>
lookup) {
if (!resolutionResult.isSingleResolution()) {
return null;
}
DexEncodedMethod dexEncodedMethod =
- lookup.apply(resolutionResult, context.getHolder(), appView.appInfo());
+ lookup.apply(resolutionResult, context.getHolder(), appView);
if (!isVerticalClassMerging() || dexEncodedMethod != null) {
return dexEncodedMethod;
}
@@ -245,7 +248,7 @@
return null;
}
DexEncodedMethod alternativeDexEncodedMethod =
- lookup.apply(resolutionResult, superContext, appView.appInfo());
+ lookup.apply(resolutionResult, superContext, appView);
if (alternativeDexEncodedMethod != null
&& alternativeDexEncodedMethod.getHolderType() == superContext.type) {
return alternativeDexEncodedMethod;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxerImpl.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxerImpl.java
index 0f7e4bb..1767d8b 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxerImpl.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxerImpl.java
@@ -332,7 +332,7 @@
InvokeCustom invoke, Set<DexType> eligibleEnums, ProgramMethod context) {
invoke.getCallSite().getMethodProto().forEachType(t -> markEnumEligible(t, eligibleEnums));
LambdaDescriptor lambdaDescriptor =
- LambdaDescriptor.tryInfer(invoke.getCallSite(), appView.appInfo(), context);
+ LambdaDescriptor.tryInfer(invoke.getCallSite(), appView, appView.appInfo(), context);
if (lambdaDescriptor == null) {
// Based on lambda we can see that enums cannot be unboxed if used in call site bootstrap
// arguments, since there might be expectations on overrides. Enums used directly in the
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlineOptimizationEventConsumer.java b/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlineOptimizationEventConsumer.java
index 86ac8ab..d9e8a39 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlineOptimizationEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlineOptimizationEventConsumer.java
@@ -6,7 +6,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileRewritingOutlineOptimizationEventConsumer;
+import com.android.tools.r8.profile.art.rewriting.ProfileRewritingOutlineOptimizationEventConsumer;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.Collection;
@@ -17,7 +17,7 @@
void finished(AppView<AppInfoWithLiveness> appView);
static OutlineOptimizationEventConsumer create(AppView<AppInfoWithLiveness> appView) {
- return ArtProfileRewritingOutlineOptimizationEventConsumer.attach(appView, empty());
+ return ProfileRewritingOutlineOptimizationEventConsumer.attach(appView, empty());
}
static EmptyOutlineOptimizationEventConsumer empty() {
diff --git a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
index cc88ca9..f10a6cf 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -30,6 +30,7 @@
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexTypeAnnotation;
import com.android.tools.r8.graph.DexValue;
import com.android.tools.r8.graph.DexValue.DexValueAnnotation;
import com.android.tools.r8.graph.DexValue.DexValueArray;
@@ -72,6 +73,7 @@
import org.objectweb.asm.MethodTooLargeException;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
+import org.objectweb.asm.TypePath;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.util.CheckClassAdapter;
@@ -268,7 +270,8 @@
assert SyntheticNaming.verifyNotInternalSynthetic(name);
writer.visit(version.raw(), access, name, signature, superName, interfaces);
appView.getSyntheticItems().writeAttributeIfIntermediateSyntheticClass(writer, clazz, appView);
- writeAnnotations(writer::visitAnnotation, clazz.annotations().annotations);
+ writeAnnotations(
+ writer::visitAnnotation, writer::visitTypeAnnotation, clazz.annotations().annotations);
ImmutableMap<DexString, DexValue> defaults = getAnnotationDefaults(clazz.annotations());
if (clazz.getEnclosingMethodAttribute() != null) {
@@ -454,7 +457,8 @@
String signature = field.getGenericSignature().toRenamedString(getNamingLens(), isTypeMissing);
Object value = getStaticValue(field);
FieldVisitor visitor = writer.visitField(access, name, desc, signature, value);
- writeAnnotations(visitor::visitAnnotation, field.annotations().annotations);
+ writeAnnotations(
+ visitor::visitAnnotation, visitor::visitTypeAnnotation, field.annotations().annotations);
visitor.visitEnd();
}
@@ -488,7 +492,10 @@
}
}
writeMethodParametersAnnotation(visitor, definition.annotations().annotations);
- writeAnnotations(visitor::visitAnnotation, definition.annotations().annotations);
+ writeAnnotations(
+ visitor::visitAnnotation,
+ visitor::visitTypeAnnotation,
+ definition.annotations().annotations);
writeParameterAnnotations(visitor, definition.parameterAnnotationsList);
if (!definition.shouldNotHaveCode()) {
writeCode(method, classFileVersion, namingLens, rewriter, visitor);
@@ -525,11 +532,13 @@
parameterAnnotations.getAnnotableParameterCount(), true);
visitor.visitAnnotableParameterCount(
parameterAnnotations.getAnnotableParameterCount(), false);
-
for (int i = 0; i < parameterAnnotations.size(); i++) {
int iFinal = i;
writeAnnotations(
(d, vis) -> visitor.visitParameterAnnotation(iFinal, d, vis),
+ (typeRef, typePath, desc, visible) -> {
+ throw new Unreachable("Type annotations are not placed on parameters");
+ },
parameterAnnotations.get(i).annotations);
}
}
@@ -538,7 +547,14 @@
AnnotationVisitor visit(String desc, boolean visible);
}
- private void writeAnnotations(AnnotationConsumer visitor, DexAnnotation[] annotations) {
+ private interface TypeAnnotationConsumer {
+ AnnotationVisitor visit(int typeRef, TypePath typePath, String desc, boolean visible);
+ }
+
+ private void writeAnnotations(
+ AnnotationConsumer visitor,
+ TypeAnnotationConsumer typeAnnotationVisitor,
+ DexAnnotation[] annotations) {
for (DexAnnotation dexAnnotation : annotations) {
if (dexAnnotation.visibility == DexAnnotation.VISIBILITY_SYSTEM) {
// Annotations with VISIBILITY_SYSTEM are not annotations in CF, but are special
@@ -546,10 +562,14 @@
// signature, throws.
continue;
}
+ String desc = getNamingLens().lookupDescriptor(dexAnnotation.annotation.type).toString();
+ boolean visible = dexAnnotation.visibility == DexAnnotation.VISIBILITY_RUNTIME;
+ DexTypeAnnotation dexTypeAnnotation = dexAnnotation.asTypeAnnotation();
AnnotationVisitor v =
- visitor.visit(
- getNamingLens().lookupDescriptor(dexAnnotation.annotation.type).toString(),
- dexAnnotation.visibility == DexAnnotation.VISIBILITY_RUNTIME);
+ dexTypeAnnotation == null
+ ? visitor.visit(desc, visible)
+ : typeAnnotationVisitor.visit(
+ dexTypeAnnotation.getTypeRef(), dexTypeAnnotation.getTypePath(), desc, visible);
if (v != null) {
writeAnnotation(v, dexAnnotation.annotation);
v.visitEnd();
diff --git a/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java b/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
index e09e9f5..689d5ff 100644
--- a/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
+++ b/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
@@ -3,17 +3,21 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.lightir;
+import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.Argument;
import com.android.tools.r8.ir.code.ArrayLength;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.CatchHandlers;
+import com.android.tools.r8.ir.code.Cmp;
+import com.android.tools.r8.ir.code.Cmp.Bias;
import com.android.tools.r8.ir.code.ConstNumber;
import com.android.tools.r8.ir.code.ConstString;
import com.android.tools.r8.ir.code.DebugLocalWrite;
@@ -23,10 +27,15 @@
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.If;
import com.android.tools.r8.ir.code.IfType;
+import com.android.tools.r8.ir.code.InstanceGet;
+import com.android.tools.r8.ir.code.InstancePut;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InvokeDirect;
+import com.android.tools.r8.ir.code.InvokeInterface;
+import com.android.tools.r8.ir.code.InvokeStatic;
import com.android.tools.r8.ir.code.InvokeVirtual;
import com.android.tools.r8.ir.code.MoveException;
+import com.android.tools.r8.ir.code.NewInstance;
import com.android.tools.r8.ir.code.NumberGenerator;
import com.android.tools.r8.ir.code.NumericType;
import com.android.tools.r8.ir.code.Phi;
@@ -91,8 +100,6 @@
AppView<?> appView,
LirDecodingStrategy<Value, EV> strategy) {
super(code);
- assert code.getPositionTable().length > 0;
- assert code.getPositionTable()[0].fromInstructionIndex == 0;
this.appView = appView;
this.code = code;
this.strategy = strategy;
@@ -370,6 +377,23 @@
addInstruction(instruction);
}
+ @Override
+ public void onInvokeStatic(DexMethod target, List<EV> arguments) {
+ // TODO(b/225838009): Maintain is-interface bit.
+ Value dest = getInvokeInstructionOutputValue(target);
+ List<Value> ssaArgumentValues = getValues(arguments);
+ InvokeStatic instruction = new InvokeStatic(target, dest, ssaArgumentValues);
+ addInstruction(instruction);
+ }
+
+ @Override
+ public void onInvokeInterface(DexMethod target, List<EV> arguments) {
+ Value dest = getInvokeInstructionOutputValue(target);
+ List<Value> ssaArgumentValues = getValues(arguments);
+ InvokeInterface instruction = new InvokeInterface(target, dest, ssaArgumentValues);
+ addInstruction(instruction);
+ }
+
private Value getInvokeInstructionOutputValue(DexMethod target) {
return target.getReturnType().isVoidType()
? null
@@ -377,12 +401,30 @@
}
@Override
+ public void onNewInstance(DexType clazz) {
+ TypeElement type = TypeElement.fromDexType(clazz, Nullability.definitelyNotNull(), appView);
+ Value dest = getOutValueForNextInstruction(type);
+ addInstruction(new NewInstance(clazz, dest));
+ }
+
+ @Override
public void onStaticGet(DexField field) {
Value dest = getOutValueForNextInstruction(field.getTypeElement(appView));
addInstruction(new StaticGet(dest, field));
}
@Override
+ public void onInstanceGet(DexField field, EV object) {
+ Value dest = getOutValueForNextInstruction(field.getTypeElement(appView));
+ addInstruction(new InstanceGet(dest, getValue(object), field));
+ }
+
+ @Override
+ public void onInstancePut(DexField field, EV object, EV value) {
+ addInstruction(new InstancePut(field, getValue(object), getValue(value)));
+ }
+
+ @Override
public void onReturnVoid() {
addInstruction(new Return());
closeCurrentBlock();
@@ -425,5 +467,39 @@
dest.setType(type);
addInstruction(new DebugLocalWrite(dest, src));
}
+
+ @Override
+ public void onCmpInstruction(int opcode, EV leftIndex, EV rightIndex) {
+ NumericType type;
+ Bias bias;
+ switch (opcode) {
+ case LirOpcodes.LCMP:
+ type = NumericType.LONG;
+ bias = Bias.NONE;
+ break;
+ case LirOpcodes.FCMPL:
+ type = NumericType.FLOAT;
+ bias = Bias.LT;
+ break;
+ case LirOpcodes.FCMPG:
+ type = NumericType.FLOAT;
+ bias = Bias.GT;
+ break;
+ case LirOpcodes.DCMPL:
+ type = NumericType.DOUBLE;
+ bias = Bias.LT;
+ break;
+ case LirOpcodes.DCMPG:
+ type = NumericType.DOUBLE;
+ bias = Bias.GT;
+ break;
+ default:
+ throw new Unreachable("Unexpected cmp opcode: " + opcode);
+ }
+ Value leftValue = getValue(leftIndex);
+ Value rightValue = getValue(rightIndex);
+ Value dest = getOutValueForNextInstruction(TypeElement.getInt());
+ addInstruction(new Cmp(type, bias, dest, leftValue, rightValue));
+ }
}
}
diff --git a/src/main/java/com/android/tools/r8/lightir/LirBuilder.java b/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
index fd4113a..8209c80 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
@@ -15,6 +15,8 @@
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.CatchHandlers;
+import com.android.tools.r8.ir.code.Cmp;
+import com.android.tools.r8.ir.code.Cmp.Bias;
import com.android.tools.r8.ir.code.IRMetadata;
import com.android.tools.r8.ir.code.IfType;
import com.android.tools.r8.ir.code.NumericType;
@@ -208,6 +210,11 @@
opcode, Collections.emptyList(), Collections.singletonList(value));
}
+ private LirBuilder<V, EV> addTwoValueInstruction(int opcode, V leftValue, V rightValue) {
+ return addInstructionTemplate(
+ opcode, Collections.emptyList(), ImmutableList.of(leftValue, rightValue));
+ }
+
private LirBuilder<V, EV> addInstructionTemplate(
int opcode, List<DexItem> items, List<V> values) {
assert values.size() < MAX_VALUE_COUNT;
@@ -291,6 +298,16 @@
return addOneItemInstruction(LirOpcodes.GETSTATIC, field);
}
+ public LirBuilder<V, EV> addInstanceGet(DexField field, V object) {
+ return addInstructionTemplate(
+ LirOpcodes.GETFIELD, Collections.singletonList(field), Collections.singletonList(object));
+ }
+
+ public LirBuilder<V, EV> addInstancePut(DexField field, V object, V value) {
+ return addInstructionTemplate(
+ LirOpcodes.PUTFIELD, Collections.singletonList(field), ImmutableList.of(object, value));
+ }
+
public LirBuilder<V, EV> addInvokeInstruction(int opcode, DexMethod method, List<V> arguments) {
return addInstructionTemplate(opcode, Collections.singletonList(method), arguments);
}
@@ -303,6 +320,18 @@
return addInvokeInstruction(LirOpcodes.INVOKEVIRTUAL, method, arguments);
}
+ public LirBuilder<V, EV> addInvokeStatic(DexMethod method, List<V> arguments) {
+ return addInvokeInstruction(LirOpcodes.INVOKESTATIC, method, arguments);
+ }
+
+ public LirBuilder<V, EV> addInvokeInterface(DexMethod method, List<V> arguments) {
+ return addInvokeInstruction(LirOpcodes.INVOKEINTERFACE, method, arguments);
+ }
+
+ public LirBuilder<V, EV> addNewInstance(DexType clazz) {
+ return addOneItemInstruction(LirOpcodes.NEW, clazz);
+ }
+
public LirBuilder<V, EV> addReturn(V value) {
throw new Unimplemented();
}
@@ -435,4 +464,21 @@
debugTable,
strategy.getStrategyInfo());
}
+
+ private int getCmpOpcode(NumericType type, Cmp.Bias bias) {
+ switch (type) {
+ case LONG:
+ return LirOpcodes.LCMP;
+ case FLOAT:
+ return bias == Cmp.Bias.LT ? LirOpcodes.FCMPL : LirOpcodes.FCMPG;
+ case DOUBLE:
+ return bias == Cmp.Bias.LT ? LirOpcodes.DCMPL : LirOpcodes.DCMPG;
+ default:
+ throw new Unreachable("Cmp has unknown type " + type);
+ }
+ }
+
+ public LirBuilder<V, EV> addCmp(NumericType type, Bias bias, V leftValue, V rightValue) {
+ return addTwoValueInstruction(getCmpOpcode(type, bias), leftValue, rightValue);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java b/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
index ed94301..a83524c 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
@@ -106,6 +106,18 @@
onInvokeMethodInstruction(method, arguments);
}
+ public void onInvokeStatic(DexMethod method, List<EV> arguments) {
+ onInvokeMethodInstruction(method, arguments);
+ }
+
+ public void onInvokeInterface(DexMethod method, List<EV> arguments) {
+ onInvokeMethodInstruction(method, arguments);
+ }
+
+ public void onNewInstance(DexType clazz) {
+ onInstruction();
+ }
+
public void onFieldInstruction(DexField field) {
onInstruction();
}
@@ -114,6 +126,10 @@
onFieldInstruction(field);
}
+ public abstract void onInstanceGet(DexField field, EV object);
+
+ public abstract void onInstancePut(DexField field, EV object, EV value);
+
public void onReturnVoid() {
onInstruction();
}
@@ -130,6 +146,11 @@
onInstruction();
}
+ public void onCmpInstruction(int opcode, EV leftValue, EV rightValue) {
+ assert LirOpcodes.LCMP <= opcode && opcode <= LirOpcodes.DCMPG;
+ onInstruction();
+ }
+
private DexItem getConstantItem(int index) {
return code.getConstantItem(index);
}
@@ -204,12 +225,50 @@
onInvokeVirtual(target, arguments);
return;
}
+ case LirOpcodes.INVOKESTATIC:
+ {
+ DexMethod target = getInvokeInstructionTarget(view);
+ List<EV> arguments = getInvokeInstructionArguments(view);
+ onInvokeStatic(target, arguments);
+ return;
+ }
+ case LirOpcodes.INVOKEINTERFACE:
+ {
+ DexMethod target = getInvokeInstructionTarget(view);
+ List<EV> arguments = getInvokeInstructionArguments(view);
+ onInvokeInterface(target, arguments);
+ return;
+ }
+ case LirOpcodes.NEW:
+ {
+ DexItem item = getConstantItem(view.getNextConstantOperand());
+ if (item instanceof DexType) {
+ onNewInstance((DexType) item);
+ return;
+ }
+ throw new Unimplemented();
+ }
case LirOpcodes.GETSTATIC:
{
DexField field = (DexField) getConstantItem(view.getNextConstantOperand());
onStaticGet(field);
return;
}
+ case LirOpcodes.GETFIELD:
+ {
+ DexField field = (DexField) getConstantItem(view.getNextConstantOperand());
+ EV object = getNextValueOperand(view);
+ onInstanceGet(field, object);
+ return;
+ }
+ case LirOpcodes.PUTFIELD:
+ {
+ DexField field = (DexField) getConstantItem(view.getNextConstantOperand());
+ EV object = getNextValueOperand(view);
+ EV value = getNextValueOperand(view);
+ onInstancePut(field, object, value);
+ return;
+ }
case LirOpcodes.RETURN:
{
onReturnVoid();
@@ -252,6 +311,17 @@
onDebugLocalWrite(srcIndex);
return;
}
+ case LirOpcodes.LCMP:
+ case LirOpcodes.FCMPL:
+ case LirOpcodes.FCMPG:
+ case LirOpcodes.DCMPL:
+ case LirOpcodes.DCMPG:
+ {
+ EV leftValue = getNextValueOperand(view);
+ EV rightValue = getNextValueOperand(view);
+ onCmpInstruction(opcode, leftValue, rightValue);
+ return;
+ }
default:
throw new Unimplemented("No dispatch for opcode " + LirOpcodes.toString(opcode));
}
diff --git a/src/main/java/com/android/tools/r8/lightir/LirPrinter.java b/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
index f4a840b..33dedd6 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.ir.code.IfType;
import com.android.tools.r8.ir.code.NumericType;
import com.android.tools.r8.utils.StringUtils;
+import java.util.Arrays;
import java.util.List;
public class LirPrinter<EV> extends LirParsedInstructionCallback<EV> {
@@ -60,6 +61,11 @@
return instructionIndex < 0 ? "--" : ("" + instructionIndex);
}
+ @SafeVarargs
+ private void appendValueArguments(EV... arguments) {
+ appendValueArguments(Arrays.asList(arguments));
+ }
+
private void appendValueArguments(List<EV> arguments) {
for (int i = 0; i < arguments.size(); i++) {
builder.append(fmtValueIndex(arguments.get(i))).append(' ');
@@ -183,6 +189,19 @@
}
@Override
+ public void onInstanceGet(DexField field, EV object) {
+ appendOutValue();
+ builder.append(field).append(' ');
+ appendValueArguments(object);
+ }
+
+ @Override
+ public void onInstancePut(DexField field, EV object, EV value) {
+ builder.append(field).append(' ');
+ appendValueArguments(object, value);
+ }
+
+ @Override
public void onReturnVoid() {
// Nothing to append.
}
@@ -203,4 +222,10 @@
appendValueArguments(operands);
builder.append(type);
}
+
+ @Override
+ public void onCmpInstruction(int opcode, EV leftValue, EV rightValue) {
+ appendOutValue();
+ appendValueArguments(leftValue, rightValue);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/naming/InterfaceMethodNameMinifier.java b/src/main/java/com/android/tools/r8/naming/InterfaceMethodNameMinifier.java
index 14f7711..d607d71 100644
--- a/src/main/java/com/android/tools/r8/naming/InterfaceMethodNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/InterfaceMethodNameMinifier.java
@@ -457,7 +457,7 @@
// Don't report errors, as the set of call sites is a conservative estimate, and can
// refer to interfaces which has been removed.
Set<DexEncodedMethod> implementedMethods =
- appView.appInfo().lookupLambdaImplementedMethods(callSite);
+ appView.appInfo().lookupLambdaImplementedMethods(callSite, appView);
for (DexEncodedMethod method : implementedMethods) {
Wrapper<DexEncodedMethod> wrapped = definitionEquivalence.wrap(method);
InterfaceMethodGroupState groupState = globalStateMap.get(wrapped);
@@ -470,8 +470,7 @@
}
// For intersection types, we have to iterate all the multiple interfaces to look for
// methods with the same signature.
- List<DexType> implementedInterfaces =
- LambdaDescriptor.getInterfaces(callSite, appView.appInfo());
+ List<DexType> implementedInterfaces = LambdaDescriptor.getInterfaces(callSite, appView);
if (implementedInterfaces != null) {
for (int i = 1; i < implementedInterfaces.size(); i++) {
// Add the merging state for all additional implemented interfaces into the state
diff --git a/src/main/java/com/android/tools/r8/naming/NamingLens.java b/src/main/java/com/android/tools/r8/naming/NamingLens.java
index 5b24eb9..ca69f67 100644
--- a/src/main/java/com/android/tools/r8/naming/NamingLens.java
+++ b/src/main/java/com/android/tools/r8/naming/NamingLens.java
@@ -17,6 +17,7 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.InnerClassAttribute;
import com.android.tools.r8.optimize.MemberRebindingAnalysis;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.google.common.collect.Sets;
@@ -55,8 +56,9 @@
if (!appView.appInfo().hasLiveness()) {
return callSite.methodName;
}
+ AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
Set<DexEncodedMethod> lambdaImplementedMethods =
- appView.appInfo().withLiveness().lookupLambdaImplementedMethods(callSite);
+ appViewWithLiveness.appInfo().lookupLambdaImplementedMethods(callSite, appViewWithLiveness);
if (lambdaImplementedMethods.isEmpty()) {
return callSite.methodName;
}
diff --git a/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java b/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
index 87af2b2..d860861 100644
--- a/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
+++ b/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
@@ -64,6 +64,10 @@
this.lensBuilder = MemberRebindingLens.builder(appView);
}
+ private AppView<AppInfoWithLiveness> appView() {
+ return appView;
+ }
+
private DexMethod validMemberRebindingTargetForNonProgramMethod(
DexClassAndMethod resolvedMethod,
SingleResolutionResult<?> resolutionResult,
@@ -167,7 +171,7 @@
}
return Iterables.all(
contexts,
- context -> resolutionResult.isAccessibleFrom(context, appView.appInfo()).isTrue());
+ context -> resolutionResult.isAccessibleFrom(context, appView, appView.appInfo()).isTrue());
}
private boolean isInvokeSuperToInterfaceMethod(DexClassAndMethod method, InvokeType invokeType) {
@@ -578,7 +582,7 @@
}
private void registerFieldReference(DexField field) {
- appView
+ appView()
.appInfo()
.resolveField(field)
.forEachSuccessfulFieldResolutionResult(
diff --git a/src/main/java/com/android/tools/r8/optimize/MemberRebindingEventConsumer.java b/src/main/java/com/android/tools/r8/optimize/MemberRebindingEventConsumer.java
index dff6597..c6d1656 100644
--- a/src/main/java/com/android/tools/r8/optimize/MemberRebindingEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/optimize/MemberRebindingEventConsumer.java
@@ -7,7 +7,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileRewritingMemberRebindingEventConsumer;
+import com.android.tools.r8.profile.art.rewriting.ProfileRewritingMemberRebindingEventConsumer;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
public interface MemberRebindingEventConsumer {
@@ -19,7 +19,7 @@
AppView<AppInfoWithLiveness> appView, MemberRebindingLens memberRebindingLens) {}
static MemberRebindingEventConsumer create(AppView<AppInfoWithLiveness> appView) {
- return ArtProfileRewritingMemberRebindingEventConsumer.attach(appView, empty());
+ return ProfileRewritingMemberRebindingEventConsumer.attach(appView, empty());
}
static EmptyMemberRebindingEventConsumer empty() {
diff --git a/src/main/java/com/android/tools/r8/optimize/RedundantBridgeRemover.java b/src/main/java/com/android/tools/r8/optimize/RedundantBridgeRemover.java
index 5cbb1b6..815a807 100644
--- a/src/main/java/com/android/tools/r8/optimize/RedundantBridgeRemover.java
+++ b/src/main/java/com/android/tools/r8/optimize/RedundantBridgeRemover.java
@@ -205,7 +205,7 @@
// Only check for interfaces if resolving the method on super type causes NoSuchMethodError.
FailedResolutionResult failedResolutionResult = superTypeResolution.asFailedResolution();
if (failedResolutionResult == null
- || !failedResolutionResult.isNoSuchMethodErrorResult(holder, appView.appInfo())
+ || !failedResolutionResult.isNoSuchMethodErrorResult(holder, appView, appView.appInfo())
|| holder.getInterfaces().isEmpty()) {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java
index 9023c00..c42b054 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java
@@ -205,7 +205,7 @@
// Use the super target instead of the resolved method to ensure that we propagate the
// argument information to the targeted method.
DexClassAndMethod target =
- resolutionResult.lookupInvokeSuperTarget(context.getHolder(), appView.appInfo());
+ resolutionResult.lookupInvokeSuperTarget(context.getHolder(), appView);
if (target == null) {
// Nothing to propagate; the invoke instruction fails.
return;
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorSyntheticEventConsumer.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorSyntheticEventConsumer.java
index 799cd92..397a23f 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorSyntheticEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorSyntheticEventConsumer.java
@@ -7,7 +7,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileRewritingArgumentPropagatorSyntheticEventConsumer;
+import com.android.tools.r8.profile.art.rewriting.ProfileRewritingArgumentPropagatorSyntheticEventConsumer;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
public interface ArgumentPropagatorSyntheticEventConsumer {
@@ -17,7 +17,7 @@
void finished(AppView<AppInfoWithLiveness> appView);
static ArgumentPropagatorSyntheticEventConsumer create(AppView<AppInfoWithLiveness> appView) {
- return ArtProfileRewritingArgumentPropagatorSyntheticEventConsumer.attach(appView, empty());
+ return ProfileRewritingArgumentPropagatorSyntheticEventConsumer.attach(appView, empty());
}
static ArgumentPropagatorSyntheticEventConsumer empty() {
diff --git a/src/main/java/com/android/tools/r8/profile/AbstractProfile.java b/src/main/java/com/android/tools/r8/profile/AbstractProfile.java
new file mode 100644
index 0000000..87b5656
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/profile/AbstractProfile.java
@@ -0,0 +1,41 @@
+// 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;
+
+import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.utils.ThrowingConsumer;
+
+public interface AbstractProfile<
+ ClassRule extends AbstractProfileClassRule, MethodRule extends AbstractProfileMethodRule> {
+
+ boolean containsClassRule(DexType type);
+
+ boolean containsMethodRule(DexMethod method);
+
+ <E1 extends Exception, E2 extends Exception> void forEachRule(
+ ThrowingConsumer<ClassRule, E1> classRuleConsumer,
+ ThrowingConsumer<MethodRule, E2> methodRuleConsumer)
+ throws E1, E2;
+
+ ClassRule getClassRule(DexType type);
+
+ MethodRule getMethodRule(DexMethod method);
+
+ interface Builder<
+ ClassRule extends AbstractProfileClassRule,
+ MethodRule extends AbstractProfileMethodRule,
+ Profile extends AbstractProfile<ClassRule, MethodRule>,
+ ProfileBuilder extends Builder<ClassRule, MethodRule, Profile, ProfileBuilder>> {
+
+ ProfileBuilder addRule(AbstractProfileRule rule);
+
+ ProfileBuilder addClassRule(ClassRule classRule);
+
+ ProfileBuilder addMethodRule(MethodRule methodRule);
+
+ Profile build();
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/profile/AbstractProfileClassRule.java b/src/main/java/com/android/tools/r8/profile/AbstractProfileClassRule.java
new file mode 100644
index 0000000..d948afb
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/profile/AbstractProfileClassRule.java
@@ -0,0 +1,17 @@
+// 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;
+
+import com.android.tools.r8.graph.DexType;
+
+public interface AbstractProfileClassRule extends AbstractProfileRule {
+
+ DexType getReference();
+
+ interface Builder<ClassRule extends AbstractProfileClassRule> {
+
+ ClassRule build();
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/profile/AbstractProfileMethodRule.java b/src/main/java/com/android/tools/r8/profile/AbstractProfileMethodRule.java
new file mode 100644
index 0000000..ddb1225
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/profile/AbstractProfileMethodRule.java
@@ -0,0 +1,27 @@
+// 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;
+
+import com.android.tools.r8.graph.DexMethod;
+
+public interface AbstractProfileMethodRule extends AbstractProfileRule {
+
+ DexMethod getReference();
+
+ interface Builder<
+ MethodRule extends AbstractProfileMethodRule,
+ MethodRuleBuilder extends Builder<MethodRule, MethodRuleBuilder>> {
+
+ boolean isGreaterThanOrEqualTo(MethodRuleBuilder methodRuleBuilder);
+
+ MethodRuleBuilder join(MethodRule methodRule);
+
+ MethodRuleBuilder join(MethodRuleBuilder methodRuleBuilder);
+
+ MethodRuleBuilder setMethod(DexMethod method);
+
+ MethodRule build();
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/profile/AbstractProfileRule.java b/src/main/java/com/android/tools/r8/profile/AbstractProfileRule.java
new file mode 100644
index 0000000..ad28bfd
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/profile/AbstractProfileRule.java
@@ -0,0 +1,21 @@
+// 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;
+
+import com.android.tools.r8.experimental.startup.profile.StartupProfileRule;
+import com.android.tools.r8.profile.art.ArtProfileRule;
+
+public interface AbstractProfileRule {
+
+ @SuppressWarnings("unchecked")
+ default ArtProfileRule asArtProfileRule() {
+ return (ArtProfileRule) this;
+ }
+
+ @SuppressWarnings("unchecked")
+ default StartupProfileRule asStartupProfileRule() {
+ return (StartupProfileRule) this;
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfile.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfile.java
index 8fb11ef..7ab727d 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfile.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfile.java
@@ -19,6 +19,8 @@
import com.android.tools.r8.graph.PrunedItems;
import com.android.tools.r8.ir.optimize.enums.EnumUnboxingLens;
import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.profile.AbstractProfile;
+import com.android.tools.r8.profile.AbstractProfileRule;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.ThrowingConsumer;
@@ -33,7 +35,7 @@
import java.util.function.Consumer;
import java.util.function.Function;
-public class ArtProfile {
+public class ArtProfile implements AbstractProfile<ArtProfileClassRule, ArtProfileMethodRule> {
private final Map<DexReference, ArtProfileRule> rules;
@@ -50,10 +52,12 @@
return new Builder(artProfileProvider, options);
}
+ @Override
public boolean containsClassRule(DexType type) {
return rules.containsKey(type);
}
+ @Override
public boolean containsMethodRule(DexMethod method) {
return rules.containsKey(method);
}
@@ -65,6 +69,7 @@
}
}
+ @Override
public <E1 extends Exception, E2 extends Exception> void forEachRule(
ThrowingConsumer<ArtProfileClassRule, E1> classRuleConsumer,
ThrowingConsumer<ArtProfileMethodRule, E2> methodRuleConsumer)
@@ -74,10 +79,12 @@
}
}
+ @Override
public ArtProfileClassRule getClassRule(DexType type) {
return (ArtProfileClassRule) rules.get(type);
}
+ @Override
public ArtProfileMethodRule getMethodRule(DexMethod method) {
return (ArtProfileMethodRule) rules.get(method);
}
@@ -259,7 +266,9 @@
methodRule.getMethodReference(), methodRule.getMethodRuleInfo()));
}
- public static class Builder implements ArtProfileBuilder {
+ public static class Builder
+ implements ArtProfileBuilder,
+ AbstractProfile.Builder<ArtProfileClassRule, ArtProfileMethodRule, ArtProfile, Builder> {
private final ArtProfileProvider artProfileProvider;
private final DexItemFactory dexItemFactory;
@@ -281,19 +290,29 @@
this.reporter = options.reporter;
}
- public Builder addRule(ArtProfileRule rule) {
- assert !rules.containsKey(rule.getReference());
- rule.accept(
- classRule -> rules.put(classRule.getType(), classRule),
- methodRule -> rules.put(methodRule.getMethod(), methodRule));
+ @Override
+ public Builder addRule(AbstractProfileRule rule) {
+ return addRule(rule.asArtProfileRule());
+ }
+
+ @Override
+ public Builder addClassRule(ArtProfileClassRule classRule) {
+ assert !rules.containsKey(classRule.getReference());
+ rules.put(classRule.getType(), classRule);
return this;
}
- public Builder addRules(Collection<ArtProfileRule> rules) {
- rules.forEach(this::addRule);
+ @Override
+ public Builder addMethodRule(ArtProfileMethodRule methodRule) {
+ assert !rules.containsKey(methodRule.getReference());
+ rules.put(methodRule.getMethod(), methodRule);
return this;
}
+ public Builder addRule(ArtProfileRule rule) {
+ return rule.apply(this::addClassRule, this::addMethodRule);
+ }
+
public Builder addRuleBuilders(Collection<ArtProfileRule.Builder> ruleBuilders) {
ruleBuilders.forEach(ruleBuilder -> addRule(ruleBuilder.build()));
return this;
@@ -303,14 +322,14 @@
public Builder addClassRule(Consumer<ArtProfileClassRuleBuilder> classRuleBuilderConsumer) {
ArtProfileClassRule.Builder classRuleBuilder = ArtProfileClassRule.builder(dexItemFactory);
classRuleBuilderConsumer.accept(classRuleBuilder);
- return addRule(classRuleBuilder.build());
+ return addClassRule(classRuleBuilder.build());
}
@Override
public Builder addMethodRule(Consumer<ArtProfileMethodRuleBuilder> methodRuleBuilderConsumer) {
ArtProfileMethodRule.Builder methodRuleBuilder = ArtProfileMethodRule.builder(dexItemFactory);
methodRuleBuilderConsumer.accept(methodRuleBuilder);
- return addRule(methodRuleBuilder.build());
+ return addMethodRule(methodRuleBuilder.build());
}
@Override
@@ -328,6 +347,7 @@
return this;
}
+ @Override
public ArtProfile build() {
return new ArtProfile(rules);
}
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileBuilderUtils.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileBuilderUtils.java
index 77d0005..bbfe13e 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileBuilderUtils.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileBuilderUtils.java
@@ -4,14 +4,11 @@
package com.android.tools.r8.profile.art;
-import static com.android.tools.r8.synthesis.SyntheticNaming.COMPANION_CLASS_SUFFIX;
-import static com.android.tools.r8.synthesis.SyntheticNaming.EXTERNAL_SYNTHETIC_CLASS_SEPARATOR;
import com.android.tools.r8.TextInputStream;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.MethodReference;
-import com.android.tools.r8.references.Reference;
import com.android.tools.r8.startup.StartupProfileBuilder;
import com.android.tools.r8.utils.MethodReferenceUtils;
import java.io.IOException;
@@ -20,60 +17,12 @@
public class ArtProfileBuilderUtils {
- public interface SyntheticToSyntheticContextGeneralization {
-
- ClassReference getSyntheticContextReference(ClassReference classReference);
-
- /**
- * When a startup profile is given to D8, the program input should be dex and the startup
- * profile should have been generated by launching the dex that is given on input. Therefore,
- * synthetic items in the ART profile should be present in the program input to D8 with the
- * exact same synthetic names as in the ART profile. This means that there is no need to
- * generalize synthetic items to their synthetic context.
- */
- static SyntheticToSyntheticContextGeneralization createForD8() {
- return classReference -> null;
- }
-
- /**
- * When a startup profile is given to R8, the program input is class files and the startup
- * profile should have been generated by dexing the program input (in release and intermediate
- * mode) and then launching the resulting app. The synthetic items in the resulting ART profile
- * do not exist in the program input to R8 (and the same synthetics may receive different names
- * in the R8 compilation). Therefore, synthetic items in the ART profile are generalized into
- * matching all synthetics from their synthetic context.
- */
- static SyntheticToSyntheticContextGeneralization createForR8() {
- return classReference -> {
- // TODO(b/243777722): Move this logic into synthetic items and extend the mapping from
- // synthetic classes to their synthetic context to all synthetic kinds.
- String classDescriptor = classReference.getDescriptor();
- for (int i = 1; i < classDescriptor.length() - 1; i++) {
- if (classDescriptor.charAt(i) != '$') {
- continue;
- }
- if (classDescriptor.regionMatches(
- i, COMPANION_CLASS_SUFFIX, 0, COMPANION_CLASS_SUFFIX.length())
- || classDescriptor.regionMatches(
- i,
- EXTERNAL_SYNTHETIC_CLASS_SEPARATOR,
- 0,
- EXTERNAL_SYNTHETIC_CLASS_SEPARATOR.length())) {
- return Reference.classFromDescriptor(classDescriptor.substring(0, i) + ";");
- }
- }
- return null;
- };
- }
- }
-
/**
* Helper for creating an {@link ArtProfileBuilder} that performs callbacks on the given {@param
* startupProfileBuilder}.
*/
public static ArtProfileBuilder createBuilderForArtProfileToStartupProfileConversion(
- StartupProfileBuilder startupProfileBuilder,
- SyntheticToSyntheticContextGeneralization syntheticToSyntheticContextGeneralization) {
+ StartupProfileBuilder startupProfileBuilder) {
return new ArtProfileBuilder() {
@Override
@@ -81,19 +30,9 @@
Consumer<ArtProfileClassRuleBuilder> classRuleBuilderConsumer) {
MutableArtProfileClassRule classRule = new MutableArtProfileClassRule();
classRuleBuilderConsumer.accept(classRule);
- ClassReference syntheticContextReference =
- syntheticToSyntheticContextGeneralization.getSyntheticContextReference(
- classRule.getClassReference());
- if (syntheticContextReference == null) {
- startupProfileBuilder.addStartupClass(
- startupClassBuilder ->
- startupClassBuilder.setClassReference(classRule.getClassReference()));
- } else {
- startupProfileBuilder.addSyntheticStartupMethod(
- syntheticStartupMethodBuilder ->
- syntheticStartupMethodBuilder.setSyntheticContextReference(
- syntheticContextReference));
- }
+ startupProfileBuilder.addStartupClass(
+ startupClassBuilder ->
+ startupClassBuilder.setClassReference(classRule.getClassReference()));
return this;
}
@@ -102,19 +41,9 @@
Consumer<ArtProfileMethodRuleBuilder> methodRuleBuilderConsumer) {
MutableArtProfileMethodRule methodRule = new MutableArtProfileMethodRule();
methodRuleBuilderConsumer.accept(methodRule);
- ClassReference syntheticContextReference =
- syntheticToSyntheticContextGeneralization.getSyntheticContextReference(
- methodRule.getMethodReference().getHolderClass());
- if (syntheticContextReference == null) {
- startupProfileBuilder.addStartupMethod(
- startupMethodBuilder ->
- startupMethodBuilder.setMethodReference(methodRule.getMethodReference()));
- } else {
- startupProfileBuilder.addSyntheticStartupMethod(
- syntheticStartupMethodBuilder ->
- syntheticStartupMethodBuilder.setSyntheticContextReference(
- syntheticContextReference));
- }
+ startupProfileBuilder.addStartupMethod(
+ startupMethodBuilder ->
+ startupMethodBuilder.setMethodReference(methodRule.getMethodReference()));
return this;
}
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRule.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRule.java
index 283e22b..625d92f 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRule.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRule.java
@@ -5,15 +5,16 @@
package com.android.tools.r8.profile.art;
import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.profile.AbstractProfileClassRule;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.ThrowingConsumer;
+import com.android.tools.r8.utils.ThrowingFunction;
import java.io.IOException;
import java.io.OutputStreamWriter;
-public class ArtProfileClassRule extends ArtProfileRule {
+public class ArtProfileClassRule extends ArtProfileRule implements AbstractProfileClassRule {
private final DexType type;
@@ -37,6 +38,14 @@
classRuleConsumer.accept(this);
}
+ @Override
+ public <T, E1 extends Exception, E2 extends Exception> T apply(
+ ThrowingFunction<ArtProfileClassRule, T, E1> classRuleFunction,
+ ThrowingFunction<ArtProfileMethodRule, T, E2> methodRuleFunction)
+ throws E1 {
+ return classRuleFunction.apply(this);
+ }
+
public ClassReference getClassReference() {
return Reference.classFromDescriptor(type.toDescriptorString());
}
@@ -46,7 +55,7 @@
}
@Override
- public DexReference getReference() {
+ public DexType getReference() {
return getType();
}
@@ -55,16 +64,6 @@
}
@Override
- public boolean isClassRule() {
- return true;
- }
-
- @Override
- public ArtProfileClassRule asClassRule() {
- return this;
- }
-
- @Override
public void writeHumanReadableRuleString(OutputStreamWriter writer) throws IOException {
writer.write(type.toDescriptorString());
}
@@ -91,7 +90,8 @@
return type.toDescriptorString();
}
- public static class Builder extends ArtProfileRule.Builder implements ArtProfileClassRuleBuilder {
+ public static class Builder extends ArtProfileRule.Builder
+ implements ArtProfileClassRuleBuilder, AbstractProfileClassRule.Builder<ArtProfileClassRule> {
private final DexItemFactory dexItemFactory;
private DexType type;
@@ -105,11 +105,6 @@
}
@Override
- public boolean isClassRuleBuilder() {
- return true;
- }
-
- @Override
Builder asClassRuleBuilder() {
return this;
}
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileCollection.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileCollection.java
index 9eb9a1c..a571922 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileCollection.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileCollection.java
@@ -48,10 +48,11 @@
private static ArtProfile createCompleteArtProfile(AppInfo appInfo) {
ArtProfile.Builder artProfileBuilder = ArtProfile.builder();
for (DexProgramClass clazz : appInfo.classesWithDeterministicOrder()) {
- artProfileBuilder.addRule(ArtProfileClassRule.builder().setType(clazz.getType()).build());
+ artProfileBuilder.addClassRule(
+ ArtProfileClassRule.builder().setType(clazz.getType()).build());
clazz.forEachMethod(
method ->
- artProfileBuilder.addRule(
+ artProfileBuilder.addMethodRule(
ArtProfileMethodRule.builder().setMethod(method.getReference()).build()));
}
return artProfileBuilder.build();
@@ -61,6 +62,8 @@
return EmptyArtProfileCollection.getInstance();
}
+ public abstract boolean isEmpty();
+
public abstract boolean isNonEmpty();
public abstract NonEmptyArtProfileCollection asNonEmpty();
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRule.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRule.java
index fe7bd78..1440b8b 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRule.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRule.java
@@ -6,14 +6,16 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.profile.AbstractProfileMethodRule;
import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.utils.MethodReferenceUtils;
import com.android.tools.r8.utils.ThrowingConsumer;
+import com.android.tools.r8.utils.ThrowingFunction;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.function.Consumer;
-public class ArtProfileMethodRule extends ArtProfileRule {
+public class ArtProfileMethodRule extends ArtProfileRule implements AbstractProfileMethodRule {
private final DexMethod method;
private final ArtProfileMethodRuleInfoImpl info;
@@ -39,6 +41,14 @@
methodRuleConsumer.accept(this);
}
+ @Override
+ public <T, E1 extends Exception, E2 extends Exception> T apply(
+ ThrowingFunction<ArtProfileClassRule, T, E1> classRuleFunction,
+ ThrowingFunction<ArtProfileMethodRule, T, E2> methodRuleFunction)
+ throws E2 {
+ return methodRuleFunction.apply(this);
+ }
+
public DexMethod getMethod() {
return method;
}
@@ -57,16 +67,6 @@
}
@Override
- public boolean isMethodRule() {
- return true;
- }
-
- @Override
- public ArtProfileMethodRule asMethodRule() {
- return this;
- }
-
- @Override
public void writeHumanReadableRuleString(OutputStreamWriter writer) throws IOException {
info.writeHumanReadableFlags(writer);
writer.write(method.toSmaliString());
@@ -97,7 +97,8 @@
}
public static class Builder extends ArtProfileRule.Builder
- implements ArtProfileMethodRuleBuilder {
+ implements ArtProfileMethodRuleBuilder,
+ AbstractProfileMethodRule.Builder<ArtProfileMethodRule, Builder> {
private final DexItemFactory dexItemFactory;
@@ -118,8 +119,8 @@
}
@Override
- public boolean isMethodRuleBuilder() {
- return true;
+ public boolean isGreaterThanOrEqualTo(Builder builder) {
+ return methodRuleInfoBuilder.isGreaterThanOrEqualTo(builder.methodRuleInfoBuilder);
}
@Override
@@ -128,11 +129,24 @@
}
@Override
+ public Builder join(Builder builder) {
+ methodRuleInfoBuilder.joinFlags(builder);
+ return this;
+ }
+
+ @Override
+ public Builder join(ArtProfileMethodRule methodRule) {
+ methodRuleInfoBuilder.joinFlags(methodRule.getMethodRuleInfo());
+ return this;
+ }
+
+ @Override
public Builder setMethodReference(MethodReference methodReference) {
assert dexItemFactory != null;
return setMethod(MethodReferenceUtils.toDexMethod(methodReference, dexItemFactory));
}
+ @Override
public Builder setMethod(DexMethod method) {
this.method = method;
return this;
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleInfoImpl.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleInfoImpl.java
index cb482d8..d91553e 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleInfoImpl.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleInfoImpl.java
@@ -105,6 +105,10 @@
return flags;
}
+ public boolean isGreaterThanOrEqualTo(Builder builder) {
+ return flags == (flags | builder.flags);
+ }
+
public Builder merge(ArtProfileMethodRuleInfo methodRuleInfo) {
if (methodRuleInfo.isHot()) {
setIsHot();
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileRule.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileRule.java
index 8d6eefd..bb0bcc1 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileRule.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileRule.java
@@ -5,17 +5,24 @@
package com.android.tools.r8.profile.art;
import com.android.tools.r8.graph.DexReference;
+import com.android.tools.r8.profile.AbstractProfileRule;
import com.android.tools.r8.utils.ThrowingConsumer;
+import com.android.tools.r8.utils.ThrowingFunction;
import java.io.IOException;
import java.io.OutputStreamWriter;
-public abstract class ArtProfileRule implements Comparable<ArtProfileRule> {
+public abstract class ArtProfileRule implements Comparable<ArtProfileRule>, AbstractProfileRule {
public abstract <E1 extends Exception, E2 extends Exception> void accept(
ThrowingConsumer<ArtProfileClassRule, E1> classRuleConsumer,
ThrowingConsumer<ArtProfileMethodRule, E2> methodRuleConsumer)
throws E1, E2;
+ public abstract <T, E1 extends Exception, E2 extends Exception> T apply(
+ ThrowingFunction<ArtProfileClassRule, T, E1> classRuleFunction,
+ ThrowingFunction<ArtProfileMethodRule, T, E2> methodRuleFunction)
+ throws E1, E2;
+
@Override
public final int compareTo(ArtProfileRule rule) {
return getReference().compareTo(rule.getReference());
@@ -23,38 +30,14 @@
public abstract DexReference getReference();
- public boolean isClassRule() {
- return false;
- }
-
- public ArtProfileClassRule asClassRule() {
- return null;
- }
-
- public boolean isMethodRule() {
- return false;
- }
-
- public ArtProfileMethodRule asMethodRule() {
- return null;
- }
-
public abstract void writeHumanReadableRuleString(OutputStreamWriter writer) throws IOException;
public abstract static class Builder {
- public boolean isClassRuleBuilder() {
- return false;
- }
-
ArtProfileClassRule.Builder asClassRuleBuilder() {
return null;
}
- public boolean isMethodRuleBuilder() {
- return false;
- }
-
ArtProfileMethodRule.Builder asMethodRuleBuilder() {
return null;
}
diff --git a/src/main/java/com/android/tools/r8/profile/art/EmptyArtProfileCollection.java b/src/main/java/com/android/tools/r8/profile/art/EmptyArtProfileCollection.java
index b66f261..744ea4d 100644
--- a/src/main/java/com/android/tools/r8/profile/art/EmptyArtProfileCollection.java
+++ b/src/main/java/com/android/tools/r8/profile/art/EmptyArtProfileCollection.java
@@ -21,6 +21,11 @@
}
@Override
+ public boolean isEmpty() {
+ return true;
+ }
+
+ @Override
public boolean isNonEmpty() {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/profile/art/NonEmptyArtProfileCollection.java b/src/main/java/com/android/tools/r8/profile/art/NonEmptyArtProfileCollection.java
index 1d4756f..0cb809e 100644
--- a/src/main/java/com/android/tools/r8/profile/art/NonEmptyArtProfileCollection.java
+++ b/src/main/java/com/android/tools/r8/profile/art/NonEmptyArtProfileCollection.java
@@ -27,6 +27,11 @@
}
@Override
+ public boolean isEmpty() {
+ return false;
+ }
+
+ @Override
public boolean isNonEmpty() {
return true;
}
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 f4400c7..6207388 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,306 +4,57 @@
package com.android.tools.r8.profile.art.rewriting;
-import static com.android.tools.r8.utils.MapUtils.ignoreKey;
-
-import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.ProgramDefinition;
-import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.profile.AbstractProfileRule;
import com.android.tools.r8.profile.art.ArtProfile;
import com.android.tools.r8.profile.art.ArtProfileClassRule;
import com.android.tools.r8.profile.art.ArtProfileMethodRule;
-import com.android.tools.r8.profile.art.ArtProfileMethodRuleInfoImpl;
import com.android.tools.r8.profile.art.ArtProfileRule;
-import com.android.tools.r8.utils.WorkList;
-import com.google.common.collect.Sets;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.stream.Collectors;
+import java.util.Comparator;
-/** Mutable extension of an existing ArtProfile. */
-public class ArtProfileAdditions {
+public class ArtProfileAdditions
+ extends ProfileAdditions<
+ ArtProfileAdditions,
+ ArtProfileClassRule,
+ ArtProfileClassRule.Builder,
+ ArtProfileMethodRule,
+ ArtProfileMethodRule.Builder,
+ ArtProfileRule,
+ ArtProfile,
+ ArtProfile.Builder> {
- public interface ArtProfileAdditionsBuilder {
-
- default ArtProfileAdditionsBuilder addRule(ProgramDefinition definition) {
- return addRule(definition.getReference());
- }
-
- default ArtProfileAdditionsBuilder addRule(DexReference reference) {
- if (reference.isDexType()) {
- return addClassRule(reference.asDexType());
- } else {
- assert reference.isDexMethod();
- return addMethodRule(reference.asDexMethod());
- }
- }
-
- ArtProfileAdditionsBuilder addClassRule(DexType type);
-
- ArtProfileAdditionsBuilder addMethodRule(DexMethod method);
-
- default ArtProfileAdditionsBuilder removeMovedMethodRule(
- ProgramMethod oldMethod, ProgramMethod newMethod) {
- return removeMovedMethodRule(oldMethod.getReference(), newMethod);
- }
-
- ArtProfileAdditionsBuilder removeMovedMethodRule(DexMethod oldMethod, ProgramMethod newMethod);
+ ArtProfileAdditions(ArtProfile profile) {
+ super(profile);
}
- private ArtProfile artProfile;
-
- private final Map<DexType, ArtProfileClassRule.Builder> classRuleAdditions =
- new ConcurrentHashMap<>();
- private final Map<DexMethod, ArtProfileMethodRule.Builder> methodRuleAdditions =
- new ConcurrentHashMap<>();
- private final Set<DexMethod> methodRuleRemovals = Sets.newConcurrentHashSet();
-
- private final NestedMethodRuleAdditionsGraph nestedMethodRuleAdditionsGraph =
- new NestedMethodRuleAdditionsGraph();
-
- ArtProfileAdditions(ArtProfile artProfile) {
- this.artProfile = artProfile;
+ @Override
+ public ArtProfileAdditions create() {
+ return new ArtProfileAdditions(profile);
}
- void applyIfContextIsInProfile(DexType context, Consumer<ArtProfileAdditions> fn) {
- if (artProfile.containsClassRule(context) || classRuleAdditions.containsKey(context)) {
- fn.accept(this);
- }
+ @Override
+ public ArtProfileClassRule.Builder createClassRuleBuilder(DexType type) {
+ return ArtProfileClassRule.builder().setType(type);
}
- void applyIfContextIsInProfile(
- DexMethod context, Consumer<ArtProfileAdditionsBuilder> builderConsumer) {
- ArtProfileMethodRule contextMethodRule = artProfile.getMethodRule(context);
- if (contextMethodRule != null) {
- builderConsumer.accept(
- new ArtProfileAdditionsBuilder() {
-
- @Override
- public ArtProfileAdditionsBuilder addClassRule(DexType type) {
- ArtProfileAdditions.this.addClassRule(type);
- return this;
- }
-
- @Override
- public ArtProfileAdditionsBuilder addMethodRule(DexMethod method) {
- ArtProfileAdditions.this.addMethodRuleFromContext(
- method,
- methodRuleInfoBuilder ->
- methodRuleInfoBuilder.joinFlags(contextMethodRule.getMethodRuleInfo()));
- return this;
- }
-
- @Override
- public ArtProfileAdditionsBuilder removeMovedMethodRule(
- DexMethod oldMethod, ProgramMethod newMethod) {
- ArtProfileAdditions.this.removeMovedMethodRule(oldMethod, newMethod);
- return this;
- }
- });
- } else if (methodRuleAdditions.containsKey(context)) {
- builderConsumer.accept(
- new ArtProfileAdditionsBuilder() {
-
- @Override
- public ArtProfileAdditionsBuilder addClassRule(DexType type) {
- ArtProfileAdditions.this.addClassRule(type);
- return this;
- }
-
- @Override
- public ArtProfileAdditionsBuilder addMethodRule(DexMethod method) {
- ArtProfileMethodRule.Builder contextRuleBuilder = methodRuleAdditions.get(context);
- ArtProfileAdditions.this.addMethodRuleFromContext(
- method,
- methodRuleInfoBuilder -> methodRuleInfoBuilder.joinFlags(contextRuleBuilder));
- nestedMethodRuleAdditionsGraph.recordMethodRuleInfoFlagsLargerThan(method, context);
- return this;
- }
-
- @Override
- public ArtProfileAdditionsBuilder removeMovedMethodRule(
- DexMethod oldMethod, ProgramMethod newMethod) {
- ArtProfileAdditions.this.removeMovedMethodRule(oldMethod, newMethod);
- return this;
- }
- });
- }
+ @Override
+ public ArtProfileMethodRule.Builder createMethodRuleBuilder(DexMethod method) {
+ return ArtProfileMethodRule.builder().setMethod(method);
}
- public ArtProfileAdditions addClassRule(DexClass clazz) {
- addClassRule(clazz.getType());
+ @Override
+ public ArtProfile.Builder createProfileBuilder() {
+ return ArtProfile.builder();
+ }
+
+ @Override
+ public Comparator<AbstractProfileRule> getRuleComparator() {
+ return Comparator.comparing(AbstractProfileRule::asArtProfileRule);
+ }
+
+ @Override
+ public ArtProfileAdditions self() {
return this;
}
-
- public void addClassRule(DexType type) {
- if (artProfile.containsClassRule(type)) {
- return;
- }
-
- // Create profile rule for class.
- classRuleAdditions.computeIfAbsent(type, key -> ArtProfileClassRule.builder().setType(key));
- }
-
- private void addMethodRuleFromContext(
- DexMethod method,
- Consumer<ArtProfileMethodRuleInfoImpl.Builder> methodRuleInfoBuilderConsumer) {
- addMethodRule(method, methodRuleInfoBuilderConsumer);
- }
-
- public ArtProfileAdditions addMethodRule(
- DexClassAndMethod method,
- Consumer<ArtProfileMethodRuleInfoImpl.Builder> methodRuleInfoBuilderConsumer) {
- return addMethodRule(method.getReference(), methodRuleInfoBuilderConsumer);
- }
-
- public ArtProfileAdditions addMethodRule(
- DexMethod method,
- Consumer<ArtProfileMethodRuleInfoImpl.Builder> methodRuleInfoBuilderConsumer) {
- // Create profile rule for method.
- ArtProfileMethodRule.Builder methodRuleBuilder =
- methodRuleAdditions.computeIfAbsent(
- method, methodReference -> ArtProfileMethodRule.builder().setMethod(method));
-
- // Setup the rule.
- synchronized (methodRuleBuilder) {
- methodRuleBuilder.acceptMethodRuleInfoBuilder(methodRuleInfoBuilderConsumer);
- }
-
- return this;
- }
-
- void removeMovedMethodRule(DexMethod oldMethod, ProgramMethod newMethod) {
- assert artProfile.containsMethodRule(oldMethod) || methodRuleAdditions.containsKey(oldMethod);
- assert methodRuleAdditions.containsKey(newMethod.getReference());
- methodRuleRemovals.add(oldMethod);
- }
-
- ArtProfile createNewArtProfile() {
- if (!hasAdditions()) {
- assert !hasRemovals();
- return artProfile;
- }
-
- nestedMethodRuleAdditionsGraph.propagateMethodRuleInfoFlags(methodRuleAdditions);
-
- // Add existing rules to new profile.
- ArtProfile.Builder artProfileBuilder = ArtProfile.builder();
- artProfile.forEachRule(
- artProfileBuilder::addRule,
- methodRule -> {
- 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);
- }
- });
-
- // Sort and add additions to new profile. Sorting is needed since the additions to this
- // collection may be concurrent.
- List<ArtProfileRule> ruleAdditionsSorted =
- new ArrayList<>(classRuleAdditions.size() + methodRuleAdditions.size());
- classRuleAdditions
- .values()
- .forEach(classRuleBuilder -> ruleAdditionsSorted.add(classRuleBuilder.build()));
- methodRuleAdditions
- .values()
- .forEach(methodRuleBuilder -> ruleAdditionsSorted.add(methodRuleBuilder.build()));
- ruleAdditionsSorted.sort(ArtProfileRule::compareTo);
- artProfileBuilder.addRules(ruleAdditionsSorted);
-
- return artProfileBuilder.build();
- }
-
- boolean hasAdditions() {
- return !classRuleAdditions.isEmpty() || !methodRuleAdditions.isEmpty();
- }
-
- private boolean hasRemovals() {
- return !methodRuleRemovals.isEmpty();
- }
-
- ArtProfileAdditions rewriteMethodReferences(Function<DexMethod, DexMethod> methodFn) {
- ArtProfileAdditions rewrittenAdditions = new ArtProfileAdditions(artProfile);
- assert methodRuleRemovals.isEmpty();
- rewrittenAdditions.classRuleAdditions.putAll(classRuleAdditions);
- methodRuleAdditions.forEach(
- (method, methodRuleBuilder) -> {
- DexMethod newMethod = methodFn.apply(method);
- ArtProfileMethodRule.Builder existingMethodRuleBuilder =
- rewrittenAdditions.methodRuleAdditions.put(
- newMethod, methodRuleBuilder.setMethod(newMethod));
- assert existingMethodRuleBuilder == null;
- });
- return rewrittenAdditions;
- }
-
- void setArtProfile(ArtProfile artProfile) {
- this.artProfile = artProfile;
- }
-
- private static class NestedMethodRuleAdditionsGraph {
-
- private final Map<DexMethod, Set<DexMethod>> successors = new ConcurrentHashMap<>();
- private final Map<DexMethod, Set<DexMethod>> predecessors = new ConcurrentHashMap<>();
-
- void recordMethodRuleInfoFlagsLargerThan(DexMethod largerFlags, DexMethod smallerFlags) {
- predecessors
- .computeIfAbsent(largerFlags, ignoreKey(Sets::newConcurrentHashSet))
- .add(smallerFlags);
- successors
- .computeIfAbsent(smallerFlags, ignoreKey(Sets::newConcurrentHashSet))
- .add(largerFlags);
- }
-
- void propagateMethodRuleInfoFlags(
- Map<DexMethod, ArtProfileMethodRule.Builder> methodRuleAdditions) {
- List<DexMethod> leaves =
- successors.keySet().stream()
- .filter(method -> predecessors.getOrDefault(method, Collections.emptySet()).isEmpty())
- .collect(Collectors.toList());
- WorkList<DexMethod> worklist = WorkList.newIdentityWorkList(leaves);
- while (worklist.hasNext()) {
- DexMethod method = worklist.next();
- ArtProfileMethodRule.Builder methodRuleBuilder = methodRuleAdditions.get(method);
- for (DexMethod successor : successors.getOrDefault(method, Collections.emptySet())) {
- methodRuleAdditions
- .get(successor)
- .acceptMethodRuleInfoBuilder(
- methodRuleInfoBuilder -> {
- int oldFlags = methodRuleInfoBuilder.getFlags();
- methodRuleInfoBuilder.joinFlags(methodRuleBuilder);
- // If this assertion fails, that means we have synthetics with multiple
- // synthesizing contexts, which are not guaranteed to be processed before the
- // synthetic itself. In that case this assertion should simply be removed.
- assert methodRuleInfoBuilder.getFlags() == oldFlags;
- });
- // Note: no need to addIgnoringSeenSet() since the graph will not have cycles. Indeed, it
- // should never be the case that a method m2(), which is synthesized from method context
- // m1(), would itself be a synthesizing context for m1().
- worklist.addIfNotSeen(successor);
- }
- }
- }
- }
}
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
deleted file mode 100644
index 5198d05..0000000
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileCollectionAdditions.java
+++ /dev/null
@@ -1,60 +0,0 @@
-// 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.AppView;
-import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.profile.art.ArtProfileCollection;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileAdditions.ArtProfileAdditionsBuilder;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-/**
- * Interface for adding (synthetic) items to an existing ArtProfileCollection.
- *
- * <p>The interface will be implemented by {@link NopArtProfileCollectionAdditions} when the
- * compilation does not contain any ART profiles, for minimal performance overhead.
- *
- * <p>When one or more ART profiles are present, this is implemented by {@link
- * ConcreteArtProfileCollectionAdditions}.
- */
-public abstract class ArtProfileCollectionAdditions {
-
- public static ArtProfileCollectionAdditions create(AppView<?> appView) {
- ArtProfileCollection artProfileCollection = appView.getArtProfileCollection();
- if (artProfileCollection.isNonEmpty()) {
- return new ConcreteArtProfileCollectionAdditions(artProfileCollection.asNonEmpty());
- }
- return nop();
- }
-
- public static NopArtProfileCollectionAdditions nop() {
- return NopArtProfileCollectionAdditions.getInstance();
- }
-
- public abstract void addMethodIfContextIsInProfile(ProgramMethod method, ProgramMethod context);
-
- public abstract void applyIfContextIsInProfile(
- DexMethod context, Consumer<ArtProfileAdditionsBuilder> builderConsumer);
-
- public abstract void commit(AppView<?> appView);
-
- public boolean isNop() {
- return false;
- }
-
- public ConcreteArtProfileCollectionAdditions asConcrete() {
- return null;
- }
-
- public abstract ArtProfileCollectionAdditions rewriteMethodReferences(
- Function<DexMethod, DexMethod> methodFn);
-
- public abstract ArtProfileCollectionAdditions setArtProfileCollection(
- ArtProfileCollection artProfileCollection);
-
- public abstract boolean verifyIsCommitted();
-}
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
deleted file mode 100644
index 1d1a897..0000000
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ConcreteArtProfileCollectionAdditions.java
+++ /dev/null
@@ -1,164 +0,0 @@
-// 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.AppView;
-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;
-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.ArtProfileMethodRuleInfoImpl;
-import com.android.tools.r8.profile.art.NonEmptyArtProfileCollection;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileAdditions.ArtProfileAdditionsBuilder;
-import com.google.common.collect.Iterables;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-public class ConcreteArtProfileCollectionAdditions extends ArtProfileCollectionAdditions {
-
- private final List<ArtProfileAdditions> additionsCollection;
-
- private boolean committed = false;
-
- private ConcreteArtProfileCollectionAdditions(List<ArtProfileAdditions> additionsCollection) {
- this.additionsCollection = additionsCollection;
- }
-
- ConcreteArtProfileCollectionAdditions(NonEmptyArtProfileCollection artProfileCollection) {
- additionsCollection = new ArrayList<>();
- for (ArtProfile artProfile : artProfileCollection) {
- additionsCollection.add(new ArtProfileAdditions(artProfile));
- }
- assert !additionsCollection.isEmpty();
- }
-
- @Override
- public void addMethodIfContextIsInProfile(ProgramMethod method, ProgramMethod context) {
- applyIfContextIsInProfile(context, additionsBuilder -> additionsBuilder.addRule(method));
- }
-
- public void addMethodIfContextIsInProfile(
- ProgramMethod method,
- DexClassAndMethod context,
- Consumer<ArtProfileMethodRuleInfoImpl.Builder> methodRuleInfoBuilderConsumer) {
- if (context.isProgramMethod()) {
- applyIfContextIsInProfile(
- context.asProgramMethod(), additionsBuilder -> additionsBuilder.addRule(method));
- } else {
- apply(
- artProfileAdditions ->
- artProfileAdditions.addMethodRule(method, methodRuleInfoBuilderConsumer));
- }
- }
-
- public void addMethodAndHolderIfContextIsInProfile(ProgramMethod method, ProgramMethod context) {
- applyIfContextIsInProfile(
- context, additionsBuilder -> additionsBuilder.addRule(method).addRule(method.getHolder()));
- }
-
- void apply(Consumer<ArtProfileAdditions> additionsConsumer) {
- for (ArtProfileAdditions artProfileAdditions : additionsCollection) {
- additionsConsumer.accept(artProfileAdditions);
- }
- }
-
- void applyIfContextIsInProfile(
- ProgramDefinition context,
- Consumer<ArtProfileAdditions> additionsConsumer,
- Consumer<ArtProfileAdditionsBuilder> additionsBuilderConsumer) {
- if (context.isProgramClass()) {
- applyIfContextIsInProfile(context.asProgramClass(), additionsConsumer);
- } else {
- assert context.isProgramMethod();
- applyIfContextIsInProfile(context.asProgramMethod(), additionsBuilderConsumer);
- }
- }
-
- void applyIfContextIsInProfile(
- DexProgramClass context, Consumer<ArtProfileAdditions> additionsConsumer) {
- applyIfContextIsInProfile(context.getType(), additionsConsumer);
- }
-
- void applyIfContextIsInProfile(DexType type, Consumer<ArtProfileAdditions> additionsConsumer) {
- for (ArtProfileAdditions artProfileAdditions : additionsCollection) {
- artProfileAdditions.applyIfContextIsInProfile(type, additionsConsumer);
- }
- }
-
- public void applyIfContextIsInProfile(
- ProgramMethod context, Consumer<ArtProfileAdditionsBuilder> builderConsumer) {
- applyIfContextIsInProfile(context.getReference(), builderConsumer);
- }
-
- @Override
- public void applyIfContextIsInProfile(
- DexMethod context, Consumer<ArtProfileAdditionsBuilder> builderConsumer) {
- for (ArtProfileAdditions artProfileAdditions : additionsCollection) {
- artProfileAdditions.applyIfContextIsInProfile(context, builderConsumer);
- }
- }
-
- @Override
- public ConcreteArtProfileCollectionAdditions asConcrete() {
- return this;
- }
-
- @Override
- public void commit(AppView<?> appView) {
- assert !committed;
- if (hasAdditions()) {
- appView.setArtProfileCollection(createNewArtProfileCollection());
- }
- committed = true;
- }
-
- private ArtProfileCollection createNewArtProfileCollection() {
- assert hasAdditions();
- List<ArtProfile> newArtProfiles = new ArrayList<>(additionsCollection.size());
- for (ArtProfileAdditions additions : additionsCollection) {
- newArtProfiles.add(additions.createNewArtProfile());
- }
- return new NonEmptyArtProfileCollection(newArtProfiles);
- }
-
- private boolean hasAdditions() {
- return Iterables.any(additionsCollection, ArtProfileAdditions::hasAdditions);
- }
-
- @Override
- public ConcreteArtProfileCollectionAdditions rewriteMethodReferences(
- Function<DexMethod, DexMethod> methodFn) {
- List<ArtProfileAdditions> rewrittenAdditionsCollection =
- new ArrayList<>(additionsCollection.size());
- for (ArtProfileAdditions additions : additionsCollection) {
- rewrittenAdditionsCollection.add(additions.rewriteMethodReferences(methodFn));
- }
- return new ConcreteArtProfileCollectionAdditions(rewrittenAdditionsCollection);
- }
-
- @Override
- public ConcreteArtProfileCollectionAdditions setArtProfileCollection(
- ArtProfileCollection artProfileCollection) {
- assert artProfileCollection.isNonEmpty();
- Iterator<ArtProfile> artProfileIterator = artProfileCollection.asNonEmpty().iterator();
- for (ArtProfileAdditions additions : additionsCollection) {
- additions.setArtProfile(artProfileIterator.next());
- }
- return this;
- }
-
- @Override
- public boolean verifyIsCommitted() {
- assert committed;
- return true;
- }
-}
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ConcreteProfileCollectionAdditions.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ConcreteProfileCollectionAdditions.java
new file mode 100644
index 0000000..90cbd6b
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ConcreteProfileCollectionAdditions.java
@@ -0,0 +1,191 @@
+// 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.experimental.startup.StartupProfile;
+import com.android.tools.r8.experimental.startup.rewriting.StartupProfileAdditions;
+import com.android.tools.r8.graph.AppView;
+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.ProgramDefinition;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.profile.AbstractProfileMethodRule;
+import com.android.tools.r8.profile.art.ArtProfile;
+import com.android.tools.r8.profile.art.ArtProfileCollection;
+import com.android.tools.r8.profile.art.NonEmptyArtProfileCollection;
+import com.android.tools.r8.profile.art.rewriting.ProfileAdditions.ProfileAdditionsBuilder;
+import com.android.tools.r8.utils.Box;
+import com.google.common.collect.Iterables;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+public class ConcreteProfileCollectionAdditions extends ProfileCollectionAdditions {
+
+ private final List<ArtProfileAdditions> additionsCollection;
+ private final Box<StartupProfileAdditions> startupProfileAdditions;
+
+ private boolean committed = false;
+
+ private ConcreteProfileCollectionAdditions(
+ List<ArtProfileAdditions> additionsCollection,
+ Box<StartupProfileAdditions> startupProfileAdditions) {
+ this.additionsCollection = additionsCollection;
+ this.startupProfileAdditions = startupProfileAdditions;
+ }
+
+ ConcreteProfileCollectionAdditions(
+ ArtProfileCollection artProfileCollection, StartupProfile startupProfile) {
+ additionsCollection = new ArrayList<>();
+ if (artProfileCollection.isNonEmpty()) {
+ for (ArtProfile artProfile : artProfileCollection.asNonEmpty()) {
+ additionsCollection.add(new ArtProfileAdditions(artProfile));
+ }
+ assert !additionsCollection.isEmpty();
+ }
+ startupProfileAdditions =
+ new Box<>(startupProfile.isEmpty() ? null : new StartupProfileAdditions(startupProfile));
+ }
+
+ void accept(Consumer<ProfileAdditions<?, ?, ?, ?, ?, ?, ?, ?>> additionsConsumer) {
+ for (ArtProfileAdditions additions : additionsCollection) {
+ additionsConsumer.accept(additions);
+ }
+ startupProfileAdditions.accept(additionsConsumer);
+ }
+
+ @Override
+ public void addMethodIfContextIsInProfile(ProgramMethod method, ProgramMethod context) {
+ applyIfContextIsInProfile(context, additionsBuilder -> additionsBuilder.addRule(method));
+ }
+
+ public void addMethodIfContextIsInProfile(
+ ProgramMethod method,
+ DexClassAndMethod context,
+ Consumer<AbstractProfileMethodRule.Builder<?, ?>> methodRuleBuilderConsumer) {
+ if (context.isProgramMethod()) {
+ addMethodIfContextIsInProfile(method, context.asProgramMethod());
+ } else {
+ accept(additions -> additions.addMethodRule(method, methodRuleBuilderConsumer));
+ }
+ }
+
+ public void addMethodAndHolderIfContextIsInProfile(ProgramMethod method, ProgramMethod context) {
+ applyIfContextIsInProfile(
+ context, additionsBuilder -> additionsBuilder.addRule(method).addRule(method.getHolder()));
+ }
+
+ void applyIfContextIsInProfile(
+ ProgramDefinition context,
+ Consumer<ProfileAdditions<?, ?, ?, ?, ?, ?, ?, ?>> additionsConsumer,
+ Consumer<ProfileAdditionsBuilder> additionsBuilderConsumer) {
+ if (context.isProgramClass()) {
+ applyIfContextIsInProfile(context.asProgramClass(), additionsConsumer);
+ } else {
+ assert context.isProgramMethod();
+ applyIfContextIsInProfile(context.asProgramMethod(), additionsBuilderConsumer);
+ }
+ }
+
+ void applyIfContextIsInProfile(
+ DexProgramClass context,
+ Consumer<ProfileAdditions<?, ?, ?, ?, ?, ?, ?, ?>> additionsConsumer) {
+ accept(additions -> additions.applyIfContextIsInProfile(context.getType(), additionsConsumer));
+ }
+
+ public void applyIfContextIsInProfile(
+ ProgramMethod context, Consumer<ProfileAdditionsBuilder> builderConsumer) {
+ applyIfContextIsInProfile(context.getReference(), builderConsumer);
+ }
+
+ @Override
+ public void applyIfContextIsInProfile(
+ DexMethod context, Consumer<ProfileAdditionsBuilder> builderConsumer) {
+ accept(additions -> additions.applyIfContextIsInProfile(context, builderConsumer));
+ }
+
+ @Override
+ public ConcreteProfileCollectionAdditions asConcrete() {
+ return this;
+ }
+
+ @Override
+ public void commit(AppView<?> appView) {
+ assert !committed;
+ if (hasArtProfileAdditions()) {
+ appView.setArtProfileCollection(createNewArtProfileCollection());
+ }
+ if (hasStartupProfileAdditions()) {
+ appView.setStartupProfile(createNewStartupProfile());
+ }
+ committed = true;
+ }
+
+ private ArtProfileCollection createNewArtProfileCollection() {
+ assert hasArtProfileAdditions();
+ List<ArtProfile> newArtProfiles = new ArrayList<>(additionsCollection.size());
+ for (ArtProfileAdditions additions : additionsCollection) {
+ newArtProfiles.add(additions.createNewProfile());
+ }
+ return new NonEmptyArtProfileCollection(newArtProfiles);
+ }
+
+ private StartupProfile createNewStartupProfile() {
+ assert hasStartupProfileAdditions();
+ return startupProfileAdditions.get().createNewProfile();
+ }
+
+ private boolean hasArtProfileAdditions() {
+ return Iterables.any(additionsCollection, ProfileAdditions::hasAdditions);
+ }
+
+ private boolean hasStartupProfileAdditions() {
+ return startupProfileAdditions.test(ProfileAdditions::hasAdditions);
+ }
+
+ @Override
+ public ConcreteProfileCollectionAdditions rewriteMethodReferences(
+ Function<DexMethod, DexMethod> methodFn) {
+ List<ArtProfileAdditions> rewrittenAdditionsCollection =
+ new ArrayList<>(additionsCollection.size());
+ for (ArtProfileAdditions additions : additionsCollection) {
+ rewrittenAdditionsCollection.add(additions.rewriteMethodReferences(methodFn));
+ }
+ Box<StartupProfileAdditions> rewrittenStartupProfileAdditions =
+ startupProfileAdditions.rebuild(additions -> additions.rewriteMethodReferences(methodFn));
+ return new ConcreteProfileCollectionAdditions(
+ rewrittenAdditionsCollection, rewrittenStartupProfileAdditions);
+ }
+
+ @Override
+ public ConcreteProfileCollectionAdditions setArtProfileCollection(
+ ArtProfileCollection artProfileCollection) {
+ if (artProfileCollection.isNonEmpty()) {
+ Iterator<ArtProfile> artProfileIterator = artProfileCollection.asNonEmpty().iterator();
+ for (ArtProfileAdditions additions : additionsCollection) {
+ additions.setProfile(artProfileIterator.next());
+ }
+ } else {
+ assert additionsCollection.isEmpty();
+ assert startupProfileAdditions.isSet();
+ }
+ return this;
+ }
+
+ @Override
+ public ProfileCollectionAdditions setStartupProfile(StartupProfile startupProfile) {
+ startupProfileAdditions.accept(additions -> additions.setProfile(startupProfile));
+ 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/NopProfileCollectionAdditions.java
similarity index 61%
rename from src/main/java/com/android/tools/r8/profile/art/rewriting/NopArtProfileCollectionAdditions.java
rename to src/main/java/com/android/tools/r8/profile/art/rewriting/NopProfileCollectionAdditions.java
index 8bfd4a6..d27a083 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/NopProfileCollectionAdditions.java
@@ -4,22 +4,22 @@
package com.android.tools.r8.profile.art.rewriting;
+import com.android.tools.r8.experimental.startup.StartupProfile;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.profile.art.ArtProfileCollection;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileAdditions.ArtProfileAdditionsBuilder;
+import com.android.tools.r8.profile.art.rewriting.ProfileAdditions.ProfileAdditionsBuilder;
import java.util.function.Consumer;
import java.util.function.Function;
-public class NopArtProfileCollectionAdditions extends ArtProfileCollectionAdditions {
+public class NopProfileCollectionAdditions extends ProfileCollectionAdditions {
- private static final NopArtProfileCollectionAdditions INSTANCE =
- new NopArtProfileCollectionAdditions();
+ private static final NopProfileCollectionAdditions INSTANCE = new NopProfileCollectionAdditions();
- private NopArtProfileCollectionAdditions() {}
+ private NopProfileCollectionAdditions() {}
- public static NopArtProfileCollectionAdditions getInstance() {
+ public static NopProfileCollectionAdditions getInstance() {
return INSTANCE;
}
@@ -30,7 +30,7 @@
@Override
public void applyIfContextIsInProfile(
- DexMethod context, Consumer<ArtProfileAdditionsBuilder> builderConsumer) {
+ DexMethod context, Consumer<ProfileAdditionsBuilder> builderConsumer) {
// Intentionally empty.
}
@@ -45,20 +45,26 @@
}
@Override
- public NopArtProfileCollectionAdditions rewriteMethodReferences(
+ public NopProfileCollectionAdditions rewriteMethodReferences(
Function<DexMethod, DexMethod> methodFn) {
// Intentionally empty.
return this;
}
@Override
- public NopArtProfileCollectionAdditions setArtProfileCollection(
+ public NopProfileCollectionAdditions setArtProfileCollection(
ArtProfileCollection artProfileCollection) {
// Intentionally empty.
return this;
}
@Override
+ public NopProfileCollectionAdditions setStartupProfile(StartupProfile startupProfile) {
+ // Intentionally empty.
+ return this;
+ }
+
+ @Override
public boolean verifyIsCommitted() {
// Nothing to commit.
return true;
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileAdditions.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileAdditions.java
new file mode 100644
index 0000000..3df9866
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileAdditions.java
@@ -0,0 +1,309 @@
+// 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 static com.android.tools.r8.utils.MapUtils.ignoreKey;
+
+import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexReference;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramDefinition;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.profile.AbstractProfile;
+import com.android.tools.r8.profile.AbstractProfileClassRule;
+import com.android.tools.r8.profile.AbstractProfileMethodRule;
+import com.android.tools.r8.profile.AbstractProfileRule;
+import com.android.tools.r8.utils.WorkList;
+import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/** Mutable extension of an existing profile. */
+public abstract class ProfileAdditions<
+ Additions extends
+ ProfileAdditions<
+ Additions,
+ ClassRule,
+ ClassRuleBuilder,
+ MethodRule,
+ MethodRuleBuilder,
+ ProfileRule,
+ Profile,
+ ProfileBuilder>,
+ ClassRule extends AbstractProfileClassRule,
+ ClassRuleBuilder extends AbstractProfileClassRule.Builder<ClassRule>,
+ MethodRule extends AbstractProfileMethodRule,
+ MethodRuleBuilder extends AbstractProfileMethodRule.Builder<MethodRule, MethodRuleBuilder>,
+ ProfileRule extends AbstractProfileRule,
+ Profile extends AbstractProfile<ClassRule, MethodRule>,
+ ProfileBuilder extends
+ AbstractProfile.Builder<ClassRule, MethodRule, Profile, ProfileBuilder>> {
+
+ public interface ProfileAdditionsBuilder {
+
+ default ProfileAdditionsBuilder addRule(ProgramDefinition definition) {
+ return addRule(definition.getReference());
+ }
+
+ default ProfileAdditionsBuilder addRule(DexReference reference) {
+ if (reference.isDexType()) {
+ return addClassRule(reference.asDexType());
+ } else {
+ assert reference.isDexMethod();
+ return addMethodRule(reference.asDexMethod());
+ }
+ }
+
+ ProfileAdditionsBuilder addClassRule(DexType type);
+
+ ProfileAdditionsBuilder addMethodRule(DexMethod method);
+
+ default void removeMovedMethodRule(ProgramMethod oldMethod, ProgramMethod newMethod) {
+ removeMovedMethodRule(oldMethod.getReference(), newMethod);
+ }
+
+ void removeMovedMethodRule(DexMethod oldMethod, ProgramMethod newMethod);
+ }
+
+ protected Profile profile;
+
+ final Map<DexType, ClassRuleBuilder> classRuleAdditions = new ConcurrentHashMap<>();
+ final Map<DexMethod, MethodRuleBuilder> methodRuleAdditions = new ConcurrentHashMap<>();
+ private final Set<DexMethod> methodRuleRemovals = Sets.newConcurrentHashSet();
+
+ private final NestedMethodRuleAdditionsGraph nestedMethodRuleAdditionsGraph =
+ new NestedMethodRuleAdditionsGraph();
+
+ protected ProfileAdditions(Profile profile) {
+ this.profile = profile;
+ }
+
+ public void applyIfContextIsInProfile(DexType context, Consumer<? super Additions> fn) {
+ if (profile.containsClassRule(context) || classRuleAdditions.containsKey(context)) {
+ fn.accept(self());
+ }
+ }
+
+ public void applyIfContextIsInProfile(
+ DexMethod context, Consumer<ProfileAdditionsBuilder> builderConsumer) {
+ MethodRule contextMethodRule = profile.getMethodRule(context);
+ if (contextMethodRule != null) {
+ builderConsumer.accept(
+ new ProfileAdditionsBuilder() {
+
+ @Override
+ public ProfileAdditionsBuilder addClassRule(DexType type) {
+ ProfileAdditions.this.addClassRule(type);
+ return this;
+ }
+
+ @Override
+ public ProfileAdditionsBuilder addMethodRule(DexMethod method) {
+ ProfileAdditions.this.addMethodRule(
+ method, methodRuleBuilder -> methodRuleBuilder.join(contextMethodRule));
+ return this;
+ }
+
+ @Override
+ public void removeMovedMethodRule(DexMethod oldMethod, ProgramMethod newMethod) {
+ ProfileAdditions.this.removeMovedMethodRule(oldMethod, newMethod);
+ }
+ });
+ } else if (methodRuleAdditions.containsKey(context)) {
+ builderConsumer.accept(
+ new ProfileAdditionsBuilder() {
+
+ @Override
+ public ProfileAdditionsBuilder addClassRule(DexType type) {
+ ProfileAdditions.this.addClassRule(type);
+ return this;
+ }
+
+ @Override
+ public ProfileAdditionsBuilder addMethodRule(DexMethod method) {
+ MethodRuleBuilder contextRuleBuilder = methodRuleAdditions.get(context);
+ ProfileAdditions.this.addMethodRule(
+ method, methodRuleBuilder -> methodRuleBuilder.join(contextRuleBuilder));
+ nestedMethodRuleAdditionsGraph.recordMethodRuleInfoFlagsLargerThan(method, context);
+ return this;
+ }
+
+ @Override
+ public void removeMovedMethodRule(DexMethod oldMethod, ProgramMethod newMethod) {
+ ProfileAdditions.this.removeMovedMethodRule(oldMethod, newMethod);
+ }
+ });
+ }
+ }
+
+ public Additions addClassRule(DexClass clazz) {
+ addClassRule(clazz.getType());
+ return self();
+ }
+
+ public void addClassRule(DexType type) {
+ if (profile.containsClassRule(type)) {
+ return;
+ }
+
+ // Create profile rule for class.
+ classRuleAdditions.computeIfAbsent(type, this::createClassRuleBuilder);
+ }
+
+ public Additions addMethodRule(
+ DexClassAndMethod method, Consumer<? super MethodRuleBuilder> methodRuleBuilderConsumer) {
+ return addMethodRule(method.getReference(), methodRuleBuilderConsumer);
+ }
+
+ public Additions addMethodRule(
+ DexMethod method, Consumer<? super MethodRuleBuilder> methodRuleBuilderConsumer) {
+ // Create profile rule for method.
+ MethodRuleBuilder methodRuleBuilder =
+ methodRuleAdditions.computeIfAbsent(method, this::createMethodRuleBuilder);
+
+ // Setup the rule.
+ synchronized (methodRuleBuilder) {
+ methodRuleBuilderConsumer.accept(methodRuleBuilder);
+ }
+
+ return self();
+ }
+
+ void removeMovedMethodRule(DexMethod oldMethod, ProgramMethod newMethod) {
+ assert profile.containsMethodRule(oldMethod) || methodRuleAdditions.containsKey(oldMethod);
+ assert methodRuleAdditions.containsKey(newMethod.getReference());
+ methodRuleRemovals.add(oldMethod);
+ }
+
+ public Profile createNewProfile() {
+ if (!hasAdditions()) {
+ assert !hasRemovals();
+ return profile;
+ }
+
+ nestedMethodRuleAdditionsGraph.propagateMethodRuleInfoFlags(methodRuleAdditions);
+
+ // Add existing rules to new profile.
+ ProfileBuilder profileBuilder = createProfileBuilder();
+ profile.forEachRule(
+ profileBuilder::addClassRule,
+ methodRule -> {
+ if (methodRuleRemovals.contains(methodRule.getReference())) {
+ return;
+ }
+ MethodRuleBuilder methodRuleBuilder =
+ methodRuleAdditions.remove(methodRule.getReference());
+ if (methodRuleBuilder != null) {
+ MethodRule newMethodRule = methodRuleBuilder.join(methodRule).build();
+ profileBuilder.addMethodRule(newMethodRule);
+ } else {
+ profileBuilder.addMethodRule(methodRule);
+ }
+ });
+
+ // Sort and add additions to new profile. Sorting is needed since the additions to this
+ // collection may be concurrent.
+ List<AbstractProfileRule> ruleAdditionsSorted =
+ new ArrayList<>(classRuleAdditions.size() + methodRuleAdditions.size());
+ classRuleAdditions
+ .values()
+ .forEach(classRuleBuilder -> ruleAdditionsSorted.add(classRuleBuilder.build()));
+ methodRuleAdditions
+ .values()
+ .forEach(methodRuleBuilder -> ruleAdditionsSorted.add(methodRuleBuilder.build()));
+ ruleAdditionsSorted.sort(getRuleComparator());
+ ruleAdditionsSorted.forEach(profileBuilder::addRule);
+
+ return profileBuilder.build();
+ }
+
+ public boolean hasAdditions() {
+ return !classRuleAdditions.isEmpty() || !methodRuleAdditions.isEmpty();
+ }
+
+ private boolean hasRemovals() {
+ return !methodRuleRemovals.isEmpty();
+ }
+
+ public Additions rewriteMethodReferences(Function<DexMethod, DexMethod> methodFn) {
+ Additions rewrittenAdditions = create();
+ assert methodRuleRemovals.isEmpty();
+ rewrittenAdditions.classRuleAdditions.putAll(classRuleAdditions);
+ methodRuleAdditions.forEach(
+ (method, methodRuleBuilder) -> {
+ DexMethod newMethod = methodFn.apply(method);
+ MethodRuleBuilder existingMethodRuleBuilder =
+ rewrittenAdditions.methodRuleAdditions.put(
+ newMethod, methodRuleBuilder.setMethod(newMethod));
+ assert existingMethodRuleBuilder == null;
+ });
+ return rewrittenAdditions;
+ }
+
+ public abstract Additions create();
+
+ public abstract ClassRuleBuilder createClassRuleBuilder(DexType type);
+
+ public abstract MethodRuleBuilder createMethodRuleBuilder(DexMethod method);
+
+ public abstract ProfileBuilder createProfileBuilder();
+
+ public abstract Comparator<AbstractProfileRule> getRuleComparator();
+
+ public abstract Additions self();
+
+ public void setProfile(Profile profile) {
+ this.profile = profile;
+ }
+
+ private class NestedMethodRuleAdditionsGraph {
+
+ private final Map<DexMethod, Set<DexMethod>> successors = new ConcurrentHashMap<>();
+ private final Map<DexMethod, Set<DexMethod>> predecessors = new ConcurrentHashMap<>();
+
+ void recordMethodRuleInfoFlagsLargerThan(DexMethod largerFlags, DexMethod smallerFlags) {
+ predecessors
+ .computeIfAbsent(largerFlags, ignoreKey(Sets::newConcurrentHashSet))
+ .add(smallerFlags);
+ successors
+ .computeIfAbsent(smallerFlags, ignoreKey(Sets::newConcurrentHashSet))
+ .add(largerFlags);
+ }
+
+ void propagateMethodRuleInfoFlags(Map<DexMethod, MethodRuleBuilder> methodRuleAdditions) {
+ List<DexMethod> leaves =
+ successors.keySet().stream()
+ .filter(method -> predecessors.getOrDefault(method, Collections.emptySet()).isEmpty())
+ .collect(Collectors.toList());
+ WorkList<DexMethod> worklist = WorkList.newIdentityWorkList(leaves);
+ while (worklist.hasNext()) {
+ DexMethod method = worklist.next();
+ MethodRuleBuilder methodRuleBuilder = methodRuleAdditions.get(method);
+ for (DexMethod successor : successors.getOrDefault(method, Collections.emptySet())) {
+ MethodRuleBuilder successorMethodRuleBuilder = methodRuleAdditions.get(successor);
+ // If this assertion fails, that means we have synthetics with multiple
+ // synthesizing contexts, which are not guaranteed to be processed before the
+ // synthetic itself. In that case this assertion should simply be removed.
+ assert successorMethodRuleBuilder.isGreaterThanOrEqualTo(methodRuleBuilder);
+ successorMethodRuleBuilder.join(methodRuleBuilder);
+ // Note: no need to addIgnoringSeenSet() since the graph will not have cycles. Indeed, it
+ // should never be the case that a method m2(), which is synthesized from method context
+ // m1(), would itself be a synthesizing context for m1().
+ worklist.addIfNotSeen(successor);
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileCollectionAdditions.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileCollectionAdditions.java
new file mode 100644
index 0000000..93be945
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileCollectionAdditions.java
@@ -0,0 +1,65 @@
+// 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.experimental.startup.StartupProfile;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.profile.art.ArtProfileCollection;
+import com.android.tools.r8.profile.art.rewriting.ProfileAdditions.ProfileAdditionsBuilder;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+/**
+ * Interface for adding (synthetic) items to existing instances of {@link
+ * com.android.tools.r8.profile.AbstractProfile}.
+ *
+ * <p>The interface will be implemented by {@link NopProfileCollectionAdditions} when the
+ * compilation does not contain any ART profiles, for minimal performance overhead.
+ *
+ * <p>When one or more ART profiles are present, or a startup profile is, then this class is
+ * implemented by {@link ConcreteProfileCollectionAdditions}.
+ */
+public abstract class ProfileCollectionAdditions {
+
+ public static ProfileCollectionAdditions create(AppView<?> appView) {
+ ArtProfileCollection artProfileCollection = appView.getArtProfileCollection();
+ StartupProfile startupProfile = appView.getStartupProfile();
+ if (artProfileCollection.isEmpty() && startupProfile.isEmpty()) {
+ return nop();
+ }
+ return new ConcreteProfileCollectionAdditions(artProfileCollection, startupProfile);
+ }
+
+ public static NopProfileCollectionAdditions nop() {
+ return NopProfileCollectionAdditions.getInstance();
+ }
+
+ public abstract void addMethodIfContextIsInProfile(ProgramMethod method, ProgramMethod context);
+
+ public abstract void applyIfContextIsInProfile(
+ DexMethod context, Consumer<ProfileAdditionsBuilder> builderConsumer);
+
+ public abstract void commit(AppView<?> appView);
+
+ public boolean isNop() {
+ return false;
+ }
+
+ public ConcreteProfileCollectionAdditions asConcrete() {
+ return null;
+ }
+
+ public abstract ProfileCollectionAdditions rewriteMethodReferences(
+ Function<DexMethod, DexMethod> methodFn);
+
+ public abstract ProfileCollectionAdditions setArtProfileCollection(
+ ArtProfileCollection artProfileCollection);
+
+ public abstract ProfileCollectionAdditions setStartupProfile(StartupProfile startupProfile);
+
+ public abstract boolean verifyIsCommitted();
+}
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingApiReferenceStubberEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingApiReferenceStubberEventConsumer.java
similarity index 76%
rename from src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingApiReferenceStubberEventConsumer.java
rename to src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingApiReferenceStubberEventConsumer.java
index 0b4dfde..4f7f76c 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingApiReferenceStubberEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingApiReferenceStubberEventConsumer.java
@@ -11,14 +11,14 @@
import com.android.tools.r8.graph.DexLibraryClass;
import com.android.tools.r8.graph.DexProgramClass;
-public class ArtProfileRewritingApiReferenceStubberEventConsumer
+public class ProfileRewritingApiReferenceStubberEventConsumer
implements ApiReferenceStubberEventConsumer {
- private final ConcreteArtProfileCollectionAdditions collectionAdditions;
+ private final ConcreteProfileCollectionAdditions collectionAdditions;
private final ApiReferenceStubberEventConsumer parent;
- private ArtProfileRewritingApiReferenceStubberEventConsumer(
- ConcreteArtProfileCollectionAdditions collectionAdditions,
+ private ProfileRewritingApiReferenceStubberEventConsumer(
+ ConcreteProfileCollectionAdditions collectionAdditions,
ApiReferenceStubberEventConsumer parent) {
this.collectionAdditions = collectionAdditions;
this.parent = parent;
@@ -27,11 +27,11 @@
public static ApiReferenceStubberEventConsumer attach(
AppView<?> appView, ApiReferenceStubberEventConsumer eventConsumer) {
if (appView.options().getArtProfileOptions().isIncludingApiReferenceStubs()) {
- ArtProfileCollectionAdditions artProfileCollectionAdditions =
- ArtProfileCollectionAdditions.create(appView);
- if (!artProfileCollectionAdditions.isNop()) {
- return new ArtProfileRewritingApiReferenceStubberEventConsumer(
- artProfileCollectionAdditions.asConcrete(), eventConsumer);
+ ProfileCollectionAdditions profileCollectionAdditions =
+ ProfileCollectionAdditions.create(appView);
+ if (!profileCollectionAdditions.isNop()) {
+ return new ProfileRewritingApiReferenceStubberEventConsumer(
+ profileCollectionAdditions.asConcrete(), eventConsumer);
}
}
return eventConsumer;
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingArgumentPropagatorSyntheticEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingArgumentPropagatorSyntheticEventConsumer.java
similarity index 77%
rename from src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingArgumentPropagatorSyntheticEventConsumer.java
rename to src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingArgumentPropagatorSyntheticEventConsumer.java
index 1084d3a..dece00f 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingArgumentPropagatorSyntheticEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingArgumentPropagatorSyntheticEventConsumer.java
@@ -10,14 +10,14 @@
import com.android.tools.r8.optimize.argumentpropagation.ArgumentPropagatorSyntheticEventConsumer;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
-public class ArtProfileRewritingArgumentPropagatorSyntheticEventConsumer
+public class ProfileRewritingArgumentPropagatorSyntheticEventConsumer
implements ArgumentPropagatorSyntheticEventConsumer {
- private final ConcreteArtProfileCollectionAdditions additionsCollection;
+ private final ConcreteProfileCollectionAdditions additionsCollection;
private final ArgumentPropagatorSyntheticEventConsumer parent;
- private ArtProfileRewritingArgumentPropagatorSyntheticEventConsumer(
- ConcreteArtProfileCollectionAdditions additionsCollection,
+ private ProfileRewritingArgumentPropagatorSyntheticEventConsumer(
+ ConcreteProfileCollectionAdditions additionsCollection,
ArgumentPropagatorSyntheticEventConsumer parent) {
this.additionsCollection = additionsCollection;
this.parent = parent;
@@ -26,12 +26,11 @@
public static ArgumentPropagatorSyntheticEventConsumer attach(
AppView<AppInfoWithLiveness> appView,
ArgumentPropagatorSyntheticEventConsumer eventConsumer) {
- ArtProfileCollectionAdditions additionsCollection =
- ArtProfileCollectionAdditions.create(appView);
+ ProfileCollectionAdditions additionsCollection = ProfileCollectionAdditions.create(appView);
if (additionsCollection.isNop()) {
return eventConsumer;
}
- return new ArtProfileRewritingArgumentPropagatorSyntheticEventConsumer(
+ return new ProfileRewritingArgumentPropagatorSyntheticEventConsumer(
additionsCollection.asConcrete(), eventConsumer);
}
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/ProfileRewritingCfClassSynthesizerDesugaringEventConsumer.java
similarity index 83%
rename from src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfClassSynthesizerDesugaringEventConsumer.java
rename to src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingCfClassSynthesizerDesugaringEventConsumer.java
index ebc4799..2d0f51c 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/ProfileRewritingCfClassSynthesizerDesugaringEventConsumer.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.profile.art.rewriting;
-import static com.android.tools.r8.profile.art.rewriting.ArtProfileRewritingVarHandleDesugaringEventConsumerUtils.handleVarHandleDesugaringClassContext;
+import static com.android.tools.r8.profile.art.rewriting.ProfileRewritingVarHandleDesugaringEventConsumerUtils.handleVarHandleDesugaringClassContext;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
@@ -15,15 +15,15 @@
import com.android.tools.r8.profile.art.ArtProfileOptions;
import java.util.Set;
-public class ArtProfileRewritingCfClassSynthesizerDesugaringEventConsumer
+public class ProfileRewritingCfClassSynthesizerDesugaringEventConsumer
extends CfClassSynthesizerDesugaringEventConsumer {
- private final ConcreteArtProfileCollectionAdditions additionsCollection;
+ private final ConcreteProfileCollectionAdditions additionsCollection;
private final ArtProfileOptions options;
private final CfClassSynthesizerDesugaringEventConsumer parent;
- private ArtProfileRewritingCfClassSynthesizerDesugaringEventConsumer(
- ConcreteArtProfileCollectionAdditions additionsCollection,
+ private ProfileRewritingCfClassSynthesizerDesugaringEventConsumer(
+ ConcreteProfileCollectionAdditions additionsCollection,
ArtProfileOptions options,
CfClassSynthesizerDesugaringEventConsumer parent) {
this.additionsCollection = additionsCollection;
@@ -33,18 +33,18 @@
public static CfClassSynthesizerDesugaringEventConsumer attach(
AppView<?> appView, CfClassSynthesizerDesugaringEventConsumer eventConsumer) {
- return attach(appView, eventConsumer, ArtProfileCollectionAdditions.create(appView));
+ return attach(appView, eventConsumer, ProfileCollectionAdditions.create(appView));
}
public static CfClassSynthesizerDesugaringEventConsumer attach(
AppView<?> appView,
CfClassSynthesizerDesugaringEventConsumer eventConsumer,
- ArtProfileCollectionAdditions artProfileCollectionAdditions) {
- if (artProfileCollectionAdditions.isNop()) {
+ ProfileCollectionAdditions profileCollectionAdditions) {
+ if (profileCollectionAdditions.isNop()) {
return eventConsumer;
}
- return new ArtProfileRewritingCfClassSynthesizerDesugaringEventConsumer(
- artProfileCollectionAdditions.asConcrete(),
+ return new ProfileRewritingCfClassSynthesizerDesugaringEventConsumer(
+ profileCollectionAdditions.asConcrete(),
appView.options().getArtProfileOptions(),
eventConsumer);
}
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/ProfileRewritingCfInstructionDesugaringEventConsumer.java
similarity index 95%
rename from src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfInstructionDesugaringEventConsumer.java
rename to src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingCfInstructionDesugaringEventConsumer.java
index 3ac8a23..60a9e96 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/ProfileRewritingCfInstructionDesugaringEventConsumer.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.profile.art.rewriting;
-import static com.android.tools.r8.profile.art.rewriting.ArtProfileRewritingVarHandleDesugaringEventConsumerUtils.handleVarHandleDesugaringClassContext;
+import static com.android.tools.r8.profile.art.rewriting.ProfileRewritingVarHandleDesugaringEventConsumerUtils.handleVarHandleDesugaringClassContext;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClassAndMethod;
@@ -22,36 +22,36 @@
import com.android.tools.r8.ir.desugar.nest.NestBasedAccessDesugaringEventConsumer;
import java.util.List;
-public class ArtProfileRewritingCfInstructionDesugaringEventConsumer
+public class ProfileRewritingCfInstructionDesugaringEventConsumer
extends CfInstructionDesugaringEventConsumer {
private final AppView<?> appView;
- private final ConcreteArtProfileCollectionAdditions additionsCollection;
+ private final ConcreteProfileCollectionAdditions additionsCollection;
private final CfInstructionDesugaringEventConsumer parent;
private final NestBasedAccessDesugaringEventConsumer nestBasedAccessDesugaringEventConsumer;
- private ArtProfileRewritingCfInstructionDesugaringEventConsumer(
+ private ProfileRewritingCfInstructionDesugaringEventConsumer(
AppView<?> appView,
- ConcreteArtProfileCollectionAdditions additionsCollection,
+ ConcreteProfileCollectionAdditions additionsCollection,
CfInstructionDesugaringEventConsumer parent) {
this.appView = appView;
this.additionsCollection = additionsCollection;
this.parent = parent;
this.nestBasedAccessDesugaringEventConsumer =
- ArtProfileRewritingNestBasedAccessDesugaringEventConsumer.attach(
+ ProfileRewritingNestBasedAccessDesugaringEventConsumer.attach(
additionsCollection, NestBasedAccessDesugaringEventConsumer.empty());
}
public static CfInstructionDesugaringEventConsumer attach(
AppView<?> appView,
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
CfInstructionDesugaringEventConsumer eventConsumer) {
- if (artProfileCollectionAdditions.isNop()) {
+ if (profileCollectionAdditions.isNop()) {
return eventConsumer;
}
- return new ArtProfileRewritingCfInstructionDesugaringEventConsumer(
- appView, artProfileCollectionAdditions.asConcrete(), eventConsumer);
+ return new ProfileRewritingCfInstructionDesugaringEventConsumer(
+ appView, profileCollectionAdditions.asConcrete(), eventConsumer);
}
@Override
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/ProfileRewritingCfPostProcessingDesugaringEventConsumer.java
similarity index 90%
rename from src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfPostProcessingDesugaringEventConsumer.java
rename to src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingCfPostProcessingDesugaringEventConsumer.java
index 568efcc..5402a78 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/ProfileRewritingCfPostProcessingDesugaringEventConsumer.java
@@ -23,15 +23,15 @@
import java.util.Set;
import java.util.concurrent.ExecutionException;
-public class ArtProfileRewritingCfPostProcessingDesugaringEventConsumer
+public class ProfileRewritingCfPostProcessingDesugaringEventConsumer
extends CfPostProcessingDesugaringEventConsumer {
- private final ConcreteArtProfileCollectionAdditions additionsCollection;
+ private final ConcreteProfileCollectionAdditions additionsCollection;
private final ArtProfileOptions options;
private final CfPostProcessingDesugaringEventConsumer parent;
- private ArtProfileRewritingCfPostProcessingDesugaringEventConsumer(
- ConcreteArtProfileCollectionAdditions additionsCollection,
+ private ProfileRewritingCfPostProcessingDesugaringEventConsumer(
+ ConcreteProfileCollectionAdditions additionsCollection,
ArtProfileOptions options,
CfPostProcessingDesugaringEventConsumer parent) {
this.additionsCollection = additionsCollection;
@@ -41,13 +41,13 @@
public static CfPostProcessingDesugaringEventConsumer attach(
AppView<?> appView,
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
CfPostProcessingDesugaringEventConsumer eventConsumer) {
- if (artProfileCollectionAdditions.isNop()) {
+ if (profileCollectionAdditions.isNop()) {
return eventConsumer;
}
- return new ArtProfileRewritingCfPostProcessingDesugaringEventConsumer(
- artProfileCollectionAdditions.asConcrete(),
+ return new ProfileRewritingCfPostProcessingDesugaringEventConsumer(
+ profileCollectionAdditions.asConcrete(),
appView.options().getArtProfileOptions(),
eventConsumer);
}
@@ -80,7 +80,7 @@
public void acceptDesugaredLibraryRetargeterForwardingMethod(
ProgramMethod method, EmulatedDispatchMethodDescriptor descriptor) {
if (options.isIncludingDesugaredLibraryRetargeterForwardingMethodsUnconditionally()) {
- additionsCollection.apply(additions -> additions.addMethodRule(method, emptyConsumer()));
+ additionsCollection.accept(additions -> additions.addMethodRule(method, emptyConsumer()));
}
parent.acceptDesugaredLibraryRetargeterForwardingMethod(method, descriptor);
}
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer.java
similarity index 73%
rename from src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer.java
rename to src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer.java
index 9722924..32c6d73 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer.java
@@ -7,26 +7,26 @@
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.desugar.CovariantReturnTypeAnnotationTransformerEventConsumer;
-public class ArtProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer
+public class ProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer
implements CovariantReturnTypeAnnotationTransformerEventConsumer {
- private final ConcreteArtProfileCollectionAdditions additionsCollection;
+ private final ConcreteProfileCollectionAdditions additionsCollection;
private final CovariantReturnTypeAnnotationTransformerEventConsumer parent;
- private ArtProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer(
- ConcreteArtProfileCollectionAdditions additionsCollection,
+ private ProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer(
+ ConcreteProfileCollectionAdditions additionsCollection,
CovariantReturnTypeAnnotationTransformerEventConsumer parent) {
this.additionsCollection = additionsCollection;
this.parent = parent;
}
public static CovariantReturnTypeAnnotationTransformerEventConsumer attach(
- ArtProfileCollectionAdditions additionsCollection,
+ ProfileCollectionAdditions additionsCollection,
CovariantReturnTypeAnnotationTransformerEventConsumer eventConsumer) {
if (additionsCollection.isNop()) {
return eventConsumer;
}
- return new ArtProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer(
+ return new ProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer(
additionsCollection.asConcrete(), eventConsumer);
}
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingMemberRebindingEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingMemberRebindingEventConsumer.java
similarity index 75%
rename from src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingMemberRebindingEventConsumer.java
rename to src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingMemberRebindingEventConsumer.java
index df87170..1c9b0a5 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingMemberRebindingEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingMemberRebindingEventConsumer.java
@@ -13,27 +13,24 @@
import com.android.tools.r8.optimize.MemberRebindingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
-public class ArtProfileRewritingMemberRebindingEventConsumer
- implements MemberRebindingEventConsumer {
+public class ProfileRewritingMemberRebindingEventConsumer implements MemberRebindingEventConsumer {
- private final ConcreteArtProfileCollectionAdditions additionsCollection;
+ private final ConcreteProfileCollectionAdditions additionsCollection;
private final MemberRebindingEventConsumer parent;
- private ArtProfileRewritingMemberRebindingEventConsumer(
- ConcreteArtProfileCollectionAdditions additionsCollection,
- MemberRebindingEventConsumer parent) {
+ private ProfileRewritingMemberRebindingEventConsumer(
+ ConcreteProfileCollectionAdditions additionsCollection, MemberRebindingEventConsumer parent) {
this.additionsCollection = additionsCollection;
this.parent = parent;
}
public static MemberRebindingEventConsumer attach(
AppView<AppInfoWithLiveness> appView, MemberRebindingEventConsumer eventConsumer) {
- ArtProfileCollectionAdditions additionsCollection =
- ArtProfileCollectionAdditions.create(appView);
+ ProfileCollectionAdditions additionsCollection = ProfileCollectionAdditions.create(appView);
if (additionsCollection.isNop()) {
return eventConsumer;
}
- return new ArtProfileRewritingMemberRebindingEventConsumer(
+ return new ProfileRewritingMemberRebindingEventConsumer(
additionsCollection.asConcrete(), eventConsumer);
}
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/ProfileRewritingMethodProcessorEventConsumer.java
similarity index 87%
rename from src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingMethodProcessorEventConsumer.java
rename to src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingMethodProcessorEventConsumer.java
index dea3841..c5193da 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/ProfileRewritingMethodProcessorEventConsumer.java
@@ -9,37 +9,35 @@
import com.android.tools.r8.ir.conversion.MethodProcessorEventConsumer;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
-public class ArtProfileRewritingMethodProcessorEventConsumer extends MethodProcessorEventConsumer {
+public class ProfileRewritingMethodProcessorEventConsumer extends MethodProcessorEventConsumer {
- private final ConcreteArtProfileCollectionAdditions additionsCollection;
+ private final ConcreteProfileCollectionAdditions additionsCollection;
private final MethodProcessorEventConsumer parent;
- private ArtProfileRewritingMethodProcessorEventConsumer(
- ConcreteArtProfileCollectionAdditions additionsCollection,
- MethodProcessorEventConsumer parent) {
+ private ProfileRewritingMethodProcessorEventConsumer(
+ ConcreteProfileCollectionAdditions additionsCollection, MethodProcessorEventConsumer parent) {
this.additionsCollection = additionsCollection;
this.parent = parent;
}
public static MethodProcessorEventConsumer attach(
AppView<?> appView, MethodProcessorEventConsumer eventConsumer) {
- ArtProfileCollectionAdditions additionsCollection =
- ArtProfileCollectionAdditions.create(appView);
+ ProfileCollectionAdditions additionsCollection = ProfileCollectionAdditions.create(appView);
if (additionsCollection.isNop()) {
return eventConsumer;
}
- return new ArtProfileRewritingMethodProcessorEventConsumer(
+ return new ProfileRewritingMethodProcessorEventConsumer(
additionsCollection.asConcrete(), eventConsumer);
}
public static MethodProcessorEventConsumer attach(
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
MethodProcessorEventConsumer eventConsumer) {
- if (artProfileCollectionAdditions.isNop()) {
+ if (profileCollectionAdditions.isNop()) {
return eventConsumer;
}
- return new ArtProfileRewritingMethodProcessorEventConsumer(
- artProfileCollectionAdditions.asConcrete(), eventConsumer);
+ return new ProfileRewritingMethodProcessorEventConsumer(
+ profileCollectionAdditions.asConcrete(), eventConsumer);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingNestBasedAccessDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingNestBasedAccessDesugaringEventConsumer.java
similarity index 85%
rename from src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingNestBasedAccessDesugaringEventConsumer.java
rename to src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingNestBasedAccessDesugaringEventConsumer.java
index 2988ce4..28552b5 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingNestBasedAccessDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingNestBasedAccessDesugaringEventConsumer.java
@@ -12,26 +12,26 @@
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.desugar.nest.NestBasedAccessDesugaringEventConsumer;
-public class ArtProfileRewritingNestBasedAccessDesugaringEventConsumer
+public class ProfileRewritingNestBasedAccessDesugaringEventConsumer
implements NestBasedAccessDesugaringEventConsumer {
- private final ConcreteArtProfileCollectionAdditions additionsCollection;
+ private final ConcreteProfileCollectionAdditions additionsCollection;
private final NestBasedAccessDesugaringEventConsumer parent;
- private ArtProfileRewritingNestBasedAccessDesugaringEventConsumer(
- ConcreteArtProfileCollectionAdditions additionsCollection,
+ private ProfileRewritingNestBasedAccessDesugaringEventConsumer(
+ ConcreteProfileCollectionAdditions additionsCollection,
NestBasedAccessDesugaringEventConsumer parent) {
this.additionsCollection = additionsCollection;
this.parent = parent;
}
public static NestBasedAccessDesugaringEventConsumer attach(
- ArtProfileCollectionAdditions additionsCollection,
+ ProfileCollectionAdditions additionsCollection,
NestBasedAccessDesugaringEventConsumer eventConsumer) {
if (additionsCollection.isNop()) {
return eventConsumer;
}
- return new ArtProfileRewritingNestBasedAccessDesugaringEventConsumer(
+ return new ProfileRewritingNestBasedAccessDesugaringEventConsumer(
additionsCollection.asConcrete(), eventConsumer);
}
@@ -46,7 +46,7 @@
context.asProgramMethod(),
additionsBuilder -> additionsBuilder.addRule(argumentClass).addRule(bridge));
} else {
- additionsCollection.apply(
+ additionsCollection.accept(
additions ->
additions.addClassRule(argumentClass).addMethodRule(bridge, emptyConsumer()));
}
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingOutlineOptimizationEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingOutlineOptimizationEventConsumer.java
similarity index 78%
rename from src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingOutlineOptimizationEventConsumer.java
rename to src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingOutlineOptimizationEventConsumer.java
index 2184a87..4343c25 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingOutlineOptimizationEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingOutlineOptimizationEventConsumer.java
@@ -10,14 +10,14 @@
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.Collection;
-public class ArtProfileRewritingOutlineOptimizationEventConsumer
+public class ProfileRewritingOutlineOptimizationEventConsumer
implements OutlineOptimizationEventConsumer {
- private final ConcreteArtProfileCollectionAdditions additionsCollection;
+ private final ConcreteProfileCollectionAdditions additionsCollection;
private final OutlineOptimizationEventConsumer parent;
- private ArtProfileRewritingOutlineOptimizationEventConsumer(
- ConcreteArtProfileCollectionAdditions additionsCollection,
+ private ProfileRewritingOutlineOptimizationEventConsumer(
+ ConcreteProfileCollectionAdditions additionsCollection,
OutlineOptimizationEventConsumer parent) {
this.additionsCollection = additionsCollection;
this.parent = parent;
@@ -25,12 +25,11 @@
public static OutlineOptimizationEventConsumer attach(
AppView<AppInfoWithLiveness> appView, OutlineOptimizationEventConsumer eventConsumer) {
- ArtProfileCollectionAdditions additionsCollection =
- ArtProfileCollectionAdditions.create(appView);
+ ProfileCollectionAdditions additionsCollection = ProfileCollectionAdditions.create(appView);
if (additionsCollection.isNop()) {
return eventConsumer;
}
- return new ArtProfileRewritingOutlineOptimizationEventConsumer(
+ return new ProfileRewritingOutlineOptimizationEventConsumer(
additionsCollection.asConcrete(), eventConsumer);
}
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/ProfileRewritingRootSetBuilderEventConsumer.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingRootSetBuilderEventConsumer.java
rename to src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingRootSetBuilderEventConsumer.java
index 005c33c..9b9d6a5 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/ProfileRewritingRootSetBuilderEventConsumer.java
@@ -7,25 +7,23 @@
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.shaking.RootSetBuilderEventConsumer;
-public class ArtProfileRewritingRootSetBuilderEventConsumer implements RootSetBuilderEventConsumer {
+public class ProfileRewritingRootSetBuilderEventConsumer implements RootSetBuilderEventConsumer {
- private final ConcreteArtProfileCollectionAdditions additionsCollection;
+ private final ConcreteProfileCollectionAdditions additionsCollection;
private final RootSetBuilderEventConsumer parent;
- private ArtProfileRewritingRootSetBuilderEventConsumer(
- ConcreteArtProfileCollectionAdditions additionsCollection,
- RootSetBuilderEventConsumer parent) {
+ private ProfileRewritingRootSetBuilderEventConsumer(
+ ConcreteProfileCollectionAdditions additionsCollection, RootSetBuilderEventConsumer parent) {
this.additionsCollection = additionsCollection;
this.parent = parent;
}
public static RootSetBuilderEventConsumer attach(
- ArtProfileCollectionAdditions additionsCollection,
- RootSetBuilderEventConsumer eventConsumer) {
+ ProfileCollectionAdditions additionsCollection, RootSetBuilderEventConsumer eventConsumer) {
if (additionsCollection.isNop()) {
return eventConsumer;
}
- return new ArtProfileRewritingRootSetBuilderEventConsumer(
+ return new ProfileRewritingRootSetBuilderEventConsumer(
additionsCollection.asConcrete(), eventConsumer);
}
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingVarHandleDesugaringEventConsumerUtils.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingVarHandleDesugaringEventConsumerUtils.java
similarity index 89%
rename from src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingVarHandleDesugaringEventConsumerUtils.java
rename to src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingVarHandleDesugaringEventConsumerUtils.java
index f53e9bc..8792769 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingVarHandleDesugaringEventConsumerUtils.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ProfileRewritingVarHandleDesugaringEventConsumerUtils.java
@@ -10,12 +10,12 @@
import com.android.tools.r8.graph.ProgramDefinition;
import com.android.tools.r8.profile.art.ArtProfileOptions;
-public class ArtProfileRewritingVarHandleDesugaringEventConsumerUtils {
+public class ProfileRewritingVarHandleDesugaringEventConsumerUtils {
static void handleVarHandleDesugaringClassContext(
DexProgramClass varHandleClass,
ProgramDefinition context,
- ConcreteArtProfileCollectionAdditions additionsCollection,
+ ConcreteProfileCollectionAdditions additionsCollection,
ArtProfileOptions options) {
if (options.isIncludingVarHandleClasses()) {
additionsCollection.applyIfContextIsInProfile(
diff --git a/src/main/java/com/android/tools/r8/repackaging/RepackagingUseRegistry.java b/src/main/java/com/android/tools/r8/repackaging/RepackagingUseRegistry.java
index 40ee16e..16bef88 100644
--- a/src/main/java/com/android/tools/r8/repackaging/RepackagingUseRegistry.java
+++ b/src/main/java/com/android/tools/r8/repackaging/RepackagingUseRegistry.java
@@ -146,7 +146,8 @@
MethodResolutionResult methodResult = resolutionResult.asMethodResolutionResult();
if (methodResult.isClassNotFoundResult()
|| methodResult.isArrayCloneMethodResult()
- || methodResult.isNoSuchMethodErrorResult(getContext().getContextClass(), appInfo)) {
+ || methodResult.isNoSuchMethodErrorResult(
+ getContext().getContextClass(), appView, appInfo)) {
return;
}
node.addNeighbor(missingTypeNode);
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java
index f82327a..2deef6f 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java
@@ -228,24 +228,28 @@
OptionalInt originalPosition = mappedRangeForFrame.position;
if (!isAmbiguous()
&& (mappedRange.minifiedRange == null || obfuscatedPosition.orElse(-1) == -1)) {
- int originalLineNumber = mappedRange.getFirstPositionOfOriginalRange(0);
- if (originalLineNumber > 0) {
- return RetracedMethodReferenceImpl.create(
- methodReference, OptionalUtils.orElse(originalPosition, originalLineNumber));
- } else {
- return RetracedMethodReferenceImpl.create(methodReference, originalPosition);
- }
+ return RetracedMethodReferenceImpl.create(
+ methodReference,
+ OptionalUtils.map(
+ originalPosition,
+ () -> {
+ int originalLineNumber = mappedRange.getFirstPositionOfOriginalRange(0);
+ return originalLineNumber > 0
+ ? OptionalInt.of(originalLineNumber)
+ : OptionalInt.empty();
+ }));
}
- if (!obfuscatedPosition.isPresent()
+ if (obfuscatedPosition.isEmpty()
|| mappedRange.minifiedRange == null
|| !mappedRange.minifiedRange.contains(obfuscatedPosition.getAsInt())) {
return RetracedMethodReferenceImpl.create(methodReference, originalPosition);
}
return RetracedMethodReferenceImpl.create(
methodReference,
- OptionalUtils.orElseGet(
+ OptionalUtils.map(
originalPosition,
- () -> mappedRange.getOriginalLineNumber(obfuscatedPosition.getAsInt())));
+ () ->
+ OptionalInt.of(mappedRange.getOriginalLineNumber(obfuscatedPosition.getAsInt()))));
}
@Override
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementStringProxy.java b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementStringProxy.java
index 761a124..b88958e 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementStringProxy.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementStringProxy.java
@@ -115,6 +115,9 @@
}
try {
String lineNumberString = getEntryInLine(lineNumber);
+ if (lineNumberString.startsWith(":")) {
+ lineNumberString = lineNumberString.substring(1);
+ }
if (lineNumberString.isEmpty()) {
return -1;
}
@@ -238,14 +241,15 @@
startIndex,
endIndex,
(retraced, original, verbose) -> {
- boolean printLineNumber =
- retraced.hasLineNumber()
- && ((original.hasLineNumber() && original.getLineNumber() > -1)
- || !retraced.isAmbiguous()
- || verbose);
- return printLineNumber
- ? ((insertSeparatorForRetraced ? ":" : "") + retraced.getLineNumber())
- : original.lineNumberAsString();
+ if (retraced.hasLineNumber()
+ && ((original.hasLineNumber() && original.getLineNumber() > -1)
+ || !retraced.isAmbiguous()
+ || verbose)) {
+ return retraced.getLineNumber() <= 0
+ ? ""
+ : ((insertSeparatorForRetraced ? ":" : "") + retraced.getLineNumber());
+ }
+ return original.lineNumberAsString();
});
orderedIndices.add(lineNumber);
return this;
@@ -326,6 +330,10 @@
}
lastSeenStartIndex = newStartIndex;
}
+
+ public String getLine() {
+ return line;
+ }
}
static class StringIndex {
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceRegularExpressionParser.java b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceRegularExpressionParser.java
index bf9123e..b73c9bc 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceRegularExpressionParser.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceRegularExpressionParser.java
@@ -297,7 +297,15 @@
if (startOfGroup == NO_MATCH) {
return false;
}
- builder.registerLineNumber(startOfGroup, matcher.end(captureGroup), false);
+ boolean insertSeparatorForRetraced = false;
+ // We need to include ':' in the group since we may want to rewrite '(SourceFile:0)` into
+ // (SourceFile) and not (SourceFile:)
+ if (startOfGroup > 0 && builder.getLine().charAt(startOfGroup + -1) == ':') {
+ startOfGroup = startOfGroup - 1;
+ insertSeparatorForRetraced = true;
+ }
+ int end = matcher.end(captureGroup);
+ builder.registerLineNumber(startOfGroup, end, insertSeparatorForRetraced);
return true;
};
}
@@ -321,9 +329,10 @@
int sourceFileEnd = startOfGroup + endOfSourceFileInGroup;
builder.registerSourceFile(startOfGroup, sourceFileEnd);
int endOfMatch = matcher.end(captureGroup);
- int lineNumberStart = sourceFileEnd + 1;
- builder.registerLineNumber(
- Integer.min(lineNumberStart, endOfMatch), endOfMatch, lineNumberStart > endOfMatch);
+ // We need to include ':' in the group since we may want to rewrite '(SourceFile:0)` into
+ // (SourceFile) and not (SourceFile:). We fix this by setting the start of the linenumber
+ // group to the end of the SourceFile group and then force inserting ':'.
+ builder.registerLineNumber(Integer.min(sourceFileEnd, endOfMatch), endOfMatch, true);
return true;
};
}
diff --git a/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java b/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
index f6959c6..9321484 100644
--- a/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
+++ b/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
@@ -129,10 +129,12 @@
if (!options.isKeepRuntimeVisibleParameterAnnotationsEnabled()) {
return false;
}
- } else {
- if (!options.isKeepRuntimeVisibleAnnotationsEnabled()) {
- return false;
- }
+ } else if (!annotation.isTypeAnnotation()
+ && !options.isKeepRuntimeVisibleAnnotationsEnabled()) {
+ return false;
+ } else if (annotation.isTypeAnnotation()
+ && !options.isKeepRuntimeVisibleTypeAnnotationsEnabled()) {
+ return false;
}
return isAnnotationTypeLive;
@@ -147,13 +149,14 @@
if (!options.isKeepRuntimeInvisibleParameterAnnotationsEnabled()) {
return false;
}
- } else {
- if (!options.isKeepRuntimeInvisibleAnnotationsEnabled()) {
- return false;
- }
+ } else if (!annotation.isTypeAnnotation()
+ && !options.isKeepRuntimeInvisibleAnnotationsEnabled()) {
+ return false;
+ } else if (annotation.isTypeAnnotation()
+ && !options.isKeepRuntimeInvisibleTypeAnnotationsEnabled()) {
+ return false;
}
return isAnnotationTypeLive;
-
default:
throw new Unreachable("Unexpected annotation visibility.");
}
diff --git a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
index 811ddc9..bd42c6a 100644
--- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
+++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
@@ -9,7 +9,6 @@
import static com.android.tools.r8.graph.MethodResolutionResult.SingleResolutionResult.isOverriding;
import com.android.tools.r8.cf.CfVersion;
-import com.android.tools.r8.experimental.startup.StartupOrder;
import com.android.tools.r8.features.ClassToFeatureSplitMap;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
@@ -202,7 +201,6 @@
ClassToFeatureSplitMap classToFeatureSplitMap,
MainDexInfo mainDexInfo,
MissingClasses missingClasses,
- StartupOrder startupOrder,
Set<DexType> deadProtoTypes,
Set<DexType> liveTypes,
Set<DexMethod> targetedMethods,
@@ -234,12 +232,7 @@
Set<DexType> lockCandidates,
Map<DexType, Visibility> initClassReferences,
Set<DexMethod> recordFieldValuesReferences) {
- super(
- committedItems,
- classToFeatureSplitMap,
- mainDexInfo,
- missingClasses,
- startupOrder);
+ super(committedItems, classToFeatureSplitMap, mainDexInfo, missingClasses);
this.deadProtoTypes = deadProtoTypes;
this.liveTypes = liveTypes;
this.targetedMethods = targetedMethods;
@@ -280,7 +273,6 @@
previous.getClassToFeatureSplitMap(),
previous.getMainDexInfo(),
previous.getMissingClasses(),
- previous.getStartupOrder(),
previous.deadProtoTypes,
CollectionUtils.addAll(previous.liveTypes, committedItems.getCommittedProgramTypes()),
previous.targetedMethods,
@@ -324,7 +316,6 @@
previous.getClassToFeatureSplitMap().withoutPrunedItems(prunedItems),
previous.getMainDexInfo().withoutPrunedItems(prunedItems),
previous.getMissingClasses(),
- previous.getStartupOrder().withoutPrunedItems(prunedItems, previous.getSyntheticItems()),
previous.deadProtoTypes,
pruneClasses(previous.liveTypes, prunedItems, executorService, futures),
pruneMethods(previous.targetedMethods, prunedItems, executorService, futures),
@@ -489,7 +480,6 @@
getClassToFeatureSplitMap(),
mainDexInfo,
getMissingClasses(),
- getStartupOrder(),
deadProtoTypes,
liveTypes,
targetedMethods,
@@ -566,8 +556,7 @@
previous.getSyntheticItems().commit(previous.app()),
previous.getClassToFeatureSplitMap(),
previous.getMainDexInfo(),
- previous.getMissingClasses(),
- previous.getStartupOrder());
+ previous.getMissingClasses());
this.deadProtoTypes = previous.deadProtoTypes;
this.liveTypes = previous.liveTypes;
this.targetedMethods = previous.targetedMethods;
@@ -767,9 +756,10 @@
* @param callSite Call site to resolve.
* @return Methods implemented by the lambda expression that created the {@code callSite}.
*/
- public Set<DexEncodedMethod> lookupLambdaImplementedMethods(DexCallSite callSite) {
+ public Set<DexEncodedMethod> lookupLambdaImplementedMethods(
+ DexCallSite callSite, AppView<AppInfoWithLiveness> appView) {
assert checkIfObsolete();
- List<DexType> callSiteInterfaces = LambdaDescriptor.getInterfaces(callSite, this);
+ List<DexType> callSiteInterfaces = LambdaDescriptor.getInterfaces(callSite, appView);
if (callSiteInterfaces == null || callSiteInterfaces.isEmpty()) {
return Collections.emptySet();
}
@@ -1159,7 +1149,6 @@
getClassToFeatureSplitMap().rewrittenWithLens(lens),
getMainDexInfo().rewrittenWithLens(getSyntheticItems(), lens),
getMissingClasses(),
- getStartupOrder().rewrittenWithLens(lens),
deadProtoTypes,
lens.rewriteReferences(liveTypes),
lens.rewriteReferences(targetedMethods),
@@ -1229,7 +1218,7 @@
}
public DexEncodedMethod lookupSingleTarget(
- AppView<? extends AppInfoWithClassHierarchy> appView,
+ AppView<AppInfoWithLiveness> appView,
InvokeType type,
DexMethod target,
ProgramMethod context,
@@ -1245,18 +1234,18 @@
case INTERFACE:
return lookupSingleVirtualTarget(appView, target, context, true, modeledPredicate);
case DIRECT:
- return lookupDirectTarget(target, context);
+ return lookupDirectTarget(target, context, appView);
case STATIC:
- return lookupStaticTarget(target, context);
+ return lookupStaticTarget(target, context, appView);
case SUPER:
- return toMethodDefinitionOrNull(lookupSuperTarget(target, context));
+ return toMethodDefinitionOrNull(lookupSuperTarget(target, context, appView));
default:
return null;
}
}
public ProgramMethod lookupSingleProgramTarget(
- AppView<? extends AppInfoWithClassHierarchy> appView,
+ AppView<AppInfoWithLiveness> appView,
InvokeType type,
DexMethod target,
ProgramMethod context,
@@ -1267,7 +1256,7 @@
/** For mapping invoke virtual instruction to single target method. */
public DexEncodedMethod lookupSingleVirtualTarget(
- AppView<? extends AppInfoWithClassHierarchy> appView,
+ AppView<AppInfoWithLiveness> appView,
DexMethod method,
ProgramMethod context,
boolean isInterface) {
@@ -1277,7 +1266,7 @@
/** For mapping invoke virtual instruction to single target method. */
public DexEncodedMethod lookupSingleVirtualTarget(
- AppView<? extends AppInfoWithClassHierarchy> appView,
+ AppView<AppInfoWithLiveness> appView,
DexMethod method,
ProgramMethod context,
boolean isInterface,
@@ -1288,7 +1277,7 @@
}
public DexEncodedMethod lookupSingleVirtualTarget(
- AppView<? extends AppInfoWithClassHierarchy> appView,
+ AppView<AppInfoWithLiveness> appView,
DexMethod method,
ProgramMethod context,
boolean isInterface,
@@ -1325,7 +1314,7 @@
SingleResolutionResult<?> resolution =
resolveMethodOnLegacy(initialResolutionHolder, method).asSingleResolution();
if (resolution == null
- || resolution.isAccessibleForVirtualDispatchFrom(context.getHolder(), this).isFalse()) {
+ || resolution.isAccessibleForVirtualDispatchFrom(context.getHolder(), appView).isFalse()) {
return null;
}
// If the method is modeled, return the resolution.
@@ -1378,7 +1367,10 @@
LookupResultSuccess lookupResult =
resolution
.lookupVirtualDispatchTargets(
- context.getHolder(), this, refinedReceiverClass.asProgramClass(), refinedLowerBound)
+ context.getHolder(),
+ appView,
+ refinedReceiverClass.asProgramClass(),
+ refinedLowerBound)
.asLookupResultSuccess();
if (lookupResult != null && !lookupResult.isIncomplete()) {
LookupTarget singleTarget = lookupResult.getSingleLookupTarget();
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 a30bcf4..f45bf9b 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -122,7 +122,7 @@
import com.android.tools.r8.naming.identifiernamestring.IdentifierNameStringLookupResult;
import com.android.tools.r8.naming.identifiernamestring.IdentifierNameStringTypeLookupResult;
import com.android.tools.r8.position.Position;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
+import com.android.tools.r8.profile.art.rewriting.ProfileCollectionAdditions;
import com.android.tools.r8.shaking.AnnotationMatchResult.MatchedAnnotation;
import com.android.tools.r8.shaking.DelayedRootSetActionItem.InterfaceMethodSyntheticBridgeAction;
import com.android.tools.r8.shaking.EnqueuerEvent.ClassEnqueuerEvent;
@@ -465,11 +465,11 @@
private final Thread mainThreadForTesting = Thread.currentThread();
- private final ArtProfileCollectionAdditions artProfileCollectionAdditions;
+ private final ProfileCollectionAdditions profileCollectionAdditions;
Enqueuer(
AppView<? extends AppInfoWithClassHierarchy> appView,
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
ExecutorService executorService,
SubtypingInfo subtypingInfo,
GraphConsumer keptGraphConsumer,
@@ -478,7 +478,7 @@
InternalOptions options = appView.options();
this.appInfo = appView.appInfo();
this.appView = appView.withClassHierarchy();
- this.artProfileCollectionAdditions = artProfileCollectionAdditions;
+ this.profileCollectionAdditions = profileCollectionAdditions;
this.deferredTracing = EnqueuerDeferredTracing.create(appView, this, mode);
this.executorService = executorService;
this.subtypingInfo = subtypingInfo;
@@ -528,8 +528,8 @@
return appView.appInfo();
}
- public ArtProfileCollectionAdditions getArtProfileCollectionAdditions() {
- return artProfileCollectionAdditions;
+ public ProfileCollectionAdditions getProfileCollectionAdditions() {
+ return profileCollectionAdditions;
}
public Mode getMode() {
@@ -1155,7 +1155,7 @@
}
}
- LambdaDescriptor descriptor = LambdaDescriptor.tryInfer(callSite, appInfo(), context);
+ LambdaDescriptor descriptor = LambdaDescriptor.tryInfer(callSite, appView, appInfo(), context);
if (descriptor == null) {
for (DexValue bootstrapArgument : callSite.getBootstrapArgs()) {
if (bootstrapArgument.isDexValueMethodHandle()) {
@@ -2877,7 +2877,7 @@
LookupResult lookupResult =
singleResolution.lookupVirtualDispatchTargets(
contextHolder,
- appInfo,
+ appView,
(type, subTypeConsumer, lambdaConsumer) -> {
assert appInfo.isSubtype(currentClass.type, type);
instantiation.apply(subTypeConsumer, lambdaConsumer);
@@ -3364,7 +3364,7 @@
DexProgramClass resolvedHolder = resolution.getResolvedHolder().asProgramClass();
DexEncodedMethod resolvedMethod = resolution.getResolvedMethod();
markMethodAsTargeted(new ProgramMethod(resolvedHolder, resolvedMethod), reason);
- if (resolution.isAccessibleForVirtualDispatchFrom(contextHolder, appInfo).isFalse()) {
+ if (resolution.isAccessibleForVirtualDispatchFrom(contextHolder, appView).isFalse()) {
// Not accessible from this context, so this call will cause a runtime exception.
return;
}
@@ -3378,7 +3378,7 @@
resolution
.lookupVirtualDispatchTargets(
contextHolder,
- appInfo,
+ appView,
(type, subTypeConsumer, lambdaConsumer) ->
objectAllocationInfoCollection.forEachInstantiatedSubType(
type, subTypeConsumer, lambdaConsumer, appInfo),
@@ -3500,7 +3500,7 @@
// If invoke target is invalid (inaccessible or not an instance-method) record it and
// stop.
DexClassAndMethod target =
- resolution.lookupInvokeSuperTarget(from.getHolder(), appInfo);
+ resolution.lookupInvokeSuperTarget(from.getHolder(), appView);
if (target == null) {
failedMethodResolutionTargets.add(resolution.getResolvedMethod().getReference());
analyses.forEach(
@@ -3628,7 +3628,7 @@
}
timing.begin("Create result");
EnqueuerResult result = createEnqueuerResult(appInfo, timing);
- artProfileCollectionAdditions.commit(appView);
+ profileCollectionAdditions.commit(appView);
timing.end();
return result;
}
@@ -4024,7 +4024,7 @@
CfInstructionDesugaringEventConsumer eventConsumer =
CfInstructionDesugaringEventConsumer.createForR8(
appView,
- artProfileCollectionAdditions,
+ profileCollectionAdditions,
lambdaCallback,
this::recordConstantDynamicSynthesizingContext,
this::recordTwrCloseResourceMethodSynthesizingContext,
@@ -4100,7 +4100,7 @@
DexProgramClass holder = bridge.getHolder();
DexEncodedMethod method = bridge.getDefinition();
holder.addVirtualMethod(method);
- artProfileCollectionAdditions.addMethodIfContextIsInProfile(bridge, action.getSingleTarget());
+ profileCollectionAdditions.addMethodIfContextIsInProfile(bridge, action.getSingleTarget());
}
syntheticInterfaceMethodBridges.clear();
}
@@ -4216,7 +4216,6 @@
? missingClassesBuilder.reportMissingClasses(
appView, lambdaSynthesizingContextOracle)
: missingClassesBuilder.assertNoMissingClasses(appView),
- appInfo.getStartupOrder(),
deadProtoTypes,
SetUtils.mapIdentityHashSet(liveTypes.getItems(), DexProgramClass::getType),
Enqueuer.toDescriptorSet(targetedMethods.getItems()),
@@ -4490,7 +4489,7 @@
CfPostProcessingDesugaringEventConsumer.createForR8(
appView,
syntheticAdditions,
- artProfileCollectionAdditions,
+ profileCollectionAdditions,
desugaring,
(context, missing) ->
missingClassesBuilder.addNewMissingClassWithDesugarDiagnostic(
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 e1d0124..e09b9be 100644
--- a/src/main/java/com/android/tools/r8/shaking/EnqueuerFactory.java
+++ b/src/main/java/com/android/tools/r8/shaking/EnqueuerFactory.java
@@ -9,7 +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.profile.art.rewriting.ProfileCollectionAdditions;
import com.android.tools.r8.shaking.Enqueuer.Mode;
import java.util.Set;
import java.util.concurrent.ExecutorService;
@@ -18,12 +18,12 @@
public static Enqueuer createForInitialTreeShaking(
AppView<? extends AppInfoWithClassHierarchy> appView,
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
ExecutorService executorService,
SubtypingInfo subtypingInfo) {
return new Enqueuer(
appView,
- artProfileCollectionAdditions,
+ profileCollectionAdditions,
executorService,
subtypingInfo,
null,
@@ -36,12 +36,12 @@
SubtypingInfo subtypingInfo,
GraphConsumer keptGraphConsumer,
Set<DexType> initialPrunedTypes) {
- ArtProfileCollectionAdditions artProfileCollectionAdditions =
- ArtProfileCollectionAdditions.create(appView);
+ ProfileCollectionAdditions profileCollectionAdditions =
+ ProfileCollectionAdditions.create(appView);
Enqueuer enqueuer =
new Enqueuer(
appView,
- artProfileCollectionAdditions,
+ profileCollectionAdditions,
executorService,
subtypingInfo,
keptGraphConsumer,
@@ -56,11 +56,11 @@
AppView<? extends AppInfoWithClassHierarchy> appView,
ExecutorService executorService,
SubtypingInfo subtypingInfo) {
- ArtProfileCollectionAdditions artProfileCollectionAdditions =
- ArtProfileCollectionAdditions.create(appView);
+ ProfileCollectionAdditions profileCollectionAdditions =
+ ProfileCollectionAdditions.create(appView);
return new Enqueuer(
appView,
- artProfileCollectionAdditions,
+ profileCollectionAdditions,
executorService,
subtypingInfo,
null,
@@ -72,11 +72,11 @@
ExecutorService executorService,
SubtypingInfo subtypingInfo,
GraphConsumer keptGraphConsumer) {
- ArtProfileCollectionAdditions artProfileCollectionAdditions =
- ArtProfileCollectionAdditions.create(appView);
+ ProfileCollectionAdditions profileCollectionAdditions =
+ ProfileCollectionAdditions.create(appView);
return new Enqueuer(
appView,
- artProfileCollectionAdditions,
+ profileCollectionAdditions,
executorService,
subtypingInfo,
keptGraphConsumer,
@@ -88,11 +88,11 @@
ExecutorService executorService,
SubtypingInfo subtypingInfo,
GraphConsumer keptGraphConsumer) {
- ArtProfileCollectionAdditions artProfileCollectionAdditions =
- ArtProfileCollectionAdditions.create(appView);
+ ProfileCollectionAdditions profileCollectionAdditions =
+ ProfileCollectionAdditions.create(appView);
return new Enqueuer(
appView,
- artProfileCollectionAdditions,
+ profileCollectionAdditions,
executorService,
subtypingInfo,
keptGraphConsumer,
@@ -104,11 +104,11 @@
ExecutorService executorService,
SubtypingInfo subtypingInfo,
GraphConsumer keptGraphConsumer) {
- ArtProfileCollectionAdditions artProfileCollectionAdditions =
- ArtProfileCollectionAdditions.create(appView);
+ ProfileCollectionAdditions profileCollectionAdditions =
+ ProfileCollectionAdditions.create(appView);
return new Enqueuer(
appView,
- artProfileCollectionAdditions,
+ profileCollectionAdditions,
executorService,
subtypingInfo,
keptGraphConsumer,
diff --git a/src/main/java/com/android/tools/r8/shaking/GlobalKeepInfoConfiguration.java b/src/main/java/com/android/tools/r8/shaking/GlobalKeepInfoConfiguration.java
index d10b35c..7ff0803 100644
--- a/src/main/java/com/android/tools/r8/shaking/GlobalKeepInfoConfiguration.java
+++ b/src/main/java/com/android/tools/r8/shaking/GlobalKeepInfoConfiguration.java
@@ -35,4 +35,8 @@
boolean isKeepRuntimeVisibleAnnotationsEnabled();
boolean isKeepRuntimeVisibleParameterAnnotationsEnabled();
+
+ boolean isKeepRuntimeVisibleTypeAnnotationsEnabled();
+
+ boolean isKeepRuntimeInvisibleTypeAnnotationsEnabled();
}
diff --git a/src/main/java/com/android/tools/r8/shaking/MainDexDirectReferenceTracer.java b/src/main/java/com/android/tools/r8/shaking/MainDexDirectReferenceTracer.java
index 8baf037..89c25ae 100644
--- a/src/main/java/com/android/tools/r8/shaking/MainDexDirectReferenceTracer.java
+++ b/src/main/java/com/android/tools/r8/shaking/MainDexDirectReferenceTracer.java
@@ -43,6 +43,10 @@
this.consumer = consumer;
}
+ private AppView<? extends AppInfoWithClassHierarchy> appView() {
+ return appView;
+ }
+
public void run(Set<DexType> roots) {
SyntheticItems syntheticItems = appView.getSyntheticItems();
DexItemFactory factory = appView.dexItemFactory();
@@ -113,7 +117,7 @@
private class DirectReferencesCollector extends UseRegistry<ProgramMethod> {
private DirectReferencesCollector(ProgramMethod context) {
- super(appView, context);
+ super(appView(), context);
}
@Override
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 9378b76..4102d80 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetBuilderEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetBuilderEventConsumer.java
@@ -6,15 +6,13 @@
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.profile.art.rewriting.ProfileCollectionAdditions;
+import com.android.tools.r8.profile.art.rewriting.ProfileRewritingRootSetBuilderEventConsumer;
public interface RootSetBuilderEventConsumer extends InterfaceMethodDesugaringBaseEventConsumer {
- static RootSetBuilderEventConsumer create(
- ArtProfileCollectionAdditions artProfileCollectionAdditions) {
- return ArtProfileRewritingRootSetBuilderEventConsumer.attach(
- artProfileCollectionAdditions, empty());
+ static RootSetBuilderEventConsumer create(ProfileCollectionAdditions profileCollectionAdditions) {
+ return ProfileRewritingRootSetBuilderEventConsumer.attach(profileCollectionAdditions, empty());
}
static EmptyRootSetBuilderEventConsumer empty() {
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 352facd..bbb8726 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
@@ -52,7 +52,7 @@
import com.android.tools.r8.ir.desugar.itf.InterfaceDesugaringSyntheticHelper;
import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple;
import com.android.tools.r8.ir.optimize.membervaluepropagation.assume.AssumeInfo;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
+import com.android.tools.r8.profile.art.rewriting.ProfileCollectionAdditions;
import com.android.tools.r8.repackaging.RepackagingUtils;
import com.android.tools.r8.shaking.AnnotationMatchResult.AnnotationsIgnoredMatchResult;
import com.android.tools.r8.shaking.AnnotationMatchResult.ConcreteAnnotationMatchResult;
@@ -176,7 +176,7 @@
SubtypingInfo subtypingInfo) {
this(
appView,
- RootSetBuilderEventConsumer.create(enqueuer.getArtProfileCollectionAdditions()),
+ RootSetBuilderEventConsumer.create(enqueuer.getProfileCollectionAdditions()),
subtypingInfo,
null);
}
@@ -2151,12 +2151,12 @@
public static RootSetBuilder builder(
AppView<? extends AppInfoWithClassHierarchy> appView,
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
SubtypingInfo subtypingInfo,
Iterable<? extends ProguardConfigurationRule> rules) {
return new RootSetBuilder(
appView,
- RootSetBuilderEventConsumer.create(artProfileCollectionAdditions),
+ RootSetBuilderEventConsumer.create(profileCollectionAdditions),
subtypingInfo,
rules);
}
@@ -2172,7 +2172,7 @@
SubtypingInfo subtypingInfo) {
super(
appView,
- RootSetBuilderEventConsumer.create(enqueuer.getArtProfileCollectionAdditions()),
+ RootSetBuilderEventConsumer.create(enqueuer.getProfileCollectionAdditions()),
subtypingInfo,
null);
this.enqueuer = enqueuer;
@@ -2220,12 +2220,12 @@
private MainDexRootSetBuilder(
AppView<? extends AppInfoWithClassHierarchy> appView,
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
SubtypingInfo subtypingInfo,
Iterable<? extends ProguardConfigurationRule> rules) {
super(
appView,
- RootSetBuilderEventConsumer.create(artProfileCollectionAdditions),
+ RootSetBuilderEventConsumer.create(profileCollectionAdditions),
subtypingInfo,
rules);
}
@@ -2279,11 +2279,10 @@
public static MainDexRootSetBuilder builder(
AppView<? extends AppInfoWithClassHierarchy> appView,
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
+ ProfileCollectionAdditions profileCollectionAdditions,
SubtypingInfo subtypingInfo,
Iterable<? extends ProguardConfigurationRule> rules) {
- return new MainDexRootSetBuilder(
- appView, artProfileCollectionAdditions, subtypingInfo, rules);
+ return new MainDexRootSetBuilder(appView, profileCollectionAdditions, subtypingInfo, rules);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
index 1049259..c0e541b 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -73,7 +73,7 @@
import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple;
import com.android.tools.r8.ir.synthetic.AbstractSynthesizedCode;
import com.android.tools.r8.ir.synthetic.ForwardMethodSourceCode;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
+import com.android.tools.r8.profile.art.rewriting.ProfileCollectionAdditions;
import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.CollectionUtils;
import com.android.tools.r8.utils.FieldSignatureEquivalence;
@@ -627,16 +627,16 @@
assert verifyGraphLens(lens);
// Include bridges in art profiles.
- ArtProfileCollectionAdditions artProfileCollectionAdditions =
- ArtProfileCollectionAdditions.create(appView);
- if (!artProfileCollectionAdditions.isNop()) {
+ ProfileCollectionAdditions profileCollectionAdditions =
+ ProfileCollectionAdditions.create(appView);
+ if (!profileCollectionAdditions.isNop()) {
for (SynthesizedBridgeCode synthesizedBridge : synthesizedBridges) {
- artProfileCollectionAdditions.applyIfContextIsInProfile(
+ profileCollectionAdditions.applyIfContextIsInProfile(
synthesizedBridge.originalMethod,
additionsBuilder -> additionsBuilder.addRule(synthesizedBridge.method));
}
}
- artProfileCollectionAdditions.commit(appView);
+ profileCollectionAdditions.commit(appView);
// Rewrite collections using the lens.
appView.rewriteWithLens(lens);
@@ -761,7 +761,7 @@
LookupResultSuccess lookupResult =
appInfo
.resolveMethodOnInterfaceLegacy(method.getHolderType(), method.getReference())
- .lookupVirtualDispatchTargets(target, appInfo)
+ .lookupVirtualDispatchTargets(target, appView)
.asLookupResultSuccess();
assert lookupResult != null;
if (lookupResult == null) {
@@ -1356,7 +1356,7 @@
// Only rewrite the invoke-super call if it does not lead to a NoSuchMethodError.
boolean resolutionSucceeds =
holder.lookupVirtualMethod(signatureInHolder) != null
- || appInfo.lookupSuperTarget(signatureInHolder, holder) != null;
+ || appInfo.lookupSuperTarget(signatureInHolder, holder, appView) != null;
if (resolutionSucceeds) {
deferredRenamings.mapVirtualMethodToDirectInType(
signatureInHolder,
@@ -1381,7 +1381,7 @@
// its super classes declared the method.
boolean resolutionSucceededBeforeMerge =
lensBuilder.hasMappingForSignatureInContext(holder, signatureInType)
- || appInfo.lookupSuperTarget(signatureInHolder, holder) != null;
+ || appInfo.lookupSuperTarget(signatureInHolder, holder, appView) != null;
if (resolutionSucceededBeforeMerge) {
deferredRenamings.mapVirtualMethodToDirectInType(
signatureInType,
diff --git a/src/main/java/com/android/tools/r8/startup/StartupProfileBuilder.java b/src/main/java/com/android/tools/r8/startup/StartupProfileBuilder.java
index 47916c1..3ee53c7 100644
--- a/src/main/java/com/android/tools/r8/startup/StartupProfileBuilder.java
+++ b/src/main/java/com/android/tools/r8/startup/StartupProfileBuilder.java
@@ -21,29 +21,6 @@
Consumer<StartupMethodBuilder> startupMethodBuilderConsumer);
/**
- * API for adding information about a synthetic startup method to the compiler.
- *
- * <p>When shrinking an app using R8, the names of synthetic classes may differ from the synthetic
- * names that arise from dexing the app using D8. Therefore, synthetic classes and methods should
- * not be added to the startup profile using {@link #addStartupClass(Consumer)} and {@link
- * #addStartupMethod(Consumer)}.
- *
- * <p>Instead, synthetic items should be added to the startup profile using this method, which
- * takes the name of the synthetic context instead of the synthetic name. The addition of the
- * synthetic context will be interpreted as the presence of any method on any synthetic class that
- * has been synthesized from the synthetic context.
- *
- * <p>Example: Instead of adding "Lcom/example/MainActivity$ExternalSynthetic0;->m()V" as a
- * (non-synthetic) startup method, a synthetic startup method should be added with synthetic
- * context "Lcom/example/MainActivity;".
- *
- * <p>NOTE: This should only be used when supplying a startup profile that is generated from an
- * unobfuscated build of the app to R8.
- */
- StartupProfileBuilder addSyntheticStartupMethod(
- Consumer<SyntheticStartupMethodBuilder> syntheticStartupMethodBuilderConsumer);
-
- /**
* Adds the rules from the given human-readable ART profile to the startup profile and then closes
* the stream.
*
diff --git a/src/main/java/com/android/tools/r8/startup/SyntheticStartupMethodBuilder.java b/src/main/java/com/android/tools/r8/startup/SyntheticStartupMethodBuilder.java
deleted file mode 100644
index 281bac7..0000000
--- a/src/main/java/com/android/tools/r8/startup/SyntheticStartupMethodBuilder.java
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2022, 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.startup;
-
-import com.android.tools.r8.Keep;
-import com.android.tools.r8.references.ClassReference;
-
-/** Interface for providing information about a synthetic startup method to the compiler. */
-@Keep
-public interface SyntheticStartupMethodBuilder {
-
- SyntheticStartupMethodBuilder setSyntheticContextReference(ClassReference classReference);
-}
diff --git a/src/main/java/com/android/tools/r8/startup/diagnostic/MissingStartupProfileItemsDiagnostic.java b/src/main/java/com/android/tools/r8/startup/diagnostic/MissingStartupProfileItemsDiagnostic.java
index 6fa28ea..0c33a74 100644
--- a/src/main/java/com/android/tools/r8/startup/diagnostic/MissingStartupProfileItemsDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/startup/diagnostic/MissingStartupProfileItemsDiagnostic.java
@@ -6,9 +6,8 @@
import com.android.tools.r8.Diagnostic;
import com.android.tools.r8.Keep;
-import com.android.tools.r8.experimental.startup.profile.StartupClass;
-import com.android.tools.r8.experimental.startup.profile.StartupMethod;
-import com.android.tools.r8.experimental.startup.profile.SyntheticStartupMethod;
+import com.android.tools.r8.experimental.startup.profile.StartupProfileClassRule;
+import com.android.tools.r8.experimental.startup.profile.StartupProfileMethodRule;
import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexString;
@@ -86,7 +85,7 @@
return !missingStartupItems.isEmpty();
}
- public boolean registerStartupClass(StartupClass startupClass) {
+ public boolean registerStartupClass(StartupProfileClassRule startupClass) {
if (definitions != null && !definitions.hasDefinitionFor(startupClass.getReference())) {
addMissingStartupItem(startupClass.getReference());
return true;
@@ -94,7 +93,7 @@
return false;
}
- public boolean registerStartupMethod(StartupMethod startupMethod) {
+ public boolean registerStartupMethod(StartupProfileMethodRule startupMethod) {
if (definitions != null && !definitions.hasDefinitionFor(startupMethod.getReference())) {
addMissingStartupItem(startupMethod.getReference());
return true;
@@ -102,15 +101,6 @@
return false;
}
- public boolean registerSyntheticStartupMethod(SyntheticStartupMethod syntheticStartupMethod) {
- if (definitions != null
- && !definitions.hasDefinitionFor(syntheticStartupMethod.getSyntheticContextType())) {
- addMissingStartupItem(syntheticStartupMethod.getSyntheticContextType());
- return true;
- }
- return false;
- }
-
private void addMissingStartupItem(DexReference reference) {
DexString jDollarDescriptorPrefix = definitions.dexItemFactory().jDollarDescriptorPrefix;
if (!reference.getContextType().getDescriptor().startsWith(jDollarDescriptorPrefix)) {
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
index 3bbb9ae..066c144 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
@@ -11,7 +11,7 @@
import com.android.tools.r8.contexts.CompilationContext.UniqueContext;
import com.android.tools.r8.errors.MissingGlobalSyntheticsConsumerDiagnostic;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.experimental.startup.StartupOrder;
+import com.android.tools.r8.experimental.startup.StartupProfile;
import com.android.tools.r8.features.ClassToFeatureSplitMap;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
@@ -539,22 +539,6 @@
return oracle.getSynthesizingContexts(clazz);
}
- public Map<DexType, List<DexProgramClass>> computeSyntheticContextsToSyntheticClasses(
- AppView<?> appView) {
- Map<DexType, List<DexProgramClass>> syntheticContextsToSyntheticClasses =
- new IdentityHashMap<>();
- for (DexProgramClass clazz : appView.appInfo().classes()) {
- if (isSyntheticClass(clazz)) {
- for (DexType synthesizingContextType : getSynthesizingContextTypes(clazz.getType())) {
- syntheticContextsToSyntheticClasses
- .computeIfAbsent(synthesizingContextType, ignoreKey -> new ArrayList<>())
- .add(clazz);
- }
- }
- }
- return syntheticContextsToSyntheticClasses;
- }
-
public Collection<Origin> getSynthesizingOrigin(DexType type) {
if (!isSynthetic(type)) {
return Collections.emptyList();
@@ -626,13 +610,13 @@
if (appView.hasClassHierarchy()) {
AppInfoWithClassHierarchy appInfo = appView.appInfoWithClassHierarchy();
return getSynthesizingContext(
- context, appInfo.getClassToFeatureSplitMap(), options, appInfo.getStartupOrder());
+ context, appInfo.getClassToFeatureSplitMap(), options, appView.getStartupProfile());
}
return getSynthesizingContext(
context,
ClassToFeatureSplitMap.createEmptyClassToFeatureSplitMap(),
options,
- StartupOrder.empty());
+ StartupProfile.empty());
}
/** Used to find the synthesizing context for a new synthetic that is about to be created. */
@@ -640,7 +624,7 @@
ProgramDefinition context,
ClassToFeatureSplitMap featureSplits,
InternalOptions options,
- StartupOrder startupOrder) {
+ StartupProfile startupProfile) {
DexType contextType = context.getContextType();
SyntheticDefinition<?, ?, ?> existingDefinition = pending.definitions.get(contextType);
if (existingDefinition != null) {
@@ -656,7 +640,8 @@
.getContext();
}
// This context is not nested in an existing synthetic context so create a new "leaf" context.
- FeatureSplit featureSplit = featureSplits.getFeatureSplit(context, options, startupOrder, this);
+ FeatureSplit featureSplit =
+ featureSplits.getFeatureSplit(context, options, startupProfile, this);
return SynthesizingContext.fromNonSyntheticInputContext(context, featureSplit);
}
diff --git a/src/main/java/com/android/tools/r8/tracereferences/TraceReferences.java b/src/main/java/com/android/tools/r8/tracereferences/TraceReferences.java
index e1000f6..ad30e62 100644
--- a/src/main/java/com/android/tools/r8/tracereferences/TraceReferences.java
+++ b/src/main/java/com/android/tools/r8/tracereferences/TraceReferences.java
@@ -13,7 +13,6 @@
import com.android.tools.r8.ResourceException;
import com.android.tools.r8.Version;
import com.android.tools.r8.dex.ApplicationReader;
-import com.android.tools.r8.experimental.startup.StartupOrder;
import com.android.tools.r8.features.ClassToFeatureSplitMap;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
@@ -87,8 +86,7 @@
new ApplicationReader(builder.build(), options, Timing.empty()).read().toDirect(),
ClassToFeatureSplitMap.createEmptyClassToFeatureSplitMap(),
MainDexInfo.none(),
- GlobalSyntheticsStrategy.forSingleOutputMode(),
- StartupOrder.empty()));
+ GlobalSyntheticsStrategy.forSingleOutputMode()));
modelLibraryMethodsWithCovariantReturnTypes(appView);
Tracer tracer =
new Tracer(
diff --git a/src/main/java/com/android/tools/r8/tracereferences/Tracer.java b/src/main/java/com/android/tools/r8/tracereferences/Tracer.java
index f182a0b..b430854 100644
--- a/src/main/java/com/android/tools/r8/tracereferences/Tracer.java
+++ b/src/main/java/com/android/tools/r8/tracereferences/Tracer.java
@@ -109,6 +109,10 @@
this.targetPredicate = targetPredicate;
}
+ AppView<? extends AppInfoWithClassHierarchy> appView() {
+ return appView;
+ }
+
AppInfoWithClassHierarchy appInfo() {
return appView.appInfo();
}
@@ -228,7 +232,7 @@
? appInfo().resolveMethodOnInterface(method.getHolder(), method.getReference())
: appInfo().resolveMethodOnClass(method.getHolder(), method.getReference());
DexClassAndMethod superTarget =
- methodResolutionResult.lookupInvokeSpecialTarget(method.getHolder(), appInfo());
+ methodResolutionResult.lookupInvokeSpecialTarget(method.getHolder(), appView);
if (superTarget != null
&& !superTarget.isProgramMethod()
&& isTargetType(superTarget.getHolderType())) {
@@ -263,7 +267,7 @@
private final DefinitionContext referencedFrom;
public MethodUseCollector(ProgramMethod context) {
- super(appView, context);
+ super(appView(), context);
this.referencedFrom = DefinitionContextUtils.create(context);
}
@@ -316,7 +320,7 @@
handleRewrittenMethodResolution(
method,
appInfo().unsafeResolveMethodDueToDexFormat(rewrittenMethod),
- result -> result.lookupInvokeSuperTarget(getContext().getHolder(), appInfo()));
+ result -> result.lookupInvokeSuperTarget(getContext().getHolder(), appView, appInfo()));
}
@Override
@@ -486,7 +490,8 @@
// For lambdas that implement an interface, also keep the interface method by simulating an
// invoke to it from the current context.
- LambdaDescriptor descriptor = LambdaDescriptor.tryInfer(callSite, appInfo(), getContext());
+ LambdaDescriptor descriptor =
+ LambdaDescriptor.tryInfer(callSite, appView(), appInfo(), getContext());
if (descriptor != null) {
for (DexType interfaceType : descriptor.interfaces) {
ClassResolutionResult classResolutionResult =
diff --git a/src/main/java/com/android/tools/r8/utils/AndroidApp.java b/src/main/java/com/android/tools/r8/utils/AndroidApp.java
index cf3047d..ee770f8 100644
--- a/src/main/java/com/android/tools/r8/utils/AndroidApp.java
+++ b/src/main/java/com/android/tools/r8/utils/AndroidApp.java
@@ -34,7 +34,7 @@
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.InternalCompilerError;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.experimental.startup.StartupOrder;
+import com.android.tools.r8.experimental.startup.StartupProfile;
import com.android.tools.r8.experimental.startup.StartupProfileProviderUtils;
import com.android.tools.r8.features.ClassToFeatureSplitMap;
import com.android.tools.r8.features.FeatureSplitConfiguration;
@@ -679,7 +679,7 @@
SyntheticItems syntheticItems = null;
FeatureSplit featureSplit =
classToFeatureSplitMap.getFeatureSplit(
- type, options, StartupOrder.empty(), syntheticItems);
+ type, options, StartupProfile.empty(), syntheticItems);
if (featureSplit != null && !featureSplit.isBase()) {
return featureSplitArchiveOutputStreams.get(featureSplit);
}
diff --git a/src/main/java/com/android/tools/r8/utils/Box.java b/src/main/java/com/android/tools/r8/utils/Box.java
index 1134718..00fde15 100644
--- a/src/main/java/com/android/tools/r8/utils/Box.java
+++ b/src/main/java/com/android/tools/r8/utils/Box.java
@@ -5,6 +5,8 @@
package com.android.tools.r8.utils;
import java.util.Comparator;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
import java.util.function.Supplier;
public class Box<T> extends BoxBase<T> {
@@ -16,6 +18,11 @@
}
@Override
+ public void accept(Consumer<? super T> consumer) {
+ super.accept(consumer);
+ }
+
+ @Override
public void clear() {
super.clear();
}
@@ -35,6 +42,13 @@
return super.getAndSet(newValue);
}
+ public <E extends Exception> Box<T> rebuild(ThrowingFunction<T, T, E> fn) throws E {
+ if (isSet()) {
+ return new Box<>(fn.apply(get()));
+ }
+ return new Box<>();
+ }
+
@Override
public void set(T value) {
super.set(value);
@@ -44,4 +58,9 @@
public void setMin(T value, Comparator<T> comparator) {
super.setMin(value, comparator);
}
+
+ @Override
+ public boolean test(Predicate<T> predicate) {
+ return super.test(predicate);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/utils/BoxBase.java b/src/main/java/com/android/tools/r8/utils/BoxBase.java
index 93f70da..c2b4492 100644
--- a/src/main/java/com/android/tools/r8/utils/BoxBase.java
+++ b/src/main/java/com/android/tools/r8/utils/BoxBase.java
@@ -6,7 +6,9 @@
import java.util.Comparator;
import java.util.Objects;
+import java.util.function.Consumer;
import java.util.function.Function;
+import java.util.function.Predicate;
import java.util.function.Supplier;
public abstract class BoxBase<T> {
@@ -19,6 +21,12 @@
set(initialValue);
}
+ void accept(Consumer<? super T> consumer) {
+ if (isSet()) {
+ consumer.accept(get());
+ }
+ }
+
void clear() {
set(null);
}
@@ -56,6 +64,10 @@
}
}
+ boolean test(Predicate<T> predicate) {
+ return isSet() && predicate.test(get());
+ }
+
public boolean isSet() {
return value != null;
}
diff --git a/src/main/java/com/android/tools/r8/utils/CompileDumpUtils.java b/src/main/java/com/android/tools/r8/utils/CompileDumpUtils.java
index f0275f5..4356671 100644
--- a/src/main/java/com/android/tools/r8/utils/CompileDumpUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/CompileDumpUtils.java
@@ -43,26 +43,16 @@
try (BufferedReader bufferedReader = Files.newBufferedReader(path)) {
while (bufferedReader.ready()) {
String rule = bufferedReader.readLine();
- if (rule.charAt(0) == 'S') {
- String classDescriptor = rule.substring(1);
- assert DescriptorUtils.isClassDescriptor(classDescriptor);
- startupProfileBuilder.addSyntheticStartupMethod(
- syntheticStartupMethodBuilder ->
- syntheticStartupMethodBuilder.setSyntheticContextReference(
- Reference.classFromDescriptor(classDescriptor)));
+ MethodReference methodReference = MethodReferenceUtils.parseSmaliString(rule);
+ if (methodReference != null) {
+ startupProfileBuilder.addStartupMethod(
+ startupMethodBuilder ->
+ startupMethodBuilder.setMethodReference(methodReference));
} else {
- MethodReference methodReference = MethodReferenceUtils.parseSmaliString(rule);
- if (methodReference != null) {
- startupProfileBuilder.addStartupMethod(
- startupMethodBuilder ->
- startupMethodBuilder.setMethodReference(methodReference));
- } else {
- assert DescriptorUtils.isClassDescriptor(rule);
- startupProfileBuilder.addStartupClass(
- startupClassBuilder ->
- startupClassBuilder.setClassReference(
- Reference.classFromDescriptor(rule)));
- }
+ assert DescriptorUtils.isClassDescriptor(rule);
+ startupProfileBuilder.addStartupClass(
+ startupClassBuilder ->
+ startupClassBuilder.setClassReference(Reference.classFromDescriptor(rule)));
}
}
}
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 0d7a71c..8275b55 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -785,6 +785,16 @@
return proguardConfiguration.getKeepAttributes().runtimeVisibleParameterAnnotations;
}
+ @Override
+ public boolean isKeepRuntimeVisibleTypeAnnotationsEnabled() {
+ return proguardConfiguration.getKeepAttributes().runtimeVisibleTypeAnnotations;
+ }
+
+ @Override
+ public boolean isKeepRuntimeInvisibleTypeAnnotationsEnabled() {
+ return proguardConfiguration.getKeepAttributes().runtimeInvisibleTypeAnnotations;
+ }
+
/**
* If any non-static class merging is enabled, information about types referred to by instanceOf
* and check cast instructions needs to be collected.
diff --git a/src/main/java/com/android/tools/r8/utils/OptionalUtils.java b/src/main/java/com/android/tools/r8/utils/OptionalUtils.java
index 974bf0c..925ca07 100644
--- a/src/main/java/com/android/tools/r8/utils/OptionalUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/OptionalUtils.java
@@ -9,11 +9,8 @@
public class OptionalUtils {
- public static OptionalInt orElse(OptionalInt optional, int orElse) {
- return optional.isPresent() ? optional : OptionalInt.of(orElse);
+ public static OptionalInt map(OptionalInt optional, Supplier<OptionalInt> orElse) {
+ return optional.isPresent() ? optional : orElse.get();
}
- public static OptionalInt orElseGet(OptionalInt optional, Supplier<Integer> orElse) {
- return optional.isPresent() ? optional : OptionalInt.of(orElse.get());
- }
}
diff --git a/src/main/java/com/android/tools/r8/utils/TypeReferenceUtils.java b/src/main/java/com/android/tools/r8/utils/TypeReferenceUtils.java
index a5145f4..bb1bbc9 100644
--- a/src/main/java/com/android/tools/r8/utils/TypeReferenceUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/TypeReferenceUtils.java
@@ -37,6 +37,10 @@
return COMPARATOR;
}
+ public static TypeReference getVoidType() {
+ return null;
+ }
+
public static DexProto toDexProto(
List<TypeReference> formalTypes, TypeReference returnType, DexItemFactory dexItemFactory) {
return toDexProto(
diff --git a/src/test/java/com/android/tools/r8/D8CommandTest.java b/src/test/java/com/android/tools/r8/D8CommandTest.java
index 487451f..f22ce21 100644
--- a/src/test/java/com/android/tools/r8/D8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/D8CommandTest.java
@@ -21,12 +21,10 @@
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.dex.Marker.Tool;
-import com.android.tools.r8.experimental.startup.profile.StartupItem;
-import com.android.tools.r8.experimental.startup.profile.StartupMethod;
-import com.android.tools.r8.experimental.startup.profile.StartupProfile;
+import com.android.tools.r8.experimental.startup.StartupProfile;
+import com.android.tools.r8.experimental.startup.profile.StartupProfileRule;
import com.android.tools.r8.origin.EmbeddedOrigin;
import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.profile.art.ArtProfileBuilderUtils.SyntheticToSyntheticContextGeneralization;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.startup.StartupProfileProvider;
import com.android.tools.r8.startup.diagnostic.MissingStartupProfileItemsDiagnostic;
@@ -807,24 +805,19 @@
MissingStartupProfileItemsDiagnostic.Builder missingStartupProfileItemsDiagnosticBuilder =
MissingStartupProfileItemsDiagnostic.Builder.nop();
StartupProfileProvider startupProfileProvider = startupProfileProviders.get(0);
- SyntheticToSyntheticContextGeneralization syntheticToSyntheticContextGeneralization =
- SyntheticToSyntheticContextGeneralization.createForD8();
StartupProfile.Builder startupProfileBuilder =
StartupProfile.builder(
- options,
- missingStartupProfileItemsDiagnosticBuilder,
- startupProfileProvider,
- syntheticToSyntheticContextGeneralization);
+ options, missingStartupProfileItemsDiagnosticBuilder, startupProfileProvider);
startupProfileProvider.getStartupProfile(startupProfileBuilder);
// Verify we found the same rule.
StartupProfile startupProfile = startupProfileBuilder.build();
- Collection<StartupItem> startupItems = startupProfile.getStartupItems();
+ Collection<StartupProfileRule> startupItems = startupProfile.getRules();
assertEquals(1, startupItems.size());
- StartupItem startupItem = startupItems.iterator().next();
- assertTrue(startupItem.isStartupMethod());
- StartupMethod startupMethod = startupItem.asStartupMethod();
- assertEquals(profileRule, startupMethod.getReference().toSmaliString());
+ StartupProfileRule startupItem = startupItems.iterator().next();
+ startupItem.accept(
+ startupClass -> fail(),
+ startupMethod -> assertEquals(profileRule, startupMethod.getReference().toSmaliString()));
}
@Test
diff --git a/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
index f3f7d40..22f879d 100644
--- a/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
@@ -93,6 +93,10 @@
Version.V13_0_0,
// TODO(120402963) Triage.
ImmutableList.of("invokecustom-with-shrinking", "invokecustom2-with-shrinking"))
+ .put(
+ Version.V14_0_0,
+ // TODO(120402963) Triage.
+ ImmutableList.of("invokecustom-with-shrinking", "invokecustom2-with-shrinking"))
.put(Version.DEFAULT, ImmutableList.of())
.build();
diff --git a/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
index de13777..59e0d13 100644
--- a/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
@@ -306,6 +306,11 @@
ImmutableList.of(
// TODO(b/120402963): Triage.
"invokecustom", "invokecustom2"))
+ .put(
+ Version.V14_0_0,
+ ImmutableList.of(
+ // TODO(b/120402963): Triage.
+ "invokecustom", "invokecustom2"))
.put(DexVm.Version.DEFAULT, ImmutableList.of());
failsOn = builder.build();
}
diff --git a/src/test/java/com/android/tools/r8/TestBase.java b/src/test/java/com/android/tools/r8/TestBase.java
index a2f3ebc..45322ff 100644
--- a/src/test/java/com/android/tools/r8/TestBase.java
+++ b/src/test/java/com/android/tools/r8/TestBase.java
@@ -26,7 +26,6 @@
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.dex.code.DexInstruction;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.experimental.startup.StartupOrder;
import com.android.tools.r8.features.ClassToFeatureSplitMap;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
@@ -46,7 +45,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.profile.art.rewriting.ProfileCollectionAdditions;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.FieldReference;
import com.android.tools.r8.references.MethodReference;
@@ -777,8 +776,7 @@
readApplicationForDexOutput(app, new InternalOptions()),
ClassToFeatureSplitMap.createEmptyClassToFeatureSplitMap(),
MainDexInfo.none(),
- GlobalSyntheticsStrategy.forSingleOutputMode(),
- StartupOrder.empty());
+ GlobalSyntheticsStrategy.forSingleOutputMode());
}
protected static AppView<AppInfoWithClassHierarchy> computeAppViewWithClassHierarchy(
@@ -847,20 +845,19 @@
computeAppViewWithClassHierarchy(app, keepConfig, optionsConsumer);
// Run the tree shaker to compute an instance of AppInfoWithLiveness.
ExecutorService executor = Executors.newSingleThreadExecutor();
- ArtProfileCollectionAdditions artProfileCollectionAdditions =
- ArtProfileCollectionAdditions.nop();
+ ProfileCollectionAdditions profileCollectionAdditions = ProfileCollectionAdditions.nop();
SubtypingInfo subtypingInfo = SubtypingInfo.create(appView);
RootSet rootSet =
RootSet.builder(
appView,
- artProfileCollectionAdditions,
+ profileCollectionAdditions,
subtypingInfo,
appView.options().getProguardConfiguration().getRules())
.build(executor);
appView.setRootSet(rootSet);
EnqueuerResult enqueuerResult =
EnqueuerFactory.createForInitialTreeShaking(
- appView, artProfileCollectionAdditions, executor, subtypingInfo)
+ appView, profileCollectionAdditions, 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/TestShrinkerBuilder.java b/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java
index 1523915..704ce16 100644
--- a/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java
@@ -438,6 +438,14 @@
return addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS);
}
+ public T addKeepRuntimeVisibleTypeAnnotations() {
+ return addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
+ }
+
+ public T addKeepRuntimeInvisibleTypeAnnotations() {
+ return addKeepAttributes(ProguardKeepAttributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
+ }
+
public T addKeepAllAttributes() {
return addKeepAttributes("*");
}
diff --git a/src/test/java/com/android/tools/r8/annotations/TypeUseAnnotationPruneTest.java b/src/test/java/com/android/tools/r8/annotations/TypeUseAnnotationPruneTest.java
new file mode 100644
index 0000000..3a72818
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/annotations/TypeUseAnnotationPruneTest.java
@@ -0,0 +1,99 @@
+// 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.annotations;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.ClassFileConsumer;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.annotations.testclasses.MainWithTypeAndGeneric;
+import com.android.tools.r8.annotations.testclasses.NotNullTestClass;
+import com.android.tools.r8.annotations.testclasses.NotNullTestRuntime;
+import com.android.tools.r8.annotations.testclasses.SuperInterface;
+import com.android.tools.r8.annotations.testclasses.TestClassWithTypeAndGenericAnnotations;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.FieldSubject;
+import com.android.tools.r8.utils.codeinspector.FoundAnnotationSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import java.lang.reflect.AnnotatedType;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class TypeUseAnnotationPruneTest extends TestBase {
+
+ @Parameter() public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().build();
+ }
+
+ private String getExpected(String notNullTestRuntimeTypeName) {
+ return StringUtils.joinLines(
+ "printAnnotation - Class: " + notNullTestRuntimeTypeName,
+ "printAnnotation - Class: NULL",
+ "printAnnotation - Field: NULL",
+ "printAnnotation - Field: NULL",
+ "printAnnotation - Method: NULL",
+ "printAnnotation - Method: NULL",
+ "Hello World!");
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ testForR8(parameters.getBackend())
+ .addProgramClasses(
+ MainWithTypeAndGeneric.class,
+ NotNullTestClass.class,
+ NotNullTestRuntime.class,
+ TestClassWithTypeAndGenericAnnotations.class,
+ SuperInterface.class)
+ .setMinApi(parameters)
+ .addKeepClassRules(NotNullTestClass.class, NotNullTestRuntime.class, SuperInterface.class)
+ .addKeepRuntimeVisibleAnnotations()
+ .addKeepRuntimeInvisibleAnnotations()
+ .addKeepRuntimeVisibleParameterAnnotations()
+ .addKeepRuntimeInvisibleParameterAnnotations()
+ .addKeepAttributeSignature()
+ .addKeepAttributeExceptions()
+ .addKeepMainRule(MainWithTypeAndGeneric.class)
+ .addKeepClassAndMembersRules(TestClassWithTypeAndGenericAnnotations.class)
+ .applyIf(parameters.isDexRuntime(), b -> b.addDontWarn(AnnotatedType.class))
+ .compile()
+ .inspectWithOptions(
+ inspector -> {
+ ClassSubject notNullTestClass = inspector.clazz(NotNullTestClass.class);
+ assertThat(notNullTestClass, isPresent());
+ ClassSubject notNullTestRuntime = inspector.clazz(NotNullTestRuntime.class);
+ assertThat(notNullTestRuntime, isPresent());
+ ClassSubject clazz = inspector.clazz(TestClassWithTypeAndGenericAnnotations.class);
+ assertThat(clazz, isPresent());
+ assertTrue(
+ clazz.annotations().stream().noneMatch(FoundAnnotationSubject::isTypeAnnotation));
+ FieldSubject field = clazz.uniqueFieldWithOriginalName("field");
+ assertThat(field, isPresent());
+ assertEquals(0, field.annotations().size());
+ MethodSubject method = clazz.uniqueMethodWithOriginalName("method");
+ assertThat(method, isPresent());
+ // We create a dex annotation for the checked exception.
+ assertEquals(1, method.annotations().size());
+ },
+ options -> options.programConsumer = ClassFileConsumer.emptyConsumer())
+ .run(parameters.getRuntime(), MainWithTypeAndGeneric.class)
+ .assertFailureWithErrorThatThrowsIf(parameters.isDexRuntime(), NoSuchMethodError.class)
+ .assertSuccessWithOutputLinesIf(
+ parameters.isCfRuntime(), getExpected(typeName(NotNullTestRuntime.class)));
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/annotations/TypeUseAnnotationWithGenericsTest.java b/src/test/java/com/android/tools/r8/annotations/TypeUseAnnotationWithGenericsTest.java
new file mode 100644
index 0000000..307e052
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/annotations/TypeUseAnnotationWithGenericsTest.java
@@ -0,0 +1,239 @@
+// 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.annotations;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeTrue;
+
+import com.android.tools.r8.ClassFileConsumer;
+import com.android.tools.r8.R8FullTestBuilder;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ThrowableConsumer;
+import com.android.tools.r8.annotations.testclasses.MainWithTypeAndGeneric;
+import com.android.tools.r8.annotations.testclasses.NotNullTestClass;
+import com.android.tools.r8.annotations.testclasses.NotNullTestRuntime;
+import com.android.tools.r8.annotations.testclasses.SuperInterface;
+import com.android.tools.r8.annotations.testclasses.TestClassWithTypeAndGenericAnnotations;
+import com.android.tools.r8.references.ClassReference;
+import com.android.tools.r8.utils.Box;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.FieldSubject;
+import com.android.tools.r8.utils.codeinspector.FoundAnnotationSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import java.lang.reflect.AnnotatedType;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class TypeUseAnnotationWithGenericsTest extends TestBase {
+
+ @Parameter() public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().build();
+ }
+
+ @Test
+ public void testJvm() throws Exception {
+ assumeTrue(parameters.isCfRuntime());
+ testForJvm(parameters)
+ .addProgramClasses(
+ MainWithTypeAndGeneric.class,
+ NotNullTestClass.class,
+ NotNullTestRuntime.class,
+ TestClassWithTypeAndGenericAnnotations.class,
+ SuperInterface.class)
+ .run(parameters.getRuntime(), MainWithTypeAndGeneric.class)
+ .assertSuccessWithOutputLines(getExpected(typeName(NotNullTestRuntime.class)));
+ }
+
+ private String getExpected(String notNullTestRuntimeTypeName) {
+ return StringUtils.joinLines(
+ "printAnnotation - Class: " + notNullTestRuntimeTypeName,
+ "printAnnotation - Class: NULL",
+ "printAnnotation - Extends(0): " + notNullTestRuntimeTypeName,
+ "printAnnotation - Implements(0): " + notNullTestRuntimeTypeName,
+ "printAnnotation - Field: NULL",
+ "printAnnotation - Field: NULL",
+ "printAnnotation - Field(0): " + notNullTestRuntimeTypeName,
+ "printAnnotation - Method: NULL",
+ "printAnnotation - Method: NULL",
+ "printAnnotation - MethodReturnType(0): " + notNullTestRuntimeTypeName,
+ "printAnnotation - MethodParameter at 0(0): " + notNullTestRuntimeTypeName,
+ "printAnnotation - MethodParameter at 1(0): " + notNullTestRuntimeTypeName,
+ "printAnnotation - MethodException at 0(0): " + notNullTestRuntimeTypeName,
+ "printAnnotation - MethodException at 1(0): " + notNullTestRuntimeTypeName,
+ "Hello World!");
+ }
+
+ @Test
+ public void testD8() throws Exception {
+ assumeTrue(parameters.isDexRuntime());
+ testForD8(parameters.getBackend())
+ .addProgramClasses(
+ MainWithTypeAndGeneric.class,
+ NotNullTestClass.class,
+ NotNullTestRuntime.class,
+ TestClassWithTypeAndGenericAnnotations.class,
+ SuperInterface.class)
+ .setMinApi(parameters)
+ .run(parameters.getRuntime(), MainWithTypeAndGeneric.class)
+ .assertFailureWithErrorThatThrows(NoSuchMethodError.class);
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ setupR8Test(
+ builder ->
+ builder.addKeepClassRules(
+ NotNullTestClass.class, NotNullTestRuntime.class, SuperInterface.class));
+ }
+
+ @Test
+ public void testR8WithRenaming() throws Exception {
+ setupR8Test(
+ builder ->
+ builder.addKeepClassRulesWithAllowObfuscation(
+ NotNullTestClass.class, NotNullTestRuntime.class, SuperInterface.class));
+ }
+
+ private void setupR8Test(ThrowableConsumer<R8FullTestBuilder> modifier) throws Exception {
+ Box<String> finalNotNullTestRuntimeName = new Box<>();
+ testForR8(parameters.getBackend())
+ .addProgramClasses(
+ MainWithTypeAndGeneric.class,
+ NotNullTestClass.class,
+ NotNullTestRuntime.class,
+ TestClassWithTypeAndGenericAnnotations.class,
+ SuperInterface.class)
+ .setMinApi(parameters)
+ .apply(modifier)
+ .addKeepRuntimeVisibleAnnotations()
+ .addKeepRuntimeInvisibleAnnotations()
+ .addKeepRuntimeVisibleTypeAnnotations()
+ .addKeepRuntimeInvisibleTypeAnnotations()
+ .addKeepAttributeSignature()
+ .addKeepAttributeExceptions()
+ .addKeepMainRule(MainWithTypeAndGeneric.class)
+ .addKeepClassAndMembersRules(TestClassWithTypeAndGenericAnnotations.class)
+ .applyIf(parameters.isDexRuntime(), b -> b.addDontWarn(AnnotatedType.class))
+ .compile()
+ .inspectWithOptions(
+ inspector -> {
+ ClassSubject notNullTestClass = inspector.clazz(NotNullTestClass.class);
+ assertThat(notNullTestClass, isPresent());
+ ClassSubject notNullTestRuntime = inspector.clazz(NotNullTestRuntime.class);
+ assertThat(notNullTestRuntime, isPresent());
+ finalNotNullTestRuntimeName.set(notNullTestRuntime.getFinalName());
+ ClassSubject clazz = inspector.clazz(TestClassWithTypeAndGenericAnnotations.class);
+ assertThat(clazz, isPresent());
+ if (parameters.isDexRuntime()) {
+ inspectAnnotations(
+ clazz.annotations(),
+ notNullTestRuntime.getFinalReference(),
+ notNullTestClass.getFinalReference(),
+ 2,
+ 0,
+ 1,
+ 1);
+ } else {
+ inspectAnnotations(
+ clazz.annotations(),
+ notNullTestRuntime.getFinalReference(),
+ notNullTestClass.getFinalReference(),
+ 10,
+ 8,
+ 5,
+ 5);
+ }
+ FieldSubject field = clazz.uniqueFieldWithOriginalName("field");
+ assertThat(field, isPresent());
+ if (parameters.isDexRuntime()) {
+ inspectAnnotations(
+ field.annotations(),
+ notNullTestRuntime.getFinalReference(),
+ notNullTestClass.getFinalReference(),
+ 0,
+ 0,
+ 0,
+ 0);
+ } else {
+ inspectAnnotations(
+ field.annotations(),
+ notNullTestRuntime.getFinalReference(),
+ notNullTestClass.getFinalReference(),
+ 4,
+ 4,
+ 2,
+ 2);
+ }
+ MethodSubject method = clazz.uniqueMethodWithOriginalName("method");
+ assertThat(method, isPresent());
+ // We create a dex annotation for the checked exception.
+ if (parameters.isDexRuntime()) {
+ inspectAnnotations(
+ method.annotations(),
+ notNullTestRuntime.getFinalReference(),
+ notNullTestClass.getFinalReference(),
+ 1,
+ 0,
+ 0,
+ 0);
+ } else {
+ inspectAnnotations(
+ method.annotations(),
+ notNullTestRuntime.getFinalReference(),
+ notNullTestClass.getFinalReference(),
+ 17,
+ 16,
+ 8,
+ 8);
+ }
+ },
+ options -> options.programConsumer = ClassFileConsumer.emptyConsumer())
+ .run(parameters.getRuntime(), MainWithTypeAndGeneric.class)
+ .assertFailureWithErrorThatThrowsIf(parameters.isDexRuntime(), NoSuchMethodError.class)
+ .assertSuccessWithOutputLinesIf(
+ parameters.isCfRuntime(), getExpected(finalNotNullTestRuntimeName.get()));
+ }
+
+ private void inspectAnnotations(
+ List<FoundAnnotationSubject> annotations,
+ ClassReference notNullRuntime,
+ ClassReference notNullClass,
+ int expectedCount,
+ int expectedTypeAnnotationCount,
+ int expectedNotNullTestRuntimeCount,
+ int expectedNotNullTestClassCount) {
+ assertEquals(expectedCount, annotations.size());
+ assertEquals(
+ expectedTypeAnnotationCount,
+ annotations.stream().filter(FoundAnnotationSubject::isTypeAnnotation).count());
+ assertEquals(
+ expectedNotNullTestRuntimeCount,
+ annotations.stream()
+ .filter(
+ annotation ->
+ annotation.getAnnotation().type.asClassReference().equals(notNullRuntime))
+ .count());
+ assertEquals(
+ expectedNotNullTestClassCount,
+ annotations.stream()
+ .filter(
+ annotation ->
+ annotation.getAnnotation().type.asClassReference().equals(notNullClass))
+ .count());
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/annotations/testclasses/MainWithTypeAndGeneric.java b/src/test/java/com/android/tools/r8/annotations/testclasses/MainWithTypeAndGeneric.java
new file mode 100644
index 0000000..b1ac103
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/annotations/testclasses/MainWithTypeAndGeneric.java
@@ -0,0 +1,59 @@
+// 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.annotations.testclasses;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedType;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+
+public class MainWithTypeAndGeneric {
+
+ public static void main(String[] args) throws Exception {
+ Class<TestClassWithTypeAndGenericAnnotations> testClass =
+ TestClassWithTypeAndGenericAnnotations.class;
+ printAnnotation("Class", testClass.getAnnotation(NotNullTestRuntime.class));
+ printAnnotation("Class", testClass.getAnnotation(NotNullTestClass.class));
+ printAnnotatedType("Extends", testClass.getAnnotatedSuperclass());
+ for (AnnotatedType annotatedInterface : testClass.getAnnotatedInterfaces()) {
+ printAnnotatedType("Implements", annotatedInterface);
+ }
+ Field field = testClass.getDeclaredField("field");
+ printAnnotation("Field", field.getAnnotation(NotNullTestRuntime.class));
+ printAnnotation("Field", field.getAnnotation(NotNullTestClass.class));
+ printAnnotatedType("Field", field.getAnnotatedType());
+ Method method = testClass.getDeclaredMethod("method", int.class, List.class, Object.class);
+ printAnnotation("Method", method.getAnnotation(NotNullTestRuntime.class));
+ printAnnotation("Method", method.getAnnotation(NotNullTestClass.class));
+ printAnnotatedType("MethodReturnType", method.getAnnotatedReturnType());
+ for (Annotation[] parameterAnnotation : method.getParameterAnnotations()) {
+ for (Annotation annotation : parameterAnnotation) {
+ printAnnotation("MethodParameter", annotation);
+ }
+ }
+ for (int i = 0; i < method.getAnnotatedParameterTypes().length; i++) {
+ printAnnotatedType("MethodParameter at " + i, method.getAnnotatedParameterTypes()[i]);
+ }
+ for (int i = 0; i < method.getAnnotatedExceptionTypes().length; i++) {
+ printAnnotatedType("MethodException at " + i, method.getAnnotatedExceptionTypes()[i]);
+ }
+ System.out.println("Hello World!");
+ }
+
+ public static void printAnnotation(String name, Annotation annotation) {
+ System.out.println(
+ "printAnnotation - "
+ + name
+ + ": "
+ + (annotation == null ? "NULL" : annotation.annotationType().getName()));
+ }
+
+ public static void printAnnotatedType(String name, AnnotatedType annotatedType) {
+ for (int i = 0; i < annotatedType.getAnnotations().length; i++) {
+ printAnnotation(name + "(" + i + ")", annotatedType.getAnnotations()[i]);
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/annotations/testclasses/NotNullTestClass.java b/src/test/java/com/android/tools/r8/annotations/testclasses/NotNullTestClass.java
new file mode 100644
index 0000000..aa5a53d
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/annotations/testclasses/NotNullTestClass.java
@@ -0,0 +1,14 @@
+// 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.annotations.testclasses;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE_USE)
+@Retention(RetentionPolicy.CLASS)
+public @interface NotNullTestClass {}
diff --git a/src/test/java/com/android/tools/r8/annotations/testclasses/NotNullTestRuntime.java b/src/test/java/com/android/tools/r8/annotations/testclasses/NotNullTestRuntime.java
new file mode 100644
index 0000000..52c5ced
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/annotations/testclasses/NotNullTestRuntime.java
@@ -0,0 +1,14 @@
+// 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.annotations.testclasses;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE_USE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface NotNullTestRuntime {}
diff --git a/src/test/java/com/android/tools/r8/annotations/testclasses/SuperInterface.java b/src/test/java/com/android/tools/r8/annotations/testclasses/SuperInterface.java
new file mode 100644
index 0000000..61e6ae6
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/annotations/testclasses/SuperInterface.java
@@ -0,0 +1,7 @@
+// 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.annotations.testclasses;
+
+public interface SuperInterface<T> {}
diff --git a/src/test/java/com/android/tools/r8/annotations/testclasses/TestClassWithTypeAndGenericAnnotations.java b/src/test/java/com/android/tools/r8/annotations/testclasses/TestClassWithTypeAndGenericAnnotations.java
new file mode 100644
index 0000000..fe1853e
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/annotations/testclasses/TestClassWithTypeAndGenericAnnotations.java
@@ -0,0 +1,39 @@
+// 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.annotations.testclasses;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+@NotNullTestRuntime
+@NotNullTestClass
+public class TestClassWithTypeAndGenericAnnotations<@NotNullTestRuntime @NotNullTestClass T>
+ extends @NotNullTestRuntime @NotNullTestClass Object
+ implements @NotNullTestRuntime @NotNullTestClass SuperInterface<
+ @NotNullTestRuntime @NotNullTestClass T> {
+
+ @NotNullTestRuntime @NotNullTestClass
+ List<@NotNullTestRuntime @NotNullTestClass Object> field = null;
+
+ @NotNullTestRuntime
+ @NotNullTestClass
+ <@NotNullTestRuntime @NotNullTestClass S>
+ List<@NotNullTestRuntime @NotNullTestClass Object> method(
+ @NotNullTestRuntime @NotNullTestClass int foo,
+ @NotNullTestRuntime @NotNullTestClass
+ List<@NotNullTestRuntime @NotNullTestClass String> bar,
+ S s)
+ throws @NotNullTestClass @NotNullTestRuntime RuntimeException,
+ @NotNullTestClass @NotNullTestRuntime IOException {
+ @NotNullTestRuntime
+ @NotNullTestClass
+ Object local = System.currentTimeMillis() > 0 ? new Object() : foo;
+ ArrayList<@NotNullTestRuntime @NotNullTestClass Object> objects = new ArrayList<>();
+ objects.add(foo);
+ this.field = objects;
+ return objects;
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/classmerging/KeptTargetsIncompleteDiamondTest.java b/src/test/java/com/android/tools/r8/classmerging/KeptTargetsIncompleteDiamondTest.java
index 57aaddc..cc9170b 100644
--- a/src/test/java/com/android/tools/r8/classmerging/KeptTargetsIncompleteDiamondTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/KeptTargetsIncompleteDiamondTest.java
@@ -87,7 +87,7 @@
DexProgramClass classL = appView.definitionForProgramType(typeL);
DexProgramClass classA = appView.definitionForProgramType(typeA);
LookupResult lookupResult =
- resolutionResult.lookupVirtualDispatchTargets(classI, appView.appInfo(), classL, classA);
+ resolutionResult.lookupVirtualDispatchTargets(classI, appView, classL, classA);
assertTrue(lookupResult.isLookupResultSuccess());
LookupResultSuccess lookupResultSuccess = lookupResult.asLookupResultSuccess();
Set<String> targets = new HashSet<>();
@@ -128,7 +128,7 @@
DexProgramClass classI = appView.definitionForProgramType(typeI);
DexProgramClass classA = appView.definitionForProgramType(typeA);
LookupResult lookupResult =
- resolutionResult.lookupVirtualDispatchTargets(classI, appView.appInfo(), classI, classA);
+ resolutionResult.lookupVirtualDispatchTargets(classI, appView, classI, classA);
assertTrue(lookupResult.isLookupResultSuccess());
LookupResultSuccess lookupResultSuccess = lookupResult.asLookupResultSuccess();
Set<String> targets = new HashSet<>();
@@ -168,7 +168,7 @@
DexProgramClass classI = appView.definitionForProgramType(typeI);
DexProgramClass classA = appView.definitionForProgramType(typeB);
LookupResult lookupResult =
- resolutionResult.lookupVirtualDispatchTargets(classI, appView.appInfo(), classA, classA);
+ resolutionResult.lookupVirtualDispatchTargets(classI, appView, classA, classA);
assertTrue(lookupResult.isLookupResultSuccess());
LookupResultSuccess lookupResultSuccess = lookupResult.asLookupResultSuccess();
Set<String> targets = new HashSet<>();
@@ -206,7 +206,7 @@
DexProgramClass classI = appView.definitionForProgramType(typeI);
DexProgramClass classA = appView.definitionForProgramType(typeB);
LookupResult lookupResult =
- resolutionResult.lookupVirtualDispatchTargets(classI, appView.appInfo(), classA, classA);
+ resolutionResult.lookupVirtualDispatchTargets(classI, appView, classA, classA);
assertTrue(lookupResult.isLookupResultSuccess());
LookupResultSuccess lookupResultSuccess = lookupResult.asLookupResultSuccess();
Set<String> targets = new HashSet<>();
@@ -246,7 +246,7 @@
DexProgramClass classI = appView.definitionForProgramType(typeI);
DexProgramClass classA = appView.definitionForProgramType(typeB);
LookupResult lookupResult =
- resolutionResult.lookupVirtualDispatchTargets(classI, appView.appInfo(), classA, classA);
+ resolutionResult.lookupVirtualDispatchTargets(classI, appView, classA, classA);
assertTrue(lookupResult.isLookupResultSuccess());
LookupResultSuccess lookupResultSuccess = lookupResult.asLookupResultSuccess();
Set<String> targets = new HashSet<>();
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorWithEquivalenceStackTraceTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorWithEquivalenceStackTraceTest.java
index c39d3ef..655e6a8 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorWithEquivalenceStackTraceTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorWithEquivalenceStackTraceTest.java
@@ -60,7 +60,8 @@
// TODO(b/124483578): Stack trace lines from the merging of equivalent
// constructors should retrace to the set of lines from each of the
// individual source constructors.
- .map(1, stackTraceLine -> stackTraceLine.builderOf().setLineNumber(0).build())
+ .map(
+ 1, stackTraceLine -> stackTraceLine.builderOf().setLineNumber(-1).build())
.build();
assertThat(stackTrace, isSame(expectedStackTraceWithMergedConstructor));
assertThat(codeInspector.clazz(B.class), not(isPresent()));
diff --git a/src/test/java/com/android/tools/r8/classmerging/vertical/SyntheticBridgeSignaturesTest.java b/src/test/java/com/android/tools/r8/classmerging/vertical/SyntheticBridgeSignaturesTest.java
index b7bb268..e8d7572 100644
--- a/src/test/java/com/android/tools/r8/classmerging/vertical/SyntheticBridgeSignaturesTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/vertical/SyntheticBridgeSignaturesTest.java
@@ -13,12 +13,14 @@
import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.ir.optimize.Inliner.Reason;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.VerticallyMergedClassesInspector;
import com.google.common.collect.ImmutableSet;
import java.util.List;
+import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -47,6 +49,9 @@
@Test
public void test() throws Throwable {
+ Assume.assumeTrue(
+ "b/273921056",
+ parameters.isCfRuntime() || !parameters.getDexRuntimeVersion().isEqualTo(Version.V14_0_0));
R8TestCompileResult compileResult =
testForR8(parameters.getBackend())
.addInnerClasses(getClass())
diff --git a/src/test/java/com/android/tools/r8/classmerging/vertical/VerticalClassMergerDebugTestRunner.java b/src/test/java/com/android/tools/r8/classmerging/vertical/VerticalClassMergerDebugTestRunner.java
index 5177efb..5ed531b 100644
--- a/src/test/java/com/android/tools/r8/classmerging/vertical/VerticalClassMergerDebugTestRunner.java
+++ b/src/test/java/com/android/tools/r8/classmerging/vertical/VerticalClassMergerDebugTestRunner.java
@@ -10,10 +10,11 @@
import static org.hamcrest.MatcherAssert.assertThat;
import com.android.tools.r8.OutputMode;
+import com.android.tools.r8.TestRuntime;
import com.android.tools.r8.debug.DebugTestBase;
import com.android.tools.r8.debug.DebugTestBase.JUnit3Wrapper.Command;
import com.android.tools.r8.debug.DebugTestBase.JUnit3Wrapper.DebuggeeState;
-import com.android.tools.r8.debug.DexDebugTestConfig;
+import com.android.tools.r8.debug.DebugTestConfig;
import com.android.tools.r8.utils.AndroidApp;
import java.io.File;
import java.nio.file.Path;
@@ -31,11 +32,11 @@
this.temp = temp;
}
- public void run(AndroidApp app, Path proguardMapPath) throws Throwable {
+ public void run(TestRuntime runtime, AndroidApp app, Path proguardMapPath) throws Throwable {
Path appPath = File.createTempFile("app", ".zip", temp.getRoot()).toPath();
app.writeToZipForTesting(appPath, OutputMode.DexIndexed);
- DexDebugTestConfig config = new DexDebugTestConfig(appPath);
+ DebugTestConfig config = DebugTestConfig.create(runtime, appPath);
config.allowUnprocessedCommands();
config.setProguardMap(proguardMapPath);
diff --git a/src/test/java/com/android/tools/r8/classmerging/vertical/VerticalClassMergerTest.java b/src/test/java/com/android/tools/r8/classmerging/vertical/VerticalClassMergerTest.java
index d8b923b..22529e5 100644
--- a/src/test/java/com/android/tools/r8/classmerging/vertical/VerticalClassMergerTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/vertical/VerticalClassMergerTest.java
@@ -223,6 +223,9 @@
// This test has a cycle in the call graph consisting of the methods A.<init> and B.<init>.
@Test
public void testCallGraphCycle() throws Throwable {
+ Assume.assumeTrue(
+ "b/273921056",
+ parameters.isCfRuntime() || !parameters.getDexRuntimeVersion().isEqualTo(Version.V14_0_0));
String main = "classmerging.CallGraphCycleTest";
Path[] programFiles =
new Path[] {
@@ -316,6 +319,9 @@
@Test
public void testFieldCollision() throws Throwable {
+ Assume.assumeTrue(
+ "b/273921056",
+ parameters.isCfRuntime() || !parameters.getDexRuntimeVersion().isEqualTo(Version.V14_0_0));
String main = "classmerging.FieldCollisionTest";
Path[] programFiles =
new Path[] {
@@ -423,6 +429,9 @@
@Test
public void testPinnedParameterTypes() throws Throwable {
+ Assume.assumeTrue(
+ "b/273921056",
+ parameters.isCfRuntime() || !parameters.getDexRuntimeVersion().isEqualTo(Version.V14_0_0));
String main = "classmerging.PinnedParameterTypesTest";
Path[] programFiles =
new Path[] {
@@ -448,6 +457,9 @@
@Test
public void testPinnedArrayParameterTypes() throws Throwable {
+ Assume.assumeTrue(
+ "b/273921056",
+ parameters.isCfRuntime() || !parameters.getDexRuntimeVersion().isEqualTo(Version.V14_0_0));
String main = "classmerging.PinnedArrayParameterTypesTest";
Path[] programFiles =
new Path[] {
@@ -841,6 +853,9 @@
// }
@Test
public void testSuperCallToMergedClassIsRewritten() throws Throwable {
+ Assume.assumeTrue(
+ "b/273921056",
+ parameters.isCfRuntime() || !parameters.getDexRuntimeVersion().isEqualTo(Version.V14_0_0));
assumeTrue(parameters.isDexRuntime()); // Due to smali input.
assumeFalse(parameters.getRuntime().asDex().getVm().getVersion() == Version.V5_1_1);
assumeFalse(parameters.getRuntime().asDex().getVm().getVersion() == Version.V6_0_1);
@@ -1217,7 +1232,7 @@
// Check that we never come across a method that has a name with "$classmerging$" in it during
// debugging.
if (debugTestRunner != null && parameters.isDexRuntime()) {
- debugTestRunner.run(compileResult.app, proguardMapPath);
+ debugTestRunner.run(parameters.getRuntime(), compileResult.app, proguardMapPath);
}
return compileResult;
}
diff --git a/src/test/java/com/android/tools/r8/classmerging/vertical/VerticalClassMergerTestBase.java b/src/test/java/com/android/tools/r8/classmerging/vertical/VerticalClassMergerTestBase.java
index e512b2b..b631cc8 100644
--- a/src/test/java/com/android/tools/r8/classmerging/vertical/VerticalClassMergerTestBase.java
+++ b/src/test/java/com/android/tools/r8/classmerging/vertical/VerticalClassMergerTestBase.java
@@ -21,6 +21,6 @@
public void runDebugTest(Class<?> mainClass, R8TestCompileResult compileResult) throws Throwable {
assertTrue(parameters.isDexRuntime());
new VerticalClassMergerDebugTestRunner(mainClass.getTypeName(), temp)
- .run(compileResult.app, compileResult.writeProguardMap());
+ .run(parameters.getRuntime(), compileResult.app, compileResult.writeProguardMap());
}
}
diff --git a/src/test/java/com/android/tools/r8/debug/ContinuousSteppingTest.java b/src/test/java/com/android/tools/r8/debug/ContinuousSteppingTest.java
index 265bb19..6676e2c 100644
--- a/src/test/java/com/android/tools/r8/debug/ContinuousSteppingTest.java
+++ b/src/test/java/com/android/tools/r8/debug/ContinuousSteppingTest.java
@@ -36,6 +36,7 @@
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.stream.Collectors;
+import org.junit.Assume;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
@@ -142,6 +143,10 @@
public void testContinuousSingleStep() throws Throwable {
DebugTestConfig config = compiledJars.apply(jarPath);
assert config != null;
+ Assume.assumeTrue(
+ "b/273921056",
+ config.isCfRuntime()
+ || !config.getRuntime().asDex().getVersion().isEqualTo(Version.V14_0_0));
runContinuousTest(mainClass, config, MAIN_METHOD_NAME);
}
diff --git a/src/test/java/com/android/tools/r8/debug/LocalsTest.java b/src/test/java/com/android/tools/r8/debug/LocalsTest.java
index 35178f8..a2254be 100644
--- a/src/test/java/com/android/tools/r8/debug/LocalsTest.java
+++ b/src/test/java/com/android/tools/r8/debug/LocalsTest.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.debug;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.debug.DebugTestBase.JUnit3Wrapper.Command;
import com.android.tools.r8.debug.DebugTestBase.JUnit3Wrapper.FrameInspector;
import java.util.ArrayList;
@@ -14,6 +15,7 @@
import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants.Tag;
import org.apache.harmony.jpda.tests.framework.jdwp.Value;
import org.junit.Assert;
+import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -277,6 +279,10 @@
@Test
public void testLocals_MoreThan16() throws Throwable {
+ Assume.assumeTrue(
+ "b/273921056",
+ config.isCfRuntime()
+ || !config.getRuntime().asDex().getVersion().isEqualTo(Version.V14_0_0));
final int minIndex = 1;
final int maxIndex = 16;
Map<String, Value> arrayLocals = new HashMap<>();
diff --git a/src/test/java/com/android/tools/r8/debuginfo/InliningWithoutPositionsTestRunner.java b/src/test/java/com/android/tools/r8/debuginfo/InliningWithoutPositionsTestRunner.java
index c164fa7..ba0dba3 100644
--- a/src/test/java/com/android/tools/r8/debuginfo/InliningWithoutPositionsTestRunner.java
+++ b/src/test/java/com/android/tools/r8/debuginfo/InliningWithoutPositionsTestRunner.java
@@ -150,7 +150,7 @@
.setClassName(TEST_CLASS)
.setFileName(TEST_FILE)
.setMethodName(methodName)
- .setLineNumber(hasPosition ? location.line : 0)
+ .setLineNumber(hasPosition ? location.line : -1)
.build();
}
}
diff --git a/src/test/java/com/android/tools/r8/debuginfo/NoLineInfoTest.java b/src/test/java/com/android/tools/r8/debuginfo/NoLineInfoTest.java
index f0d4c89..3831e44 100644
--- a/src/test/java/com/android/tools/r8/debuginfo/NoLineInfoTest.java
+++ b/src/test/java/com/android/tools/r8/debuginfo/NoLineInfoTest.java
@@ -207,17 +207,16 @@
private StackTrace getUnexpectedRetracedStacktrace() {
assertFalse(parameters.isCfRuntime());
StackTraceLine fooLine;
- if (customSourceFile) {
- // TODO(b/232212653): Should retrace convert out of "0" and represent it as <noline>/-1?
- fooLine = inputLine("foo", 0);
- } else if (isRuntimeWithPcAsLineNumberSupport()) {
+ if (isRuntimeWithPcAsLineNumberSupport() && !customSourceFile) {
// TODO(b/232212653): Retrace should convert PC 1 to line <noline>/-1/0.
fooLine = inputLine("foo", 1);
} else {
fooLine = inputLine("foo", -1);
}
- StackTraceLine barLine = inputLine("bar", getPcEncoding(0));
- StackTraceLine bazLine = inputLine("baz", getPcEncoding(0));
+ int position =
+ isCompileWithPcAsLineNumberSupport() && !customSourceFile ? -1 : getPcEncoding(0);
+ StackTraceLine barLine = inputLine("bar", position);
+ StackTraceLine bazLine = inputLine("baz", position);
return StackTrace.builder()
.add(fooLine)
.add(barLine)
diff --git a/src/test/java/com/android/tools/r8/debuginfo/OverloadWithNoLineNumberTest.java b/src/test/java/com/android/tools/r8/debuginfo/OverloadWithNoLineNumberTest.java
index 3695c0e..d0a41c5 100644
--- a/src/test/java/com/android/tools/r8/debuginfo/OverloadWithNoLineNumberTest.java
+++ b/src/test/java/com/android/tools/r8/debuginfo/OverloadWithNoLineNumberTest.java
@@ -65,8 +65,8 @@
String className = typeName(SimpleCallChainClassWithOverloads.class);
assertEquals(
StringUtils.joinLines(
- "\tat " + className + ".void test(long)(" + SOURCE_FILE_NAME + ":0)",
- "\tat " + className + ".void test()(" + SOURCE_FILE_NAME + ":0)",
+ "\tat " + className + ".void test(long)(" + SOURCE_FILE_NAME + ")",
+ "\tat " + className + ".void test()(" + SOURCE_FILE_NAME + ")",
"\tat "
+ className
+ ".void main(java.lang.String[])("
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/MethodBackportTest.java b/src/test/java/com/android/tools/r8/desugar/backports/MethodBackportTest.java
new file mode 100644
index 0000000..78c2770
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/desugar/backports/MethodBackportTest.java
@@ -0,0 +1,39 @@
+// 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.desugar.backports;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public final class MethodBackportTest extends AbstractBackportTest {
+ @Parameters(name = "{0}")
+ public static Iterable<?> data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().build();
+ }
+
+ public MethodBackportTest(TestParameters parameters) {
+ super(parameters, String.class, Main.class);
+ registerTarget(AndroidApiLevel.O, 0);
+ }
+
+ static final class Main extends MiniAssert {
+ public static void main(String[] args) throws NoSuchMethodException {
+ assertEquals(0, Main.class.getMethod("empty").getParameterCount());
+ assertEquals(
+ 2, Main.class.getMethod("wideArgs", long.class, double.class).getParameterCount());
+ assertEquals(1, Main.class.getMethod("args", Object[].class).getParameterCount());
+ }
+
+ public static void empty() {}
+
+ public static void wideArgs(long l, double d) {}
+
+ public static void args(Object... o) {}
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/LintFilesTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/LintFilesTest.java
index 28e63fa..446b84e 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/LintFilesTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/LintFilesTest.java
@@ -96,6 +96,10 @@
minApiLevel == AndroidApiLevel.L,
supportsMethodButNotAllMethodsInClass(
"java/util/stream/DoubleStream#parallel()Ljava/util/stream/DoubleStream;"));
+ assertEquals(
+ minApiLevel == AndroidApiLevel.L,
+ supportsMethodButNotAllMethodsInClass(
+ "java/util/stream/BaseStream#parallel()Ljava/util/stream/BaseStream;"));
assertTrue(
supportsMethodButNotAllMethodsInClass(
"java/util/stream/DoubleStream#allMatch(Ljava/util/function/DoublePredicate;)Z"));
@@ -222,9 +226,10 @@
}
public static void main(String[] args) throws Exception {
- // Generate all html docs.
- Path folder = Paths.get("html");
- Files.createDirectories(folder);
+ // Generate all html docs and lint files.
+ Path top = Paths.get("generated");
+ Path html = top.resolve("html");
+ Files.createDirectories(html);
ImmutableList<LibraryDesugaringSpecification> specs =
ImmutableList.of(JDK8, JDK11_MINIMAL, JDK11, JDK11_PATH, JDK11_LEGACY);
for (LibraryDesugaringSpecification spec : specs) {
@@ -232,9 +237,13 @@
spec == JDK8
? ToolHelper.DESUGARED_JDK_8_LIB_JAR
: LibraryDesugaringSpecification.getTempLibraryJDK11Undesugar();
- new GenerateHtmlDoc(
- spec.getSpecification().toString(), jdkLibJar.toString(), folder.toString())
+ new GenerateHtmlDoc(spec.getSpecification().toString(), jdkLibJar.toString(), html.toString())
.run(spec + ".html");
+ Path lint = top.resolve("lint_" + spec);
+ Files.createDirectories(lint);
+ new GenerateLintFiles(
+ spec.getSpecification().toString(), jdkLibJar.toString(), lint.toString())
+ .run();
}
}
}
diff --git a/src/test/java/com/android/tools/r8/desugaring/interfacemethods/InterfaceMethodDesugaringTests.java b/src/test/java/com/android/tools/r8/desugaring/interfacemethods/InterfaceMethodDesugaringTests.java
index 9b23bd1..96b1358 100644
--- a/src/test/java/com/android/tools/r8/desugaring/interfacemethods/InterfaceMethodDesugaringTests.java
+++ b/src/test/java/com/android/tools/r8/desugaring/interfacemethods/InterfaceMethodDesugaringTests.java
@@ -138,7 +138,7 @@
}
@Test
- @IgnoreForRangeOfVmVersions(from = Version.V7_0_0, to = Version.V13_0_0) // No desugaring
+ @IgnoreForRangeOfVmVersions(from = Version.V7_0_0, to = Version.V14_0_0) // No desugaring
public void testInvokeDefault1() throws Exception {
ensureCustomCheck(
(javaResult, d8Result, r8Result, r8ShakenResult) -> {
diff --git a/src/test/java/com/android/tools/r8/graph/TargetLookupTest.java b/src/test/java/com/android/tools/r8/graph/TargetLookupTest.java
index ced7e4f..84a1bf3 100644
--- a/src/test/java/com/android/tools/r8/graph/TargetLookupTest.java
+++ b/src/test/java/com/android/tools/r8/graph/TargetLookupTest.java
@@ -92,7 +92,8 @@
);
AndroidApp application = buildApplication(builder);
- AppInfoWithClassHierarchy appInfo = computeAppInfoWithClassHierarchy(application);
+ AppView<AppInfoWithClassHierarchy> appView = computeAppViewWithClassHierarchy(application);
+ AppInfoWithClassHierarchy appInfo = appView.appInfo();
CodeInspector inspector = new CodeInspector(appInfo.app());
ProgramMethod method = getMethod(inspector, DEFAULT_CLASS_NAME, "int", "x", ImmutableList.of());
assertFalse(
@@ -100,8 +101,8 @@
.resolveMethodOnClassHolderLegacy(method.getReference())
.getSingleTarget()
.isVirtualMethod());
- assertNull(appInfo.lookupDirectTarget(method.getReference(), method));
- assertNotNull(appInfo.lookupStaticTarget(method.getReference(), method));
+ assertNull(appInfo.lookupDirectTarget(method.getReference(), method, appView));
+ assertNotNull(appInfo.lookupStaticTarget(method.getReference(), method, appView));
if (ToolHelper.getDexVm().getVersion().isOlderThanOrEqual(DexVm.Version.V4_4_4)) {
// Dalvik rejects at verification time instead of producing the
@@ -165,7 +166,8 @@
);
AndroidApp application = buildApplication(builder);
- AppInfoWithClassHierarchy appInfo = computeAppInfoWithClassHierarchy(application);
+ AppView<AppInfoWithClassHierarchy> appView = computeAppViewWithClassHierarchy(application);
+ AppInfoWithClassHierarchy appInfo = appView.appInfo();
CodeInspector inspector = new CodeInspector(appInfo.app());
ProgramMethod methodXOnTestSuper =
@@ -191,13 +193,14 @@
assertNull(
appInfo.resolveMethodOnClassLegacy(classTest, methodXOnTestReference).getSingleTarget());
- assertNull(appInfo.lookupDirectTarget(methodXOnTestSuper.getReference(), methodXOnTestSuper));
- assertNull(appInfo.lookupDirectTarget(methodXOnTestReference, methodYOnTest));
+ assertNull(
+ appInfo.lookupDirectTarget(methodXOnTestSuper.getReference(), methodXOnTestSuper, appView));
+ assertNull(appInfo.lookupDirectTarget(methodXOnTestReference, methodYOnTest, appView));
assertNotNull(
- appInfo.lookupStaticTarget(methodXOnTestSuper.getReference(), methodXOnTestSuper));
+ appInfo.lookupStaticTarget(methodXOnTestSuper.getReference(), methodXOnTestSuper, appView));
// Accessing a private target on a different type will fail resolution outright.
- assertNull(appInfo.lookupStaticTarget(methodXOnTestReference, methodYOnTest));
+ assertNull(appInfo.lookupStaticTarget(methodXOnTestReference, methodYOnTest, appView));
assertEquals("OK", runArt(application));
}
@@ -254,7 +257,8 @@
builder.addLibraryFiles(ToolHelper.getDefaultAndroidJar());
}
AndroidApp application = builder.build();
- AppInfoWithClassHierarchy appInfo = computeAppInfoWithClassHierarchy(application);
+ AppView<AppInfoWithClassHierarchy> appView = computeAppViewWithClassHierarchy(application);
+ AppInfoWithClassHierarchy appInfo = appView.appInfo();
DexItemFactory factory = appInfo.dexItemFactory();
DexType i0 = factory.createType("L" + pkg + "/I0;");
@@ -276,13 +280,13 @@
DexMethod mOnI3 = factory.createMethod(i3, mProto, m);
DexMethod mOnI4 = factory.createMethod(i4, mProto, m);
- assertEquals(mOnI0, appInfo.lookupSuperTarget(mOnC0, c1).getReference());
- assertEquals(mOnI1, appInfo.lookupSuperTarget(mOnI1, c1).getReference());
- assertEquals(mOnI2, appInfo.lookupSuperTarget(mOnI2, c1).getReference());
+ assertEquals(mOnI0, appInfo.lookupSuperTarget(mOnC0, c1, appView).getReference());
+ assertEquals(mOnI1, appInfo.lookupSuperTarget(mOnI1, c1, appView).getReference());
+ assertEquals(mOnI2, appInfo.lookupSuperTarget(mOnI2, c1, appView).getReference());
- assertNull(appInfo.lookupSuperTarget(mOnC1, c2)); // C2 is not a subclass of C1.
- assertEquals(mOnI1, appInfo.lookupSuperTarget(mOnI3, c2).getReference());
- assertEquals(mOnI2, appInfo.lookupSuperTarget(mOnI4, c2).getReference());
+ assertNull(appInfo.lookupSuperTarget(mOnC1, c2, appView)); // C2 is not a subclass of C1.
+ assertEquals(mOnI1, appInfo.lookupSuperTarget(mOnI3, c2, appView).getReference());
+ assertEquals(mOnI2, appInfo.lookupSuperTarget(mOnI4, c2, appView).getReference());
// Copy classes to run on the Java VM.
Path out = temp.newFolder().toPath();
diff --git a/src/test/java/com/android/tools/r8/internal/R8GMSCoreLookupTest.java b/src/test/java/com/android/tools/r8/internal/R8GMSCoreLookupTest.java
index b8078ae..440e8f8 100644
--- a/src/test/java/com/android/tools/r8/internal/R8GMSCoreLookupTest.java
+++ b/src/test/java/com/android/tools/r8/internal/R8GMSCoreLookupTest.java
@@ -81,7 +81,7 @@
AppInfoWithLiveness appInfo = null; // TODO(b/154881041): Remove or compute liveness.
LookupResult lookupResult =
resolutionResult.lookupVirtualDispatchTargets(
- clazz, appInfo(), appInfo, dexReference -> false);
+ clazz, appView, appInfo, dexReference -> false);
assertTrue(lookupResult.isLookupResultSuccess());
assertTrue(lookupResult.asLookupResultSuccess().contains(method));
}
@@ -99,7 +99,7 @@
LookupResultSuccess lookupResult =
appInfo()
.resolveMethodOnInterfaceLegacy(clazz, method.getReference())
- .lookupVirtualDispatchTargets(clazz, appInfo(), appInfo, dexReference -> false)
+ .lookupVirtualDispatchTargets(clazz, appView, appInfo, dexReference -> false)
.asLookupResultSuccess();
assertNotNull(lookupResult);
assertFalse(lookupResult.hasLambdaTargets());
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 037bb82..bd6303e 100644
--- a/src/test/java/com/android/tools/r8/ir/InlineTest.java
+++ b/src/test/java/com/android/tools/r8/ir/InlineTest.java
@@ -23,7 +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.profile.art.rewriting.ProfileCollectionAdditions;
import com.android.tools.r8.shaking.Enqueuer;
import com.android.tools.r8.shaking.EnqueuerFactory;
import com.android.tools.r8.shaking.EnqueuerResult;
@@ -74,21 +74,20 @@
throws ExecutionException {
AppView<AppInfoWithClassHierarchy> appView = AppView.createForR8(application.asDirect());
appView.setAppServices(AppServices.builder(appView).build());
- ArtProfileCollectionAdditions artProfileCollectionAdditions =
- ArtProfileCollectionAdditions.nop();
+ ProfileCollectionAdditions profileCollectionAdditions = ProfileCollectionAdditions.nop();
ExecutorService executorService = ThreadUtils.getExecutorService(options);
SubtypingInfo subtypingInfo = SubtypingInfo.create(appView);
appView.setRootSet(
RootSet.builder(
appView,
- artProfileCollectionAdditions,
+ profileCollectionAdditions,
subtypingInfo,
ImmutableList.of(ProguardKeepRule.defaultKeepAllRule(unused -> {})))
.build(executorService));
Timing timing = Timing.empty();
Enqueuer enqueuer =
EnqueuerFactory.createForInitialTreeShaking(
- appView, artProfileCollectionAdditions, executorService, subtypingInfo);
+ appView, profileCollectionAdditions, executorService, subtypingInfo);
EnqueuerResult enqueuerResult =
enqueuer.traceApplication(appView.rootSet(), executorService, timing);
appView.setAppInfo(enqueuerResult.getAppInfo());
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/backports/GenerateBackportMethods.java b/src/test/java/com/android/tools/r8/ir/desugar/backports/GenerateBackportMethods.java
index 429f2be..3a7cb1e 100644
--- a/src/test/java/com/android/tools/r8/ir/desugar/backports/GenerateBackportMethods.java
+++ b/src/test/java/com/android/tools/r8/ir/desugar/backports/GenerateBackportMethods.java
@@ -50,6 +50,7 @@
IntegerMethods.class,
LongMethods.class,
MathMethods.class,
+ MethodMethods.class,
ObjectsMethods.class,
OptionalMethods.class,
PredicateMethods.class,
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/backports/MethodMethods.java b/src/test/java/com/android/tools/r8/ir/desugar/backports/MethodMethods.java
new file mode 100644
index 0000000..0c03f1f6
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/desugar/backports/MethodMethods.java
@@ -0,0 +1,14 @@
+// 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.ir.desugar.backports;
+
+import java.lang.reflect.Method;
+
+public class MethodMethods {
+
+ public static int getParameterCount(Method method) {
+ return method.getParameterTypes().length;
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/resolution/InvokeSuperCallInStaticTest.java b/src/test/java/com/android/tools/r8/resolution/InvokeSuperCallInStaticTest.java
index 1b62946..028675a 100644
--- a/src/test/java/com/android/tools/r8/resolution/InvokeSuperCallInStaticTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/InvokeSuperCallInStaticTest.java
@@ -63,8 +63,7 @@
assertTrue(resolutionResult.isSingleResolution());
DexProgramClass context =
appView.definitionForProgramType(buildType(A.class, appInfo.dexItemFactory()));
- DexClassAndMethod lookedUpMethod =
- resolutionResult.lookupInvokeSuperTarget(context, appView.appInfo());
+ DexClassAndMethod lookedUpMethod = resolutionResult.lookupInvokeSuperTarget(context, appView);
assertNotNull(lookedUpMethod);
assertEquals(lookedUpMethod.getReference(), method);
}
diff --git a/src/test/java/com/android/tools/r8/resolution/SingleTargetLookupTest.java b/src/test/java/com/android/tools/r8/resolution/SingleTargetLookupTest.java
index 4c668d0..e010bfe 100644
--- a/src/test/java/com/android/tools/r8/resolution/SingleTargetLookupTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/SingleTargetLookupTest.java
@@ -215,7 +215,7 @@
LookupResult lookupResult =
resolutionResult.lookupVirtualDispatchTargets(
appView.definitionForProgramType(buildType(Main.class, appView.dexItemFactory())),
- appInfo);
+ appView);
assertTrue(lookupResult.isLookupResultSuccess());
assertFalse(lookupResult.asLookupResultSuccess().hasLambdaTargets());
Set<DexType> targetHolders = Sets.newIdentityHashSet();
diff --git a/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfPrivateStaticMethodTest.java b/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfPrivateStaticMethodTest.java
index 86a0415..a2bf03a 100644
--- a/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfPrivateStaticMethodTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfPrivateStaticMethodTest.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.MethodResolutionResult;
@@ -59,14 +60,15 @@
public static List<Class<?>> CLASSES =
ImmutableList.of(A.class, B.class, C.class, I.class, Main.class);
+ private static AppView<AppInfoWithLiveness> appView;
private static AppInfoWithLiveness appInfo;
@BeforeClass
public static void computeAppInfo() throws Exception {
- appInfo =
+ appView =
computeAppViewWithLiveness(
- buildClasses(CLASSES).addLibraryFile(getMostRecentAndroidJar()).build(), Main.class)
- .appInfo();
+ buildClasses(CLASSES).addLibraryFile(getMostRecentAndroidJar()).build(), Main.class);
+ appInfo = appView.appInfo();
}
private static DexMethod buildMethod(Class<?> clazz, String name) {
@@ -92,7 +94,7 @@
MethodResolutionResult resolutionResult =
appInfo.resolveMethodOnClassLegacy(methodOnB.holder, methodOnB);
DexClass context = appInfo.definitionFor(methodOnB.holder);
- assertTrue(resolutionResult.isIllegalAccessErrorResult(context, appInfo));
+ assertTrue(resolutionResult.isIllegalAccessErrorResult(context, appView));
}
@Test
diff --git a/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialInterfaceMethodAccessTest.java b/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialInterfaceMethodAccessTest.java
index 2c0e590..8a540f7 100644
--- a/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialInterfaceMethodAccessTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialInterfaceMethodAccessTest.java
@@ -132,11 +132,11 @@
assertEquals(
OptionalBool.of(inSameNest),
- resolutionResult.isAccessibleFrom(callerClassDefinition, appInfo));
+ resolutionResult.isAccessibleFrom(callerClassDefinition, appView));
DexClassAndMethod targetSpecial =
- resolutionResult.lookupInvokeSpecialTarget(callerClassDefinition, appInfo);
+ resolutionResult.lookupInvokeSpecialTarget(callerClassDefinition, appView);
DexClassAndMethod targetSuper =
- resolutionResult.lookupInvokeSuperTarget(callerClassDefinition, appInfo);
+ resolutionResult.lookupInvokeSuperTarget(callerClassDefinition, appView);
if (inSameNest) {
assertEquals(definingClassDefinition.getType(), targetSpecial.getHolderType());
assertEquals(targetSpecial.getReference(), targetSuper.getReference());
diff --git a/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodAccessTest.java b/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodAccessTest.java
index 61712f9..a165e20 100644
--- a/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodAccessTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodAccessTest.java
@@ -105,13 +105,13 @@
// Verify that the resolved method is accessible if in the same nest.
assertEquals(
OptionalBool.of(inSameNest),
- resolutionResult.isAccessibleFrom(callerClassDefinition, appInfo));
+ resolutionResult.isAccessibleFrom(callerClassDefinition, appView));
// Verify that looking up the dispatch target returns the defining method.
DexClassAndMethod targetSpecial =
- resolutionResult.lookupInvokeSpecialTarget(callerClassDefinition, appInfo);
+ resolutionResult.lookupInvokeSpecialTarget(callerClassDefinition, appView);
DexClassAndMethod targetSuper =
- resolutionResult.lookupInvokeSuperTarget(callerClassDefinition, appInfo);
+ resolutionResult.lookupInvokeSuperTarget(callerClassDefinition, appView);
if (inSameNest) {
assertEquals(definingClassDefinition.type, targetSpecial.getHolderType());
assertEquals(targetSpecial.getReference(), targetSuper.getReference());
diff --git a/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodAccessWithIntermediateTest.java b/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodAccessWithIntermediateTest.java
index 465b11e..5609ff3 100644
--- a/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodAccessWithIntermediateTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodAccessWithIntermediateTest.java
@@ -126,9 +126,11 @@
// Resolution fails when there is a mismatch between the symbolic reference and the definition.
if (!symbolicReferenceIsDefiningType) {
if (inSameNest) {
- assertTrue(resolutionResult.isNoSuchMethodErrorResult(callerClassDefinition, appInfo));
+ assertTrue(
+ resolutionResult.isNoSuchMethodErrorResult(callerClassDefinition, appView, appInfo));
} else {
- assertTrue(resolutionResult.isIllegalAccessErrorResult(callerClassDefinition, appInfo));
+ assertTrue(
+ resolutionResult.isIllegalAccessErrorResult(callerClassDefinition, appView, appInfo));
}
return;
}
@@ -140,14 +142,14 @@
// Verify that the resolved method is accessible only when in the same nest.
assertEquals(
OptionalBool.of(inSameNest),
- resolutionResult.isAccessibleFrom(callerClassDefinition, appInfo));
+ resolutionResult.isAccessibleFrom(callerClassDefinition, appView));
// Verify that looking up the dispatch target returns a valid target
// iff in the same nest and declaredHolder == definingHolder.
DexClassAndMethod targetSpecial =
- resolutionResult.lookupInvokeSpecialTarget(callerClassDefinition, appInfo);
+ resolutionResult.lookupInvokeSpecialTarget(callerClassDefinition, appView);
DexClassAndMethod targetSuper =
- resolutionResult.lookupInvokeSuperTarget(callerClassDefinition, appInfo);
+ resolutionResult.lookupInvokeSuperTarget(callerClassDefinition, appView);
if (inSameNest) {
assertEquals(definingClassDefinition.type, targetSpecial.getHolderType());
assertEquals(targetSpecial.getReference(), targetSuper.getReference());
diff --git a/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodPublicAccessWithIntermediateTest.java b/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodPublicAccessWithIntermediateTest.java
index 0a20eab..1a72976 100644
--- a/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodPublicAccessWithIntermediateTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodPublicAccessWithIntermediateTest.java
@@ -106,15 +106,15 @@
// Verify that the resolved method is accessible (it is public).
assertEquals(
- OptionalBool.TRUE, resolutionResult.isAccessibleFrom(callerClassDefinition, appInfo));
+ OptionalBool.TRUE, resolutionResult.isAccessibleFrom(callerClassDefinition, appView));
// Verify that looking up the dispatch target returns the defining method.
DexClassAndMethod targetSpecial =
- resolutionResult.lookupInvokeSpecialTarget(callerClassDefinition, appInfo);
+ resolutionResult.lookupInvokeSpecialTarget(callerClassDefinition, appView);
assertEquals(definingClassDefinition.type, targetSpecial.getHolderType());
DexClassAndMethod targetSuper =
- resolutionResult.lookupInvokeSuperTarget(callerClassDefinition, appInfo);
+ resolutionResult.lookupInvokeSuperTarget(callerClassDefinition, appView);
assertEquals(targetSpecial.getReference(), targetSuper.getReference());
}
diff --git a/src/test/java/com/android/tools/r8/resolution/access/NestStaticMethodAccessTest.java b/src/test/java/com/android/tools/r8/resolution/access/NestStaticMethodAccessTest.java
index 9216e56..d0b2806 100644
--- a/src/test/java/com/android/tools/r8/resolution/access/NestStaticMethodAccessTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/access/NestStaticMethodAccessTest.java
@@ -75,7 +75,7 @@
appInfo.definitionFor(buildType(B.class, appInfo.dexItemFactory())).asProgramClass();
DexMethod bar = buildMethod(A.class.getDeclaredMethod("bar"), appInfo.dexItemFactory());
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(bar);
- assertEquals(OptionalBool.of(inSameNest), resolutionResult.isAccessibleFrom(bClass, appInfo));
+ assertEquals(OptionalBool.of(inSameNest), resolutionResult.isAccessibleFrom(bClass, appView));
}
@Test
diff --git a/src/test/java/com/android/tools/r8/resolution/access/NestStaticMethodAccessWithIntermediateClassTest.java b/src/test/java/com/android/tools/r8/resolution/access/NestStaticMethodAccessWithIntermediateClassTest.java
index 235b3d1..3d09c38 100644
--- a/src/test/java/com/android/tools/r8/resolution/access/NestStaticMethodAccessWithIntermediateClassTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/access/NestStaticMethodAccessWithIntermediateClassTest.java
@@ -74,7 +74,7 @@
appInfo.definitionFor(buildType(B.class, appInfo.dexItemFactory())).asProgramClass();
DexMethod bar = buildMethod(A.class.getDeclaredMethod("bar"), appInfo.dexItemFactory());
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(bar);
- assertEquals(OptionalBool.of(inSameNest), resolutionResult.isAccessibleFrom(bClass, appInfo));
+ assertEquals(OptionalBool.of(inSameNest), resolutionResult.isAccessibleFrom(bClass, appView));
}
@Test
diff --git a/src/test/java/com/android/tools/r8/resolution/access/NestVirtualMethodAccessTest.java b/src/test/java/com/android/tools/r8/resolution/access/NestVirtualMethodAccessTest.java
index d86d67d..b2f74fb 100644
--- a/src/test/java/com/android/tools/r8/resolution/access/NestVirtualMethodAccessTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/access/NestVirtualMethodAccessTest.java
@@ -77,7 +77,7 @@
appInfo.definitionFor(buildType(B.class, appInfo.dexItemFactory())).asProgramClass();
DexMethod bar = buildMethod(A.class.getDeclaredMethod("bar"), appInfo.dexItemFactory());
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(bar);
- assertEquals(OptionalBool.of(inSameNest), resolutionResult.isAccessibleFrom(bClass, appInfo));
+ assertEquals(OptionalBool.of(inSameNest), resolutionResult.isAccessibleFrom(bClass, appView));
}
@Test
diff --git a/src/test/java/com/android/tools/r8/resolution/access/NestVirtualMethodAccessWithIntermediateClassTest.java b/src/test/java/com/android/tools/r8/resolution/access/NestVirtualMethodAccessWithIntermediateClassTest.java
index 6c3e040..96fe463 100644
--- a/src/test/java/com/android/tools/r8/resolution/access/NestVirtualMethodAccessWithIntermediateClassTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/access/NestVirtualMethodAccessWithIntermediateClassTest.java
@@ -73,7 +73,7 @@
appInfo.definitionFor(buildType(B.class, appInfo.dexItemFactory())).asProgramClass();
DexMethod bar = buildMethod(A.class.getDeclaredMethod("bar"), appInfo.dexItemFactory());
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(bar);
- assertEquals(OptionalBool.of(inSameNest), resolutionResult.isAccessibleFrom(bClass, appInfo));
+ assertEquals(OptionalBool.of(inSameNest), resolutionResult.isAccessibleFrom(bClass, appView));
}
@Test
diff --git a/src/test/java/com/android/tools/r8/resolution/access/SelfVirtualMethodAccessTest.java b/src/test/java/com/android/tools/r8/resolution/access/SelfVirtualMethodAccessTest.java
index aff8d60..d6f4618 100644
--- a/src/test/java/com/android/tools/r8/resolution/access/SelfVirtualMethodAccessTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/access/SelfVirtualMethodAccessTest.java
@@ -60,7 +60,7 @@
appInfo.definitionFor(buildType(A.class, appInfo.dexItemFactory())).asProgramClass();
DexMethod bar = buildMethod(A.class.getDeclaredMethod("bar"), appInfo.dexItemFactory());
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(bar);
- assertEquals(OptionalBool.TRUE, resolutionResult.isAccessibleFrom(aClass, appInfo));
+ assertEquals(OptionalBool.TRUE, resolutionResult.isAccessibleFrom(aClass, appView));
}
@Test
diff --git a/src/test/java/com/android/tools/r8/resolution/access/indirectfield/IndirectFieldAccessTest.java b/src/test/java/com/android/tools/r8/resolution/access/indirectfield/IndirectFieldAccessTest.java
index 99b02c3..f2b60f2 100644
--- a/src/test/java/com/android/tools/r8/resolution/access/indirectfield/IndirectFieldAccessTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/access/indirectfield/IndirectFieldAccessTest.java
@@ -67,7 +67,7 @@
appInfo.dexItemFactory());
FieldResolutionResult resolutionResult = appInfo.resolveField(f);
assertTrue(resolutionResult.isSingleFieldResolutionResult());
- assertEquals(OptionalBool.TRUE, resolutionResult.isAccessibleFrom(barMethod, appInfo));
+ assertEquals(OptionalBool.TRUE, resolutionResult.isAccessibleFrom(barMethod, appView));
}
@Test
diff --git a/src/test/java/com/android/tools/r8/resolution/access/indirectmethod/IndirectMethodAccessTest.java b/src/test/java/com/android/tools/r8/resolution/access/indirectmethod/IndirectMethodAccessTest.java
index 528b8aa..0599233 100644
--- a/src/test/java/com/android/tools/r8/resolution/access/indirectmethod/IndirectMethodAccessTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/access/indirectmethod/IndirectMethodAccessTest.java
@@ -67,7 +67,7 @@
DexMethod bar = buildMethod(B.class.getMethod("foo"), appInfo.dexItemFactory());
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(bar);
assertEquals(
- OptionalBool.TRUE, resolutionResult.isAccessibleForVirtualDispatchFrom(cClass, appInfo));
+ OptionalBool.TRUE, resolutionResult.isAccessibleForVirtualDispatchFrom(cClass, appView));
}
@Test
diff --git a/src/test/java/com/android/tools/r8/resolution/duplicatedefinitions/MaximallySpecificSingleLibraryPartialTest.java b/src/test/java/com/android/tools/r8/resolution/duplicatedefinitions/MaximallySpecificSingleLibraryPartialTest.java
index e2fd96f..0aac67a 100644
--- a/src/test/java/com/android/tools/r8/resolution/duplicatedefinitions/MaximallySpecificSingleLibraryPartialTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/duplicatedefinitions/MaximallySpecificSingleLibraryPartialTest.java
@@ -95,7 +95,7 @@
(resolution.getResolvedHolder().isProgramClass() ? "Program: " : "Library: ")
+ resolution.getResolvedMethod().getReference().toString());
} else {
- assertTrue(result.isNoSuchMethodErrorResult(mainClass, appInfo));
+ assertTrue(result.isNoSuchMethodErrorResult(mainClass, appView));
methodResults.add(typeName(NoSuchMethodError.class));
result
.asFailedResolution()
diff --git a/src/test/java/com/android/tools/r8/resolution/duplicatedefinitions/MaximallySpecificSingleProgramPartialTest.java b/src/test/java/com/android/tools/r8/resolution/duplicatedefinitions/MaximallySpecificSingleProgramPartialTest.java
index 3d22646..ca57c2f 100644
--- a/src/test/java/com/android/tools/r8/resolution/duplicatedefinitions/MaximallySpecificSingleProgramPartialTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/duplicatedefinitions/MaximallySpecificSingleProgramPartialTest.java
@@ -93,7 +93,7 @@
(resolution.getResolvedHolder().isProgramClass() ? "Program: " : "Library: ")
+ resolution.getResolvedMethod().getReference().toString());
} else {
- assertTrue(result.isNoSuchMethodErrorResult(mainClass, appInfo));
+ assertTrue(result.isNoSuchMethodErrorResult(mainClass, appView));
methodResults.add(typeName(NoSuchMethodError.class));
result
.asFailedResolution()
diff --git a/src/test/java/com/android/tools/r8/resolution/interfacetargets/DefaultMethodAsOverrideWithLambdaTest.java b/src/test/java/com/android/tools/r8/resolution/interfacetargets/DefaultMethodAsOverrideWithLambdaTest.java
index 200a3ad..91562c7 100644
--- a/src/test/java/com/android/tools/r8/resolution/interfacetargets/DefaultMethodAsOverrideWithLambdaTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/interfacetargets/DefaultMethodAsOverrideWithLambdaTest.java
@@ -67,7 +67,7 @@
appInfo.resolveMethodOnInterfaceLegacy(method.holder, method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Main.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
Set<String> targets = new HashSet<>();
lookupResult.forEach(
diff --git a/src/test/java/com/android/tools/r8/resolution/interfacetargets/DefaultMethodLambdaTest.java b/src/test/java/com/android/tools/r8/resolution/interfacetargets/DefaultMethodLambdaTest.java
index 3f9476e..cf0e5f4 100644
--- a/src/test/java/com/android/tools/r8/resolution/interfacetargets/DefaultMethodLambdaTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/interfacetargets/DefaultMethodLambdaTest.java
@@ -66,7 +66,7 @@
appInfo.resolveMethodOnInterfaceLegacy(method.holder, method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Main.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
Set<String> targets = new HashSet<>();
lookupResult.forEach(
diff --git a/src/test/java/com/android/tools/r8/resolution/interfacetargets/DefaultWithoutTopTest.java b/src/test/java/com/android/tools/r8/resolution/interfacetargets/DefaultWithoutTopTest.java
index 1579e3f..49ec9ea 100644
--- a/src/test/java/com/android/tools/r8/resolution/interfacetargets/DefaultWithoutTopTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/interfacetargets/DefaultWithoutTopTest.java
@@ -66,7 +66,7 @@
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnInterfaceHolderLegacy(method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Main.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
Set<String> targets = new HashSet<>();
lookupResult.forEach(
@@ -115,7 +115,7 @@
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnInterfaceHolderLegacy(method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Main.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
Set<String> targets = new HashSet<>();
lookupResult.forEach(
diff --git a/src/test/java/com/android/tools/r8/resolution/interfacetargets/DuplicateImportsTest.java b/src/test/java/com/android/tools/r8/resolution/interfacetargets/DuplicateImportsTest.java
index 56e1a51..62c0d0c 100644
--- a/src/test/java/com/android/tools/r8/resolution/interfacetargets/DuplicateImportsTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/interfacetargets/DuplicateImportsTest.java
@@ -66,7 +66,7 @@
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnInterfaceHolderLegacy(method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Main.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
Set<String> targets = new HashSet<>();
lookupResult.forEach(
diff --git a/src/test/java/com/android/tools/r8/resolution/interfacetargets/InvokeInterfaceWithStaticTargetTest.java b/src/test/java/com/android/tools/r8/resolution/interfacetargets/InvokeInterfaceWithStaticTargetTest.java
index 667b6c7..3c6d716 100644
--- a/src/test/java/com/android/tools/r8/resolution/interfacetargets/InvokeInterfaceWithStaticTargetTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/interfacetargets/InvokeInterfaceWithStaticTargetTest.java
@@ -57,7 +57,7 @@
() ->
appInfo
.resolveMethodOnInterfaceHolderLegacy(method)
- .lookupVirtualDispatchTargets(context, appInfo));
+ .lookupVirtualDispatchTargets(context, appView));
}
@Test
diff --git a/src/test/java/com/android/tools/r8/resolution/interfacetargets/LambdaMultipleInterfacesTest.java b/src/test/java/com/android/tools/r8/resolution/interfacetargets/LambdaMultipleInterfacesTest.java
index c01dc38..ba0ffb3 100644
--- a/src/test/java/com/android/tools/r8/resolution/interfacetargets/LambdaMultipleInterfacesTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/interfacetargets/LambdaMultipleInterfacesTest.java
@@ -66,7 +66,7 @@
appInfo.resolveMethodOnInterfaceLegacy(method.holder, method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Main.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
Set<String> targets = new HashSet<>();
lookupResult.forEach(
diff --git a/src/test/java/com/android/tools/r8/resolution/interfacetargets/MultipleImplementsTest.java b/src/test/java/com/android/tools/r8/resolution/interfacetargets/MultipleImplementsTest.java
index 5dad4b6..455c14d 100644
--- a/src/test/java/com/android/tools/r8/resolution/interfacetargets/MultipleImplementsTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/interfacetargets/MultipleImplementsTest.java
@@ -64,7 +64,7 @@
appInfo.resolveMethodOnInterfaceLegacy(method.holder, method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Main.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
Set<String> targets = new HashSet<>();
lookupResult.forEach(
diff --git a/src/test/java/com/android/tools/r8/resolution/interfacetargets/SimpleInterfaceInvokeTest.java b/src/test/java/com/android/tools/r8/resolution/interfacetargets/SimpleInterfaceInvokeTest.java
index fab0e87..75af94a 100644
--- a/src/test/java/com/android/tools/r8/resolution/interfacetargets/SimpleInterfaceInvokeTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/interfacetargets/SimpleInterfaceInvokeTest.java
@@ -64,7 +64,7 @@
appInfo.resolveMethodOnInterfaceLegacy(method.holder, method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Main.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
assertFalse(lookupResult.asLookupResultSuccess().hasLambdaTargets());
Set<String> targets = new HashSet<>();
diff --git a/src/test/java/com/android/tools/r8/resolution/interfacetargets/SubInterfaceOverridesTest.java b/src/test/java/com/android/tools/r8/resolution/interfacetargets/SubInterfaceOverridesTest.java
index 4fb6ea3..c2727e5 100644
--- a/src/test/java/com/android/tools/r8/resolution/interfacetargets/SubInterfaceOverridesTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/interfacetargets/SubInterfaceOverridesTest.java
@@ -66,7 +66,7 @@
appInfo.resolveMethodOnInterfaceLegacy(method.holder, method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Main.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
assertFalse(lookupResult.asLookupResultSuccess().hasLambdaTargets());
Set<String> targets = new HashSet<>();
diff --git a/src/test/java/com/android/tools/r8/resolution/interfacetargets/SubTypeMissingOverridesTest.java b/src/test/java/com/android/tools/r8/resolution/interfacetargets/SubTypeMissingOverridesTest.java
index 5563d1c..a0c812a 100644
--- a/src/test/java/com/android/tools/r8/resolution/interfacetargets/SubTypeMissingOverridesTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/interfacetargets/SubTypeMissingOverridesTest.java
@@ -63,7 +63,7 @@
appInfo.resolveMethodOnInterfaceLegacy(method.holder, method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Main.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
assertFalse(lookupResult.asLookupResultSuccess().hasLambdaTargets());
Set<String> targets = new HashSet<>();
diff --git a/src/test/java/com/android/tools/r8/resolution/interfacetargets/SubTypeOverridesTest.java b/src/test/java/com/android/tools/r8/resolution/interfacetargets/SubTypeOverridesTest.java
index edc31a9..b5d846d 100644
--- a/src/test/java/com/android/tools/r8/resolution/interfacetargets/SubTypeOverridesTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/interfacetargets/SubTypeOverridesTest.java
@@ -63,7 +63,7 @@
appInfo.resolveMethodOnInterfaceLegacy(method.holder, method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Main.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
assertFalse(lookupResult.asLookupResultSuccess().hasLambdaTargets());
Set<String> targets = new HashSet<>();
diff --git a/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateClasspathWidenTest.java b/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateClasspathWidenTest.java
index 8a36359..5da6e09 100644
--- a/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateClasspathWidenTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateClasspathWidenTest.java
@@ -77,7 +77,7 @@
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Abstract.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
Set<String> targets = new HashSet<>();
lookupResult.forEach(
diff --git a/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateInitialResolutionHolderTest.java b/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateInitialResolutionHolderTest.java
index ae99bf7..68bcc86 100644
--- a/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateInitialResolutionHolderTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateInitialResolutionHolderTest.java
@@ -66,7 +66,7 @@
appInfo.definitionForProgramType(
buildType(
Reference.classFromDescriptor(descriptor(Main.class)), appInfo.dexItemFactory()));
- assertEquals(OptionalBool.FALSE, resolutionResult.isAccessibleFrom(programClass, appInfo));
+ assertEquals(OptionalBool.FALSE, resolutionResult.isAccessibleFrom(programClass, appView));
DexType cType =
buildType(Reference.classFromDescriptor(newCDescriptor), appInfo.dexItemFactory());
DexProgramClass cClass = appView.definitionForProgramType(cType);
diff --git a/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateReentryTest.java b/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateReentryTest.java
index d6c548d..7513d4d 100644
--- a/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateReentryTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateReentryTest.java
@@ -62,7 +62,7 @@
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(method);
DexProgramClass context =
appView.definitionForProgramType(buildType(A.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
Set<String> targets = new HashSet<>();
lookupResult.forEach(
diff --git a/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateReentryWithNarrowingTest.java b/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateReentryWithNarrowingTest.java
index 7cbbb62..e4da615 100644
--- a/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateReentryWithNarrowingTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateReentryWithNarrowingTest.java
@@ -66,7 +66,7 @@
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(method);
DexProgramClass context =
appView.definitionForProgramType(buildType(A.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
Set<String> targets = new HashSet<>();
lookupResult.forEach(
diff --git a/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateWithDefaultMethod2Test.java b/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateWithDefaultMethod2Test.java
index 4bf6dc7..10e3530 100644
--- a/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateWithDefaultMethod2Test.java
+++ b/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateWithDefaultMethod2Test.java
@@ -76,7 +76,7 @@
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(method);
DexProgramClass context =
appView.definitionForProgramType(buildType(A.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
Set<String> targets = new HashSet<>();
lookupResult.forEach(
diff --git a/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateWithDefaultMethodTest.java b/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateWithDefaultMethodTest.java
index 9984687..ead6a82 100644
--- a/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateWithDefaultMethodTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateWithDefaultMethodTest.java
@@ -71,7 +71,7 @@
DexProgramClass context =
appView.definitionForProgramType(buildType(A.class, appInfo.dexItemFactory()));
assertTrue(resolutionResult.isAccessibleFrom(context, appView).isFalse());
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultFailure());
}
diff --git a/src/test/java/com/android/tools/r8/resolution/packageprivate/WidenAccessOutsidePackageTest.java b/src/test/java/com/android/tools/r8/resolution/packageprivate/WidenAccessOutsidePackageTest.java
index 8745ee1..21c346c 100644
--- a/src/test/java/com/android/tools/r8/resolution/packageprivate/WidenAccessOutsidePackageTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/packageprivate/WidenAccessOutsidePackageTest.java
@@ -63,7 +63,7 @@
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(method);
DexProgramClass context =
appView.definitionForProgramType(buildType(A.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertFalse(lookupResult.asLookupResultSuccess().hasLambdaTargets());
Set<String> targets = new HashSet<>();
lookupResult
diff --git a/src/test/java/com/android/tools/r8/resolution/singletarget/InstantiatedLowerBoundTest.java b/src/test/java/com/android/tools/r8/resolution/singletarget/InstantiatedLowerBoundTest.java
index 42733a1..788e55b 100644
--- a/src/test/java/com/android/tools/r8/resolution/singletarget/InstantiatedLowerBoundTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/singletarget/InstantiatedLowerBoundTest.java
@@ -136,7 +136,7 @@
DexProgramClass upperBound = appView.definitionForProgramType(typeA);
DexProgramClass lowerBound = appView.definitionForProgramType(typeC);
LookupResult lookupResult =
- resolution.lookupVirtualDispatchTargets(context, appInfo, upperBound, lowerBound);
+ resolution.lookupVirtualDispatchTargets(context, appView, upperBound, lowerBound);
Set<DexMethod> expected = Sets.newIdentityHashSet();
expected.add(fooA);
expected.add(fooB);
diff --git a/src/test/java/com/android/tools/r8/resolution/virtualtargets/AbstractInMiddleTest.java b/src/test/java/com/android/tools/r8/resolution/virtualtargets/AbstractInMiddleTest.java
index ac915f2..f9c5927 100644
--- a/src/test/java/com/android/tools/r8/resolution/virtualtargets/AbstractInMiddleTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/virtualtargets/AbstractInMiddleTest.java
@@ -62,7 +62,7 @@
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Main.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
Set<String> targets = new HashSet<>();
lookupResult.forEach(
diff --git a/src/test/java/com/android/tools/r8/resolution/virtualtargets/DefaultInterfaceMethodInSubInterfaceSubTypeTest.java b/src/test/java/com/android/tools/r8/resolution/virtualtargets/DefaultInterfaceMethodInSubInterfaceSubTypeTest.java
index efed293..a64145e 100644
--- a/src/test/java/com/android/tools/r8/resolution/virtualtargets/DefaultInterfaceMethodInSubInterfaceSubTypeTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/virtualtargets/DefaultInterfaceMethodInSubInterfaceSubTypeTest.java
@@ -65,7 +65,7 @@
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Main.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
Set<String> targets = new HashSet<>();
lookupResult.forEach(
diff --git a/src/test/java/com/android/tools/r8/resolution/virtualtargets/DefaultInterfaceMethodInSubInterfaceTest.java b/src/test/java/com/android/tools/r8/resolution/virtualtargets/DefaultInterfaceMethodInSubInterfaceTest.java
index bfe1d1b..c227f79 100644
--- a/src/test/java/com/android/tools/r8/resolution/virtualtargets/DefaultInterfaceMethodInSubInterfaceTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/virtualtargets/DefaultInterfaceMethodInSubInterfaceTest.java
@@ -65,7 +65,7 @@
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Main.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
Set<String> targets = new HashSet<>();
lookupResult.forEach(
diff --git a/src/test/java/com/android/tools/r8/resolution/virtualtargets/DefaultWithoutTopTest.java b/src/test/java/com/android/tools/r8/resolution/virtualtargets/DefaultWithoutTopTest.java
index 57b31a1..d9f121b 100644
--- a/src/test/java/com/android/tools/r8/resolution/virtualtargets/DefaultWithoutTopTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/virtualtargets/DefaultWithoutTopTest.java
@@ -66,7 +66,7 @@
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Main.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
Set<String> targets = new HashSet<>();
lookupResult.forEach(
diff --git a/src/test/java/com/android/tools/r8/resolution/virtualtargets/InvokeVirtualToInterfaceDefinitionTest.java b/src/test/java/com/android/tools/r8/resolution/virtualtargets/InvokeVirtualToInterfaceDefinitionTest.java
index 64e046a..edb66c9 100644
--- a/src/test/java/com/android/tools/r8/resolution/virtualtargets/InvokeVirtualToInterfaceDefinitionTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/virtualtargets/InvokeVirtualToInterfaceDefinitionTest.java
@@ -65,7 +65,7 @@
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Main.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
Set<String> targets = new HashSet<>();
lookupResult.forEach(
diff --git a/src/test/java/com/android/tools/r8/resolution/virtualtargets/KeptTargetsIncompleteLookupTest.java b/src/test/java/com/android/tools/r8/resolution/virtualtargets/KeptTargetsIncompleteLookupTest.java
index a96b487..d2dae9b 100644
--- a/src/test/java/com/android/tools/r8/resolution/virtualtargets/KeptTargetsIncompleteLookupTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/virtualtargets/KeptTargetsIncompleteLookupTest.java
@@ -94,7 +94,7 @@
.appInfo()
.definitionForWithoutExistenceAssert(
buildType(Unrelated.class, appInfo.dexItemFactory())));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
LookupResultSuccess lookupResultSuccess = lookupResult.asLookupResultSuccess();
Set<String> targets = new HashSet<>();
@@ -245,7 +245,7 @@
LookupResult lookupResult =
resolutionResult.lookupVirtualDispatchTargets(
classB,
- appInfo,
+ appView,
(type, subTypeConsumer, callSiteConsumer) -> {
if (type == typeB) {
subTypeConsumer.accept(classB);
@@ -276,7 +276,7 @@
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Unrelated.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
LookupResultSuccess lookupResultSuccess = lookupResult.asLookupResultSuccess();
Set<String> targets = new HashSet<>();
diff --git a/src/test/java/com/android/tools/r8/resolution/virtualtargets/PackagePrivateChainTest.java b/src/test/java/com/android/tools/r8/resolution/virtualtargets/PackagePrivateChainTest.java
index e1dad43..e1b4be1 100644
--- a/src/test/java/com/android/tools/r8/resolution/virtualtargets/PackagePrivateChainTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/virtualtargets/PackagePrivateChainTest.java
@@ -65,7 +65,7 @@
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(method);
DexProgramClass context =
appView.definitionForProgramType(buildType(TopRunner.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
Set<String> targets = new HashSet<>();
lookupResult.forEach(
diff --git a/src/test/java/com/android/tools/r8/resolution/virtualtargets/PackagePrivateFinalOverrideTest.java b/src/test/java/com/android/tools/r8/resolution/virtualtargets/PackagePrivateFinalOverrideTest.java
index ad30339..4b5f8d2 100644
--- a/src/test/java/com/android/tools/r8/resolution/virtualtargets/PackagePrivateFinalOverrideTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/virtualtargets/PackagePrivateFinalOverrideTest.java
@@ -72,7 +72,7 @@
DexProgramClass context =
appView.definitionForProgramType(
buildType(ViewModelRunner.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
Set<String> targets = new HashSet<>();
lookupResult.forEach(
@@ -122,7 +122,7 @@
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Main.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultFailure());
}
@@ -175,7 +175,7 @@
DexProgramClass context =
appView.definitionForProgramType(
buildType(ViewModelRunnerWithCast.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
Set<String> targets = new HashSet<>();
lookupResult.forEach(
diff --git a/src/test/java/com/android/tools/r8/resolution/virtualtargets/PrivateOverrideOfVirtualTargetTest.java b/src/test/java/com/android/tools/r8/resolution/virtualtargets/PrivateOverrideOfVirtualTargetTest.java
index 536e845..a076a58 100644
--- a/src/test/java/com/android/tools/r8/resolution/virtualtargets/PrivateOverrideOfVirtualTargetTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/virtualtargets/PrivateOverrideOfVirtualTargetTest.java
@@ -64,7 +64,7 @@
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(method);
DexProgramClass context =
appView.definitionForProgramType(buildType(B.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
Set<String> targets = new HashSet<>();
lookupResult.forEach(
diff --git a/src/test/java/com/android/tools/r8/resolution/virtualtargets/ProtectedDifferentPackageLookupTest.java b/src/test/java/com/android/tools/r8/resolution/virtualtargets/ProtectedDifferentPackageLookupTest.java
index f7bff16..4ec5810 100644
--- a/src/test/java/com/android/tools/r8/resolution/virtualtargets/ProtectedDifferentPackageLookupTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/virtualtargets/ProtectedDifferentPackageLookupTest.java
@@ -57,7 +57,7 @@
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Main.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
// TODO(b/173363527): Should be an error.
assertTrue(lookupResult.isLookupResultSuccess());
}
diff --git a/src/test/java/com/android/tools/r8/resolution/virtualtargets/ProtectedSamePackageLookupTest.java b/src/test/java/com/android/tools/r8/resolution/virtualtargets/ProtectedSamePackageLookupTest.java
index fcfd723..cc72a23 100644
--- a/src/test/java/com/android/tools/r8/resolution/virtualtargets/ProtectedSamePackageLookupTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/virtualtargets/ProtectedSamePackageLookupTest.java
@@ -53,7 +53,7 @@
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnClassHolderLegacy(method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Main.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
}
diff --git a/src/test/java/com/android/tools/r8/resolution/virtualtargets/TargetInDefaultMethodTest.java b/src/test/java/com/android/tools/r8/resolution/virtualtargets/TargetInDefaultMethodTest.java
index 56fa675..8aef8bb 100644
--- a/src/test/java/com/android/tools/r8/resolution/virtualtargets/TargetInDefaultMethodTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/virtualtargets/TargetInDefaultMethodTest.java
@@ -66,7 +66,7 @@
MethodResolutionResult resolutionResult = appInfo.resolveMethodOnInterfaceHolderLegacy(method);
DexProgramClass context =
appView.definitionForProgramType(buildType(Main.class, appInfo.dexItemFactory()));
- LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appInfo);
+ LookupResult lookupResult = resolutionResult.lookupVirtualDispatchTargets(context, appView);
assertTrue(lookupResult.isLookupResultSuccess());
assertFalse(lookupResult.asLookupResultSuccess().hasLambdaTargets());
Set<String> targets = new HashSet<>();
diff --git a/src/test/java/com/android/tools/r8/retrace/OverloadsWithoutLineNumberTest.java b/src/test/java/com/android/tools/r8/retrace/OverloadsWithoutLineNumberTest.java
index cbe2680..b1c1b96 100644
--- a/src/test/java/com/android/tools/r8/retrace/OverloadsWithoutLineNumberTest.java
+++ b/src/test/java/com/android/tools/r8/retrace/OverloadsWithoutLineNumberTest.java
@@ -66,7 +66,7 @@
assertEquals(
"\tat "
+ typeName(ClassWithOverload.class)
- + ".void test(int)(OverloadsWithoutLineNumberTest.java:0)",
+ + ".void test(int)(OverloadsWithoutLineNumberTest.java)",
box.get().get(1));
}
diff --git a/src/test/java/com/android/tools/r8/retrace/StackTraceWithPcAndNoLineTableTestRunner.java b/src/test/java/com/android/tools/r8/retrace/StackTraceWithPcAndNoLineTableTestRunner.java
index a89c8a4..8258c8b 100644
--- a/src/test/java/com/android/tools/r8/retrace/StackTraceWithPcAndNoLineTableTestRunner.java
+++ b/src/test/java/com/android/tools/r8/retrace/StackTraceWithPcAndNoLineTableTestRunner.java
@@ -88,8 +88,7 @@
b -> b.setLineNumber(10),
b -> {
if (parameters.isDexRuntime()) {
- // TODO(b/255705077): Should not have position 0.
- b.setLineNumber(0);
+ b.setLineNumber(-1);
}
})
.build())
@@ -103,8 +102,7 @@
b -> b.setLineNumber(15),
b -> {
if (parameters.isDexRuntime()) {
- // TODO(b/255705077): Should not have position 0.
- b.setLineNumber(0);
+ b.setLineNumber(-1);
}
})
.build())
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineFileNameStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineFileNameStackTrace.java
index 048b941..b8243aa 100644
--- a/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineFileNameStackTrace.java
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineFileNameStackTrace.java
@@ -21,7 +21,7 @@
public List<String> retracedStackTrace() {
return Arrays.asList(
"Exception in thread \"main\" java.lang.NullPointerException",
- "\tat foo.Bar$Baz.baz(Bar.java:0)",
+ "\tat foo.Bar$Baz.baz(Bar.java)",
"\tat Foo$Bar.bar(Foo.java:2)",
"\tat com.android.tools.r8.naming.retrace.Main$Foo.method1(Main.java:8)",
"\tat com.android.tools.r8.naming.retrace.Main.main(Main.java:7)");
@@ -31,7 +31,7 @@
public List<String> retraceVerboseStackTrace() {
return Arrays.asList(
"Exception in thread \"main\" java.lang.NullPointerException",
- "\tat foo.Bar$Baz.void baz(long)(Bar.java:0)",
+ "\tat foo.Bar$Baz.void baz(long)(Bar.java)",
"\tat Foo$Bar.void bar(int)(Foo.java:2)",
"\tat com.android.tools.r8.naming.retrace.Main$Foo"
+ ".void method1(java.lang.String)(Main.java:8)",
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineFileNameWithInnerClassesStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineFileNameWithInnerClassesStackTrace.java
index 177eb8a..1c53b40 100644
--- a/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineFileNameWithInnerClassesStackTrace.java
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineFileNameWithInnerClassesStackTrace.java
@@ -21,7 +21,7 @@
public List<String> retracedStackTrace() {
return Arrays.asList(
"Exception in thread \"main\" java.lang.NullPointerException",
- "\tat foo.Bar$Baz$Qux.baz(Bar.java:0)",
+ "\tat foo.Bar$Baz$Qux.baz(Bar.java)",
"\tat com.android.tools.r8.naming.retrace.Main.main(Main.java:7)");
}
@@ -29,7 +29,7 @@
public List<String> retraceVerboseStackTrace() {
return Arrays.asList(
"Exception in thread \"main\" java.lang.NullPointerException",
- "\tat foo.Bar$Baz$Qux.void baz(long)(Bar.java:0)",
+ "\tat foo.Bar$Baz$Qux.void baz(long)(Bar.java)",
"\tat com.android.tools.r8.naming.retrace.Main.void main(java.lang.String[])(Main.java:7)");
}
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineNoLineNumberStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineNoLineNumberStackTrace.java
index 763ec80..28e94c5 100644
--- a/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineNoLineNumberStackTrace.java
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineNoLineNumberStackTrace.java
@@ -21,20 +21,20 @@
public List<String> retracedStackTrace() {
return Arrays.asList(
"Exception in thread \"main\" java.lang.NullPointerException",
- "\tat com.android.tools.r8.naming.retrace.Main.method3(Main.java:0)",
- "\tat com.android.tools.r8.naming.retrace.Main.method2(Main.java:0)",
- "\tat com.android.tools.r8.naming.retrace.Main.method1(Main.java:0)",
- "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java:0)");
+ "\tat com.android.tools.r8.naming.retrace.Main.method3(Main.java)",
+ "\tat com.android.tools.r8.naming.retrace.Main.method2(Main.java)",
+ "\tat com.android.tools.r8.naming.retrace.Main.method1(Main.java)",
+ "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java)");
}
@Override
public List<String> retraceVerboseStackTrace() {
return Arrays.asList(
"Exception in thread \"main\" java.lang.NullPointerException",
- "\tat com.android.tools.r8.naming.retrace.Main.void method3(long)(Main.java:0)",
- "\tat com.android.tools.r8.naming.retrace.Main.void method2(int)(Main.java:0)",
- "\tat com.android.tools.r8.naming.retrace.Main.void method1(java.lang.String)(Main.java:0)",
- "\tat com.android.tools.r8.naming.retrace.Main.void main(java.lang.String[])(Main.java:0)");
+ "\tat com.android.tools.r8.naming.retrace.Main.void method3(long)(Main.java)",
+ "\tat com.android.tools.r8.naming.retrace.Main.void method2(int)(Main.java)",
+ "\tat com.android.tools.r8.naming.retrace.Main.void method1(java.lang.String)(Main.java)",
+ "\tat com.android.tools.r8.naming.retrace.Main.void main(java.lang.String[])(Main.java)");
}
@Override
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/NoObfuscationRangeMappingWithStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/NoObfuscationRangeMappingWithStackTrace.java
index 8ec36a8..67a0d43 100644
--- a/src/test/java/com/android/tools/r8/retrace/stacktraces/NoObfuscationRangeMappingWithStackTrace.java
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/NoObfuscationRangeMappingWithStackTrace.java
@@ -26,8 +26,8 @@
"Exception in thread \"main\" java.lang.NullPointerException",
"\tat com.android.tools.r8.naming.retrace.Main.foo(Main.java:1)",
"\tat com.android.tools.r8.naming.retrace.Main.bar(Main.java:3)",
- "\tat com.android.tools.r8.naming.retrace.Main.baz(Main.java:0)",
- "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java:0)");
+ "\tat com.android.tools.r8.naming.retrace.Main.baz(Main.java)",
+ "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java)");
}
@Override
@@ -36,8 +36,8 @@
"Exception in thread \"main\" java.lang.NullPointerException",
"\tat com.android.tools.r8.naming.retrace.Main.void foo(long)(Main.java:1)",
"\tat com.android.tools.r8.naming.retrace.Main.void bar(int)(Main.java:3)",
- "\tat com.android.tools.r8.naming.retrace.Main.void baz()(Main.java:0)",
- "\tat com.android.tools.r8.naming.retrace.Main.void main(java.lang.String[])(Main.java:0)");
+ "\tat com.android.tools.r8.naming.retrace.Main.void baz()(Main.java)",
+ "\tat com.android.tools.r8.naming.retrace.Main.void main(java.lang.String[])(Main.java)");
}
@Override
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/PreambleLineNumberStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/PreambleLineNumberStackTrace.java
index 98a6ed6..bbd72bd 100644
--- a/src/test/java/com/android/tools/r8/retrace/stacktraces/PreambleLineNumberStackTrace.java
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/PreambleLineNumberStackTrace.java
@@ -33,7 +33,7 @@
return Arrays.asList(
"Exception in thread \"main\" java.lang.NullPointerException",
" at kotlin.ResultKt.createFailure(Result.kt)",
- " at kotlin.ResultKt.createFailure(Result.kt:0)",
+ " at kotlin.ResultKt.createFailure(Result.kt)",
" at kotlin.ResultKt.createFailure(Result.kt:122)",
" at kotlin.ResultKt.createFailure(Result.kt:124)");
}
@@ -43,7 +43,7 @@
return Arrays.asList(
"Exception in thread \"main\" java.lang.NullPointerException",
" at kotlin.ResultKt.void createFailure(java.lang.Throwable)(Result.kt)",
- " at kotlin.ResultKt.void createFailure(java.lang.Throwable)(Result.kt:0)",
+ " at kotlin.ResultKt.void createFailure(java.lang.Throwable)(Result.kt)",
" at kotlin.ResultKt.void createFailure(java.lang.Throwable)(Result.kt:122)",
" at kotlin.ResultKt.void createFailure(java.lang.Throwable)(Result.kt:124)");
}
diff --git a/src/test/java/com/android/tools/r8/shaking/ForwardingConstructorShakingOnDexTest.java b/src/test/java/com/android/tools/r8/shaking/constructor/ForwardingConstructorShakingOnDexTest.java
similarity index 96%
rename from src/test/java/com/android/tools/r8/shaking/ForwardingConstructorShakingOnDexTest.java
rename to src/test/java/com/android/tools/r8/shaking/constructor/ForwardingConstructorShakingOnDexTest.java
index 34fe591..96e9e92 100644
--- a/src/test/java/com/android/tools/r8/shaking/ForwardingConstructorShakingOnDexTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/constructor/ForwardingConstructorShakingOnDexTest.java
@@ -1,8 +1,8 @@
-// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// 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.shaking;
+package com.android.tools.r8.shaking.constructor;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;
diff --git a/src/test/java/com/android/tools/r8/shaking/ForwardingConstructorShakingOnDexWithClassMergingTest.java b/src/test/java/com/android/tools/r8/shaking/constructor/ForwardingConstructorShakingOnDexWithClassMergingTest.java
similarity index 97%
rename from src/test/java/com/android/tools/r8/shaking/ForwardingConstructorShakingOnDexWithClassMergingTest.java
rename to src/test/java/com/android/tools/r8/shaking/constructor/ForwardingConstructorShakingOnDexWithClassMergingTest.java
index 587abff..fddfa66 100644
--- a/src/test/java/com/android/tools/r8/shaking/ForwardingConstructorShakingOnDexWithClassMergingTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/constructor/ForwardingConstructorShakingOnDexWithClassMergingTest.java
@@ -1,8 +1,8 @@
-// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// 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.shaking;
+package com.android.tools.r8.shaking.constructor;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;
diff --git a/src/test/java/com/android/tools/r8/shaking/constructor/ForwardingConstructorUsedFromPlatformShakingOnDexTest.java b/src/test/java/com/android/tools/r8/shaking/constructor/ForwardingConstructorUsedFromPlatformShakingOnDexTest.java
new file mode 100644
index 0000000..534bbb9
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/shaking/constructor/ForwardingConstructorUsedFromPlatformShakingOnDexTest.java
@@ -0,0 +1,75 @@
+// 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.shaking.constructor;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.NeverClassInline;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class ForwardingConstructorUsedFromPlatformShakingOnDexTest extends TestBase {
+
+ @Parameter(0)
+ public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().build();
+ }
+
+ @Test
+ public void test() throws Exception {
+ testForR8(parameters.getBackend())
+ .addProgramClasses(Main.class, MyFragment.class)
+ .addLibraryClasses(Fragment.class)
+ .addLibraryFiles(parameters.getDefaultRuntimeLibrary())
+ .addKeepMainRule(Main.class)
+ .enableNeverClassInliningAnnotations()
+ .setMinApi(parameters)
+ .compile()
+ .inspect(this::inspect)
+ .addBootClasspathClasses(Fragment.class)
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines("Instantiating");
+ }
+
+ private void inspect(CodeInspector inspector) {
+ ClassSubject myFragmentClassSubject = inspector.clazz(MyFragment.class);
+ assertThat(myFragmentClassSubject, isPresent());
+ assertThat(myFragmentClassSubject.init(), isPresent());
+ }
+
+ public abstract static class Fragment {
+
+ public Fragment newInstance() throws Exception {
+ System.out.println("Instantiating");
+ return getClass().getDeclaredConstructor().newInstance();
+ }
+ }
+
+ public static class Main {
+
+ public static void main(String[] args) throws Exception {
+ new MyFragment().newInstance();
+ }
+ }
+
+ @NeverClassInline
+ public static class MyFragment extends Fragment {
+
+ public MyFragment() {}
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/startup/MinimalStartupDexTest.java b/src/test/java/com/android/tools/r8/startup/MinimalStartupDexTest.java
index fa1dd30..53c02be 100644
--- a/src/test/java/com/android/tools/r8/startup/MinimalStartupDexTest.java
+++ b/src/test/java/com/android/tools/r8/startup/MinimalStartupDexTest.java
@@ -12,7 +12,6 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.profile.art.ArtProfileBuilderUtils.SyntheticToSyntheticContextGeneralization;
import com.android.tools.r8.startup.profile.ExternalStartupItem;
import com.android.tools.r8.startup.utils.StartupTestingUtils;
import com.android.tools.r8.utils.AndroidApiLevel;
@@ -55,9 +54,7 @@
.compile()
.addRunClasspathFiles(StartupTestingUtils.getAndroidUtilLog(temp))
.run(parameters.getRuntime(), Main.class)
- .apply(
- StartupTestingUtils.removeStartupListFromStdout(
- startupList::add, SyntheticToSyntheticContextGeneralization.createForR8()))
+ .apply(StartupTestingUtils.removeStartupListFromStdout(startupList::add))
.assertSuccessWithOutputLines(getExpectedOutput());
testForR8(parameters.getBackend())
diff --git a/src/test/java/com/android/tools/r8/startup/StartupInstrumentationTest.java b/src/test/java/com/android/tools/r8/startup/StartupInstrumentationTest.java
index 8399d05..d53257c 100644
--- a/src/test/java/com/android/tools/r8/startup/StartupInstrumentationTest.java
+++ b/src/test/java/com/android/tools/r8/startup/StartupInstrumentationTest.java
@@ -9,7 +9,6 @@
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.profile.art.ArtProfileBuilderUtils.SyntheticToSyntheticContextGeneralization;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.startup.profile.ExternalStartupClass;
import com.android.tools.r8.startup.profile.ExternalStartupItem;
@@ -50,8 +49,6 @@
public void test() throws Exception {
Path out = temp.newFolder().toPath().resolve("out.txt").toAbsolutePath();
Set<ExternalStartupItem> startupList = new LinkedHashSet<>();
- SyntheticToSyntheticContextGeneralization syntheticGeneralization =
- SyntheticToSyntheticContextGeneralization.createForD8();
testForD8(parameters.getBackend())
.addInnerClasses(getClass())
.applyIf(
@@ -68,11 +65,8 @@
.run(parameters.getRuntime(), Main.class, Boolean.toString(logcat), out.toString())
.applyIf(
logcat,
- StartupTestingUtils.removeStartupListFromStdout(
- startupList::add, syntheticGeneralization),
- runResult ->
- StartupTestingUtils.readStartupListFromFile(
- out, startupList::add, syntheticGeneralization))
+ StartupTestingUtils.removeStartupListFromStdout(startupList::add),
+ runResult -> StartupTestingUtils.readStartupListFromFile(out, startupList::add))
.assertSuccessWithOutputLines(getExpectedOutput());
assertEquals(getExpectedStartupList(), startupList);
}
diff --git a/src/test/java/com/android/tools/r8/startup/StartupSyntheticPlacementTest.java b/src/test/java/com/android/tools/r8/startup/StartupSyntheticPlacementTest.java
index 742361e..92d3129 100644
--- a/src/test/java/com/android/tools/r8/startup/StartupSyntheticPlacementTest.java
+++ b/src/test/java/com/android/tools/r8/startup/StartupSyntheticPlacementTest.java
@@ -14,23 +14,23 @@
import com.android.tools.r8.D8TestCompileResult;
import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestCompileResult;
import com.android.tools.r8.TestCompilerBuilder;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.ir.desugar.LambdaClass;
-import com.android.tools.r8.profile.art.ArtProfileBuilderUtils.SyntheticToSyntheticContextGeneralization;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.startup.profile.ExternalStartupClass;
import com.android.tools.r8.startup.profile.ExternalStartupItem;
import com.android.tools.r8.startup.profile.ExternalStartupMethod;
-import com.android.tools.r8.startup.profile.ExternalSyntheticStartupMethod;
import com.android.tools.r8.startup.utils.MixedSectionLayoutInspector;
import com.android.tools.r8.startup.utils.StartupTestingUtils;
import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.MethodReferenceUtils;
+import com.android.tools.r8.utils.TypeReferenceUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
@@ -38,6 +38,7 @@
import com.google.common.collect.ImmutableSet;
import java.nio.file.Path;
import java.util.Collection;
+import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -51,6 +52,11 @@
@RunWith(Parameterized.class)
public class StartupSyntheticPlacementTest extends TestBase {
+ private enum Compiler {
+ D8,
+ R8
+ }
+
@Parameter(0)
public TestParameters parameters;
@@ -103,9 +109,7 @@
.compile()
.addRunClasspathFiles(StartupTestingUtils.getAndroidUtilLog(temp))
.run(parameters.getRuntime(), Main.class, Boolean.toString(useLambda))
- .apply(
- StartupTestingUtils.removeStartupListFromStdout(
- startupList::add, SyntheticToSyntheticContextGeneralization.createForD8()))
+ .apply(StartupTestingUtils.removeStartupListFromStdout(startupList::add))
.assertSuccessWithOutputLines(getExpectedOutput())
.apply(
runResult ->
@@ -123,6 +127,7 @@
.compile()
.inspectMultiDex(
r8CompileResult.writeProguardMap(), this::inspectPrimaryDex, this::inspectSecondaryDex)
+ .apply(this::checkCompleteness)
.run(parameters.getRuntime(), Main.class, Boolean.toString(useLambda))
.assertSuccessWithOutputLines(getExpectedOutput());
}
@@ -144,9 +149,7 @@
instrumentationCompileResult
.addRunClasspathFiles(StartupTestingUtils.getAndroidUtilLog(temp))
.run(parameters.getRuntime(), Main.class, Boolean.toString(useLambda))
- .apply(
- StartupTestingUtils.removeStartupListFromStdout(
- startupList::add, SyntheticToSyntheticContextGeneralization.createForR8()))
+ .apply(StartupTestingUtils.removeStartupListFromStdout(startupList::add))
.assertSuccessWithOutputLines(getExpectedOutput())
.apply(
runResult ->
@@ -164,11 +167,17 @@
.setMinApi(parameters)
.compile()
.inspectMultiDex(this::inspectPrimaryDex, this::inspectSecondaryDex)
+ .apply(this::checkCompleteness)
.run(parameters.getRuntime(), Main.class, Boolean.toString(useLambda))
- .applyIf(
- enableStartupCompletenessCheck && useLambda,
- runResult -> runResult.assertFailureWithErrorThatThrows(NullPointerException.class),
- runResult -> runResult.assertSuccessWithOutputLines(getExpectedOutput()));
+ .assertSuccessWithOutputLines(getExpectedOutput());
+ }
+
+ private void checkCompleteness(TestCompileResult<?, ?> compileResult) throws Exception {
+ if (enableStartupCompletenessCheck && !useLambda) {
+ compileResult
+ .run(parameters.getRuntime(), Main.class, "true")
+ .assertFailureWithErrorThatThrows(NullPointerException.class);
+ }
}
private void configureStartupOptions(
@@ -185,7 +194,7 @@
options
.getTestingOptions()
.setMixedSectionLayoutStrategyInspector(
- getMixedSectionLayoutInspector(inspector));
+ getMixedSectionLayoutInspector(inspector, testBuilder.isD8TestBuilder()));
})
.apply(ignore -> StartupTestingUtils.setStartupConfiguration(testBuilder, startupList));
}
@@ -215,10 +224,34 @@
Reference.methodFromMethod(B.class.getDeclaredMethod("b", boolean.class)))
.build());
if (useLambda) {
+ builder.add(
+ ExternalStartupMethod.builder()
+ .setMethodReference(
+ Reference.methodFromMethod(B.class.getDeclaredMethod("synthesize")))
+ .build());
if (isStartupListForOriginalApp) {
+ ClassReference syntheticLambdaClassReference = getSyntheticLambdaClassReference();
builder.add(
- ExternalSyntheticStartupMethod.builder()
- .setSyntheticContextReference(Reference.classFromClass(B.class))
+ ExternalStartupClass.builder().setClassReference(syntheticLambdaClassReference).build(),
+ ExternalStartupMethod.builder()
+ .setMethodReference(
+ MethodReferenceUtils.instanceConstructor(syntheticLambdaClassReference))
+ .build(),
+ ExternalStartupMethod.builder()
+ .setMethodReference(
+ Reference.method(
+ syntheticLambdaClassReference,
+ "accept",
+ Collections.singletonList(Reference.classFromClass(Object.class)),
+ TypeReferenceUtils.getVoidType()))
+ .build(),
+ ExternalStartupMethod.builder()
+ .setMethodReference(
+ Reference.method(
+ Reference.classFromClass(B.class),
+ "lambda$synthesize$0",
+ Collections.singletonList(Reference.classFromClass(Object.class)),
+ TypeReferenceUtils.getVoidType()))
.build());
} else {
ClassSubject bClassSubject = inspector.clazz(B.class);
@@ -266,7 +299,8 @@
builder.add(
ExternalStartupMethod.builder()
.setMethodReference(
- Reference.methodFromMethod(B.class.getDeclaredMethod("lambda$b$0", Object.class)))
+ Reference.methodFromMethod(
+ B.class.getDeclaredMethod("lambda$synthesize$0", Object.class)))
.build());
}
builder.add(
@@ -278,7 +312,7 @@
}
private List<ClassReference> getExpectedClassDataLayout(
- CodeInspector inspector, int virtualFile) {
+ CodeInspector inspector, boolean isD8, int virtualFile) {
ClassSubject syntheticLambdaClassSubject = inspector.clazz(getSyntheticLambdaClassReference());
// The synthetic lambda should only be placed alongside its synthetic context (B) if it is used.
@@ -289,10 +323,17 @@
Reference.classFromClass(Main.class),
Reference.classFromClass(A.class),
Reference.classFromClass(B.class));
- if (useLambda) {
- layoutBuilder.add(syntheticLambdaClassSubject.getFinalReference());
+ if (isD8) {
+ if (useLambda) {
+ layoutBuilder.add(syntheticLambdaClassSubject.getFinalReference());
+ }
+ layoutBuilder.add(Reference.classFromClass(C.class));
+ } else {
+ layoutBuilder.add(Reference.classFromClass(C.class));
+ if (useLambda) {
+ layoutBuilder.add(syntheticLambdaClassSubject.getFinalReference());
+ }
}
- layoutBuilder.add(Reference.classFromClass(C.class));
}
if (!useLambda) {
if (!enableMinimalStartupDex || virtualFile == 1) {
@@ -302,12 +343,14 @@
return layoutBuilder.build();
}
- private MixedSectionLayoutInspector getMixedSectionLayoutInspector(CodeInspector inspector) {
+ private MixedSectionLayoutInspector getMixedSectionLayoutInspector(
+ CodeInspector inspector, boolean isD8) {
return new MixedSectionLayoutInspector() {
@Override
public void inspectClassDataLayout(int virtualFile, Collection<DexProgramClass> layout) {
assertThat(
- layout, isEqualToClassDataLayout(getExpectedClassDataLayout(inspector, virtualFile)));
+ layout,
+ isEqualToClassDataLayout(getExpectedClassDataLayout(inspector, isD8, virtualFile)));
}
};
}
@@ -357,11 +400,15 @@
static void b(boolean useLambda) {
String message = System.currentTimeMillis() > 0 ? "B" : null;
if (useLambda) {
- Consumer<Object> consumer = obj -> {};
- consumer.accept(consumer);
+ synthesize();
}
System.out.println(message);
}
+
+ static void synthesize() {
+ Consumer<Object> consumer = obj -> {};
+ consumer.accept(consumer);
+ }
}
static class C {
diff --git a/src/test/java/com/android/tools/r8/startup/StartupSyntheticWithoutContextTest.java b/src/test/java/com/android/tools/r8/startup/StartupSyntheticWithoutContextTest.java
index 815b50d..14a1e1b 100644
--- a/src/test/java/com/android/tools/r8/startup/StartupSyntheticWithoutContextTest.java
+++ b/src/test/java/com/android/tools/r8/startup/StartupSyntheticWithoutContextTest.java
@@ -15,23 +15,23 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.profile.art.ArtProfileBuilderUtils.SyntheticToSyntheticContextGeneralization;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.startup.profile.ExternalStartupClass;
import com.android.tools.r8.startup.profile.ExternalStartupItem;
import com.android.tools.r8.startup.profile.ExternalStartupMethod;
-import com.android.tools.r8.startup.profile.ExternalSyntheticStartupMethod;
import com.android.tools.r8.startup.utils.MixedSectionLayoutInspector;
import com.android.tools.r8.startup.utils.StartupTestingUtils;
import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.MethodReferenceUtils;
+import com.android.tools.r8.utils.TypeReferenceUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.util.Collection;
+import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -63,7 +63,7 @@
}
@Test
- public void test() throws Exception {
+ public void testR8() throws Exception {
LinkedHashSet<ExternalStartupItem> startupList = new LinkedHashSet<>();
testForD8(parameters.getBackend())
.addInnerClasses(getClass())
@@ -74,9 +74,7 @@
.compile()
.addRunClasspathFiles(StartupTestingUtils.getAndroidUtilLog(temp))
.run(parameters.getRuntime(), Main.class)
- .apply(
- StartupTestingUtils.removeStartupListFromStdout(
- startupList::add, SyntheticToSyntheticContextGeneralization.createForR8()))
+ .apply(StartupTestingUtils.removeStartupListFromStdout(startupList::add))
.assertSuccessWithOutputLines(getExpectedOutput());
assertEquals(getExpectedStartupList(), startupList);
@@ -122,8 +120,20 @@
ExternalStartupMethod.builder()
.setMethodReference(Reference.methodFromMethod(B.class.getDeclaredMethod("b")))
.build(),
- ExternalSyntheticStartupMethod.builder()
- .setSyntheticContextReference(Reference.classFromClass(B.class))
+ ExternalStartupClass.builder()
+ .setClassReference(getSyntheticLambdaClassReference(B.class))
+ .build(),
+ ExternalStartupMethod.builder()
+ .setMethodReference(
+ MethodReferenceUtils.instanceConstructor(getSyntheticLambdaClassReference(B.class)))
+ .build(),
+ ExternalStartupMethod.builder()
+ .setMethodReference(
+ Reference.method(
+ getSyntheticLambdaClassReference(B.class),
+ "run",
+ Collections.emptyList(),
+ TypeReferenceUtils.getVoidType()))
.build(),
ExternalStartupMethod.builder()
.setMethodReference(Reference.methodFromMethod(B.class.getDeclaredMethod("lambda$b$0")))
@@ -140,8 +150,8 @@
builder.add(
Reference.classFromClass(Main.class),
Reference.classFromClass(A.class),
- getSyntheticLambdaClassReference(B.class),
- Reference.classFromClass(C.class));
+ Reference.classFromClass(C.class),
+ getSyntheticLambdaClassReference(B.class));
}
if (!enableMinimalStartupDex || virtualFile == 1) {
builder.add(getSyntheticLambdaClassReference(Main.class));
@@ -186,13 +196,15 @@
public static void main(String[] args) {
A.a();
- Runnable r = System.currentTimeMillis() > 0 ? B.b() : Main::error;
+ Runnable r = System.currentTimeMillis() > 0 ? B.b() : error();
r.run();
C.c();
}
- static void error() {
- throw new RuntimeException();
+ static Runnable error() {
+ return () -> {
+ throw new RuntimeException();
+ };
}
}
@@ -203,6 +215,8 @@
}
}
+ // Class B will be pruned as a result of inlining, yet the synthetic derived from B.b() remains in
+ // the startup list.
static class B {
static Runnable b() {
diff --git a/src/test/java/com/android/tools/r8/startup/diagnostic/MissingStartupProfileItemsDiagnosticTest.java b/src/test/java/com/android/tools/r8/startup/diagnostic/MissingStartupProfileItemsDiagnosticTest.java
index d9ed155..5cf70dd 100644
--- a/src/test/java/com/android/tools/r8/startup/diagnostic/MissingStartupProfileItemsDiagnosticTest.java
+++ b/src/test/java/com/android/tools/r8/startup/diagnostic/MissingStartupProfileItemsDiagnosticTest.java
@@ -9,6 +9,7 @@
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.equalTo;
+import com.android.tools.r8.D8TestCompileResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestDiagnosticMessages;
import com.android.tools.r8.TestParameters;
@@ -42,8 +43,16 @@
@Test
public void testD8() throws Exception {
+ // In D8 the startup profile is used to relayout an existing apk. Therefore, we first compile
+ // the program to dex, and then relayout the dex using D8 with a startup profile.
+ D8TestCompileResult compileResult =
+ testForD8(Backend.DEX)
+ .addProgramClasses(Main.class)
+ .release()
+ .setMinApi(AndroidApiLevel.LATEST)
+ .compile();
testForD8(Backend.DEX)
- .addProgramClasses(Main.class)
+ .addProgramFiles(compileResult.writeToZip())
.addStartupProfileProviders(getStartupProfileProviders())
.release()
.setMinApi(AndroidApiLevel.LATEST)
@@ -52,13 +61,15 @@
@Test
public void testR8() throws Exception {
+ // In R8 we expect a startup profile that matches the input app. Since profiles gathered from
+ // running on ART will include synthetics, and these synthetics are not in the input app, we do
+ // not raise warnings if some rules in the profile do not match anything.
testForR8(Backend.DEX)
.addProgramClasses(Main.class)
.addKeepMainRule(Main.class)
.addStartupProfileProviders(getStartupProfileProviders())
- .allowDiagnosticWarningMessages()
.setMinApi(AndroidApiLevel.LATEST)
- .compileWithExpectedDiagnostics(this::inspectDiagnostics);
+ .compileWithExpectedDiagnostics(TestDiagnosticMessages::assertNoMessages);
}
private static Collection<StartupProfileProvider> getStartupProfileProviders() {
@@ -68,7 +79,6 @@
public void getStartupProfile(StartupProfileBuilder startupProfileBuilder) {
ClassReference fooClassReference = Reference.classFromTypeName("Foo");
ClassReference barClassReference = Reference.classFromTypeName("Bar");
- ClassReference bazClassReference = Reference.classFromTypeName("Baz");
ClassReference jDollarClassReference = Reference.classFromTypeName("j$.Foo");
startupProfileBuilder
.addStartupClass(
@@ -77,10 +87,6 @@
startupMethodBuilder ->
startupMethodBuilder.setMethodReference(
MethodReferenceUtils.mainMethod(barClassReference)))
- .addSyntheticStartupMethod(
- syntheticStartupMethodBuilder ->
- syntheticStartupMethodBuilder.setSyntheticContextReference(
- bazClassReference))
.addStartupClass(
startupClassBuilder ->
startupClassBuilder.setClassReference(jDollarClassReference));
@@ -102,7 +108,6 @@
equalTo(
StringUtils.joinLines(
"Startup method not found: void Bar.main(java.lang.String[])",
- "Startup class not found: Baz",
"Startup class not found: Foo")))));
}
diff --git a/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupClass.java b/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupClass.java
index 4eee018..1bcbb45 100644
--- a/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupClass.java
+++ b/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupClass.java
@@ -23,8 +23,7 @@
@Override
public <T> T apply(
Function<ExternalStartupClass, T> classFunction,
- Function<ExternalStartupMethod, T> methodFunction,
- Function<ExternalSyntheticStartupMethod, T> syntheticMethodFunction) {
+ Function<ExternalStartupMethod, T> methodFunction) {
return classFunction.apply(this);
}
diff --git a/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupItem.java b/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupItem.java
index e3aa745..6009d74 100644
--- a/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupItem.java
+++ b/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupItem.java
@@ -10,6 +10,5 @@
public abstract <T> T apply(
Function<ExternalStartupClass, T> classFunction,
- Function<ExternalStartupMethod, T> methodFunction,
- Function<ExternalSyntheticStartupMethod, T> syntheticMethodFunction);
+ Function<ExternalStartupMethod, T> methodFunction);
}
diff --git a/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupMethod.java b/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupMethod.java
index 109a028..55775ea 100644
--- a/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupMethod.java
+++ b/src/test/java/com/android/tools/r8/startup/profile/ExternalStartupMethod.java
@@ -24,8 +24,7 @@
@Override
public <T> T apply(
Function<ExternalStartupClass, T> classFunction,
- Function<ExternalStartupMethod, T> methodFunction,
- Function<ExternalSyntheticStartupMethod, T> syntheticMethodFunction) {
+ Function<ExternalStartupMethod, T> methodFunction) {
return methodFunction.apply(this);
}
diff --git a/src/test/java/com/android/tools/r8/startup/profile/ExternalSyntheticStartupMethod.java b/src/test/java/com/android/tools/r8/startup/profile/ExternalSyntheticStartupMethod.java
deleted file mode 100644
index 6d07638..0000000
--- a/src/test/java/com/android/tools/r8/startup/profile/ExternalSyntheticStartupMethod.java
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2022, 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.startup.profile;
-
-import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.startup.SyntheticStartupMethodBuilder;
-import java.util.function.Function;
-
-public class ExternalSyntheticStartupMethod extends ExternalStartupItem {
-
- private final ClassReference syntheticContextReference;
-
- ExternalSyntheticStartupMethod(ClassReference syntheticContextReference) {
- this.syntheticContextReference = syntheticContextReference;
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- @Override
- public <T> T apply(
- Function<ExternalStartupClass, T> classFunction,
- Function<ExternalStartupMethod, T> methodFunction,
- Function<ExternalSyntheticStartupMethod, T> syntheticMethodFunction) {
- return syntheticMethodFunction.apply(this);
- }
-
- public ClassReference getSyntheticContextReference() {
- return syntheticContextReference;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- ExternalSyntheticStartupMethod that = (ExternalSyntheticStartupMethod) o;
- return syntheticContextReference.equals(that.syntheticContextReference);
- }
-
- @Override
- public int hashCode() {
- return syntheticContextReference.hashCode();
- }
-
- @Override
- public String toString() {
- return "S(" + syntheticContextReference.getTypeName() + ")";
- }
-
- public static class Builder implements SyntheticStartupMethodBuilder {
-
- private ClassReference syntheticContextReference;
-
- @Override
- public Builder setSyntheticContextReference(ClassReference syntheticContextReference) {
- this.syntheticContextReference = syntheticContextReference;
- return this;
- }
-
- public ExternalSyntheticStartupMethod build() {
- return new ExternalSyntheticStartupMethod(syntheticContextReference);
- }
- }
-}
diff --git a/src/test/java/com/android/tools/r8/startup/utils/StartupTestingUtils.java b/src/test/java/com/android/tools/r8/startup/utils/StartupTestingUtils.java
index b6e08bf..93dc0a0 100644
--- a/src/test/java/com/android/tools/r8/startup/utils/StartupTestingUtils.java
+++ b/src/test/java/com/android/tools/r8/startup/utils/StartupTestingUtils.java
@@ -21,18 +21,15 @@
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.profile.art.ArtProfileBuilder;
import com.android.tools.r8.profile.art.ArtProfileBuilderUtils;
-import com.android.tools.r8.profile.art.ArtProfileBuilderUtils.SyntheticToSyntheticContextGeneralization;
import com.android.tools.r8.profile.art.HumanReadableArtProfileParser;
import com.android.tools.r8.profile.art.HumanReadableArtProfileParserBuilder;
import com.android.tools.r8.startup.StartupClassBuilder;
import com.android.tools.r8.startup.StartupMethodBuilder;
import com.android.tools.r8.startup.StartupProfileBuilder;
import com.android.tools.r8.startup.StartupProfileProvider;
-import com.android.tools.r8.startup.SyntheticStartupMethodBuilder;
import com.android.tools.r8.startup.profile.ExternalStartupClass;
import com.android.tools.r8.startup.profile.ExternalStartupItem;
import com.android.tools.r8.startup.profile.ExternalStartupMethod;
-import com.android.tools.r8.startup.profile.ExternalSyntheticStartupMethod;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.StringUtils;
@@ -49,8 +46,7 @@
private static String startupInstrumentationTag = "startup";
private static ArtProfileBuilder createStartupItemFactory(
- Consumer<ExternalStartupItem> startupItemConsumer,
- SyntheticToSyntheticContextGeneralization syntheticToSyntheticContextGeneralization) {
+ Consumer<ExternalStartupItem> startupItemConsumer) {
StartupProfileBuilder startupProfileBuilder =
new StartupProfileBuilder() {
@Override
@@ -72,16 +68,6 @@
}
@Override
- public StartupProfileBuilder addSyntheticStartupMethod(
- Consumer<SyntheticStartupMethodBuilder> syntheticStartupMethodBuilderConsumer) {
- ExternalSyntheticStartupMethod.Builder syntheticStartupMethodBuilder =
- ExternalSyntheticStartupMethod.builder();
- syntheticStartupMethodBuilderConsumer.accept(syntheticStartupMethodBuilder);
- startupItemConsumer.accept(syntheticStartupMethodBuilder.build());
- return this;
- }
-
- @Override
public StartupProfileBuilder addHumanReadableArtProfile(
TextInputStream textInputStream,
Consumer<HumanReadableArtProfileParserBuilder> parserBuilderConsumer) {
@@ -90,8 +76,7 @@
}
};
return ArtProfileBuilderUtils.createBuilderForArtProfileToStartupProfileConversion(
- startupProfileBuilder,
- syntheticToSyntheticContextGeneralization);
+ startupProfileBuilder);
}
public static ThrowableConsumer<D8TestBuilder>
@@ -135,41 +120,29 @@
}
public static void readStartupListFromFile(
- Path path,
- Consumer<ExternalStartupItem> startupItemConsumer,
- SyntheticToSyntheticContextGeneralization syntheticToSyntheticContextGeneralization)
- throws IOException {
+ Path path, Consumer<ExternalStartupItem> startupItemConsumer) throws IOException {
TestDiagnosticMessagesImpl diagnostics = new TestDiagnosticMessagesImpl();
HumanReadableArtProfileParser parser =
HumanReadableArtProfileParser.builder()
.setReporter(new Reporter(diagnostics))
- .setProfileBuilder(
- createStartupItemFactory(
- startupItemConsumer, syntheticToSyntheticContextGeneralization))
+ .setProfileBuilder(createStartupItemFactory(startupItemConsumer))
.build();
parser.parse(new UTF8TextInputStream(path), Origin.unknown());
diagnostics.assertNoMessages();
}
public static ThrowingConsumer<D8TestRunResult, RuntimeException> removeStartupListFromStdout(
- Consumer<ExternalStartupItem> startupItemConsumer,
- SyntheticToSyntheticContextGeneralization syntheticToSyntheticContextGeneralization) {
- return runResult ->
- removeStartupListFromStdout(
- runResult, startupItemConsumer, syntheticToSyntheticContextGeneralization);
+ Consumer<ExternalStartupItem> startupItemConsumer) {
+ return runResult -> removeStartupListFromStdout(runResult, startupItemConsumer);
}
public static void removeStartupListFromStdout(
- D8TestRunResult runResult,
- Consumer<ExternalStartupItem> startupItemConsumer,
- SyntheticToSyntheticContextGeneralization syntheticToSyntheticContextGeneralization) {
+ D8TestRunResult runResult, Consumer<ExternalStartupItem> startupItemConsumer) {
TestDiagnosticMessagesImpl diagnostics = new TestDiagnosticMessagesImpl();
HumanReadableArtProfileParser parser =
HumanReadableArtProfileParser.builder()
.setReporter(new Reporter(diagnostics))
- .setProfileBuilder(
- createStartupItemFactory(
- startupItemConsumer, syntheticToSyntheticContextGeneralization))
+ .setProfileBuilder(createStartupItemFactory(startupItemConsumer))
.build();
StringBuilder stdoutBuilder = new StringBuilder();
String startupDescriptorPrefix = "[" + startupInstrumentationTag + "] ";
@@ -202,12 +175,7 @@
startupProfileBuilder.addStartupMethod(
startupMethodBuilder ->
startupMethodBuilder.setMethodReference(
- startupMethod.getReference())),
- syntheticStartupMethod ->
- startupProfileBuilder.addSyntheticStartupMethod(
- syntheticStartupMethodBuilder ->
- syntheticStartupMethodBuilder.setSyntheticContextReference(
- syntheticStartupMethod.getSyntheticContextReference())));
+ startupMethod.getReference())));
}
}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentAnnotationSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentAnnotationSubject.java
index 610b054..2ad1eb6 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentAnnotationSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentAnnotationSubject.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexEncodedAnnotation;
+import com.android.tools.r8.graph.DexTypeAnnotation;
public class AbsentAnnotationSubject extends AnnotationSubject {
@@ -28,4 +29,19 @@
public DexEncodedAnnotation getAnnotation() {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public int isVisible() {
+ throw new Unreachable("Subject is absent");
+ }
+
+ @Override
+ public boolean isTypeAnnotation() {
+ throw new Unreachable("Subject is absent");
+ }
+
+ @Override
+ public DexTypeAnnotation asDexTypeAnnotation() {
+ throw new Unreachable("Subject is absent");
+ }
}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/AnnotationSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/AnnotationSubject.java
index 4bffcca..ddd737b 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/AnnotationSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/AnnotationSubject.java
@@ -5,8 +5,15 @@
package com.android.tools.r8.utils.codeinspector;
import com.android.tools.r8.graph.DexEncodedAnnotation;
+import com.android.tools.r8.graph.DexTypeAnnotation;
public abstract class AnnotationSubject extends Subject {
public abstract DexEncodedAnnotation getAnnotation();
+
+ public abstract int isVisible();
+
+ public abstract boolean isTypeAnnotation();
+
+ public abstract DexTypeAnnotation asDexTypeAnnotation();
}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundAnnotationSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundAnnotationSubject.java
index e73c25a..4d67e5d 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundAnnotationSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundAnnotationSubject.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationSet;
import com.android.tools.r8.graph.DexEncodedAnnotation;
+import com.android.tools.r8.graph.DexTypeAnnotation;
import com.android.tools.r8.utils.ListUtils;
import java.util.List;
@@ -51,4 +52,19 @@
public DexEncodedAnnotation getAnnotation() {
return annotation.annotation;
}
+
+ @Override
+ public int isVisible() {
+ return annotation.getVisibility();
+ }
+
+ @Override
+ public boolean isTypeAnnotation() {
+ return annotation.isTypeAnnotation();
+ }
+
+ @Override
+ public DexTypeAnnotation asDexTypeAnnotation() {
+ return annotation.asTypeAnnotation();
+ }
}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundFieldSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundFieldSubject.java
index d16221e..abc83be 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundFieldSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundFieldSubject.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.utils.codeinspector;
-import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.graph.AccessFlags;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexEncodedField;
@@ -115,7 +114,7 @@
@Override
public List<FoundAnnotationSubject> annotations() {
- throw new Unimplemented();
+ return FoundAnnotationSubject.listFromDex(dexField.annotations(), codeInspector);
}
@Override
@@ -133,9 +132,7 @@
@Override
public String getJvmFieldSignatureAsString() {
- return dexField.getReference().name.toString()
- + ":"
- + dexField.getReference().type.toDescriptorString();
+ return dexField.getReference().name + ":" + dexField.getReference().type.toDescriptorString();
}
@Override
diff --git a/tools/retrace.py b/tools/retrace.py
index a7ff23d..cbb2d33 100755
--- a/tools/retrace.py
+++ b/tools/retrace.py
@@ -3,6 +3,8 @@
# 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.
+from os import path
+
import argparse
import os
import subprocess
@@ -122,7 +124,7 @@
else:
args.commit_hash = r8_version_or_hash
map_path = None
- if get_hash_from_map_file(utils.R8LIB_MAP) == maphash:
+ if path.exists(utils.R8LIB_MAP) and get_hash_from_map_file(utils.R8LIB_MAP) == maphash:
return utils.R8LIB_MAP
try: