Use profile rewriting framework for startup profile
Bug: b/271822426
Change-Id: I76130d01b061bfd03efbc2b863272327d1ab5aac
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
index 1f12cb3..2522234 100644
--- 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
@@ -14,7 +14,6 @@
import com.android.tools.r8.profile.art.rewriting.ProfileAdditions;
import java.util.Comparator;
-// TODO(b/271822426): Use to include synthetics in startup profile.
public class StartupProfileAdditions
extends ProfileAdditions<
StartupProfileAdditions,
@@ -26,7 +25,7 @@
StartupProfile,
StartupProfile.Builder> {
- StartupProfileAdditions(StartupProfile profile) {
+ public StartupProfileAdditions(StartupProfile profile) {
super(profile);
}
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 b3381c3..32dd38f 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
@@ -193,6 +193,7 @@
// Amend art profile collection.
profileCollectionAdditions
.setArtProfileCollection(appView.getArtProfileCollection())
+ .setStartupProfile(appView.getStartupProfile())
.commit(appView);
// Record where the synthesized $r8$classId fields are read and written.
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 0a256ba..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
@@ -62,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/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/ArtProfileRewritingCfPostProcessingDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfPostProcessingDesugaringEventConsumer.java
index d73b2ce..3012624 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfPostProcessingDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfPostProcessingDesugaringEventConsumer.java
@@ -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/ArtProfileRewritingNestBasedAccessDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingNestBasedAccessDesugaringEventConsumer.java
index 59346f70..0978cec 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/ArtProfileRewritingNestBasedAccessDesugaringEventConsumer.java
@@ -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/ConcreteProfileCollectionAdditions.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ConcreteProfileCollectionAdditions.java
index 83cb551..90cbd6b 100644
--- 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
@@ -4,18 +4,20 @@
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.DexType;
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.ArtProfileMethodRuleInfoImpl;
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;
@@ -26,19 +28,35 @@
public class ConcreteProfileCollectionAdditions extends ProfileCollectionAdditions {
private final List<ArtProfileAdditions> additionsCollection;
+ private final Box<StartupProfileAdditions> startupProfileAdditions;
private boolean committed = false;
- private ConcreteProfileCollectionAdditions(List<ArtProfileAdditions> additionsCollection) {
+ private ConcreteProfileCollectionAdditions(
+ List<ArtProfileAdditions> additionsCollection,
+ Box<StartupProfileAdditions> startupProfileAdditions) {
this.additionsCollection = additionsCollection;
+ this.startupProfileAdditions = startupProfileAdditions;
}
- ConcreteProfileCollectionAdditions(NonEmptyArtProfileCollection artProfileCollection) {
+ ConcreteProfileCollectionAdditions(
+ ArtProfileCollection artProfileCollection, StartupProfile startupProfile) {
additionsCollection = new ArrayList<>();
- for (ArtProfile artProfile : artProfileCollection) {
- additionsCollection.add(new ArtProfileAdditions(artProfile));
+ if (artProfileCollection.isNonEmpty()) {
+ for (ArtProfile artProfile : artProfileCollection.asNonEmpty()) {
+ additionsCollection.add(new ArtProfileAdditions(artProfile));
+ }
+ assert !additionsCollection.isEmpty();
}
- 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
@@ -49,18 +67,11 @@
public void addMethodIfContextIsInProfile(
ProgramMethod method,
DexClassAndMethod context,
- Consumer<ArtProfileMethodRuleInfoImpl.Builder> methodRuleInfoBuilderConsumer) {
+ Consumer<AbstractProfileMethodRule.Builder<?, ?>> methodRuleBuilderConsumer) {
if (context.isProgramMethod()) {
- applyIfContextIsInProfile(
- context.asProgramMethod(), additionsBuilder -> additionsBuilder.addRule(method));
+ addMethodIfContextIsInProfile(method, context.asProgramMethod());
} else {
- apply(
- artProfileAdditions ->
- artProfileAdditions.addMethodRule(
- method,
- methodRuleBuilder ->
- methodRuleBuilder.acceptMethodRuleInfoBuilder(
- methodRuleInfoBuilderConsumer)));
+ accept(additions -> additions.addMethodRule(method, methodRuleBuilderConsumer));
}
}
@@ -69,15 +80,9 @@
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<ProfileAdditions<?, ?, ?, ?, ?, ?, ?, ?>> additionsConsumer,
Consumer<ProfileAdditionsBuilder> additionsBuilderConsumer) {
if (context.isProgramClass()) {
applyIfContextIsInProfile(context.asProgramClass(), additionsConsumer);
@@ -88,14 +93,9 @@
}
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);
- }
+ DexProgramClass context,
+ Consumer<ProfileAdditions<?, ?, ?, ?, ?, ?, ?, ?>> additionsConsumer) {
+ accept(additions -> additions.applyIfContextIsInProfile(context.getType(), additionsConsumer));
}
public void applyIfContextIsInProfile(
@@ -106,9 +106,7 @@
@Override
public void applyIfContextIsInProfile(
DexMethod context, Consumer<ProfileAdditionsBuilder> builderConsumer) {
- for (ArtProfileAdditions artProfileAdditions : additionsCollection) {
- artProfileAdditions.applyIfContextIsInProfile(context, builderConsumer);
- }
+ accept(additions -> additions.applyIfContextIsInProfile(context, builderConsumer));
}
@Override
@@ -119,14 +117,17 @@
@Override
public void commit(AppView<?> appView) {
assert !committed;
- if (hasAdditions()) {
+ if (hasArtProfileAdditions()) {
appView.setArtProfileCollection(createNewArtProfileCollection());
}
+ if (hasStartupProfileAdditions()) {
+ appView.setStartupProfile(createNewStartupProfile());
+ }
committed = true;
}
private ArtProfileCollection createNewArtProfileCollection() {
- assert hasAdditions();
+ assert hasArtProfileAdditions();
List<ArtProfile> newArtProfiles = new ArrayList<>(additionsCollection.size());
for (ArtProfileAdditions additions : additionsCollection) {
newArtProfiles.add(additions.createNewProfile());
@@ -134,8 +135,17 @@
return new NonEmptyArtProfileCollection(newArtProfiles);
}
- private boolean hasAdditions() {
- return Iterables.any(additionsCollection, ArtProfileAdditions::hasAdditions);
+ 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
@@ -146,21 +156,34 @@
for (ArtProfileAdditions additions : additionsCollection) {
rewrittenAdditionsCollection.add(additions.rewriteMethodReferences(methodFn));
}
- return new ConcreteProfileCollectionAdditions(rewrittenAdditionsCollection);
+ Box<StartupProfileAdditions> rewrittenStartupProfileAdditions =
+ startupProfileAdditions.rebuild(additions -> additions.rewriteMethodReferences(methodFn));
+ return new ConcreteProfileCollectionAdditions(
+ rewrittenAdditionsCollection, rewrittenStartupProfileAdditions);
}
@Override
public ConcreteProfileCollectionAdditions setArtProfileCollection(
ArtProfileCollection artProfileCollection) {
- assert artProfileCollection.isNonEmpty();
- Iterator<ArtProfile> artProfileIterator = artProfileCollection.asNonEmpty().iterator();
- for (ArtProfileAdditions additions : additionsCollection) {
- additions.setProfile(artProfileIterator.next());
+ 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/NopProfileCollectionAdditions.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/NopProfileCollectionAdditions.java
index 7cad8bf..d27a083 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/NopProfileCollectionAdditions.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/NopProfileCollectionAdditions.java
@@ -4,6 +4,7 @@
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;
@@ -58,6 +59,12 @@
}
@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
index d4bd1bc..3df9866 100644
--- 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
@@ -90,13 +90,13 @@
this.profile = profile;
}
- void applyIfContextIsInProfile(DexType context, Consumer<Additions> fn) {
+ public void applyIfContextIsInProfile(DexType context, Consumer<? super Additions> fn) {
if (profile.containsClassRule(context) || classRuleAdditions.containsKey(context)) {
fn.accept(self());
}
}
- void applyIfContextIsInProfile(
+ public void applyIfContextIsInProfile(
DexMethod context, Consumer<ProfileAdditionsBuilder> builderConsumer) {
MethodRule contextMethodRule = profile.getMethodRule(context);
if (contextMethodRule != null) {
@@ -163,12 +163,12 @@
}
public Additions addMethodRule(
- DexClassAndMethod method, Consumer<MethodRuleBuilder> methodRuleBuilderConsumer) {
+ DexClassAndMethod method, Consumer<? super MethodRuleBuilder> methodRuleBuilderConsumer) {
return addMethodRule(method.getReference(), methodRuleBuilderConsumer);
}
public Additions addMethodRule(
- DexMethod method, Consumer<MethodRuleBuilder> methodRuleBuilderConsumer) {
+ DexMethod method, Consumer<? super MethodRuleBuilder> methodRuleBuilderConsumer) {
// Create profile rule for method.
MethodRuleBuilder methodRuleBuilder =
methodRuleAdditions.computeIfAbsent(method, this::createMethodRuleBuilder);
@@ -187,7 +187,7 @@
methodRuleRemovals.add(oldMethod);
}
- Profile createNewProfile() {
+ public Profile createNewProfile() {
if (!hasAdditions()) {
assert !hasRemovals();
return profile;
@@ -229,7 +229,7 @@
return profileBuilder.build();
}
- boolean hasAdditions() {
+ public boolean hasAdditions() {
return !classRuleAdditions.isEmpty() || !methodRuleAdditions.isEmpty();
}
@@ -237,7 +237,7 @@
return !methodRuleRemovals.isEmpty();
}
- Additions rewriteMethodReferences(Function<DexMethod, DexMethod> methodFn) {
+ public Additions rewriteMethodReferences(Function<DexMethod, DexMethod> methodFn) {
Additions rewrittenAdditions = create();
assert methodRuleRemovals.isEmpty();
rewrittenAdditions.classRuleAdditions.putAll(classRuleAdditions);
@@ -264,7 +264,7 @@
public abstract Additions self();
- void setProfile(Profile profile) {
+ public void setProfile(Profile profile) {
this.profile = profile;
}
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
index 31af956..93be945 100644
--- 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
@@ -4,6 +4,7 @@
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;
@@ -26,10 +27,11 @@
public static ProfileCollectionAdditions create(AppView<?> appView) {
ArtProfileCollection artProfileCollection = appView.getArtProfileCollection();
- if (artProfileCollection.isNonEmpty()) {
- return new ConcreteProfileCollectionAdditions(artProfileCollection.asNonEmpty());
+ StartupProfile startupProfile = appView.getStartupProfile();
+ if (artProfileCollection.isEmpty() && startupProfile.isEmpty()) {
+ return nop();
}
- return nop();
+ return new ConcreteProfileCollectionAdditions(artProfileCollection, startupProfile);
}
public static NopProfileCollectionAdditions nop() {
@@ -57,5 +59,7 @@
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/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;
}