blob: 85c54e185f21847de9875b3fc044e046c48a5776 [file] [log] [blame]
// 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.DexClass;
import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
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.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 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();
}
void applyIfContextIsInProfile(
DexClass 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(
DexClassAndMethod 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) {
if (hasAdditions()) {
appView.setArtProfileCollection(createNewArtProfileCollection());
}
}
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;
}
}