Dump: deduplicate
- Generate 1 dump for L8 compilation
- Do not generate a dump while asserting in R8
Bug: 171195238
Change-Id: Ic71df8ed21b20e8c0ae13b00760c24934f1be333
diff --git a/src/main/java/com/android/tools/r8/D8Command.java b/src/main/java/com/android/tools/r8/D8Command.java
index 84bc9b3..3372bc9 100644
--- a/src/main/java/com/android/tools/r8/D8Command.java
+++ b/src/main/java/com/android/tools/r8/D8Command.java
@@ -73,6 +73,7 @@
private String synthesizedClassPrefix = "";
private boolean enableMainDexListCheck = true;
private boolean minimalMainDex = false;
+ private boolean skipDump = false;
private Builder() {
this(new DefaultD8DiagnosticsHandler());
@@ -163,6 +164,15 @@
return self();
}
+ /**
+ * Allow to skip to dump into file and dump into directory instruction, this is primarily used
+ * for chained compilation in L8 so there are no duplicated dumps.
+ */
+ Builder skipDump() {
+ skipDump = true;
+ return self();
+ }
+
@Override
Builder self() {
return this;
@@ -255,6 +265,7 @@
getAssertionsConfiguration(),
getOutputInspections(),
synthesizedClassPrefix,
+ skipDump,
enableMainDexListCheck,
minimalMainDex,
getThreadCount(),
@@ -269,6 +280,7 @@
private final StringConsumer desugaredLibraryKeepRuleConsumer;
private final DesugaredLibraryConfiguration libraryConfiguration;
private final String synthesizedClassPrefix;
+ private final boolean skipDump;
private final boolean enableMainDexListCheck;
private final boolean minimalMainDex;
private final DexItemFactory factory;
@@ -331,6 +343,7 @@
List<AssertionsConfiguration> assertionsConfiguration,
List<Consumer<Inspector>> outputInspections,
String synthesizedClassPrefix,
+ boolean skipDump,
boolean enableMainDexListCheck,
boolean minimalMainDex,
int threadCount,
@@ -354,6 +367,7 @@
this.desugaredLibraryKeepRuleConsumer = desugaredLibraryKeepRuleConsumer;
this.libraryConfiguration = libraryConfiguration;
this.synthesizedClassPrefix = synthesizedClassPrefix;
+ this.skipDump = skipDump;
this.enableMainDexListCheck = enableMainDexListCheck;
this.minimalMainDex = minimalMainDex;
this.factory = factory;
@@ -366,6 +380,7 @@
desugaredLibraryKeepRuleConsumer = null;
libraryConfiguration = null;
synthesizedClassPrefix = null;
+ skipDump = false;
enableMainDexListCheck = true;
minimalMainDex = false;
factory = null;
@@ -430,6 +445,11 @@
internal.threadCount = getThreadCount();
}
+ if (skipDump) {
+ internal.dumpInputToDirectory = null;
+ internal.dumpInputToFile = null;
+ }
+
return internal;
}
}
diff --git a/src/main/java/com/android/tools/r8/L8Command.java b/src/main/java/com/android/tools/r8/L8Command.java
index 1141688..8e4bb2a 100644
--- a/src/main/java/com/android/tools/r8/L8Command.java
+++ b/src/main/java/com/android/tools/r8/L8Command.java
@@ -317,6 +317,7 @@
libraryConfiguration.getExtraKeepRules(), Origin.unknown());
r8Builder.addProguardConfigurationFiles(proguardConfigFiles);
r8Builder.setDisableDesugaring(true);
+ r8Builder.skipDump();
r8Command = r8Builder.makeCommand();
} else if (!(getProgramConsumer() instanceof ClassFileConsumer)) {
l8CfConsumer = new InMemoryJarContent();
@@ -335,6 +336,7 @@
d8Builder.addLibraryResourceProvider(libraryResourceProvider);
}
d8Builder.setDisableDesugaring(true);
+ d8Builder.skipDump();
d8Command = d8Builder.makeCommand();
} else {
assert getProgramConsumer() instanceof ClassFileConsumer;
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index ebc0bc6..408e3a0 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -907,7 +907,7 @@
.verifyMappingToOriginalProgram(
appView,
new ApplicationReader(inputApp.withoutMainDexList(), options, timing)
- .read(executorService));
+ .readWithoutDumping(executorService));
// Report synthetic rules (only for testing).
// TODO(b/120959039): Move this to being reported through the graph consumer.
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index bbe9387..4a68964 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -107,6 +107,7 @@
private BiFunction<String, Long, Boolean> dexClassChecksumFilter = (name, checksum) -> true;
private final List<FeatureSplit> featureSplits = new ArrayList<>();
private String synthesizedClassPrefix = "";
+ private boolean skipDump = false;
private boolean allowPartiallyImplementedProguardOptions = false;
private boolean allowTestProguardOptions =
@@ -270,6 +271,15 @@
}
/**
+ * Allow to skip to dump into file and dump into directory instruction, this is primarily used
+ * for chained compilation in L8 so there are no duplicated dumps.
+ */
+ Builder skipDump() {
+ skipDump = true;
+ return self();
+ }
+
+ /**
* Set a consumer for receiving the proguard usage information.
*
* <p>Note that any subsequent calls to this method will replace the previous setting.
@@ -584,6 +594,7 @@
getAssertionsConfiguration(),
getOutputInspections(),
synthesizedClassPrefix,
+ skipDump,
getThreadCount());
return command;
@@ -667,6 +678,7 @@
private final DesugaredLibraryConfiguration libraryConfiguration;
private final FeatureSplitConfiguration featureSplitConfiguration;
private final String synthesizedClassPrefix;
+ private final boolean skipDump;
/** Get a new {@link R8Command.Builder}. */
public static Builder builder() {
@@ -745,6 +757,7 @@
List<AssertionsConfiguration> assertionsConfiguration,
List<Consumer<Inspector>> outputInspections,
String synthesizedClassPrefix,
+ boolean skipDump,
int threadCount) {
super(
inputApp,
@@ -779,6 +792,7 @@
this.libraryConfiguration = libraryConfiguration;
this.featureSplitConfiguration = featureSplitConfiguration;
this.synthesizedClassPrefix = synthesizedClassPrefix;
+ this.skipDump = skipDump;
}
private R8Command(boolean printHelp, boolean printVersion) {
@@ -800,6 +814,7 @@
libraryConfiguration = null;
featureSplitConfiguration = null;
synthesizedClassPrefix = null;
+ skipDump = false;
}
/** Get the enable-tree-shaking state. */
@@ -955,6 +970,11 @@
internal.threadCount = getThreadCount();
}
+ if (skipDump) {
+ internal.dumpInputToDirectory = null;
+ internal.dumpInputToFile = null;
+ }
+
return internal;
}
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationReader.java b/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
index 6b0d055..2f3c56e 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
@@ -100,6 +100,15 @@
ProgramClassCollection.defaultConflictResolver(options.reporter));
}
+ public final LazyLoadedDexApplication readWithoutDumping(ExecutorService executorService)
+ throws IOException {
+ return read(
+ inputApp.getProguardMapInputData(),
+ executorService,
+ ProgramClassCollection.defaultConflictResolver(options.reporter),
+ false);
+ }
+
public final LazyLoadedDexApplication read(
StringResource proguardMap,
ExecutorService executorService)
@@ -115,31 +124,18 @@
ExecutorService executorService,
ProgramClassConflictResolver resolver)
throws IOException {
+ return read(proguardMap, executorService, resolver, true);
+ }
+
+ public final LazyLoadedDexApplication read(
+ StringResource proguardMap,
+ ExecutorService executorService,
+ ProgramClassConflictResolver resolver,
+ boolean shouldDump)
+ throws IOException {
assert verifyMainDexOptionsCompatible(inputApp, options);
- Path dumpOutput = null;
- boolean cleanDump = false;
- if (options.dumpInputToFile != null) {
- dumpOutput = Paths.get(options.dumpInputToFile);
- } else if (options.dumpInputToDirectory != null) {
- dumpOutput =
- Paths.get(options.dumpInputToDirectory).resolve("dump" + System.nanoTime() + ".zip");
- } else if (options.testing.dumpAll) {
- cleanDump = true;
- dumpOutput = Paths.get("/tmp").resolve("dump" + System.nanoTime() + ".zip");
- }
- if (dumpOutput != null) {
- timing.begin("ApplicationReader.dump");
- dumpInputToFile(inputApp, dumpOutput, options);
- if (cleanDump) {
- Files.delete(dumpOutput);
- }
- timing.end();
- Diagnostic message = new StringDiagnostic("Dumped compilation inputs to: " + dumpOutput);
- if (options.dumpInputToFile != null) {
- throw options.reporter.fatalError(message);
- } else if (!cleanDump) {
- options.reporter.info(message);
- }
+ if (shouldDump) {
+ dumpApplication();
}
timing.begin("DexApplication.read");
final LazyLoadedDexApplication.Builder builder =
@@ -174,6 +170,34 @@
return builder.build();
}
+ private void dumpApplication() throws IOException {
+ Path dumpOutput = null;
+ boolean cleanDump = false;
+ if (options.dumpInputToFile != null) {
+ dumpOutput = Paths.get(options.dumpInputToFile);
+ } else if (options.dumpInputToDirectory != null) {
+ dumpOutput =
+ Paths.get(options.dumpInputToDirectory).resolve("dump" + System.nanoTime() + ".zip");
+ } else if (options.testing.dumpAll) {
+ cleanDump = true;
+ dumpOutput = Paths.get("/tmp").resolve("dump" + System.nanoTime() + ".zip");
+ }
+ if (dumpOutput != null) {
+ timing.begin("ApplicationReader.dump");
+ dumpInputToFile(inputApp, dumpOutput, options);
+ if (cleanDump) {
+ Files.delete(dumpOutput);
+ }
+ timing.end();
+ Diagnostic message = new StringDiagnostic("Dumped compilation inputs to: " + dumpOutput);
+ if (options.dumpInputToFile != null) {
+ throw options.reporter.fatalError(message);
+ } else if (!cleanDump) {
+ options.reporter.info(message);
+ }
+ }
+ }
+
public MainDexClasses readMainDexClasses(DexApplication app) {
MainDexClasses.Builder builder = MainDexClasses.builder();
if (inputApp.hasMainDexList()) {
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryDumpInputsTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryDumpInputsTest.java
index faba098..ea80848 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryDumpInputsTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryDumpInputsTest.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.desugar.desugaredlibrary;
import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.TestParameters;
@@ -101,6 +102,7 @@
private void verifyDumpDir(Path dumpDir) throws IOException {
assertTrue(Files.isDirectory(dumpDir));
List<Path> paths = Files.walk(dumpDir, 1).collect(Collectors.toList());
+ assertEquals(3, paths.size());
boolean hasVerified = false;
for (Path path : paths) {
if (!path.equals(dumpDir)) {