Fail L8 compilation when profile is present and compiling to CF
This also adds a test to ensure that the L8 dump contains the given profile when compiling to DEX.
Change-Id: I5574babf1d9bf6c577225300d61833154770c170
diff --git a/src/main/java/com/android/tools/r8/BaseCompilerCommand.java b/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
index c22cadd..44e051b 100644
--- a/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
+++ b/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
@@ -745,8 +745,12 @@
*/
public B addArtProfileForRewriting(
ArtProfileProvider artProfileProvider, ArtProfileConsumer residualArtProfileProvider) {
- artProfilesForRewriting.add(
+ return addArtProfileForRewriting(
new ArtProfileForRewriting(artProfileProvider, residualArtProfileProvider));
+ }
+
+ B addArtProfileForRewriting(ArtProfileForRewriting artProfileForRewriting) {
+ artProfilesForRewriting.add(artProfileForRewriting);
return self();
}
diff --git a/src/main/java/com/android/tools/r8/L8Command.java b/src/main/java/com/android/tools/r8/L8Command.java
index 7847c1d..c471c33 100644
--- a/src/main/java/com/android/tools/r8/L8Command.java
+++ b/src/main/java/com/android/tools/r8/L8Command.java
@@ -337,6 +337,7 @@
return;
}
Reporter reporter = getReporter();
+ boolean isGeneratingClassFiles = getProgramConsumer() instanceof ClassFileConsumer;
if (!hasDesugaredLibraryConfiguration()) {
reporter.error("L8 requires a desugared library configuration");
}
@@ -348,11 +349,18 @@
} else if (getMainDexListConsumer() != null) {
reporter.error("L8 does not support generating a main dex list");
}
- if (isShrinking() && getProgramConsumer() instanceof ClassFileConsumer) {
- reporter.error("L8 does not support shrinking when generating class files");
- }
- if (!isShrinking() && (proguardMapConsumer != null || partitionMapConsumer != null)) {
- reporter.error("L8 does not support defining a map consumer when not shrinking");
+ if (isShrinking()) {
+ if (isGeneratingClassFiles) {
+ reporter.error("L8 does not support shrinking when generating class files");
+ }
+ } else {
+ if (proguardMapConsumer != null || partitionMapConsumer != null) {
+ reporter.error("L8 does not support defining a map consumer when not shrinking");
+ }
+ if (isGeneratingClassFiles && !getArtProfilesForRewriting().isEmpty()) {
+ reporter.error(
+ "L8 does not support rewriting of ART profiles when generating class files");
+ }
}
super.validate();
}
@@ -389,9 +397,7 @@
.setDexClassChecksumFilter(getDexClassChecksumFilter())
.setProgramConsumer(getProgramConsumer());
for (ArtProfileForRewriting artProfileForRewriting : getArtProfilesForRewriting()) {
- r8Builder.addArtProfileForRewriting(
- artProfileForRewriting.getArtProfileProvider(),
- artProfileForRewriting.getResidualArtProfileConsumer());
+ r8Builder.addArtProfileForRewriting(artProfileForRewriting);
}
for (ClassFileResourceProvider libraryResourceProvider :
inputs.getLibraryResourceProviders()) {
diff --git a/src/test/java/com/android/tools/r8/L8TestBuilder.java b/src/test/java/com/android/tools/r8/L8TestBuilder.java
index e064ba5..8807ebc 100644
--- a/src/test/java/com/android/tools/r8/L8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/L8TestBuilder.java
@@ -255,6 +255,13 @@
// The rewriting confuses the generic signatures in some methods. Such signatures are never
// used by tools (they use the non library desugared version) and are stripped when compiling
// with R8 anyway.
+ if (info.getDiagnosticMessage()
+ .equals("Running R8 version " + Version.LABEL + " with assertions enabled.")) {
+ continue;
+ }
+ if (info.getDiagnosticMessage().startsWith("Dumped compilation inputs to:")) {
+ continue;
+ }
if (info instanceof UnusedProguardKeepRuleDiagnostic) {
// The default keep rules on desugared library may be unused. They should all be defined
// with keepclassmembers or keep,allowshrinking.
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestCompileResult.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestCompileResult.java
index 221a5c7..023803d 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestCompileResult.java
@@ -127,6 +127,12 @@
return this;
}
+ public DesugaredLibraryTestCompileResult<T> inspectL8DiagnosticMessages(
+ Consumer<TestDiagnosticMessages> consumer) {
+ l8Compile.inspectDiagnosticMessages(consumer);
+ return this;
+ }
+
public SingleTestRunResult<?> run(TestRuntime runtime, Class<?> mainClass, String... args)
throws ExecutionException, IOException {
return run(runtime, mainClass.getTypeName(), args);
diff --git a/src/test/java/com/android/tools/r8/profile/art/dump/DumpArtProfileProvidersTest.java b/src/test/java/com/android/tools/r8/profile/art/dump/DumpArtProfileProvidersTest.java
index 71a58e7..83f869c 100644
--- a/src/test/java/com/android/tools/r8/profile/art/dump/DumpArtProfileProvidersTest.java
+++ b/src/test/java/com/android/tools/r8/profile/art/dump/DumpArtProfileProvidersTest.java
@@ -10,26 +10,32 @@
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.D8TestBuilder;
import com.android.tools.r8.R8FullTestBuilder;
-import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestDiagnosticMessages;
import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
+import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
+import com.android.tools.r8.desugar.desugaredlibrary.test.DesugaredLibraryTestBuilder;
+import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.profile.art.ArtProfileBuilder;
import com.android.tools.r8.profile.art.ArtProfileProvider;
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.DumpInputFlags;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.MethodReferenceUtils;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.UTF8TextInputStream;
import com.android.tools.r8.utils.ZipUtils;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.Test;
@@ -40,7 +46,7 @@
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
-public class DumpArtProfileProvidersTest extends TestBase {
+public class DumpArtProfileProvidersTest extends DesugaredLibraryTestBase {
private enum DumpStrategy {
DIRECTORY,
@@ -71,40 +77,88 @@
@Parameters(name = "{1}, {0}")
public static List<Object[]> data() {
- return buildParameters(DumpStrategy.values(), getTestParameters().withNoneRuntime().build());
+ return buildParameters(
+ DumpStrategy.values(),
+ getTestParameters().withDefaultDexRuntime().withMinimumApiLevel().build());
}
@Test
- public void test() throws Exception {
+ public void testD8() throws Exception {
Path dump = dumpStrategy.createDumpPath(temp);
DumpInputFlags dumpInputFlags = dumpStrategy.createDumpInputFlags(dump);
try {
- testForR8(Backend.DEX)
+ testForD8(parameters.getBackend())
+ .addProgramClasses(Main.class)
+ .addOptionsModification(options -> options.setDumpInputFlags(dumpInputFlags))
+ .apply(this::addArtProfileProviders)
+ .setMinApi(parameters)
+ .compileWithExpectedDiagnostics(
+ diagnostics -> inspectDiagnosticMessages(diagnostics, dumpInputFlags));
+ assertFalse("Expected compilation to fail", dumpInputFlags.shouldFailCompilation());
+ } catch (CompilationFailedException e) {
+ assertTrue("Expected compilation to succeed", dumpInputFlags.shouldFailCompilation());
+ }
+ inspectDump(dump);
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ Path dump = dumpStrategy.createDumpPath(temp);
+ DumpInputFlags dumpInputFlags = dumpStrategy.createDumpInputFlags(dump);
+ try {
+ testForR8(parameters.getBackend())
.addProgramClasses(Main.class)
.addKeepMainRule(Main.class)
.addOptionsModification(options -> options.setDumpInputFlags(dumpInputFlags))
.allowDiagnosticInfoMessages()
.apply(this::addArtProfileProviders)
- .setMinApi(AndroidApiLevel.LATEST)
+ .setMinApi(parameters)
.compileWithExpectedDiagnostics(
- diagnostics -> {
- if (dumpInputFlags.shouldFailCompilation()) {
- diagnostics.assertErrorsMatch(
- diagnosticMessage(containsString("Dumped compilation inputs to:")));
- } else {
- diagnostics.assertInfosMatch(
- diagnosticMessage(containsString("Dumped compilation inputs to:")));
- }
- });
+ diagnostics -> inspectDiagnosticMessages(diagnostics, dumpInputFlags));
assertFalse("Expected compilation to fail", dumpInputFlags.shouldFailCompilation());
} catch (CompilationFailedException e) {
assertTrue("Expected compilation to succeed", dumpInputFlags.shouldFailCompilation());
}
- verifyDump(dump);
+ inspectDump(dump);
+ }
+
+ @Test
+ public void testL8() throws Exception {
+ Path dump = dumpStrategy.createDumpPath(temp);
+ DumpInputFlags dumpInputFlags = dumpStrategy.createDumpInputFlags(dump);
+ CompilationSpecification compilationSpecification = CompilationSpecification.D8_L8SHRINK;
+ LibraryDesugaringSpecification libraryDesugaringSpecification =
+ LibraryDesugaringSpecification.JDK11;
+ try {
+ testForDesugaredLibrary(parameters, libraryDesugaringSpecification, compilationSpecification)
+ .addProgramClasses(Main.class)
+ .addKeepMainRule(Main.class)
+ .addL8OptionsModification(options -> options.setDumpInputFlags(dumpInputFlags))
+ .apply(this::addArtProfileProviders)
+ .compile()
+ .inspectL8DiagnosticMessages(
+ diagnostics -> inspectDiagnosticMessages(diagnostics, dumpInputFlags));
+ assertFalse("Expected compilation to fail", dumpInputFlags.shouldFailCompilation());
+ } catch (CompilationFailedException e) {
+ assertTrue("Expected compilation to succeed", dumpInputFlags.shouldFailCompilation());
+ }
+ inspectDump(dump);
+ }
+
+ private void addArtProfileProviders(D8TestBuilder testBuilder) {
+ getArtProfileProviders().forEach(testBuilder::addArtProfileForRewriting);
}
private void addArtProfileProviders(R8FullTestBuilder testBuilder) {
- testBuilder.addArtProfileForRewriting(
+ getArtProfileProviders().forEach(testBuilder::addArtProfileForRewriting);
+ }
+
+ private void addArtProfileProviders(DesugaredLibraryTestBuilder<?> testBuilder) {
+ getArtProfileProviders().forEach(testBuilder::addL8ArtProfileForRewriting);
+ }
+
+ private Collection<ArtProfileProvider> getArtProfileProviders() {
+ return ImmutableList.of(
new ArtProfileProvider() {
@Override
@@ -129,8 +183,7 @@
public Origin getOrigin() {
return Origin.unknown();
}
- });
- testBuilder.addArtProfileForRewriting(
+ },
new ArtProfileProvider() {
@Override
@@ -158,7 +211,18 @@
});
}
- private void verifyDump(Path dump) throws IOException {
+ private void inspectDiagnosticMessages(
+ TestDiagnosticMessages diagnostics, DumpInputFlags dumpInputFlags) {
+ if (dumpInputFlags.shouldFailCompilation()) {
+ diagnostics.assertErrorsMatch(
+ diagnosticMessage(containsString("Dumped compilation inputs to:")));
+ } else {
+ diagnostics.assertInfosMatch(
+ diagnosticMessage(containsString("Dumped compilation inputs to:")));
+ }
+ }
+
+ private void inspectDump(Path dump) throws IOException {
if (dumpStrategy == DumpStrategy.DIRECTORY) {
List<Path> dumps =
Files.walk(dump, 1).filter(path -> path.toFile().isFile()).collect(Collectors.toList());