Pass desugared classes directly to R8 in R8 partial
Bug: b/389575762
Change-Id: Ib399005edbd42926974b96d9e9a3df9b1fe1fa2c
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index 22492d9..ab2ef1b 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -357,8 +357,8 @@
InternalOptions options = appView.options();
R8PartialSubCompilationConfiguration subCompilationConfiguration =
options.partialSubCompilationConfiguration;
- if (subCompilationConfiguration != null
- && subCompilationConfiguration.writeApplication(appView.appInfo().classes(), options)) {
+ if (subCompilationConfiguration != null) {
+ subCompilationConfiguration.writeApplication(appView.appInfo().classes(), options);
return;
}
if (options.isGeneratingClassFiles()) {
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index ce41b05..03917cd 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -21,6 +21,7 @@
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppServices;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexApplicationReadFlags;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMethod;
@@ -300,6 +301,13 @@
keepDeclarations = lazyLoaded.getKeepDeclarations();
timing.begin("To direct app");
DirectMappedDexApplication application = lazyLoaded.toDirect();
+ if (options.partialSubCompilationConfiguration != null) {
+ application =
+ options
+ .partialSubCompilationConfiguration
+ .asR8SubCompilationConfiguration()
+ .commitDesugaringOutputClasses(application);
+ }
timing.end();
timing.end();
options.loadMachineDesugaredLibrarySpecification(timing, application);
@@ -822,14 +830,7 @@
// Validity checks.
assert getDirectApp(appView).verifyCodeObjectsOwners();
assert appView.appInfo().classes().stream().allMatch(clazz -> clazz.isValid(options));
-
- assert options.testing.disableMappingToOriginalProgramVerification
- || appView
- .graphLens()
- .verifyMappingToOriginalProgram(
- appView,
- new ApplicationReader(inputApp.withoutMainDexList(), options, timing)
- .readWithoutDumping(executorService));
+ assert verifyMappingToOriginalProgram(appView, inputApp, executorService);
// Report synthetic rules (only for testing).
// TODO(b/120959039): Move this to being reported through the graph consumer.
@@ -923,6 +924,25 @@
timing.end();
}
+ private boolean verifyMappingToOriginalProgram(
+ AppView<AppInfoWithClassHierarchy> appView,
+ AndroidApp inputAndroidApp,
+ ExecutorService executorService)
+ throws IOException {
+ if (options.testing.disableMappingToOriginalProgramVerification) {
+ return true;
+ }
+ if (options.partialSubCompilationConfiguration != null) {
+ // TODO(b/390587690): Find a way to re-enable this assert in R8 partial.
+ return true;
+ }
+ DexApplication inputApp =
+ new ApplicationReader(inputAndroidApp.withoutMainDexList(), options, timing)
+ .readWithoutDumping(executorService);
+ assert appView.graphLens().verifyMappingToOriginalProgram(appView, inputApp);
+ return true;
+ }
+
private void writeKeepDeclarationsToConfigurationConsumer(
List<KeepDeclaration> keepDeclarations) {
if (options.configurationConsumer == null) {
diff --git a/src/main/java/com/android/tools/r8/R8Partial.java b/src/main/java/com/android/tools/r8/R8Partial.java
index 4c6de4e..bb44f32 100644
--- a/src/main/java/com/android/tools/r8/R8Partial.java
+++ b/src/main/java/com/android/tools/r8/R8Partial.java
@@ -161,11 +161,11 @@
}
InternalOptions d8Options = d8Command.getInternalOptions();
options.partialCompilationConfiguration.d8DexOptionsConsumer.accept(d8Options);
- R8PartialD8DexSubCompilationConfiguration partialSubCompilationConfiguration =
+ R8PartialD8DexSubCompilationConfiguration subCompilationConfiguration =
new R8PartialD8DexSubCompilationConfiguration(timing);
- d8Options.partialSubCompilationConfiguration = partialSubCompilationConfiguration;
+ d8Options.partialSubCompilationConfiguration = subCompilationConfiguration;
D8.runInternal(d8App, d8Options, executor);
- return new R8PartialD8DexResult(partialSubCompilationConfiguration.getOutputClasses());
+ return new R8PartialD8DexResult(subCompilationConfiguration.getOutputClasses());
}
private R8PartialDesugarResult runDesugarStep(R8PartialInput input, ExecutorService executor)
@@ -176,9 +176,8 @@
// As a simple example, it should be safe to postpone backporting to the R8 compilation.
// TODO(b/389039057): This runs a full D8 compilation. For build speed, consider if the various
// passes in D8 can be disabled when the `partialSubCompilationConfiguration` is set.
- Path desugarOutput = resolveTmp("desugar-output.zip");
D8Command.Builder d8Builder =
- D8Command.builder(options.reporter).setOutput(desugarOutput, OutputMode.ClassFile);
+ D8Command.builder(options.reporter).setProgramConsumer(ClassFileConsumer.emptyConsumer());
// TODO(b/390327883): This should enable intermediate mode.
input.configureDesugar(d8Builder);
d8Builder.validate();
@@ -186,10 +185,11 @@
AndroidApp d8App = d8Command.getInputApp();
InternalOptions d8Options = d8Command.getInternalOptions();
options.partialCompilationConfiguration.d8DesugarOptionsConsumer.accept(d8Options);
- d8Options.partialSubCompilationConfiguration =
+ R8PartialD8DesugarSubCompilationConfiguration subCompilationConfiguration =
new R8PartialD8DesugarSubCompilationConfiguration(timing);
+ d8Options.partialSubCompilationConfiguration = subCompilationConfiguration;
D8.runInternal(d8App, d8Options, executor);
- return new R8PartialDesugarResult(desugarOutput);
+ return new R8PartialDesugarResult(subCompilationConfiguration.getOutputClasses());
}
private void runR8PartialStep(
@@ -214,7 +214,6 @@
// TODO(b/390389764): Disable desugaring.
R8Command.Builder r8Builder =
R8Command.builder(r8DiagnosticsHandler)
- .addProgramFiles(desugarResult.getOutputPath())
.enableLegacyFullModeForKeepRules(true)
.setProgramConsumer(options.programConsumer);
input.configure(r8Builder);
@@ -227,7 +226,8 @@
InternalOptions r8Options = r8Command.getInternalOptions();
options.partialCompilationConfiguration.r8OptionsConsumer.accept(r8Options);
r8Options.partialSubCompilationConfiguration =
- new R8PartialR8SubCompilationConfiguration(dexingResult.getOutputClasses(), timing);
+ new R8PartialR8SubCompilationConfiguration(
+ desugarResult.getOutputClasses(), dexingResult.getOutputClasses(), timing);
r8Options.mapConsumer = options.mapConsumer;
if (options.androidResourceProvider != null) {
r8Options.androidResourceProvider = options.androidResourceProvider;
diff --git a/src/main/java/com/android/tools/r8/partial/R8PartialDesugarResult.java b/src/main/java/com/android/tools/r8/partial/R8PartialDesugarResult.java
index 6885303..37bae17 100644
--- a/src/main/java/com/android/tools/r8/partial/R8PartialDesugarResult.java
+++ b/src/main/java/com/android/tools/r8/partial/R8PartialDesugarResult.java
@@ -3,17 +3,18 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.partial;
-import java.nio.file.Path;
+import com.android.tools.r8.graph.DexProgramClass;
+import java.util.Collection;
public class R8PartialDesugarResult {
- private final Path outputPath;
+ private final Collection<DexProgramClass> outputClasses;
- public R8PartialDesugarResult(Path outputPath) {
- this.outputPath = outputPath;
+ public R8PartialDesugarResult(Collection<DexProgramClass> outputClasses) {
+ this.outputClasses = outputClasses;
}
- public Path getOutputPath() {
- return outputPath;
+ public Collection<DexProgramClass> getOutputClasses() {
+ return outputClasses;
}
}
diff --git a/src/main/java/com/android/tools/r8/partial/R8PartialSubCompilationConfiguration.java b/src/main/java/com/android/tools/r8/partial/R8PartialSubCompilationConfiguration.java
index 08eb55d..0906f8a 100644
--- a/src/main/java/com/android/tools/r8/partial/R8PartialSubCompilationConfiguration.java
+++ b/src/main/java/com/android/tools/r8/partial/R8PartialSubCompilationConfiguration.java
@@ -33,9 +33,8 @@
}
/** Returns true if normal writing should be aborted. */
- public boolean writeApplication(
- Collection<DexProgramClass> outputClasses, InternalOptions options) {
- return false;
+ public void writeApplication(Collection<DexProgramClass> outputClasses, InternalOptions options) {
+ assert false;
}
public static class R8PartialD8DexSubCompilationConfiguration
@@ -58,29 +57,45 @@
}
@Override
- public boolean writeApplication(
+ public void writeApplication(
Collection<DexProgramClass> outputClasses, InternalOptions options) {
this.outputClasses = outputClasses;
- return true;
}
}
public static class R8PartialD8DesugarSubCompilationConfiguration
extends R8PartialSubCompilationConfiguration {
+ private Collection<DexProgramClass> outputClasses;
+
public R8PartialD8DesugarSubCompilationConfiguration(Timing timing) {
super(timing);
}
+
+ public Collection<DexProgramClass> getOutputClasses() {
+ assert outputClasses != null;
+ return outputClasses;
+ }
+
+ @Override
+ public void writeApplication(
+ Collection<DexProgramClass> outputClasses, InternalOptions options) {
+ this.outputClasses = outputClasses;
+ }
}
public static class R8PartialR8SubCompilationConfiguration
extends R8PartialSubCompilationConfiguration {
+ private Collection<DexProgramClass> desugaringOutputClasses;
private Collection<DexProgramClass> dexingOutputClasses;
public R8PartialR8SubCompilationConfiguration(
- Collection<DexProgramClass> dexingOutputClasses, Timing timing) {
+ Collection<DexProgramClass> desugaringOutputClasses,
+ Collection<DexProgramClass> dexingOutputClasses,
+ Timing timing) {
super(timing);
+ this.desugaringOutputClasses = desugaringOutputClasses;
this.dexingOutputClasses = dexingOutputClasses;
}
@@ -89,6 +104,15 @@
return dexingOutputClasses;
}
+ public DirectMappedDexApplication commitDesugaringOutputClasses(
+ DirectMappedDexApplication app) {
+ assert app.classes().isEmpty();
+ DirectMappedDexApplication newApp =
+ app.builder().addProgramClasses(desugaringOutputClasses).build();
+ desugaringOutputClasses = null;
+ return newApp;
+ }
+
public void commitDexingOutputClasses(AppView<AppInfoWithClassHierarchy> appView) {
DirectMappedDexApplication newApp =
appView
diff --git a/src/test/java/com/android/tools/r8/partial/PartialCompilationBasicPreviewPatternsTest.java b/src/test/java/com/android/tools/r8/partial/PartialCompilationBasicPreviewPatternsTest.java
index 791d1ee..f102830 100644
--- a/src/test/java/com/android/tools/r8/partial/PartialCompilationBasicPreviewPatternsTest.java
+++ b/src/test/java/com/android/tools/r8/partial/PartialCompilationBasicPreviewPatternsTest.java
@@ -61,9 +61,6 @@
.inspectD8Input(
inspector ->
assertTrue(inspector.hasExactlyProgramClasses(C1.class, C2.class, Main.class)))
- .inspectR8Input(
- inspector ->
- assertTrue(inspector.hasExactlyProgramClasses(A1.class, A2.class, B.class)))
.inspect(
inspector ->
assertTrue(inspector.hasExactlyProgramClasses(C1.class, C2.class, Main.class)))
@@ -87,8 +84,6 @@
inspector ->
assertTrue(
inspector.hasExactlyProgramClasses(B.class, C1.class, C2.class, Main.class)))
- .inspectR8Input(
- inspector -> assertTrue(inspector.hasExactlyProgramClasses(A1.class, A2.class)))
.inspect(
inspector ->
assertTrue(
@@ -113,8 +108,6 @@
inspector ->
assertTrue(
inspector.hasExactlyProgramClasses(C1.class, C2.class, B.class, Main.class)))
- .inspectR8Input(
- inspector -> assertTrue(inspector.hasExactlyProgramClasses(A1.class, A2.class)))
.inspect(
inspector ->
assertTrue(
@@ -140,7 +133,6 @@
assertTrue(
inspector.hasExactlyProgramClasses(
A1.class, A2.class, C1.class, C2.class, Main.class)))
- .inspectR8Input(inspector -> assertTrue(inspector.hasExactlyProgramClasses(B.class)))
.inspect(
inspector ->
assertTrue(
@@ -168,7 +160,6 @@
assertTrue(
inspector.hasExactlyProgramClasses(
A1.class, A2.class, C1.class, C2.class, Main.class)))
- .inspectR8Input(inspector -> assertTrue(inspector.hasExactlyProgramClasses(B.class)))
.inspect(
inspector ->
assertTrue(
@@ -193,10 +184,6 @@
.compile()
.inspectD8Input(
inspector -> assertTrue(inspector.hasExactlyProgramClasses(C1.class, Main.class)))
- .inspectR8Input(
- inspector ->
- assertTrue(
- inspector.hasExactlyProgramClasses(A1.class, A2.class, B.class, C2.class)))
.inspect(inspector -> assertTrue(inspector.hasExactlyProgramClasses(C1.class, Main.class)))
.run(parameters.getRuntime(), Main.class, ALL_TYPE_NAMES)
.assertSuccessWithOutputLines(
@@ -222,10 +209,6 @@
.compile()
.inspectD8Input(
inspector -> assertTrue(inspector.hasExactlyProgramClasses(A1.class, Main.class)))
- .inspectR8Input(
- inspector ->
- assertTrue(
- inspector.hasExactlyProgramClasses(A2.class, B.class, C1.class, C2.class)))
.inspect(inspector -> assertTrue(inspector.hasExactlyProgramClasses(A1.class, Main.class)))
.run(parameters.getRuntime(), Main.class, ALL_TYPE_NAMES)
.assertSuccessWithOutputLines(
@@ -250,10 +233,6 @@
.compile()
.inspectD8Input(
inspector -> assertTrue(inspector.hasExactlyProgramClasses(B.class, Main.class)))
- .inspectR8Input(
- inspector ->
- assertTrue(
- inspector.hasExactlyProgramClasses(A1.class, A2.class, C1.class, C2.class)))
.inspect(inspector -> assertTrue(inspector.hasExactlyProgramClasses(B.class, Main.class)))
.run(parameters.getRuntime(), Main.class, ALL_TYPE_NAMES)
.assertSuccessWithOutputLines(
diff --git a/src/test/java/com/android/tools/r8/partial/PartialCompilationBasicTest.java b/src/test/java/com/android/tools/r8/partial/PartialCompilationBasicTest.java
index a3b2251..95eed20 100644
--- a/src/test/java/com/android/tools/r8/partial/PartialCompilationBasicTest.java
+++ b/src/test/java/com/android/tools/r8/partial/PartialCompilationBasicTest.java
@@ -35,12 +35,6 @@
.addKeepMainRule(Main.class)
.setR8PartialConfiguration(builder -> builder.includeAll().excludeClasses(A.class))
.compile()
- .inspectR8Input(
- inspector -> {
- assertThat(inspector.programClass(A.class), isAbsent());
- assertThat(inspector.programClass(B.class), isPresent());
- assertThat(inspector.programClass(Main.class), isPresent());
- })
.inspectD8Input(
inspector -> {
assertThat(inspector.programClass(A.class), isPresent());
@@ -65,14 +59,6 @@
.addKeepMainRule(Main.class)
.setR8PartialConfiguration(builder -> builder.includeAll().excludeClasses(B.class))
.compile()
- .inspectR8Input(
- inspector -> {
- // TODO(b/309743298): These are all present as inspection currently also look at
- // classpath.
- assertThat(inspector.programClass(A.class), isPresent());
- assertThat(inspector.programClass(B.class), isAbsent());
- assertThat(inspector.programClass(Main.class), isPresent());
- })
.inspectD8Input(
inspector -> {
// TODO(b/309743298): These are all present as inspection currently also look at
diff --git a/src/test/testbase/java/com/android/tools/r8/R8PartialTestBuilder.java b/src/test/testbase/java/com/android/tools/r8/R8PartialTestBuilder.java
index c18c4c7..14df886 100644
--- a/src/test/testbase/java/com/android/tools/r8/R8PartialTestBuilder.java
+++ b/src/test/testbase/java/com/android/tools/r8/R8PartialTestBuilder.java
@@ -137,17 +137,11 @@
Box<List<ProguardConfigurationRule>> syntheticProguardRulesConsumer,
StringBuilder proguardMapBuilder)
throws CompilationFailedException {
- Box<AndroidApp> r8InputAppBox = new Box<>();
Box<AndroidApp> d8InputAppBox = new Box<>();
- Box<AndroidApp> r8OutputAppBox = new Box<>();
- Box<AndroidApp> d8OutputAppBox = new Box<>();
Consumer<InternalOptions> configureR8PartialCompilation =
options -> {
options.partialCompilationConfiguration = getPartialConfiguration();
- options.partialCompilationConfiguration.r8InputAppConsumer = r8InputAppBox::set;
options.partialCompilationConfiguration.d8InputAppConsumer = d8InputAppBox::set;
- options.partialCompilationConfiguration.r8OutputAppConsumer = r8OutputAppBox::set;
- options.partialCompilationConfiguration.d8OutputAppConsumer = d8OutputAppBox::set;
};
ToolHelper.runAndBenchmarkR8PartialWithoutResult(
builder, configureR8PartialCompilation.andThen(optionsConsumer), benchmarkResults);
@@ -166,10 +160,7 @@
resourceShrinkerOutput,
resourceShrinkerOutputForFeatures,
buildMetadata != null ? buildMetadata.get() : null,
- r8InputAppBox.get(),
- d8InputAppBox.get(),
- r8OutputAppBox.get(),
- d8OutputAppBox.get());
+ d8InputAppBox.get());
}
@Override
diff --git a/src/test/testbase/java/com/android/tools/r8/R8PartialTestCompileResult.java b/src/test/testbase/java/com/android/tools/r8/R8PartialTestCompileResult.java
index 3c53df4..a722661 100644
--- a/src/test/testbase/java/com/android/tools/r8/R8PartialTestCompileResult.java
+++ b/src/test/testbase/java/com/android/tools/r8/R8PartialTestCompileResult.java
@@ -20,10 +20,7 @@
public class R8PartialTestCompileResult
extends R8TestCompileResultBase<R8PartialTestCompileResult> {
- private final AndroidApp r8InputApp;
private final AndroidApp d8InputApp;
- private final AndroidApp r8OutputApp;
- private final AndroidApp d8OutputApp;
R8PartialTestCompileResult(
TestState state,
@@ -40,10 +37,7 @@
Path resourceShrinkerOutput,
HashMap<String, Path> resourceShrinkerOutputForFeatures,
R8BuildMetadata buildMetadata,
- AndroidApp r8InputApp,
- AndroidApp d8InputApp,
- AndroidApp r8OutputApp,
- AndroidApp d8OutputApp) {
+ AndroidApp d8InputApp) {
super(
state,
outputMode,
@@ -59,10 +53,7 @@
resourceShrinkerOutput,
resourceShrinkerOutputForFeatures,
buildMetadata);
- this.r8InputApp = r8InputApp;
this.d8InputApp = d8InputApp;
- this.r8OutputApp = r8OutputApp;
- this.d8OutputApp = d8OutputApp;
}
@Override
@@ -70,21 +61,6 @@
return this;
}
- public CodeInspector inspectorR8Input() throws IOException {
- return new CodeInspector(r8InputApp);
- }
-
- public CodeInspector inspectorR8Input(Consumer<InternalOptions> debugOptionsConsumer)
- throws IOException {
- return new CodeInspector(r8InputApp, debugOptionsConsumer);
- }
-
- public <E extends Throwable> R8PartialTestCompileResult inspectR8Input(
- ThrowingConsumer<CodeInspector, E> consumer) throws IOException, E {
- consumer.accept(inspectorR8Input());
- return self();
- }
-
public CodeInspector inspectorD8Input() throws IOException {
return new CodeInspector(d8InputApp);
}