Extend profile rewriting to var handle desugaring
Bug: b/265729283
Change-Id: I0cb55036c5236fc8f1b35646a02e1cb410442774
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 80eb732..c227e1c 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -73,7 +73,6 @@
import com.android.tools.r8.optimize.proto.ProtoNormalizer;
import com.android.tools.r8.origin.CommandLineOrigin;
import com.android.tools.r8.profile.art.ArtProfileCompletenessChecker;
-import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
import com.android.tools.r8.repackaging.Repackaging;
import com.android.tools.r8.repackaging.RepackagingLens;
import com.android.tools.r8.shaking.AbstractMethodRemover;
@@ -303,13 +302,11 @@
appView.dexItemFactory());
// Upfront desugaring generation: Generates new program classes to be added in the app.
- ArtProfileCollectionAdditions artProfileCollectionAdditions =
- ArtProfileCollectionAdditions.create(appView);
CfClassSynthesizerDesugaringEventConsumer classSynthesizerEventConsumer =
- CfClassSynthesizerDesugaringEventConsumer.create(artProfileCollectionAdditions);
+ CfClassSynthesizerDesugaringEventConsumer.createForR8(appView);
CfClassSynthesizerDesugaringCollection.create(appView)
.synthesizeClasses(executorService, classSynthesizerEventConsumer);
- artProfileCollectionAdditions.commit(appView);
+ classSynthesizerEventConsumer.finished(appView);
if (appView.getSyntheticItems().hasPendingSyntheticClasses()) {
appView.setAppInfo(
appView
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 7b3641f..7cbb122 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
@@ -117,7 +117,8 @@
ArtProfileCollectionAdditions artProfileCollectionAdditions =
methodProcessor.getArtProfileCollectionAdditions();
CfClassSynthesizerDesugaringEventConsumer classSynthesizerEventConsumer =
- CfClassSynthesizerDesugaringEventConsumer.create(artProfileCollectionAdditions);
+ CfClassSynthesizerDesugaringEventConsumer.createForD8(
+ appView, artProfileCollectionAdditions);
converter.classSynthesisDesugaring(executorService, classSynthesizerEventConsumer);
if (!classSynthesizerEventConsumer.getSynthesizedClasses().isEmpty()) {
classes =
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 f2cdd81..4e7a473 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
@@ -4,7 +4,10 @@
package com.android.tools.r8.ir.desugar;
+import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
+import com.android.tools.r8.graph.AppView;
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.ir.desugar.desugaredlibrary.apiconversion.DesugaredLibraryWrapperSynthesizerEventConsumer.DesugaredLibraryL8ProgramWrapperSynthesizerEventConsumer;
import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.DesugaredLibraryRetargeterSynthesizerEventConsumer.DesugaredLibraryRetargeterL8SynthesizerEventConsumer;
@@ -25,14 +28,24 @@
protected CfClassSynthesizerDesugaringEventConsumer() {}
- public static CfClassSynthesizerDesugaringEventConsumer create(
- ArtProfileCollectionAdditions artProfileCollectionAdditions) {
+ public static CfClassSynthesizerDesugaringEventConsumer createForD8(
+ AppView<?> appView, ArtProfileCollectionAdditions artProfileCollectionAdditions) {
CfClassSynthesizerDesugaringEventConsumer eventConsumer =
new D8R8CfClassSynthesizerDesugaringEventConsumer();
return ArtProfileRewritingCfClassSynthesizerDesugaringEventConsumer.attach(
- artProfileCollectionAdditions, eventConsumer);
+ appView, eventConsumer, artProfileCollectionAdditions);
}
+ public static CfClassSynthesizerDesugaringEventConsumer createForR8(
+ AppView<? extends AppInfoWithClassHierarchy> appView) {
+ CfClassSynthesizerDesugaringEventConsumer eventConsumer =
+ new D8R8CfClassSynthesizerDesugaringEventConsumer();
+ return ArtProfileRewritingCfClassSynthesizerDesugaringEventConsumer.attach(
+ appView, eventConsumer);
+ }
+
+ public void finished(AppView<? extends AppInfoWithClassHierarchy> appView) {}
+
public abstract Set<DexProgramClass> getSynthesizedClasses();
private static class D8R8CfClassSynthesizerDesugaringEventConsumer
@@ -77,6 +90,12 @@
}
@Override
+ public void acceptVarHandleDesugaringClassContext(
+ DexProgramClass clazz, ProgramDefinition context) {
+ // Intentionally empty.
+ }
+
+ @Override
public Set<DexProgramClass> getSynthesizedClasses() {
return synthesizedClasses;
}
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 595d1db..42fda4f 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
@@ -10,6 +10,7 @@
import com.android.tools.r8.graph.DexClasspathClass;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexReference;
+import com.android.tools.r8.graph.ProgramDefinition;
import com.android.tools.r8.graph.ProgramField;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.conversion.ClassConverterResult;
@@ -219,6 +220,12 @@
}
@Override
+ public void acceptVarHandleDesugaringClassContext(
+ DexProgramClass clazz, ProgramDefinition context) {
+ // Intentionally empty.
+ }
+
+ @Override
public void acceptLambdaClass(LambdaClass lambdaClass, ProgramMethod context) {
synchronized (synthesizedLambdaClasses) {
synthesizedLambdaClasses.add(lambdaClass);
@@ -488,6 +495,12 @@
}
@Override
+ public void acceptVarHandleDesugaringClassContext(
+ DexProgramClass clazz, ProgramDefinition context) {
+ // Intentionally empty.
+ }
+
+ @Override
public void acceptCollectionConversion(ProgramMethod arrayConversion) {
// Intentionally empty. The method will be hit by tracing if required.
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaring.java
index d8382b7..ceb6b75 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaring.java
@@ -22,6 +22,7 @@
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
@@ -174,19 +175,24 @@
}
private void ensureMethodHandlesLookupClass(
- VarHandleDesugaringEventConsumer eventConsumer, Collection<ProgramDefinition> contexts) {
- appView
- .getSyntheticItems()
- .ensureGlobalClass(
- () -> new MissingGlobalSyntheticsConsumerDiagnostic("VarHandle desugaring"),
- kinds -> kinds.METHOD_HANDLES_LOOKUP,
- factory.lookupType,
- contexts,
- appView,
- builder ->
- VarHandleDesugaringMethods.generateDesugarMethodHandlesLookupClass(
- builder, appView.dexItemFactory()),
- eventConsumer::acceptVarHandleDesugaringClass);
+ VarHandleDesugaringEventConsumer eventConsumer,
+ Collection<? extends ProgramDefinition> contexts) {
+ DexProgramClass clazz =
+ appView
+ .getSyntheticItems()
+ .ensureGlobalClass(
+ () -> new MissingGlobalSyntheticsConsumerDiagnostic("VarHandle desugaring"),
+ kinds -> kinds.METHOD_HANDLES_LOOKUP,
+ factory.lookupType,
+ contexts,
+ appView,
+ builder ->
+ VarHandleDesugaringMethods.generateDesugarMethodHandlesLookupClass(
+ builder, appView.dexItemFactory()),
+ eventConsumer::acceptVarHandleDesugaringClass);
+ for (ProgramDefinition context : contexts) {
+ eventConsumer.acceptVarHandleDesugaringClassContext(clazz, context);
+ }
}
private void ensureMethodHandlesLookupClass(
@@ -195,19 +201,24 @@
}
private void ensureVarHandleClass(
- VarHandleDesugaringEventConsumer eventConsumer, Collection<ProgramDefinition> contexts) {
- appView
- .getSyntheticItems()
- .ensureGlobalClass(
- () -> new MissingGlobalSyntheticsConsumerDiagnostic("VarHandle desugaring"),
- kinds -> kinds.VAR_HANDLE,
- factory.varHandleType,
- contexts,
- appView,
- builder ->
- VarHandleDesugaringMethods.generateDesugarVarHandleClass(
- builder, appView.dexItemFactory()),
- eventConsumer::acceptVarHandleDesugaringClass);
+ VarHandleDesugaringEventConsumer eventConsumer,
+ Collection<? extends ProgramDefinition> contexts) {
+ DexProgramClass clazz =
+ appView
+ .getSyntheticItems()
+ .ensureGlobalClass(
+ () -> new MissingGlobalSyntheticsConsumerDiagnostic("VarHandle desugaring"),
+ kinds -> kinds.VAR_HANDLE,
+ factory.varHandleType,
+ contexts,
+ appView,
+ builder ->
+ VarHandleDesugaringMethods.generateDesugarVarHandleClass(
+ builder, appView.dexItemFactory()),
+ eventConsumer::acceptVarHandleDesugaringClass);
+ for (ProgramDefinition context : contexts) {
+ eventConsumer.acceptVarHandleDesugaringClassContext(clazz, context);
+ }
}
private void ensureVarHandleClass(
@@ -598,9 +609,9 @@
DexApplicationReadFlags flags,
Predicate<DexApplicationReadFlags> hasReadReferenceFromProgramClass,
Function<DexApplicationReadFlags, Set<DexType>> getWitnesses,
- Consumer<List<ProgramDefinition>> consumeProgramWitnesses) {
+ Consumer<? super List<DexProgramClass>> consumeProgramWitnesses) {
if (hasReadReferenceFromProgramClass.test(flags)) {
- List<ProgramDefinition> classes = new ArrayList<>();
+ List<DexProgramClass> classes = new ArrayList<>();
for (DexType witness : getWitnesses.apply(flags)) {
DexClass dexClass = appView.contextIndependentDefinitionFor(witness);
assert dexClass != null;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaringEventConsumer.java
index 8251809..d27e4d8 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaringEventConsumer.java
@@ -4,8 +4,11 @@
package com.android.tools.r8.ir.desugar.varhandle;
import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.ProgramDefinition;
public interface VarHandleDesugaringEventConsumer {
- void acceptVarHandleDesugaringClass(DexProgramClass varHandleClass);
+ void acceptVarHandleDesugaringClass(DexProgramClass clazz);
+
+ void acceptVarHandleDesugaringClassContext(DexProgramClass clazz, ProgramDefinition context);
}
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileOptions.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileOptions.java
index eb21c54..623790d 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileOptions.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileOptions.java
@@ -38,6 +38,13 @@
return enableCompletenessCheckForTesting;
}
+ public boolean isIncludingVarHandleClasses() {
+ // We only include var handle classes in the residual ART profiles for completeness testing,
+ // since the classes synthesized by var handle desugaring are fairly large and may not be that
+ // important for runtime performance.
+ return enableCompletenessCheckForTesting;
+ }
+
public ArtProfileOptions setArtProfilesForRewriting(Collection<ArtProfileForRewriting> inputs) {
this.artProfilesForRewriting = inputs;
return this;
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfClassSynthesizerDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfClassSynthesizerDesugaringEventConsumer.java
index 3cc4631..fc09831 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfClassSynthesizerDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfClassSynthesizerDesugaringEventConsumer.java
@@ -4,32 +4,49 @@
package com.android.tools.r8.profile.art.rewriting;
+import static com.android.tools.r8.profile.art.rewriting.ArtProfileRewritingVarHandleDesugaringEventConsumerUtils.handleVarHandleDesugaringClassContext;
+
+import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
+import com.android.tools.r8.graph.AppView;
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.ir.desugar.CfClassSynthesizerDesugaringEventConsumer;
+import com.android.tools.r8.profile.art.ArtProfileOptions;
import java.util.Set;
public class ArtProfileRewritingCfClassSynthesizerDesugaringEventConsumer
extends CfClassSynthesizerDesugaringEventConsumer {
private final ConcreteArtProfileCollectionAdditions additionsCollection;
+ private final ArtProfileOptions options;
private final CfClassSynthesizerDesugaringEventConsumer parent;
private ArtProfileRewritingCfClassSynthesizerDesugaringEventConsumer(
ConcreteArtProfileCollectionAdditions additionsCollection,
+ ArtProfileOptions options,
CfClassSynthesizerDesugaringEventConsumer parent) {
this.additionsCollection = additionsCollection;
+ this.options = options;
this.parent = parent;
}
public static CfClassSynthesizerDesugaringEventConsumer attach(
- ArtProfileCollectionAdditions artProfileCollectionAdditions,
- CfClassSynthesizerDesugaringEventConsumer eventConsumer) {
+ AppView<?> appView, CfClassSynthesizerDesugaringEventConsumer eventConsumer) {
+ return attach(appView, eventConsumer, ArtProfileCollectionAdditions.create(appView));
+ }
+
+ public static CfClassSynthesizerDesugaringEventConsumer attach(
+ AppView<?> appView,
+ CfClassSynthesizerDesugaringEventConsumer eventConsumer,
+ ArtProfileCollectionAdditions artProfileCollectionAdditions) {
if (artProfileCollectionAdditions.isNop()) {
return eventConsumer;
}
return new ArtProfileRewritingCfClassSynthesizerDesugaringEventConsumer(
- artProfileCollectionAdditions.asConcrete(), eventConsumer);
+ artProfileCollectionAdditions.asConcrete(),
+ appView.options().getArtProfileOptions(),
+ eventConsumer);
}
@Override
@@ -79,8 +96,21 @@
}
@Override
- public void acceptVarHandleDesugaringClass(DexProgramClass varHandleClass) {
- parent.acceptVarHandleDesugaringClass(varHandleClass);
+ public void acceptVarHandleDesugaringClass(DexProgramClass clazz) {
+ parent.acceptVarHandleDesugaringClass(clazz);
+ }
+
+ @Override
+ public void acceptVarHandleDesugaringClassContext(
+ DexProgramClass clazz, ProgramDefinition context) {
+ handleVarHandleDesugaringClassContext(clazz, context, additionsCollection, options);
+ parent.acceptVarHandleDesugaringClassContext(clazz, context);
+ }
+
+ @Override
+ public void finished(AppView<? extends AppInfoWithClassHierarchy> appView) {
+ additionsCollection.commit(appView);
+ parent.finished(appView);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfInstructionDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfInstructionDesugaringEventConsumer.java
index 4a51eaf..ecfe904 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfInstructionDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfInstructionDesugaringEventConsumer.java
@@ -4,12 +4,14 @@
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.utils.ConsumerUtils.emptyConsumer;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexClasspathClass;
import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.ProgramDefinition;
import com.android.tools.r8.graph.ProgramField;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
@@ -352,8 +354,16 @@
}
@Override
- public void acceptVarHandleDesugaringClass(DexProgramClass varHandleClass) {
- parent.acceptVarHandleDesugaringClass(varHandleClass);
+ public void acceptVarHandleDesugaringClass(DexProgramClass clazz) {
+ parent.acceptVarHandleDesugaringClass(clazz);
+ }
+
+ @Override
+ public void acceptVarHandleDesugaringClassContext(
+ DexProgramClass clazz, ProgramDefinition context) {
+ handleVarHandleDesugaringClassContext(
+ clazz, context, additionsCollection, appView.options().getArtProfileOptions());
+ parent.acceptVarHandleDesugaringClassContext(clazz, context);
}
@Override
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/ArtProfileRewritingVarHandleDesugaringEventConsumerUtils.java
new file mode 100644
index 0000000..f53e9bc
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingVarHandleDesugaringEventConsumerUtils.java
@@ -0,0 +1,34 @@
+// 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.ConsumerUtils.emptyConsumer;
+
+import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.ProgramDefinition;
+import com.android.tools.r8.profile.art.ArtProfileOptions;
+
+public class ArtProfileRewritingVarHandleDesugaringEventConsumerUtils {
+
+ static void handleVarHandleDesugaringClassContext(
+ DexProgramClass varHandleClass,
+ ProgramDefinition context,
+ ConcreteArtProfileCollectionAdditions additionsCollection,
+ ArtProfileOptions options) {
+ if (options.isIncludingVarHandleClasses()) {
+ additionsCollection.applyIfContextIsInProfile(
+ context,
+ additions -> {
+ additions.addClassRule(varHandleClass);
+ varHandleClass.forEachProgramMethod(
+ method -> additions.addMethodRule(method, emptyConsumer()));
+ },
+ additionsBuilder -> {
+ additionsBuilder.addRule(varHandleClass);
+ varHandleClass.forEachProgramMethod(additionsBuilder::addRule);
+ });
+ }
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ConcreteArtProfileCollectionAdditions.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ConcreteArtProfileCollectionAdditions.java
index fde8889..da03c64 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ConcreteArtProfileCollectionAdditions.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ConcreteArtProfileCollectionAdditions.java
@@ -9,6 +9,7 @@
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;
@@ -69,6 +70,18 @@
}
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);
}