Reland "Interface processing as post processing in D8"
This relands commit 79f75ed44e00bd6d0e5996ff854117939c1f0ed8.
Reland "InterfaceMethodProcessorFacade clean-up"
This relands commit fc459a413afdfe1aacf78d0f7382e3ac4cb67c82.
Reland "Do not process forwarding methods while adding them"
This relands commit 69a1e1774a35e8d7f91ad7a3d5c3f2548706cebf.
Change-Id: I29a8bd70c871bbc7c4cc15aef288b4c69d198f1a
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java
index 9508da1..136d452 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java
@@ -13,8 +13,6 @@
import com.android.tools.r8.ir.desugar.CfClassDesugaringEventConsumer.D8CfClassDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer.D8CfInstructionDesugaringEventConsumer;
-import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer;
-import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer.D8CfPostProcessingDesugaringEventConsumer;
import com.android.tools.r8.utils.ThreadUtils;
import com.google.common.collect.Sets;
import java.util.ArrayList;
@@ -112,13 +110,6 @@
classes = deferred;
}
-
- D8CfPostProcessingDesugaringEventConsumer eventConsumer =
- CfPostProcessingDesugaringEventConsumer.createForD8(methodProcessor, appView);
- methodProcessor.newWave();
- converter.postProcessDesugaring(eventConsumer);
- methodProcessor.awaitMethodProcessing();
- eventConsumer.finalizeDesugaring();
}
abstract void convertClass(
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index b01f268..3144113 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -51,11 +51,13 @@
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer.D8CfInstructionDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringCollection;
import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer;
+import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer.D8CfPostProcessingDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.CovariantReturnTypeAnnotationTransformer;
import com.android.tools.r8.ir.desugar.ProgramAdditions;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAPIConverter;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAPIConverter.Mode;
import com.android.tools.r8.ir.desugar.itf.EmulatedInterfaceApplicationRewriter;
+import com.android.tools.r8.ir.desugar.itf.InterfaceMethodProcessorFacade;
import com.android.tools.r8.ir.desugar.itf.InterfaceMethodRewriter;
import com.android.tools.r8.ir.desugar.itf.InterfaceMethodRewriter.Flavor;
import com.android.tools.r8.ir.desugar.lambda.LambdaDeserializationMethodRemover;
@@ -225,10 +227,7 @@
assert options.desugarState.isOn();
this.instructionDesugaring = CfInstructionDesugaringCollection.create(appView);
this.classDesugaring = instructionDesugaring.createClassDesugaringCollection();
- this.interfaceMethodRewriter =
- options.desugaredLibraryConfiguration.getEmulateLibraryInterface().isEmpty()
- ? null
- : new InterfaceMethodRewriter(appView, this);
+ this.interfaceMethodRewriter = null;
this.desugaredLibraryAPIConverter =
new DesugaredLibraryAPIConverter(appView, Mode.GENERATE_CALLBACKS_AND_WRAPPERS);
this.covariantReturnTypeAnnotationTransformer = null;
@@ -258,7 +257,7 @@
: CfInstructionDesugaringCollection.create(appView);
this.classDesugaring = instructionDesugaring.createClassDesugaringCollection();
this.interfaceMethodRewriter =
- options.isInterfaceMethodDesugaringEnabled()
+ options.isInterfaceMethodDesugaringEnabled() && appView.enableWholeProgramOptimizations()
? new InterfaceMethodRewriter(appView, this)
: null;
this.covariantReturnTypeAnnotationTransformer =
@@ -366,11 +365,6 @@
D8NestBasedAccessDesugaring::clearNestAttributes);
}
- void postProcessDesugaring(CfPostProcessingDesugaringEventConsumer eventConsumer) {
- CfPostProcessingDesugaringCollection.create(appView, instructionDesugaring.getRetargetingInfo())
- .postProcessingDesugaring(eventConsumer);
- }
-
private void staticizeClasses(
OptimizationFeedback feedback, ExecutorService executorService, GraphLens applied)
throws ExecutionException {
@@ -393,11 +387,11 @@
}
}
- private void runInterfaceDesugaringProcessors(
+ private void runInterfaceDesugaringProcessorsForR8(
Flavor includeAllResources, ExecutorService executorService) throws ExecutionException {
assert !appView.getSyntheticItems().hasPendingSyntheticClasses();
if (interfaceMethodRewriter != null) {
- interfaceMethodRewriter.runInterfaceDesugaringProcessors(
+ interfaceMethodRewriter.runInterfaceDesugaringProcessorsForR8(
this, includeAllResources, executorService);
}
}
@@ -414,25 +408,24 @@
workaroundAbstractMethodOnNonAbstractClassVerificationBug(
executor, OptimizationFeedbackIgnore.getInstance());
DexApplication application = appView.appInfo().app();
+ D8MethodProcessor methodProcessor = new D8MethodProcessor(this, executor);
+
timing.begin("IR conversion");
- convertClasses(executor);
+ convertClasses(methodProcessor, executor);
reportNestDesugarDependencies();
clearNestAttributes();
- if (appView.getSyntheticItems().hasPendingSyntheticClasses()) {
- appView.setAppInfo(
- new AppInfo(
- appView.appInfo().getSyntheticItems().commit(application),
- appView.appInfo().getMainDexInfo()));
- application = appView.appInfo().app();
- }
+ application = commitPendingSyntheticItems(appView, application);
+
+ postProcessingDesugaringForD8(methodProcessor, executor);
+
+ application = commitPendingSyntheticItems(appView, application);
// Build a new application with jumbo string info,
Builder<?> builder = application.builder().setHighestSortingString(highestSortingString);
- runInterfaceDesugaringProcessors(ExcludeDexResources, executor);
if (appView.options().isDesugaredLibraryCompilation()) {
new EmulatedInterfaceApplicationRewriter(appView).rewriteApplication(builder);
}
@@ -448,8 +441,34 @@
appView.appInfo().getMainDexInfo()));
}
- private void convertClasses(ExecutorService executorService) throws ExecutionException {
- D8MethodProcessor methodProcessor = new D8MethodProcessor(this, executorService);
+ private DexApplication commitPendingSyntheticItems(
+ AppView<AppInfo> appView, DexApplication application) {
+ if (appView.getSyntheticItems().hasPendingSyntheticClasses()) {
+ appView.setAppInfo(
+ new AppInfo(
+ appView.appInfo().getSyntheticItems().commit(application),
+ appView.appInfo().getMainDexInfo()));
+ application = appView.appInfo().app();
+ }
+ return application;
+ }
+
+ private void postProcessingDesugaringForD8(
+ D8MethodProcessor methodProcessor, ExecutorService executorService)
+ throws ExecutionException {
+ D8CfPostProcessingDesugaringEventConsumer eventConsumer =
+ CfPostProcessingDesugaringEventConsumer.createForD8(methodProcessor, appView);
+ methodProcessor.newWave();
+ InterfaceMethodProcessorFacade interfaceDesugaring =
+ instructionDesugaring.getInterfaceMethodPostProcessingDesugaring(ExcludeDexResources);
+ CfPostProcessingDesugaringCollection.create(
+ appView, interfaceDesugaring, instructionDesugaring.getRetargetingInfo())
+ .postProcessingDesugaring(eventConsumer, executorService);
+ eventConsumer.finalizeDesugaring();
+ }
+
+ private void convertClasses(D8MethodProcessor methodProcessor, ExecutorService executorService)
+ throws ExecutionException {
ClassConverterResult classConverterResult =
ClassConverter.create(appView, this, methodProcessor).convertClasses(executorService);
@@ -796,7 +815,7 @@
printPhase("Interface method desugaring");
finalizeInterfaceMethodRewritingThroughIR(executorService);
- runInterfaceDesugaringProcessors(IncludeAllResources, executorService);
+ runInterfaceDesugaringProcessorsForR8(IncludeAllResources, executorService);
feedback.updateVisibleOptimizationInfo();
printPhase("Desugared library API Conversion finalization");
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringCollection.java b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringCollection.java
index 6efa25b..8512734 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringCollection.java
@@ -8,6 +8,8 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.desugar.desugaredlibrary.RetargetingInfo;
+import com.android.tools.r8.ir.desugar.itf.InterfaceMethodProcessorFacade;
+import com.android.tools.r8.ir.desugar.itf.InterfaceMethodRewriter.Flavor;
import com.android.tools.r8.ir.desugar.nest.D8NestBasedAccessDesugaring;
import com.android.tools.r8.utils.ThrowingConsumer;
@@ -58,5 +60,8 @@
public abstract <T extends Throwable> void withD8NestBasedAccessDesugaring(
ThrowingConsumer<D8NestBasedAccessDesugaring, T> consumer) throws T;
+ public abstract InterfaceMethodProcessorFacade getInterfaceMethodPostProcessingDesugaring(
+ Flavor flavor);
+
public abstract RetargetingInfo getRetargetingInfo();
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaring.java
index 2a2de5f..38a0413 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaring.java
@@ -3,7 +3,12 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.desugar;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+
public interface CfPostProcessingDesugaring {
- void postProcessingDesugaring(CfPostProcessingDesugaringEventConsumer eventConsumer);
+ void postProcessingDesugaring(
+ CfPostProcessingDesugaringEventConsumer eventConsumer, ExecutorService executorService)
+ throws ExecutionException;
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringCollection.java b/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringCollection.java
index f659ad8..986c6ea 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringCollection.java
@@ -6,15 +6,21 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryRetargeterPostProcessor;
import com.android.tools.r8.ir.desugar.desugaredlibrary.RetargetingInfo;
-import java.util.Collections;
+import com.android.tools.r8.ir.desugar.itf.InterfaceMethodProcessorFacade;
+import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
public abstract class CfPostProcessingDesugaringCollection {
public static CfPostProcessingDesugaringCollection create(
- AppView<?> appView, RetargetingInfo retargetingInfo) {
+ AppView<?> appView,
+ InterfaceMethodProcessorFacade interfaceMethodProcessorFacade,
+ RetargetingInfo retargetingInfo) {
if (appView.options().desugarState.isOn()) {
- return NonEmptyCfPostProcessingDesugaringCollection.create(appView, retargetingInfo);
+ return NonEmptyCfPostProcessingDesugaringCollection.create(
+ appView, interfaceMethodProcessorFacade, retargetingInfo);
}
return empty();
}
@@ -24,7 +30,8 @@
}
public abstract void postProcessingDesugaring(
- CfPostProcessingDesugaringEventConsumer eventConsumer);
+ CfPostProcessingDesugaringEventConsumer eventConsumer, ExecutorService executorService)
+ throws ExecutionException;
public static class NonEmptyCfPostProcessingDesugaringCollection
extends CfPostProcessingDesugaringCollection {
@@ -37,19 +44,29 @@
}
public static CfPostProcessingDesugaringCollection create(
- AppView<?> appView, RetargetingInfo retargetingInfo) {
- if (appView.options().desugaredLibraryConfiguration.getRetargetCoreLibMember().isEmpty()) {
+ AppView<?> appView,
+ InterfaceMethodProcessorFacade interfaceMethodProcessorFacade,
+ RetargetingInfo retargetingInfo) {
+ if (appView.options().desugaredLibraryConfiguration.getRetargetCoreLibMember().isEmpty()
+ && interfaceMethodProcessorFacade == null) {
return empty();
}
- return new NonEmptyCfPostProcessingDesugaringCollection(
- Collections.singletonList(
- new DesugaredLibraryRetargeterPostProcessor(appView, retargetingInfo)));
+ ArrayList<CfPostProcessingDesugaring> desugarings = new ArrayList<>();
+ if (!appView.options().desugaredLibraryConfiguration.getRetargetCoreLibMember().isEmpty()) {
+ desugarings.add(new DesugaredLibraryRetargeterPostProcessor(appView, retargetingInfo));
+ }
+ if (interfaceMethodProcessorFacade != null) {
+ desugarings.add(interfaceMethodProcessorFacade);
+ }
+ return new NonEmptyCfPostProcessingDesugaringCollection(desugarings);
}
@Override
- public void postProcessingDesugaring(CfPostProcessingDesugaringEventConsumer eventConsumer) {
+ public void postProcessingDesugaring(
+ CfPostProcessingDesugaringEventConsumer eventConsumer, ExecutorService executorService)
+ throws ExecutionException {
for (CfPostProcessingDesugaring desugaring : desugarings) {
- desugaring.postProcessingDesugaring(eventConsumer);
+ desugaring.postProcessingDesugaring(eventConsumer, executorService);
}
}
}
@@ -67,7 +84,9 @@
}
@Override
- public void postProcessingDesugaring(CfPostProcessingDesugaringEventConsumer eventConsumer) {
+ public void postProcessingDesugaring(
+ CfPostProcessingDesugaringEventConsumer eventConsumer, ExecutorService executorService)
+ throws ExecutionException {
// Intentionally empty.
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java
index dc67ee9..5734cab 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java
@@ -11,7 +11,10 @@
import com.android.tools.r8.ir.conversion.D8MethodProcessor;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAPIConverter;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryRetargeterInstructionEventConsumer.DesugaredLibraryRetargeterPostProcessingEventConsumer;
+import com.android.tools.r8.ir.desugar.itf.InterfaceProcessingDesugaringEventConsumer;
import com.android.tools.r8.shaking.Enqueuer.SyntheticAdditions;
+import com.android.tools.r8.utils.collections.ProgramMethodSet;
+import java.util.concurrent.ExecutionException;
/**
* Specialized Event consumer for desugaring finalization. During finalization, it is not possible
@@ -19,7 +22,8 @@
* explicit calls must be done here.
*/
public abstract class CfPostProcessingDesugaringEventConsumer
- implements DesugaredLibraryRetargeterPostProcessingEventConsumer {
+ implements DesugaredLibraryRetargeterPostProcessingEventConsumer,
+ InterfaceProcessingDesugaringEventConsumer {
protected DesugaredLibraryAPIConverter desugaredLibraryAPIConverter;
protected CfPostProcessingDesugaringEventConsumer(AppView<?> appView) {
@@ -36,13 +40,14 @@
return new R8PostProcessingDesugaringEventConsumer(appView, additions);
}
- public void finalizeDesugaring() {
- desugaredLibraryAPIConverter.generateTrackingWarnings();
- }
+ public abstract void finalizeDesugaring() throws ExecutionException;
public static class D8CfPostProcessingDesugaringEventConsumer
extends CfPostProcessingDesugaringEventConsumer {
private final D8MethodProcessor methodProcessor;
+ // Methods cannot be processed directly because we cannot add method to classes while
+ // concurrently processing other methods.
+ private final ProgramMethodSet methodsToReprocess = ProgramMethodSet.createConcurrent();
private D8CfPostProcessingDesugaringEventConsumer(
D8MethodProcessor methodProcessor, AppView<?> appView) {
@@ -52,7 +57,7 @@
@Override
public void acceptDesugaredLibraryRetargeterDispatchProgramClass(DexProgramClass clazz) {
- methodProcessor.scheduleDesugaredMethodsForProcessing(clazz.programMethods());
+ methodsToReprocess.addAll(clazz.programMethods());
}
@Override
@@ -67,9 +72,25 @@
@Override
public void acceptForwardingMethod(ProgramMethod method) {
- methodProcessor.scheduleDesugaredMethodForProcessing(method);
- // TODO(b/189912077): Uncomment when API conversion is performed cf to cf in D8.
- // desugaredLibraryAPIConverter.generateCallbackIfRequired(method);
+ methodsToReprocess.add(method);
+ }
+
+ @Override
+ public void acceptCompanionClassClinit(ProgramMethod method) {
+ methodsToReprocess.add(method);
+ }
+
+ @Override
+ public void acceptEmulatedInterfaceMethod(ProgramMethod method) {
+ methodsToReprocess.add(method);
+ }
+
+ @Override
+ public void finalizeDesugaring() throws ExecutionException {
+ assert methodProcessor.verifyNoPendingMethodProcessing();
+ methodProcessor.newWave();
+ methodProcessor.scheduleDesugaredMethodsForProcessing(methodsToReprocess);
+ methodProcessor.awaitMethodProcessing();
}
}
@@ -84,6 +105,11 @@
}
@Override
+ public void finalizeDesugaring() throws ExecutionException {
+ desugaredLibraryAPIConverter.generateTrackingWarnings();
+ }
+
+ @Override
public void acceptDesugaredLibraryRetargeterDispatchProgramClass(DexProgramClass clazz) {
additions.addLiveMethods(clazz.programMethods());
}
@@ -106,5 +132,15 @@
additions.addLiveMethod(callback);
}
}
+
+ @Override
+ public void acceptCompanionClassClinit(ProgramMethod method) {
+ assert false : "TODO(b/183998768): Support Interface processing in R8";
+ }
+
+ @Override
+ public void acceptEmulatedInterfaceMethod(ProgramMethod method) {
+ assert false : "TODO(b/183998768): Support Interface processing in R8";
+ }
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/EmptyCfInstructionDesugaringCollection.java b/src/main/java/com/android/tools/r8/ir/desugar/EmptyCfInstructionDesugaringCollection.java
index 61c9617..7991ac3 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/EmptyCfInstructionDesugaringCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/EmptyCfInstructionDesugaringCollection.java
@@ -8,6 +8,8 @@
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.desugar.CfClassDesugaringCollection.EmptyCfClassDesugaringCollection;
import com.android.tools.r8.ir.desugar.desugaredlibrary.RetargetingInfo;
+import com.android.tools.r8.ir.desugar.itf.InterfaceMethodProcessorFacade;
+import com.android.tools.r8.ir.desugar.itf.InterfaceMethodRewriter.Flavor;
import com.android.tools.r8.ir.desugar.nest.D8NestBasedAccessDesugaring;
import com.android.tools.r8.utils.ThrowingConsumer;
@@ -63,6 +65,11 @@
}
@Override
+ public InterfaceMethodProcessorFacade getInterfaceMethodPostProcessingDesugaring(Flavor flavor) {
+ return null;
+ }
+
+ @Override
public RetargetingInfo getRetargetingInfo() {
return null;
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java b/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java
index 150fc0a..a7f1a33 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java
@@ -17,7 +17,9 @@
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryRetargeter;
import com.android.tools.r8.ir.desugar.desugaredlibrary.RetargetingInfo;
import com.android.tools.r8.ir.desugar.invokespecial.InvokeSpecialToSelfDesugaring;
+import com.android.tools.r8.ir.desugar.itf.InterfaceMethodProcessorFacade;
import com.android.tools.r8.ir.desugar.itf.InterfaceMethodRewriter;
+import com.android.tools.r8.ir.desugar.itf.InterfaceMethodRewriter.Flavor;
import com.android.tools.r8.ir.desugar.lambda.LambdaInstructionDesugaring;
import com.android.tools.r8.ir.desugar.nest.D8NestBasedAccessDesugaring;
import com.android.tools.r8.ir.desugar.nest.NestBasedAccessDesugaring;
@@ -42,6 +44,7 @@
private final NestBasedAccessDesugaring nestBasedAccessDesugaring;
private final RecordRewriter recordRewriter;
private final DesugaredLibraryRetargeter desugaredLibraryRetargeter;
+ private final InterfaceMethodRewriter interfaceMethodRewriter;
NonEmptyCfInstructionDesugaringCollection(AppView<?> appView) {
this.appView = appView;
@@ -49,6 +52,7 @@
this.nestBasedAccessDesugaring = null;
this.recordRewriter = null;
this.desugaredLibraryRetargeter = null;
+ this.interfaceMethodRewriter = null;
return;
}
this.nestBasedAccessDesugaring = NestBasedAccessDesugaring.create(appView);
@@ -68,11 +72,14 @@
desugarings.add(new TwrInstructionDesugaring(appView));
}
// TODO(b/183998768): Enable interface method rewriter cf to cf also in R8.
- if (appView.options().isInterfaceMethodDesugaringEnabled()
- && !appView.enableWholeProgramOptimizations()) {
- desugarings.add(
- new InterfaceMethodRewriter(
- appView, backportedMethodRewriter, desugaredLibraryRetargeter));
+ interfaceMethodRewriter =
+ appView.options().isInterfaceMethodDesugaringEnabled()
+ && !appView.enableWholeProgramOptimizations()
+ ? new InterfaceMethodRewriter(
+ appView, backportedMethodRewriter, desugaredLibraryRetargeter)
+ : null;
+ if (interfaceMethodRewriter != null) {
+ desugarings.add(interfaceMethodRewriter);
}
desugarings.add(new LambdaInstructionDesugaring(appView));
desugarings.add(new InvokeSpecialToSelfDesugaring(appView));
@@ -312,6 +319,13 @@
}
@Override
+ public InterfaceMethodProcessorFacade getInterfaceMethodPostProcessingDesugaring(Flavor flavor) {
+ return interfaceMethodRewriter != null
+ ? interfaceMethodRewriter.getPostProcessingDesugaring(flavor)
+ : null;
+ }
+
+ @Override
public RetargetingInfo getRetargetingInfo() {
if (desugaredLibraryRetargeter != null) {
return desugaredLibraryRetargeter.getRetargetingInfo();
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterPostProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterPostProcessor.java
index 0b0039e..dac3079 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterPostProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterPostProcessor.java
@@ -23,6 +23,8 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
// The rewrite of virtual calls requires to go through emulate dispatch. This class is responsible
// for inserting interfaces on library boundaries and forwarding methods in the program, and to
@@ -41,7 +43,9 @@
}
@Override
- public void postProcessingDesugaring(CfPostProcessingDesugaringEventConsumer eventConsumer) {
+ public void postProcessingDesugaring(
+ CfPostProcessingDesugaringEventConsumer eventConsumer, ExecutorService executorService)
+ throws ExecutionException {
if (appView.options().isDesugaredLibraryCompilation()) {
ensureEmulatedDispatchMethodsSynthesized(eventConsumer);
} else {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/ClassProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/ClassProcessor.java
index d86d22c..14e5fea 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/ClassProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/ClassProcessor.java
@@ -380,7 +380,8 @@
}
@Override
- public void process(DexProgramClass clazz, ProgramMethodSet synthesizedMethods) {
+ public void process(
+ DexProgramClass clazz, InterfaceProcessingDesugaringEventConsumer eventConsumer) {
if (!clazz.isInterface()) {
visitClassInfo(clazz, new ReportingContext(clazz, clazz));
}
@@ -389,11 +390,11 @@
// We introduce forwarding methods only once all desugaring has been performed to avoid
// confusing the look-up with inserted forwarding methods.
@Override
- public final void finalizeProcessing(ProgramMethodSet synthesizedMethods) {
+ public final void finalizeProcessing(InterfaceProcessingDesugaringEventConsumer eventConsumer) {
newSyntheticMethods.forEach(
(clazz, newForwardingMethods) -> {
clazz.addVirtualMethods(newForwardingMethods.toDefinitionSet());
- newForwardingMethods.forEach(synthesizedMethods::add);
+ newForwardingMethods.forEach(eventConsumer::acceptForwardingMethod);
});
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/EmulatedInterfaceProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/EmulatedInterfaceProcessor.java
index 46bd871..1c29a09 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/EmulatedInterfaceProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/EmulatedInterfaceProcessor.java
@@ -19,7 +19,6 @@
import com.android.tools.r8.synthesis.SyntheticNaming;
import com.android.tools.r8.utils.Pair;
import com.android.tools.r8.utils.StringDiagnostic;
-import com.android.tools.r8.utils.collections.ProgramMethodSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import java.util.ArrayList;
@@ -89,7 +88,7 @@
}
DexProgramClass ensureEmulateInterfaceLibrary(
- DexProgramClass emulatedInterface, ProgramMethodSet synthesizedMethods) {
+ DexProgramClass emulatedInterface, InterfaceProcessingDesugaringEventConsumer eventConsumer) {
assert rewriter.isEmulatedInterface(emulatedInterface.type);
DexProgramClass emulateInterfaceClass =
appView
@@ -107,7 +106,7 @@
synthesizeEmulatedInterfaceMethod(
method, emulatedInterface, methodBuilder))),
ignored -> {});
- emulateInterfaceClass.forEachProgramMethod(synthesizedMethods::add);
+ emulateInterfaceClass.forEachProgramMethod(eventConsumer::acceptEmulatedInterfaceMethod);
assert emulateInterfaceClass.getType()
== InterfaceMethodRewriter.getEmulateLibraryInterfaceClassType(
emulatedInterface.type, appView.dexItemFactory());
@@ -212,14 +211,15 @@
}
@Override
- public void process(DexProgramClass emulatedInterface, ProgramMethodSet synthesizedMethods) {
+ public void process(
+ DexProgramClass emulatedInterface, InterfaceProcessingDesugaringEventConsumer eventConsumer) {
if (!appView.options().isDesugaredLibraryCompilation()
|| !rewriter.isEmulatedInterface(emulatedInterface.type)
|| appView.isAlreadyLibraryDesugared(emulatedInterface)) {
return;
}
if (needsEmulateInterfaceLibrary(emulatedInterface)) {
- ensureEmulateInterfaceLibrary(emulatedInterface, synthesizedMethods);
+ ensureEmulateInterfaceLibrary(emulatedInterface, eventConsumer);
}
}
@@ -228,7 +228,7 @@
}
@Override
- public void finalizeProcessing(ProgramMethodSet synthesizedMethods) {
+ public void finalizeProcessing(InterfaceProcessingDesugaringEventConsumer eventConsumer) {
warnMissingEmulatedInterfaces();
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringProcessor.java
index 7f3d047..4f4ba32 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringProcessor.java
@@ -5,7 +5,6 @@
package com.android.tools.r8.ir.desugar.itf;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.utils.collections.ProgramMethodSet;
public interface InterfaceDesugaringProcessor {
@@ -14,11 +13,11 @@
// so this phase cannot modify the classes themselves (for example insertion/removal of methods).
// The phase can insert new classes with new methods, such as emulated interface dispatch classes
// or companion classes with their methods.
- void process(DexProgramClass clazz, ProgramMethodSet synthesizedMethods);
+ void process(DexProgramClass clazz, InterfaceProcessingDesugaringEventConsumer eventConsumer);
// The finalization phase is done at a join point, after all code desugaring have been performed.
// All finalization phases of all desugaring processors are performed sequentially.
// Complex computations should be avoided if possible here and be moved to the concurrent phase.
// Classes may be mutated here (new methods can be inserted, etc.).
- void finalizeProcessing(ProgramMethodSet synthesizedMethods);
+ void finalizeProcessing(InterfaceProcessingDesugaringEventConsumer eventConsumer);
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodProcessorFacade.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodProcessorFacade.java
index 731316f..71844b0 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodProcessorFacade.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodProcessorFacade.java
@@ -6,7 +6,10 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.conversion.IRConverter;
+import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaring;
+import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.itf.InterfaceMethodRewriter.Flavor;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.collections.SortedProgramMethodSet;
@@ -16,21 +19,22 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
-class InterfaceMethodProcessorFacade {
+public class InterfaceMethodProcessorFacade implements CfPostProcessingDesugaring {
private final AppView<?> appView;
+ private final Flavor flavour;
+ private final List<InterfaceDesugaringProcessor> interfaceDesugaringProcessors;
- InterfaceMethodProcessorFacade(AppView<?> appView) {
+ InterfaceMethodProcessorFacade(
+ AppView<?> appView, Flavor flavour, InterfaceMethodRewriter rewriter) {
this.appView = appView;
+ this.flavour = flavour;
+ interfaceDesugaringProcessors = instantiateInterfaceDesugaringProcessors(appView, rewriter);
}
- /** Runs the interfaceProcessor, the class processor and the emulated interface processor. */
- void runInterfaceDesugaringProcessors(
- InterfaceMethodRewriter rewriter,
- IRConverter converter,
- Flavor flavour,
- ExecutorService executorService)
- throws ExecutionException {
+ private List<InterfaceDesugaringProcessor> instantiateInterfaceDesugaringProcessors(
+ AppView<?> appView, InterfaceMethodRewriter rewriter) {
+
// During L8 compilation, emulated interfaces are processed to be renamed, to have
// their interfaces fixed-up and to generate the emulated dispatch code.
EmulatedInterfaceProcessor emulatedInterfaceProcessor =
@@ -46,17 +50,47 @@
// classes if needed.
InterfaceProcessor interfaceProcessor = new InterfaceProcessor(appView, rewriter);
- // The interface processors must be ordered so that finalization of the processing is performed
- // in that order. The emulatedInterfaceProcessor has to be last at this point to avoid renaming
- // emulated interfaces before the other processing.
- ImmutableList<InterfaceDesugaringProcessor> orderedInterfaceDesugaringProcessors =
- ImmutableList.of(classProcessor, interfaceProcessor, emulatedInterfaceProcessor);
+ // The processors can be listed in any order.
+ return ImmutableList.of(classProcessor, interfaceProcessor, emulatedInterfaceProcessor);
+ }
+
+ /** Runs the interfaceProcessor, the class processor and the emulated interface processor. */
+ void runInterfaceDesugaringProcessorsForR8(IRConverter converter, ExecutorService executorService)
+ throws ExecutionException {
+
+ CollectingInterfaceDesugaringEventConsumer eventConsumer =
+ new CollectingInterfaceDesugaringEventConsumer();
+ processClassesConcurrently(eventConsumer, executorService);
+ converter.processMethodsConcurrently(
+ eventConsumer.getSortedSynthesizedMethods(), executorService);
+ }
+
+ // This temporary class avoids the duality between collecting with IR processing and
+ // having events with the Cf desugaring.
+ private static class CollectingInterfaceDesugaringEventConsumer
+ implements InterfaceProcessingDesugaringEventConsumer {
SortedProgramMethodSet sortedSynthesizedMethods = SortedProgramMethodSet.createConcurrent();
- processClassesConcurrently(
- orderedInterfaceDesugaringProcessors, sortedSynthesizedMethods, flavour, executorService);
- assert converter != null;
- converter.processMethodsConcurrently(sortedSynthesizedMethods, executorService);
+
+ @Override
+ public void acceptForwardingMethod(ProgramMethod method) {
+ sortedSynthesizedMethods.add(method);
+ }
+
+ @Override
+ public void acceptCompanionClassClinit(ProgramMethod method) {
+ sortedSynthesizedMethods.add(method);
+ }
+
+ @Override
+ public void acceptEmulatedInterfaceMethod(ProgramMethod method) {
+
+ sortedSynthesizedMethods.add(method);
+ }
+
+ public SortedProgramMethodSet getSortedSynthesizedMethods() {
+ return sortedSynthesizedMethods;
+ }
}
private boolean shouldProcess(DexProgramClass clazz, Flavor flavour) {
@@ -67,22 +101,28 @@
}
private void processClassesConcurrently(
- List<InterfaceDesugaringProcessor> processors,
- SortedProgramMethodSet sortedSynthesizedMethods,
- Flavor flavour,
- ExecutorService executorService)
+ InterfaceProcessingDesugaringEventConsumer eventConsumer, ExecutorService executorService)
throws ExecutionException {
ThreadUtils.processItems(
Iterables.filter(
appView.appInfo().classes(), (DexProgramClass clazz) -> shouldProcess(clazz, flavour)),
clazz -> {
- for (InterfaceDesugaringProcessor processor : processors) {
- processor.process(clazz, sortedSynthesizedMethods);
+ for (InterfaceDesugaringProcessor processor : interfaceDesugaringProcessors) {
+ processor.process(clazz, eventConsumer);
}
},
executorService);
- for (InterfaceDesugaringProcessor processor : processors) {
- processor.finalizeProcessing(sortedSynthesizedMethods);
+ for (InterfaceDesugaringProcessor processor : interfaceDesugaringProcessors) {
+ processor.finalizeProcessing(eventConsumer);
}
}
+
+ @Override
+ public void postProcessingDesugaring(
+ CfPostProcessingDesugaringEventConsumer eventConsumer, ExecutorService executorService)
+ throws ExecutionException {
+ // TODO(b/183998768): Would be nice to use the ClassProcessing for the processing of classes,
+ // and do here only the finalization.
+ processClassesConcurrently(eventConsumer, executorService);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
index 6ab6f1f..3e93691 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
@@ -1376,11 +1376,15 @@
this.synthesizedMethods.clear();
}
- public void runInterfaceDesugaringProcessors(
+ public void runInterfaceDesugaringProcessorsForR8(
IRConverter converter, Flavor flavour, ExecutorService executorService)
throws ExecutionException {
- new InterfaceMethodProcessorFacade(appView)
- .runInterfaceDesugaringProcessors(this, converter, flavour, executorService);
+ getPostProcessingDesugaring(flavour)
+ .runInterfaceDesugaringProcessorsForR8(converter, executorService);
+ }
+
+ public InterfaceMethodProcessorFacade getPostProcessingDesugaring(Flavor flavour) {
+ return new InterfaceMethodProcessorFacade(appView, flavour, this);
}
final boolean isDefaultMethod(DexEncodedMethod method) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessingDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessingDesugaringEventConsumer.java
new file mode 100644
index 0000000..2581364
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessingDesugaringEventConsumer.java
@@ -0,0 +1,16 @@
+// Copyright (c) 2021, 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.ir.desugar.itf;
+
+import com.android.tools.r8.graph.ProgramMethod;
+
+public interface InterfaceProcessingDesugaringEventConsumer {
+
+ void acceptForwardingMethod(ProgramMethod method);
+
+ void acceptCompanionClassClinit(ProgramMethod method);
+
+ void acceptEmulatedInterfaceMethod(ProgramMethod method);
+}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessor.java
index cb752ad..2dd65a9 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessor.java
@@ -47,7 +47,6 @@
import com.android.tools.r8.utils.collections.BidirectionalOneToOneHashMap;
import com.android.tools.r8.utils.collections.BidirectionalOneToOneMap;
import com.android.tools.r8.utils.collections.MutableBidirectionalOneToOneMap;
-import com.android.tools.r8.utils.collections.ProgramMethodSet;
import com.google.common.collect.ImmutableList;
import java.util.ArrayDeque;
import java.util.ArrayList;
@@ -80,12 +79,13 @@
}
@Override
- public void process(DexProgramClass iface, ProgramMethodSet synthesizedMethods) {
+ public void process(
+ DexProgramClass iface, InterfaceProcessingDesugaringEventConsumer eventConsumer) {
if (!iface.isInterface()) {
return;
}
analyzeBridges(iface);
- ensureCompanionClassMethods(iface, synthesizedMethods);
+ ensureCompanionClassMethods(iface, eventConsumer);
}
private void analyzeBridges(DexProgramClass iface) {
@@ -99,8 +99,8 @@
}
private void ensureCompanionClassMethods(
- DexProgramClass iface, ProgramMethodSet synthesizedMethods) {
- ensureCompanionClassInitializesInterface(iface, synthesizedMethods);
+ DexProgramClass iface, InterfaceProcessingDesugaringEventConsumer eventConsumer) {
+ ensureCompanionClassInitializesInterface(iface, eventConsumer);
// TODO(b/183998768): Once fixed, the methods should be added for processing.
// D8 and R8 don't need to optimize the methods since they are just moved from interfaces and
// don't need to be re-processed.
@@ -134,7 +134,7 @@
}
private void ensureCompanionClassInitializesInterface(
- DexProgramClass iface, ProgramMethodSet synthesizedMethods) {
+ DexProgramClass iface, InterfaceProcessingDesugaringEventConsumer eventConsumer) {
if (!hasStaticMethodThatTriggersNonTrivialClassInitializer(iface)) {
return;
}
@@ -146,7 +146,7 @@
appView.dexItemFactory().createProto(appView.dexItemFactory().voidType),
appView,
methodBuilder -> createCompanionClassInitializer(iface, clinitField, methodBuilder));
- synthesizedMethods.add(clinit);
+ eventConsumer.acceptCompanionClassClinit(clinit);
}
private DexEncodedField ensureStaticClinitFieldToTriggerInterfaceInitialization(
@@ -441,7 +441,7 @@
}
@Override
- public void finalizeProcessing(ProgramMethodSet synthesizedMethods) {
+ public void finalizeProcessing(InterfaceProcessingDesugaringEventConsumer eventConsumer) {
InterfaceProcessorNestedGraphLens graphLens = postProcessInterfaces();
if (appView.enableWholeProgramOptimizations() && graphLens != null) {
appView.setGraphLens(graphLens);
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 20366b4..645d5b9 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -3890,14 +3890,14 @@
}
}
- private void postProcessingDesugaring() {
+ private void postProcessingDesugaring() throws ExecutionException {
SyntheticAdditions syntheticAdditions =
new SyntheticAdditions(appView.createProcessorContext());
R8PostProcessingDesugaringEventConsumer eventConsumer =
CfPostProcessingDesugaringEventConsumer.createForR8(appView, syntheticAdditions);
- CfPostProcessingDesugaringCollection.create(appView, desugaring.getRetargetingInfo())
- .postProcessingDesugaring(eventConsumer);
+ CfPostProcessingDesugaringCollection.create(appView, null, desugaring.getRetargetingInfo())
+ .postProcessingDesugaring(eventConsumer, executorService);
if (syntheticAdditions.isEmpty()) {
return;