Add a test for removing duplicates in profiles after optimizing
Change-Id: Id3f5b048f8713ac5d91207abc3c9dd82a5c3fbad
diff --git a/src/test/java/com/android/tools/r8/profile/art/ArtProfileCollisionAfterClassMergingRewritingTest.java b/src/test/java/com/android/tools/r8/profile/art/ArtProfileCollisionAfterClassMergingRewritingTest.java
new file mode 100644
index 0000000..c66dee4
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/profile/art/ArtProfileCollisionAfterClassMergingRewritingTest.java
@@ -0,0 +1,161 @@
+// 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.profile.art;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+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.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.MethodReferenceUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import com.google.common.collect.Lists;
+import java.util.Collections;
+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 ArtProfileCollisionAfterClassMergingRewritingTest extends TestBase {
+
+ private static final ClassReference mainClassReference = Reference.classFromClass(Main.class);
+ private static final MethodReference mainMethodReference =
+ MethodReferenceUtils.mainMethod(Main.class);
+
+ private static final ClassReference fooClassReference = Reference.classFromClass(Foo.class);
+ private static final MethodReference helloMethodReference =
+ MethodReferenceUtils.methodFromMethod(Foo.class, "hello");
+
+ private static final ClassReference barClassReference = Reference.classFromClass(Bar.class);
+ private static final MethodReference worldMethodReference =
+ MethodReferenceUtils.methodFromMethod(Bar.class, "world");
+
+ @Parameter(0)
+ public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withNoneRuntime().build();
+ }
+
+ @Test
+ public void test() throws Exception {
+ ResidualArtProfileConsumerForTesting residualArtProfileConsumer =
+ new ResidualArtProfileConsumerForTesting();
+ MyArtProfileInput artProfileInput = new MyArtProfileInput(residualArtProfileConsumer);
+ testForR8(Backend.DEX)
+ .addInnerClasses(getClass())
+ .addKeepMainRule(Main.class)
+ .addOptionsModification(
+ options ->
+ options
+ .getArtProfileOptions()
+ .setArtProfileInputs(Collections.singleton(artProfileInput)))
+ .addHorizontallyMergedClassesInspector(
+ inspector ->
+ inspector.assertMergedInto(Foo.class, Bar.class).assertNoOtherClassesMerged())
+ .enableInliningAnnotations()
+ .setMinApi(AndroidApiLevel.LATEST)
+ .compile()
+ .inspect(inspector -> inspect(inspector, residualArtProfileConsumer));
+ }
+
+ private void inspect(
+ CodeInspector inspector, ResidualArtProfileConsumerForTesting residualArtProfileConsumer) {
+ ClassSubject barClassSubject = inspector.clazz(Bar.class);
+ assertThat(barClassSubject, isPresentAndRenamed());
+
+ MethodSubject helloMethodSubject = barClassSubject.uniqueMethodWithName("hello");
+ assertThat(helloMethodSubject, isPresentAndRenamed());
+
+ MethodSubject worldMethodSubject = barClassSubject.uniqueMethodWithName("world");
+ assertThat(worldMethodSubject, isPresentAndRenamed());
+
+ assertTrue(residualArtProfileConsumer.finished);
+ assertEquals(
+ Lists.newArrayList(
+ mainClassReference,
+ mainMethodReference,
+ barClassSubject.getFinalReference(),
+ helloMethodSubject.getFinalReference(),
+ // TODO(b/237043695): Bar should not occur twice in the profile.
+ barClassSubject.getFinalReference(),
+ worldMethodSubject.getFinalReference()),
+ residualArtProfileConsumer.references);
+ assertEquals(
+ Lists.newArrayList(
+ ArtProfileClassRuleInfoImpl.empty(),
+ ArtProfileMethodRuleInfoImpl.empty(),
+ ArtProfileClassRuleInfoImpl.empty(),
+ ArtProfileMethodRuleInfoImpl.empty(),
+ ArtProfileClassRuleInfoImpl.empty(),
+ ArtProfileMethodRuleInfoImpl.empty()),
+ residualArtProfileConsumer.infos);
+ }
+
+ static class MyArtProfileInput implements ArtProfileInput {
+
+ private final ResidualArtProfileConsumerForTesting residualArtProfileConsumer;
+
+ MyArtProfileInput(ResidualArtProfileConsumerForTesting residualArtProfileConsumer) {
+ this.residualArtProfileConsumer = residualArtProfileConsumer;
+ }
+
+ @Override
+ public ResidualArtProfileConsumer getArtProfileConsumer() {
+ return residualArtProfileConsumer;
+ }
+
+ @Override
+ public void getArtProfile(ArtProfileBuilder profileBuilder) {
+ profileBuilder
+ .addClassRule(classRuleBuilder -> classRuleBuilder.setClassReference(mainClassReference))
+ .addMethodRule(
+ methodRuleBuilder -> methodRuleBuilder.setMethodReference(mainMethodReference))
+ .addClassRule(classRuleBuilder -> classRuleBuilder.setClassReference(fooClassReference))
+ .addMethodRule(
+ methodRuleBuilder -> methodRuleBuilder.setMethodReference(helloMethodReference))
+ .addClassRule(classRuleBuilder -> classRuleBuilder.setClassReference(barClassReference))
+ .addMethodRule(
+ methodRuleBuilder -> methodRuleBuilder.setMethodReference(worldMethodReference));
+ }
+ }
+
+ static class Main {
+
+ public static void main(String[] args) {
+ Foo.hello();
+ Bar.world();
+ }
+ }
+
+ static class Foo {
+
+ @NeverInline
+ static void hello() {
+ System.out.print("Hello");
+ }
+ }
+
+ static class Bar {
+
+ @NeverInline
+ static void world() {
+ System.out.println(", world!");
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/profile/art/ArtProfileRewritingTest.java b/src/test/java/com/android/tools/r8/profile/art/ArtProfileRewritingTest.java
index 860d603..0a3fa08 100644
--- a/src/test/java/com/android/tools/r8/profile/art/ArtProfileRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/profile/art/ArtProfileRewritingTest.java
@@ -9,7 +9,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
@@ -23,9 +22,7 @@
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.Lists;
-import java.util.ArrayList;
import java.util.Collections;
-import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -54,7 +51,9 @@
@Test
public void test() throws Exception {
- MyArtProfileInput artProfileInput = new MyArtProfileInput();
+ ResidualArtProfileConsumerForTesting residualArtProfileConsumer =
+ new ResidualArtProfileConsumerForTesting();
+ MyArtProfileInput artProfileInput = new MyArtProfileInput(residualArtProfileConsumer);
testForR8(Backend.DEX)
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
@@ -66,68 +65,45 @@
.enableInliningAnnotations()
.setMinApi(AndroidApiLevel.LATEST)
.compile()
- .inspect(inspector -> inspect(inspector, artProfileInput));
+ .inspect(inspector -> inspect(inspector, residualArtProfileConsumer));
}
- private void inspect(CodeInspector inspector, MyArtProfileInput artProfileInput) {
+ private void inspect(
+ CodeInspector inspector, ResidualArtProfileConsumerForTesting residualArtProfileConsumer) {
ClassSubject greeterClassSubject = inspector.clazz(Greeter.class);
assertThat(greeterClassSubject, isPresentAndRenamed());
MethodSubject greetMethodSubject = greeterClassSubject.uniqueMethodWithName("greet");
assertThat(greetMethodSubject, isPresentAndRenamed());
- assertTrue(artProfileInput.finished);
+ assertTrue(residualArtProfileConsumer.finished);
assertEquals(
Lists.newArrayList(
mainClassReference,
mainMethodReference,
greeterClassSubject.getFinalReference(),
greetMethodSubject.getFinalReference()),
- artProfileInput.references);
+ residualArtProfileConsumer.references);
assertEquals(
Lists.newArrayList(
ArtProfileClassRuleInfoImpl.empty(),
ArtProfileMethodRuleInfoImpl.builder().setIsStartup().build(),
ArtProfileClassRuleInfoImpl.empty(),
ArtProfileMethodRuleInfoImpl.builder().setIsHot().setIsPostStartup().build()),
- artProfileInput.infos);
+ residualArtProfileConsumer.infos);
}
static class MyArtProfileInput implements ArtProfileInput {
- boolean finished;
- List<Object> references = new ArrayList<>();
- List<Object> infos = new ArrayList<>();
+ private final ResidualArtProfileConsumerForTesting residualArtProfileConsumer;
+
+ MyArtProfileInput(ResidualArtProfileConsumerForTesting residualArtProfileConsumer) {
+ this.residualArtProfileConsumer = residualArtProfileConsumer;
+ }
@Override
public ResidualArtProfileConsumer getArtProfileConsumer() {
- return new ResidualArtProfileConsumer() {
-
- @Override
- public ResidualArtProfileRuleConsumer getRuleConsumer() {
- return new ResidualArtProfileRuleConsumer() {
-
- @Override
- public void acceptClassRule(
- ClassReference classReference, ArtProfileClassRuleInfo classRuleInfo) {
- references.add(classReference);
- infos.add(classRuleInfo);
- }
-
- @Override
- public void acceptMethodRule(
- MethodReference methodReference, ArtProfileMethodRuleInfo methodRuleInfo) {
- references.add(methodReference);
- infos.add(methodRuleInfo);
- }
- };
- }
-
- @Override
- public void finished(DiagnosticsHandler handler) {
- finished = true;
- }
- };
+ return residualArtProfileConsumer;
}
@Override
diff --git a/src/test/java/com/android/tools/r8/profile/art/ResidualArtProfileConsumerForTesting.java b/src/test/java/com/android/tools/r8/profile/art/ResidualArtProfileConsumerForTesting.java
new file mode 100644
index 0000000..9afc6da
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/profile/art/ResidualArtProfileConsumerForTesting.java
@@ -0,0 +1,43 @@
+// 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.profile.art;
+
+import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.references.ClassReference;
+import com.android.tools.r8.references.MethodReference;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ResidualArtProfileConsumerForTesting implements ResidualArtProfileConsumer {
+
+ boolean finished;
+ List<Object> references = new ArrayList<>();
+ List<Object> infos = new ArrayList<>();
+
+ @Override
+ public ResidualArtProfileRuleConsumer getRuleConsumer() {
+ return new ResidualArtProfileRuleConsumer() {
+
+ @Override
+ public void acceptClassRule(
+ ClassReference classReference, ArtProfileClassRuleInfo classRuleInfo) {
+ references.add(classReference);
+ infos.add(classRuleInfo);
+ }
+
+ @Override
+ public void acceptMethodRule(
+ MethodReference methodReference, ArtProfileMethodRuleInfo methodRuleInfo) {
+ references.add(methodReference);
+ infos.add(methodRuleInfo);
+ }
+ };
+ }
+
+ @Override
+ public void finished(DiagnosticsHandler handler) {
+ finished = true;
+ }
+}