Revert removal of IR processing in D8 due to Google 3 issues
Blocking bugs below.
Revert "Interface processing as post processing in D8"
This reverts commit 79f75ed44e00bd6d0e5996ff854117939c1f0ed8.
Revert "Desugared lib API conversion D8 Cf to Cf"
This reverts commit df7a8a3a9be6b7ef56a852eca07de72f37d582a9.
Revert "No IR in Cf to Cf D8"
This reverts commit ca45fed7f1b1f5cb0870344c713327ab8fa5acf3.
Revert "InterfaceMethodProcessorFacade clean-up"
This reverts commit fc459a413afdfe1aacf78d0f7382e3ac4cb67c82.
Revert "Do not process forwarding methods while adding them"
This reverts commit 69a1e1774a35e8d7f91ad7a3d5c3f2548706cebf.
Bug: 193001902
Bug: 193002912
Bug: 193002915
Change-Id: I574f98e4905b23997156a8fe199815ea6e025280
diff --git a/src/main/java/com/android/tools/r8/graph/analysis/DesugaredLibraryConversionWrapperAnalysis.java b/src/main/java/com/android/tools/r8/graph/analysis/DesugaredLibraryConversionWrapperAnalysis.java
index c9788bd..28d6be7 100644
--- a/src/main/java/com/android/tools/r8/graph/analysis/DesugaredLibraryConversionWrapperAnalysis.java
+++ b/src/main/java/com/android/tools/r8/graph/analysis/DesugaredLibraryConversionWrapperAnalysis.java
@@ -8,8 +8,6 @@
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.ProgramDefinition;
import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.ir.code.Invoke;
-import com.android.tools.r8.ir.code.Invoke.Type;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAPIConverter;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAPIConverter.Mode;
import com.android.tools.r8.utils.collections.ProgramMethodSet;
@@ -32,33 +30,33 @@
converter.registerCallbackIfRequired(method);
}
- private void traceInvoke(DexMethod invokedMethod, Type invokeType, ProgramMethod context) {
- converter.registerWrappersForLibraryInvokeIfRequired(invokedMethod, invokeType, context);
+ private void traceInvoke(DexMethod invokedMethod) {
+ converter.registerWrappersForLibraryInvokeIfRequired(invokedMethod);
}
@Override
public void traceInvokeStatic(DexMethod invokedMethod, ProgramMethod context) {
- this.traceInvoke(invokedMethod, Type.STATIC, context);
+ this.traceInvoke(invokedMethod);
}
@Override
public void traceInvokeDirect(DexMethod invokedMethod, ProgramMethod context) {
- this.traceInvoke(invokedMethod, Type.DIRECT, context);
+ this.traceInvoke(invokedMethod);
}
@Override
public void traceInvokeInterface(DexMethod invokedMethod, ProgramMethod context) {
- this.traceInvoke(invokedMethod, Type.INTERFACE, context);
+ this.traceInvoke(invokedMethod);
}
@Override
public void traceInvokeSuper(DexMethod invokedMethod, ProgramMethod context) {
- this.traceInvoke(invokedMethod, Type.SUPER, context);
+ this.traceInvoke(invokedMethod);
}
@Override
public void traceInvokeVirtual(DexMethod invokedMethod, ProgramMethod context) {
- this.traceInvoke(invokedMethod, Invoke.Type.VIRTUAL, context);
+ this.traceInvoke(invokedMethod);
}
public ProgramMethodSet generateCallbackMethods() {
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 3129b82..9508da1 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,6 +13,8 @@
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;
@@ -76,11 +78,6 @@
D8CfInstructionDesugaringEventConsumer instructionDesugaringEventConsumer =
CfInstructionDesugaringEventConsumer.createForD8(methodProcessor);
- // TODO(b/191656218): Move upfront the loop and use maybe the class event consumer.
- if (appView.options().isDesugaredLibraryCompilation()) {
- converter.ensureWrappersForL8(instructionDesugaringEventConsumer);
- }
-
// Process the wave and wait for all IR processing to complete.
methodProcessor.newWave();
ThreadUtils.processItems(
@@ -115,6 +112,13 @@
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 e3f6065..0b3c524 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,13 +51,11 @@
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;
@@ -96,6 +94,7 @@
import com.android.tools.r8.ir.optimize.string.StringOptimizer;
import com.android.tools.r8.ir.regalloc.LinearScanRegisterAllocator;
import com.android.tools.r8.ir.regalloc.RegisterAllocator;
+import com.android.tools.r8.ir.synthetic.SynthesizedCode;
import com.android.tools.r8.logging.Log;
import com.android.tools.r8.naming.IdentifierNameStringMarker;
import com.android.tools.r8.position.MethodPosition;
@@ -227,8 +226,12 @@
assert options.desugarState.isOn();
this.instructionDesugaring = CfInstructionDesugaringCollection.create(appView);
this.classDesugaring = instructionDesugaring.createClassDesugaringCollection();
- this.interfaceMethodRewriter = null;
- this.desugaredLibraryAPIConverter = null;
+ this.interfaceMethodRewriter =
+ options.desugaredLibraryConfiguration.getEmulateLibraryInterface().isEmpty()
+ ? null
+ : new InterfaceMethodRewriter(appView, this);
+ this.desugaredLibraryAPIConverter =
+ new DesugaredLibraryAPIConverter(appView, Mode.GENERATE_CALLBACKS_AND_WRAPPERS);
this.covariantReturnTypeAnnotationTransformer = null;
this.dynamicTypeOptimization = null;
this.classInliner = null;
@@ -256,7 +259,7 @@
: CfInstructionDesugaringCollection.create(appView);
this.classDesugaring = instructionDesugaring.createClassDesugaringCollection();
this.interfaceMethodRewriter =
- options.isInterfaceMethodDesugaringEnabled() && appView.enableWholeProgramOptimizations()
+ options.isInterfaceMethodDesugaringEnabled()
? new InterfaceMethodRewriter(appView, this)
: null;
this.covariantReturnTypeAnnotationTransformer =
@@ -320,7 +323,10 @@
this.identifierNameStringMarker = null;
this.devirtualizer = null;
this.typeChecker = null;
- this.desugaredLibraryAPIConverter = null;
+ this.desugaredLibraryAPIConverter =
+ appView.rewritePrefix.isRewriting()
+ ? new DesugaredLibraryAPIConverter(appView, Mode.GENERATE_CALLBACKS_AND_WRAPPERS)
+ : null;
this.serviceLoaderRewriter = null;
this.methodOptimizationInfoCollector = null;
this.enumValueOptimizer = null;
@@ -361,11 +367,9 @@
D8NestBasedAccessDesugaring::clearNestAttributes);
}
- public void ensureWrappersForL8(
- D8CfInstructionDesugaringEventConsumer instructionDesugaringEventConsumer) {
- assert appView.options().isDesugaredLibraryCompilation();
- instructionDesugaring.withDesugaredLibraryAPIConverter(
- converter -> converter.ensureWrappersForL8(instructionDesugaringEventConsumer));
+ void postProcessDesugaring(CfPostProcessingDesugaringEventConsumer eventConsumer) {
+ CfPostProcessingDesugaringCollection.create(appView, instructionDesugaring.getRetargetingInfo())
+ .postProcessingDesugaring(eventConsumer);
}
private void staticizeClasses(
@@ -390,11 +394,11 @@
}
}
- private void runInterfaceDesugaringProcessorsForR8(
+ private void runInterfaceDesugaringProcessors(
Flavor includeAllResources, ExecutorService executorService) throws ExecutionException {
assert !appView.getSyntheticItems().hasPendingSyntheticClasses();
if (interfaceMethodRewriter != null) {
- interfaceMethodRewriter.runInterfaceDesugaringProcessorsForR8(
+ interfaceMethodRewriter.runInterfaceDesugaringProcessors(
this, includeAllResources, executorService);
}
}
@@ -411,28 +415,30 @@
workaroundAbstractMethodOnNonAbstractClassVerificationBug(
executor, OptimizationFeedbackIgnore.getInstance());
DexApplication application = appView.appInfo().app();
- D8MethodProcessor methodProcessor = new D8MethodProcessor(this, executor);
-
timing.begin("IR conversion");
- convertClasses(methodProcessor, executor);
+ convertClasses(executor);
reportNestDesugarDependencies();
clearNestAttributes();
- application = commitPendingSyntheticItems(appView, application);
-
- postProcessingDesugaringForD8(methodProcessor, executor);
-
- application = commitPendingSyntheticItems(appView, application);
+ if (appView.getSyntheticItems().hasPendingSyntheticClasses()) {
+ appView.setAppInfo(
+ new AppInfo(
+ appView.appInfo().getSyntheticItems().commit(application),
+ appView.appInfo().getMainDexInfo()));
+ application = appView.appInfo().app();
+ }
// 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);
}
processCovariantReturnTypeAnnotations(builder);
+ generateDesugaredLibraryAPIWrappers(builder, executor);
timing.end();
@@ -443,33 +449,8 @@
appView.appInfo().getMainDexInfo()));
}
- 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);
- 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 {
+ private void convertClasses(ExecutorService executorService) throws ExecutionException {
+ D8MethodProcessor methodProcessor = new D8MethodProcessor(this, executorService);
ClassConverterResult classConverterResult =
ClassConverter.create(appView, this, methodProcessor).convertClasses(executorService);
@@ -482,9 +463,6 @@
rewriteEnclosingLambdaMethodAttributes(
appView, classConverterResult.getForcefullyMovedLambdaMethods());
-
- instructionDesugaring.withDesugaredLibraryAPIConverter(
- DesugaredLibraryAPIConverter::generateTrackingWarnings);
}
public void desugarClassesForD8(
@@ -593,14 +571,32 @@
}
}
- private boolean needsIRConversion() {
+ private boolean needsIRConversion(ProgramMethod method) {
if (appView.enableWholeProgramOptimizations()) {
return true;
}
if (options.testing.forceIRForCfToCfDesugar) {
return true;
}
- return !options.cfToCfDesugar;
+ if (options.isDesugaredLibraryCompilation()) {
+ return true;
+ }
+ if (!options.cfToCfDesugar) {
+ return true;
+ }
+ if (desugaredLibraryAPIConverter != null
+ && desugaredLibraryAPIConverter.shouldRegisterCallback(method)) {
+ return true;
+ }
+ if (method.getDefinition().getCode() instanceof SynthesizedCode) {
+ // SynthesizedCode needs IR to generate the code.
+ return true;
+ } else {
+ NeedsIRDesugarUseRegistry useRegistry =
+ new NeedsIRDesugarUseRegistry(method, appView, desugaredLibraryAPIConverter);
+ method.registerCodeReferences(useRegistry);
+ return useRegistry.needsDesugaring();
+ }
}
private void checkPrefixMerging(ProgramMethod method) {
@@ -801,9 +797,12 @@
printPhase("Interface method desugaring");
finalizeInterfaceMethodRewritingThroughIR(executorService);
- runInterfaceDesugaringProcessorsForR8(IncludeAllResources, executorService);
+ runInterfaceDesugaringProcessors(IncludeAllResources, executorService);
feedback.updateVisibleOptimizationInfo();
+ printPhase("Desugared library API Conversion finalization");
+ generateDesugaredLibraryAPIWrappers(builder, executorService);
+
if (serviceLoaderRewriter != null) {
processSynthesizedServiceLoaderMethods(
serviceLoaderRewriter.getServiceLoadMethods(), executorService);
@@ -967,6 +966,14 @@
removeDeadCodeAndFinalizeIR(code, OptimizationFeedbackIgnore.getInstance(), Timing.empty());
}
+ private void generateDesugaredLibraryAPIWrappers(
+ DexApplication.Builder<?> builder, ExecutorService executorService)
+ throws ExecutionException {
+ if (desugaredLibraryAPIConverter != null) {
+ desugaredLibraryAPIConverter.finalizeWrappers(builder, this, executorService);
+ }
+ }
+
private void clearDexMethodCompilationState() {
appView.appInfo().classes().forEach(this::clearDexMethodCompilationState);
}
@@ -1134,7 +1141,7 @@
options.testing.hookInIrConversion.run();
}
- if (!needsIRConversion() || options.skipIR) {
+ if (!needsIRConversion(method) || options.skipIR) {
feedback.markProcessed(method.getDefinition(), ConstraintWithTarget.NEVER);
return Timing.empty();
}
@@ -1492,9 +1499,10 @@
previous = printMethod(code, "IR after interface method rewriting (SSA)", previous);
+ // This pass has to be after interfaceMethodRewriter and BackportedMethodRewriter.
if (desugaredLibraryAPIConverter != null
- && appView.enableWholeProgramOptimizations()
- && methodProcessor.isPrimaryMethodProcessor()) {
+ && (!appView.enableWholeProgramOptimizations()
+ || methodProcessor.isPrimaryMethodProcessor())) {
timing.begin("Desugar library API");
desugaredLibraryAPIConverter.desugar(code);
timing.end();
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/NeedsIRDesugarUseRegistry.java b/src/main/java/com/android/tools/r8/ir/conversion/NeedsIRDesugarUseRegistry.java
new file mode 100644
index 0000000..0d1c587
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/conversion/NeedsIRDesugarUseRegistry.java
@@ -0,0 +1,108 @@
+// Copyright (c) 2020, 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.conversion;
+
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexCallSite;
+import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.graph.UseRegistry;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAPIConverter;
+
+class NeedsIRDesugarUseRegistry extends UseRegistry {
+
+ private boolean needsDesugaring = false;
+ private final ProgramMethod context;
+ private final DesugaredLibraryAPIConverter desugaredLibraryAPIConverter;
+
+ public NeedsIRDesugarUseRegistry(
+ ProgramMethod method,
+ AppView<?> appView,
+ DesugaredLibraryAPIConverter desugaredLibraryAPIConverter) {
+ super(appView.dexItemFactory());
+ this.context = method;
+ this.desugaredLibraryAPIConverter = desugaredLibraryAPIConverter;
+ }
+
+ public boolean needsDesugaring() {
+ return needsDesugaring;
+ }
+
+ @Override
+ public void registerInitClass(DexType type) {
+ if (!needsDesugaring
+ && desugaredLibraryAPIConverter != null
+ && desugaredLibraryAPIConverter.canConvert(type)) {
+ needsDesugaring = true;
+ }
+ }
+
+ @Override
+ public void registerInvokeVirtual(DexMethod method) {
+ registerDesugaredLibraryAPIConverter(method);
+ }
+
+ @Override
+ public void registerInvokeDirect(DexMethod method) {
+ registerDesugaredLibraryAPIConverter(method);
+ }
+
+ private void registerDesugaredLibraryAPIConverter(DexMethod method) {
+ if (!needsDesugaring) {
+ needsDesugaring =
+ desugaredLibraryAPIConverter != null
+ && desugaredLibraryAPIConverter.shouldRewriteInvoke(method);
+ }
+ }
+
+ @Override
+ public void registerInvokeStatic(DexMethod method) {
+ registerDesugaredLibraryAPIConverter(method);
+ }
+
+ @Override
+ public void registerInvokeInterface(DexMethod method) {
+ registerDesugaredLibraryAPIConverter(method);
+ }
+
+ @Override
+ public void registerInvokeStatic(DexMethod method, boolean itf) {
+ registerInvokeStatic(method);
+ }
+
+ @Override
+ public void registerCallSite(DexCallSite callSite) {
+ super.registerCallSite(callSite);
+ needsDesugaring = true;
+ }
+
+ @Override
+ public void registerInvokeSuper(DexMethod method) {
+ registerDesugaredLibraryAPIConverter(method);
+ }
+
+ @Override
+ public void registerInstanceFieldRead(DexField field) {}
+
+ @Override
+ public void registerInstanceFieldWrite(DexField field) {}
+
+ @Override
+ public void registerNewInstance(DexType type) {}
+
+ @Override
+ public void registerStaticFieldRead(DexField field) {}
+
+ @Override
+ public void registerStaticFieldWrite(DexField field) {}
+
+ @Override
+ public void registerTypeReference(DexType type) {}
+
+ @Override
+ public void registerInstanceOf(DexType type) {}
+}
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 b4f0bec..6efa25b 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
@@ -7,13 +7,9 @@
import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAPIConverter;
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;
-import java.util.function.Consumer;
/**
* Abstracts a collection of low-level desugarings (i.e., mappings from class-file instructions to
@@ -62,11 +58,5 @@
public abstract <T extends Throwable> void withD8NestBasedAccessDesugaring(
ThrowingConsumer<D8NestBasedAccessDesugaring, T> consumer) throws T;
- public abstract InterfaceMethodProcessorFacade getInterfaceMethodPostProcessingDesugaring(
- Flavor flavor);
-
public abstract RetargetingInfo getRetargetingInfo();
-
- public abstract void withDesugaredLibraryAPIConverter(
- Consumer<DesugaredLibraryAPIConverter> consumer);
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
index 83e5d08..d497332 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
@@ -15,7 +15,6 @@
import com.android.tools.r8.ir.conversion.ClassConverterResult;
import com.android.tools.r8.ir.conversion.D8MethodProcessor;
import com.android.tools.r8.ir.desugar.backports.BackportedMethodDesugaringEventConsumer;
-import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAPIConverterEventConsumer;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryRetargeterInstructionEventConsumer;
import com.android.tools.r8.ir.desugar.invokespecial.InvokeSpecialBridgeInfo;
import com.android.tools.r8.ir.desugar.invokespecial.InvokeSpecialToSelfDesugaringEventConsumer;
@@ -26,7 +25,6 @@
import com.android.tools.r8.ir.desugar.records.RecordDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.twr.TwrCloseResourceDesugaringEventConsumer;
import com.android.tools.r8.shaking.Enqueuer.SyntheticAdditions;
-import com.android.tools.r8.utils.collections.SortedProgramMethodSet;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.Collections;
@@ -35,7 +33,6 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
@@ -51,8 +48,7 @@
RecordDesugaringEventConsumer,
TwrCloseResourceDesugaringEventConsumer,
InterfaceMethodDesugaringEventConsumer,
- DesugaredLibraryRetargeterInstructionEventConsumer,
- DesugaredLibraryAPIConverterEventConsumer {
+ DesugaredLibraryRetargeterInstructionEventConsumer {
public static D8CfInstructionDesugaringEventConsumer createForD8(
D8MethodProcessor methodProcessor) {
@@ -72,26 +68,6 @@
return new CfInstructionDesugaringEventConsumer() {
@Override
- public void acceptWrapperProgramClass(DexProgramClass clazz) {
- assert false;
- }
-
- @Override
- public void acceptWrapperClasspathClass(DexClasspathClass clazz) {
- assert false;
- }
-
- @Override
- public void acceptAPIConversion(ProgramMethod method) {
- assert false;
- }
-
- @Override
- public void acceptSuperAPIConversion(ProgramMethod method) {
- assert false;
- }
-
- @Override
public void acceptDesugaredLibraryRetargeterDispatchProgramClass(DexProgramClass clazz) {
assert false;
}
@@ -171,8 +147,6 @@
private final Map<DexReference, InvokeSpecialBridgeInfo> pendingInvokeSpecialBridges =
new LinkedHashMap<>();
- private final Map<DexProgramClass, SortedProgramMethodSet> pendingSuperAPIConversions =
- new ConcurrentHashMap<>();
private final List<LambdaClass> synthesizedLambdaClasses = new ArrayList<>();
private D8CfInstructionDesugaringEventConsumer(D8MethodProcessor methodProcessor) {
@@ -255,48 +229,14 @@
methodProcessor.scheduleDesugaredMethodForProcessing(method);
}
- @Override
- public void acceptWrapperProgramClass(DexProgramClass clazz) {
- methodProcessor.scheduleDesugaredMethodsForProcessing(clazz.programMethods());
- }
-
- @Override
- public void acceptWrapperClasspathClass(DexClasspathClass clazz) {
- // Intentionally empty.
- }
-
- @Override
- public void acceptAPIConversion(ProgramMethod method) {
- methodProcessor.scheduleDesugaredMethodForProcessing(method);
- }
-
- @Override
- public void acceptSuperAPIConversion(ProgramMethod method) {
- SortedProgramMethodSet superAPIConversions =
- pendingSuperAPIConversions.computeIfAbsent(
- method.getHolder(), ignored -> SortedProgramMethodSet.createConcurrent());
- superAPIConversions.add(method);
- }
-
public List<ProgramMethod> finalizeDesugaring(
AppView<?> appView, ClassConverterResult.Builder classConverterResultBuilder) {
List<ProgramMethod> needsProcessing = new ArrayList<>();
finalizeInvokeSpecialDesugaring(appView, needsProcessing::add);
finalizeLambdaDesugaring(classConverterResultBuilder, needsProcessing::add);
- finalizeSuperAPIConversionDesugaring(needsProcessing::add);
return needsProcessing;
}
- private void finalizeSuperAPIConversionDesugaring(Consumer<ProgramMethod> needsProcessing) {
- for (SortedProgramMethodSet superAPIConversions : pendingSuperAPIConversions.values()) {
- for (ProgramMethod superAPIConversion : superAPIConversions) {
- superAPIConversion.getHolder().addDirectMethod(superAPIConversion.getDefinition());
- needsProcessing.accept(superAPIConversion);
- }
- }
- pendingSuperAPIConversions.clear();
- }
-
private void finalizeInvokeSpecialDesugaring(
AppView<?> appView, Consumer<ProgramMethod> needsProcessing) {
// Fixup the code of the new private methods have that been synthesized.
@@ -408,30 +348,6 @@
}
@Override
- public void acceptWrapperProgramClass(DexProgramClass clazz) {
- // TODO(b/189912077): There should be nothing to do.
- assert false;
- }
-
- @Override
- public void acceptWrapperClasspathClass(DexClasspathClass clazz) {
- // TODO(b/189912077): Should be added to live non program types.
- assert false;
- }
-
- @Override
- public void acceptAPIConversion(ProgramMethod method) {
- // TODO(b/189912077): There should be nothing to do.
- assert false;
- }
-
- @Override
- public void acceptSuperAPIConversion(ProgramMethod method) {
- // TODO(b/189912077): Manage pending conversions.
- assert false;
- }
-
- @Override
public void acceptBackportedMethod(ProgramMethod backportedMethod, ProgramMethod context) {
// Intentionally empty. The backported method will be hit by the tracing in R8 as if it was
// present in the input code, and thus nothing needs to be done.
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 38a0413..2a2de5f 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,12 +3,7 @@
// 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, ExecutorService executorService)
- throws ExecutionException;
+ void postProcessingDesugaring(CfPostProcessingDesugaringEventConsumer eventConsumer);
}
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 367e0ca..f659ad8 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
@@ -4,24 +4,17 @@
package com.android.tools.r8.ir.desugar;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAPIConverter;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryRetargeterPostProcessor;
import com.android.tools.r8.ir.desugar.desugaredlibrary.RetargetingInfo;
-import com.android.tools.r8.ir.desugar.itf.InterfaceMethodProcessorFacade;
-import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
public abstract class CfPostProcessingDesugaringCollection {
public static CfPostProcessingDesugaringCollection create(
- AppView<?> appView,
- InterfaceMethodProcessorFacade interfaceMethodProcessorFacade,
- RetargetingInfo retargetingInfo) {
+ AppView<?> appView, RetargetingInfo retargetingInfo) {
if (appView.options().desugarState.isOn()) {
- return NonEmptyCfPostProcessingDesugaringCollection.create(
- appView, interfaceMethodProcessorFacade, retargetingInfo);
+ return NonEmptyCfPostProcessingDesugaringCollection.create(appView, retargetingInfo);
}
return empty();
}
@@ -31,8 +24,7 @@
}
public abstract void postProcessingDesugaring(
- CfPostProcessingDesugaringEventConsumer eventConsumer, ExecutorService executorService)
- throws ExecutionException;
+ CfPostProcessingDesugaringEventConsumer eventConsumer);
public static class NonEmptyCfPostProcessingDesugaringCollection
extends CfPostProcessingDesugaringCollection {
@@ -45,37 +37,19 @@
}
public static CfPostProcessingDesugaringCollection create(
- AppView<?> appView,
- InterfaceMethodProcessorFacade interfaceMethodProcessorFacade,
- RetargetingInfo retargetingInfo) {
- ArrayList<CfPostProcessingDesugaring> desugarings = new ArrayList<>();
- if (!appView.options().desugaredLibraryConfiguration.getRetargetCoreLibMember().isEmpty()) {
- desugarings.add(new DesugaredLibraryRetargeterPostProcessor(appView, retargetingInfo));
- }
- if (interfaceMethodProcessorFacade != null) {
- desugarings.add(interfaceMethodProcessorFacade);
- }
- DesugaredLibraryAPIConverter desugaredLibraryAPIConverter =
- appView.rewritePrefix.isRewriting() && !appView.enableWholeProgramOptimizations()
- ? new DesugaredLibraryAPIConverter(appView, null)
- : null;
- // At this point the desugaredLibraryAPIConverter is required to be last to generate
- // call-backs on the forwarding methods.
- if (desugaredLibraryAPIConverter != null) {
- desugarings.add(desugaredLibraryAPIConverter);
- }
- if (desugarings.isEmpty()) {
+ AppView<?> appView, RetargetingInfo retargetingInfo) {
+ if (appView.options().desugaredLibraryConfiguration.getRetargetCoreLibMember().isEmpty()) {
return empty();
}
- return new NonEmptyCfPostProcessingDesugaringCollection(desugarings);
+ return new NonEmptyCfPostProcessingDesugaringCollection(
+ Collections.singletonList(
+ new DesugaredLibraryRetargeterPostProcessor(appView, retargetingInfo)));
}
@Override
- public void postProcessingDesugaring(
- CfPostProcessingDesugaringEventConsumer eventConsumer, ExecutorService executorService)
- throws ExecutionException {
+ public void postProcessingDesugaring(CfPostProcessingDesugaringEventConsumer eventConsumer) {
for (CfPostProcessingDesugaring desugaring : desugarings) {
- desugaring.postProcessingDesugaring(eventConsumer, executorService);
+ desugaring.postProcessingDesugaring(eventConsumer);
}
}
}
@@ -93,9 +67,7 @@
}
@Override
- public void postProcessingDesugaring(
- CfPostProcessingDesugaringEventConsumer eventConsumer, ExecutorService executorService)
- throws ExecutionException {
+ public void postProcessingDesugaring(CfPostProcessingDesugaringEventConsumer eventConsumer) {
// 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 f5af1f1..dc67ee9 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
@@ -10,12 +10,8 @@
import com.android.tools.r8.graph.ProgramMethod;
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.DesugaredLibraryAPIConverterEventConsumer.DesugaredLibraryAPIConverterPostProcessingEventConsumer;
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
@@ -23,13 +19,16 @@
* explicit calls must be done here.
*/
public abstract class CfPostProcessingDesugaringEventConsumer
- implements DesugaredLibraryRetargeterPostProcessingEventConsumer,
- InterfaceProcessingDesugaringEventConsumer,
- DesugaredLibraryAPIConverterPostProcessingEventConsumer {
+ implements DesugaredLibraryRetargeterPostProcessingEventConsumer {
+ protected DesugaredLibraryAPIConverter desugaredLibraryAPIConverter;
+
+ protected CfPostProcessingDesugaringEventConsumer(AppView<?> appView) {
+ this.desugaredLibraryAPIConverter = new DesugaredLibraryAPIConverter(appView, null);
+ }
public static D8CfPostProcessingDesugaringEventConsumer createForD8(
- D8MethodProcessor methodProcessor) {
- return new D8CfPostProcessingDesugaringEventConsumer(methodProcessor);
+ D8MethodProcessor methodProcessor, AppView<?> appView) {
+ return new D8CfPostProcessingDesugaringEventConsumer(methodProcessor, appView);
}
public static R8PostProcessingDesugaringEventConsumer createForR8(
@@ -37,22 +36,23 @@
return new R8PostProcessingDesugaringEventConsumer(appView, additions);
}
- public abstract void finalizeDesugaring() throws ExecutionException;
+ public void finalizeDesugaring() {
+ desugaredLibraryAPIConverter.generateTrackingWarnings();
+ }
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) {
+ private D8CfPostProcessingDesugaringEventConsumer(
+ D8MethodProcessor methodProcessor, AppView<?> appView) {
+ super(appView);
this.methodProcessor = methodProcessor;
}
@Override
public void acceptDesugaredLibraryRetargeterDispatchProgramClass(DexProgramClass clazz) {
- methodsToReprocess.addAll(clazz.programMethods());
+ methodProcessor.scheduleDesugaredMethodsForProcessing(clazz.programMethods());
}
@Override
@@ -67,30 +67,9 @@
@Override
public void acceptForwardingMethod(ProgramMethod 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 acceptAPIConversionCallback(ProgramMethod method) {
- methodsToReprocess.add(method);
- }
-
- @Override
- public void finalizeDesugaring() throws ExecutionException {
- assert methodProcessor.verifyNoPendingMethodProcessing();
- methodProcessor.newWave();
- methodProcessor.scheduleDesugaredMethodsForProcessing(methodsToReprocess);
- methodProcessor.awaitMethodProcessing();
+ methodProcessor.scheduleDesugaredMethodForProcessing(method);
+ // TODO(b/189912077): Uncomment when API conversion is performed cf to cf in D8.
+ // desugaredLibraryAPIConverter.generateCallbackIfRequired(method);
}
}
@@ -98,22 +77,13 @@
extends CfPostProcessingDesugaringEventConsumer {
private final SyntheticAdditions additions;
- // The desugaredLibraryAPIConverter is required here because call-backs need to be generated
- // once forwarding methods are generated. We should be able to remove it once the interface
- // method desugaring and the API converter are moved cf to cf in R8.
- private final DesugaredLibraryAPIConverter desugaredLibraryAPIConverter;
-
- R8PostProcessingDesugaringEventConsumer(AppView<?> appView, SyntheticAdditions additions) {
- this.desugaredLibraryAPIConverter = new DesugaredLibraryAPIConverter(appView, null);
+ protected R8PostProcessingDesugaringEventConsumer(
+ AppView<?> appView, SyntheticAdditions additions) {
+ super(appView);
this.additions = additions;
}
@Override
- public void finalizeDesugaring() throws ExecutionException {
- desugaredLibraryAPIConverter.generateTrackingWarnings();
- }
-
- @Override
public void acceptDesugaredLibraryRetargeterDispatchProgramClass(DexProgramClass clazz) {
additions.addLiveMethods(clazz.programMethods());
}
@@ -131,22 +101,10 @@
@Override
public void acceptForwardingMethod(ProgramMethod method) {
additions.addLiveMethod(method);
- desugaredLibraryAPIConverter.generateCallbackIfRequired(method, this);
- }
-
- @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";
- }
-
- @Override
- public void acceptAPIConversionCallback(ProgramMethod method) {
- additions.addLiveMethod(method);
+ ProgramMethod callback = desugaredLibraryAPIConverter.generateCallbackIfRequired(method);
+ if (callback != null) {
+ additions.addLiveMethod(callback);
+ }
}
}
}
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 17e219e..61c9617 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
@@ -7,13 +7,9 @@
import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.desugar.CfClassDesugaringCollection.EmptyCfClassDesugaringCollection;
-import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAPIConverter;
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;
-import java.util.function.Consumer;
public class EmptyCfInstructionDesugaringCollection extends CfInstructionDesugaringCollection {
@@ -67,17 +63,7 @@
}
@Override
- public InterfaceMethodProcessorFacade getInterfaceMethodPostProcessingDesugaring(Flavor flavor) {
- return null;
- }
-
- @Override
public RetargetingInfo getRetargetingInfo() {
return null;
}
-
- @Override
- public void withDesugaredLibraryAPIConverter(Consumer<DesugaredLibraryAPIConverter> consumer) {
- // Intentionally empty.
- }
}
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 9d67cf1..8ddd45c 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
@@ -14,13 +14,10 @@
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.desugar.CfClassDesugaringCollection.EmptyCfClassDesugaringCollection;
import com.android.tools.r8.ir.desugar.CfClassDesugaringCollection.NonEmptyCfClassDesugaringCollection;
-import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAPIConverter;
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;
@@ -36,7 +33,6 @@
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
-import java.util.function.Consumer;
public class NonEmptyCfInstructionDesugaringCollection extends CfInstructionDesugaringCollection {
@@ -46,8 +42,6 @@
private final NestBasedAccessDesugaring nestBasedAccessDesugaring;
private final RecordRewriter recordRewriter;
private final DesugaredLibraryRetargeter desugaredLibraryRetargeter;
- private final InterfaceMethodRewriter interfaceMethodRewriter;
- private final DesugaredLibraryAPIConverter desugaredLibraryAPIConverter;
NonEmptyCfInstructionDesugaringCollection(AppView<?> appView) {
this.appView = appView;
@@ -55,8 +49,6 @@
this.nestBasedAccessDesugaring = null;
this.recordRewriter = null;
this.desugaredLibraryRetargeter = null;
- this.interfaceMethodRewriter = null;
- this.desugaredLibraryAPIConverter = null;
return;
}
this.nestBasedAccessDesugaring = NestBasedAccessDesugaring.create(appView);
@@ -78,23 +70,9 @@
// TODO(b/183998768): Enable interface method rewriter cf to cf also in R8.
if (appView.options().isInterfaceMethodDesugaringEnabled()
&& !appView.enableWholeProgramOptimizations()) {
- interfaceMethodRewriter =
+ desugarings.add(
new InterfaceMethodRewriter(
- appView, backportedMethodRewriter, desugaredLibraryRetargeter);
- desugarings.add(interfaceMethodRewriter);
- } else {
- interfaceMethodRewriter = null;
- }
- desugaredLibraryAPIConverter =
- appView.rewritePrefix.isRewriting() && !appView.enableWholeProgramOptimizations()
- ? new DesugaredLibraryAPIConverter(
- appView,
- interfaceMethodRewriter,
- desugaredLibraryRetargeter,
- backportedMethodRewriter)
- : null;
- if (desugaredLibraryAPIConverter != null) {
- desugarings.add(desugaredLibraryAPIConverter);
+ appView, backportedMethodRewriter, desugaredLibraryRetargeter));
}
desugarings.add(new LambdaInstructionDesugaring(appView));
desugarings.add(new InvokeSpecialToSelfDesugaring(appView));
@@ -334,24 +312,10 @@
}
@Override
- public InterfaceMethodProcessorFacade getInterfaceMethodPostProcessingDesugaring(Flavor flavor) {
- return interfaceMethodRewriter != null
- ? interfaceMethodRewriter.getPostProcessingDesugaring(flavor)
- : null;
- }
-
- @Override
public RetargetingInfo getRetargetingInfo() {
if (desugaredLibraryRetargeter != null) {
return desugaredLibraryRetargeter.getRetargetingInfo();
}
return null;
}
-
- @Override
- public void withDesugaredLibraryAPIConverter(Consumer<DesugaredLibraryAPIConverter> consumer) {
- if (desugaredLibraryAPIConverter != null) {
- consumer.accept(desugaredLibraryAPIConverter);
- }
- }
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryAPIConverter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryAPIConverter.java
index 3fb9030..b50ac86 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryAPIConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryAPIConverter.java
@@ -4,13 +4,10 @@
package com.android.tools.r8.ir.desugar.desugaredlibrary;
-import com.android.tools.r8.cf.code.CfInstruction;
-import com.android.tools.r8.cf.code.CfInvoke;
-import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.DebugLocalInfo;
-import com.android.tools.r8.graph.DexAnnotationSet;
+import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexClasspathClass;
@@ -20,9 +17,6 @@
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
-import com.android.tools.r8.graph.MethodAccessFlags;
-import com.android.tools.r8.graph.ParameterAnnotationsList;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
@@ -31,22 +25,11 @@
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionListIterator;
import com.android.tools.r8.ir.code.Invoke;
-import com.android.tools.r8.ir.code.Invoke.Type;
import com.android.tools.r8.ir.code.InvokeMethod;
import com.android.tools.r8.ir.code.InvokeStatic;
import com.android.tools.r8.ir.code.Value;
-import com.android.tools.r8.ir.desugar.BackportedMethodRewriter;
-import com.android.tools.r8.ir.desugar.CfInstructionDesugaring;
-import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
-import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaring;
-import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer;
-import com.android.tools.r8.ir.desugar.FreshLocalProvider;
-import com.android.tools.r8.ir.desugar.LocalStackAllocator;
-import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAPIConverterEventConsumer.DesugaredLibraryAPIConverterPostProcessingEventConsumer;
-import com.android.tools.r8.ir.desugar.itf.InterfaceMethodRewriter;
-import com.android.tools.r8.ir.synthetic.DesugaredLibraryAPIConversionCfCodeProvider.APIConversionCfCodeProvider;
+import com.android.tools.r8.ir.conversion.IRConverter;
import com.android.tools.r8.ir.synthetic.DesugaredLibraryAPIConversionCfCodeProvider.APIConverterWrapperCfCodeProvider;
-import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.OptionalBool;
@@ -55,17 +38,15 @@
import com.android.tools.r8.utils.collections.SortedProgramMethodSet;
import com.google.common.collect.Sets;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.function.Consumer;
-import org.jetbrains.annotations.Nullable;
-import org.objectweb.asm.Opcodes;
// I convert library calls with desugared parameters/return values so they can work normally.
// In the JSON of the desugared library, one can specify conversions between desugared and
@@ -81,31 +62,22 @@
// DesugarType is only a rewritten type (generated through rewriting of type).
// The type, from the library, may either be rewritten to the desugarType,
// or be a rewritten type (generated through rewriting of vivifiedType).
-public class DesugaredLibraryAPIConverter
- implements CfInstructionDesugaring, CfPostProcessingDesugaring {
+public class DesugaredLibraryAPIConverter {
static final String VIVIFIED_PREFIX = "$-vivified-$.";
public static final String DESCRIPTOR_VIVIFIED_PREFIX = "L$-vivified-$/";
- private static final String SUPER_CONVERSION_METHOD_PREFIX = "api$super$conversion$";
private final AppView<?> appView;
private final DexItemFactory factory;
// For debugging only, allows to assert that synthesized code in R8 have been synthesized in the
// Enqueuer and not during IR processing.
private final Mode mode;
- // This is used to filter out double desugaring on backported methods.
- private final BackportedMethodRewriter backportedMethodRewriter;
- private final InterfaceMethodRewriter interfaceMethodRewriter;
- private final DesugaredLibraryRetargeter retargeter;
-
private final DesugaredLibraryWrapperSynthesizer wrapperSynthesizor;
private final Map<DexClass, Set<DexEncodedMethod>> callBackMethods = new IdentityHashMap<>();
private final Map<DexProgramClass, List<DexEncodedMethod>> pendingCallBackMethods =
new IdentityHashMap<>();
private final Set<DexMethod> trackedCallBackAPIs;
private final Set<DexMethod> trackedAPIs;
- private final MethodAccessFlags superAPIConversionMethodAccessFlags =
- MethodAccessFlags.createPublicStaticSynthetic();
public enum Mode {
GENERATE_CALLBACKS_AND_WRAPPERS,
@@ -113,29 +85,9 @@
}
public DesugaredLibraryAPIConverter(AppView<?> appView, Mode mode) {
- this(appView, mode, null, null, null);
- }
-
- public DesugaredLibraryAPIConverter(
- AppView<?> appView,
- InterfaceMethodRewriter interfaceMethodRewriter,
- DesugaredLibraryRetargeter retargeter,
- BackportedMethodRewriter backportedMethodRewriter) {
- this(appView, null, interfaceMethodRewriter, retargeter, backportedMethodRewriter);
- }
-
- private DesugaredLibraryAPIConverter(
- AppView<?> appView,
- Mode mode,
- InterfaceMethodRewriter interfaceMethodRewriter,
- DesugaredLibraryRetargeter retargeter,
- BackportedMethodRewriter backportedMethodRewriter) {
this.appView = appView;
this.factory = appView.dexItemFactory();
this.mode = mode;
- this.interfaceMethodRewriter = interfaceMethodRewriter;
- this.retargeter = retargeter;
- this.backportedMethodRewriter = backportedMethodRewriter;
this.wrapperSynthesizor = new DesugaredLibraryWrapperSynthesizer(appView, this);
if (appView.options().testing.trackDesugaredAPIConversions) {
trackedCallBackAPIs = Sets.newConcurrentHashSet();
@@ -146,95 +98,6 @@
}
}
- // TODO(b/191656218): Consider parallelizing post processing across classes instead of per
- // implementor
- // method.
- @Override
- public void postProcessingDesugaring(
- CfPostProcessingDesugaringEventConsumer eventConsumer, ExecutorService executorService) {
- assert noPendingWrappersOrConversions();
- for (DexProgramClass clazz : appView.appInfo().classes()) {
- if (!appView.isAlreadyLibraryDesugared(clazz)) {
- ArrayList<DexEncodedMethod> callbacks = new ArrayList<>();
- for (ProgramMethod virtualProgramMethod : clazz.virtualProgramMethods()) {
- if (shouldRegisterCallback(virtualProgramMethod)) {
- if (trackedCallBackAPIs != null) {
- trackedCallBackAPIs.add(virtualProgramMethod.getReference());
- }
- ProgramMethod callback =
- generateCallbackMethod(
- virtualProgramMethod.getDefinition(),
- virtualProgramMethod.getHolder(),
- eventConsumer);
- callbacks.add(callback.getDefinition());
- }
- }
- if (!callbacks.isEmpty()) {
- clazz.addVirtualMethods(callbacks);
- }
- }
- }
- assert noPendingWrappersOrConversions();
- generateTrackingWarnings();
- }
-
- private boolean noPendingWrappersOrConversions() {
- for (DexProgramClass pendingSyntheticClass :
- appView.getSyntheticItems().getPendingSyntheticClasses()) {
- assert !isAPIConversionSyntheticType(pendingSyntheticClass.type);
- }
- return true;
- }
-
- @Override
- public Collection<CfInstruction> desugarInstruction(
- CfInstruction instruction,
- FreshLocalProvider freshLocalProvider,
- LocalStackAllocator localStackAllocator,
- CfInstructionDesugaringEventConsumer eventConsumer,
- ProgramMethod context,
- MethodProcessingContext methodProcessingContext,
- DexItemFactory dexItemFactory) {
- assert !appView.enableWholeProgramOptimizations();
- if (needsDesugaring(instruction, context)) {
- assert instruction.isInvoke();
- return Collections.singletonList(
- rewriteLibraryInvoke(
- instruction.asInvoke(), methodProcessingContext, eventConsumer, context));
- }
- return null;
- }
-
- @Override
- public boolean needsDesugaring(CfInstruction instruction, ProgramMethod context) {
- if (!instruction.isInvoke()) {
- return false;
- }
- if (skipDesugaring(context)) {
- return false;
- }
- CfInvoke invoke = instruction.asInvoke();
- return shouldRewriteInvoke(
- invoke.getMethod(), invoke.getInvokeType(context), invoke.isInterface(), context);
- }
-
- // We should not generate conversion for Wrappers and for conversion methods.
- private boolean skipDesugaring(ProgramMethod method) {
- return isAPIConversionSyntheticType(method.getHolderType())
- || isSuperAPIConversionMethod(method);
- }
-
- private boolean isSuperAPIConversionMethod(ProgramMethod method) {
- return method.getDefinition().isD8R8Synthesized()
- && method.getAccessFlags().equals(superAPIConversionMethodAccessFlags)
- && method.getName().toString().startsWith(SUPER_CONVERSION_METHOD_PREFIX);
- }
-
- private boolean isAPIConversionSyntheticType(DexType type) {
- return wrapperSynthesizor.isSyntheticWrapper(type)
- || appView.getSyntheticItems().isSyntheticOfKind(type, SyntheticKind.API_CONVERSION);
- }
-
public static boolean isVivifiedType(DexType type) {
return type.descriptor.toString().startsWith(DESCRIPTOR_VIVIFIED_PREFIX);
}
@@ -245,8 +108,6 @@
public void desugar(IRCode code) {
- assert appView.enableWholeProgramOptimizations();
-
if (wrapperSynthesizor.isSyntheticWrapper(code.method().getHolderType())) {
return;
}
@@ -267,34 +128,26 @@
continue;
}
InvokeMethod invokeMethod = instruction.asInvokeMethod();
- DexMethod invokedMethod = invokeMethod.getInvokedMethod();
+ DexMethod invokedMethod;
+ if (invokeMethod.isInvokeSuper()) {
+ DexClassAndMethod result =
+ appView
+ .appInfoForDesugaring()
+ .lookupSuperTarget(invokeMethod.getInvokedMethod(), code.context());
+ invokedMethod = result != null ? result.getReference() : null;
+ } else {
+ // TODO(b/192439456): Make a test to prove resolution is needed here and fix it.
+ invokedMethod = invokeMethod.getInvokedMethod();
+ }
// Library methods do not understand desugared types, hence desugared types have to be
// converted around non desugared library calls for the invoke to resolve.
- if (invokedMethod != null
- && shouldRewriteInvoke(
- invokedMethod,
- invokeMethod.getType(),
- invokeMethod.getInterfaceBit(),
- code.context())) {
+ if (invokedMethod != null && shouldRewriteInvoke(invokedMethod)) {
rewriteLibraryInvoke(code, invokeMethod, iterator, blockIterator);
}
}
}
}
- @Nullable
- private DexMethod getMethodForDesugaring(
- DexMethod invokedMethod, boolean isInvokeSuper, ProgramMethod context) {
- if (isInvokeSuper) {
- // TODO(b/191656218): Use lookupInvokeSpecial instead when this is all to Cf.
- DexClassAndMethod result =
- appView.appInfoForDesugaring().lookupSuperTarget(invokedMethod, context);
- return result != null ? result.getReference() : null;
- }
- // TODO(b/192439456): Make a test to prove resolution is needed here and fix it.
- return invokedMethod;
- }
-
private boolean validateCallbackWasGeneratedInEnqueuer(ProgramMethod method) {
if (!shouldRegisterCallback(method)) {
return true;
@@ -304,17 +157,7 @@
return true;
}
- private boolean shouldRewriteInvoke(
- DexMethod unresolvedInvokedMethod,
- Type invokeType,
- Boolean isInterface,
- ProgramMethod context) {
- DexMethod invokedMethod =
- getMethodForDesugaring(unresolvedInvokedMethod, invokeType == Type.SUPER, context);
- if (invokedMethod == null) {
- // Implies a resolution/look-up failure, we do not convert to keep the runtime error.
- return false;
- }
+ public boolean shouldRewriteInvoke(DexMethod invokedMethod) {
if (appView.rewritePrefix.hasRewrittenType(invokedMethod.holder, appView)
|| invokedMethod.holder.isArrayType()) {
return false;
@@ -323,19 +166,6 @@
if (dexClass == null || !dexClass.isLibraryClass()) {
return false;
}
- if (interfaceMethodRewriter != null
- && interfaceMethodRewriter.needsRewriting(invokedMethod, invokeType, context)) {
- return false;
- }
- assert retargeter == null || isInterface != null;
- if (retargeter != null
- && retargeter.hasNewInvokeTarget(invokedMethod, false, invokeType == Type.SUPER, context)) {
- return false;
- }
- if (backportedMethodRewriter != null
- && backportedMethodRewriter.methodIsBackport(invokedMethod)) {
- return false;
- }
return appView.rewritePrefix.hasRewrittenTypeInSignature(invokedMethod.proto, appView);
}
@@ -345,18 +175,16 @@
}
}
- public void generateCallbackIfRequired(
- ProgramMethod method, DesugaredLibraryAPIConverterPostProcessingEventConsumer eventConsumer) {
+ public ProgramMethod generateCallbackIfRequired(ProgramMethod method) {
if (!shouldRegisterCallback(method)) {
- return;
+ return null;
}
if (trackedCallBackAPIs != null) {
trackedCallBackAPIs.add(method.getReference());
}
- ProgramMethod callback =
- generateCallbackMethod(method.getDefinition(), method.getHolder(), eventConsumer);
- callback.getHolder().addVirtualMethod(callback.getDefinition());
- assert noPendingWrappersOrConversions();
+ ProgramMethod callback = generateCallbackMethod(method.getDefinition(), method.getHolder());
+ method.getHolder().addVirtualMethod(callback.getDefinition());
+ return callback;
}
public boolean shouldRegisterCallback(ProgramMethod method) {
@@ -370,7 +198,6 @@
DexEncodedMethod definition = method.getDefinition();
if (definition.isPrivateMethod()
|| definition.isStatic()
- || definition.isAbstract()
|| definition.isLibraryMethodOverride().isFalse()) {
return false;
}
@@ -495,9 +322,19 @@
return appView.dexItemFactory().createMethod(holder, newProto, originalMethod.name);
}
- public void ensureWrappersForL8(CfInstructionDesugaringEventConsumer eventConsumer) {
- assert appView.options().isDesugaredLibraryCompilation();
- wrapperSynthesizor.ensureWrappersForL8(eventConsumer);
+ public void finalizeWrappers(
+ DexApplication.Builder<?> builder, IRConverter irConverter, ExecutorService executorService)
+ throws ExecutionException {
+ // In D8, we generate the wrappers here. In R8, wrappers have already been generated in the
+ // enqueuer, so nothing needs to be done.
+ if (appView.enableWholeProgramOptimizations()) {
+ return;
+ }
+ SortedProgramMethodSet callbacks = generateCallbackMethods();
+ irConverter.processMethodsConcurrently(callbacks, executorService);
+ if (appView.options().isDesugaredLibraryCompilation()) {
+ wrapperSynthesizor.finalizeWrappersForL8();
+ }
}
public SortedProgramMethodSet generateCallbackMethods() {
@@ -508,7 +345,7 @@
List<DexEncodedMethod> newVirtualMethods = new ArrayList<>();
callbacks.forEach(
callback -> {
- ProgramMethod callbackMethod = generateCallbackMethod(callback, clazz, null);
+ ProgramMethod callbackMethod = generateCallbackMethod(callback, clazz);
newVirtualMethods.add(callbackMethod.getDefinition());
allCallbackMethods.add(callbackMethod);
});
@@ -532,14 +369,12 @@
}
private ProgramMethod generateCallbackMethod(
- DexEncodedMethod originalMethod,
- DexProgramClass clazz,
- DesugaredLibraryAPIConverterPostProcessingEventConsumer eventConsumer) {
+ DexEncodedMethod originalMethod, DexProgramClass clazz) {
DexMethod methodToInstall =
methodWithVivifiedTypeInSignature(originalMethod.getReference(), clazz.type, appView);
CfCode cfCode =
new APIConverterWrapperCfCodeProvider(
- appView, originalMethod.getReference(), null, this, clazz.isInterface(), null)
+ appView, originalMethod.getReference(), null, this, clazz.isInterface())
.generateCfCode();
DexEncodedMethod newMethod =
wrapperSynthesizor.newSynthesizedMethod(methodToInstall, originalMethod, cfCode);
@@ -547,13 +382,7 @@
if (originalMethod.isLibraryMethodOverride().isTrue()) {
newMethod.setLibraryMethodOverride(OptionalBool.TRUE);
}
- ProgramMethod callback = new ProgramMethod(clazz, newMethod);
- if (eventConsumer != null) {
- eventConsumer.acceptAPIConversionCallback(callback);
- } else {
- assert appView.enableWholeProgramOptimizations();
- }
- return callback;
+ return new ProgramMethod(clazz, newMethod);
}
private void generateTrackDesugaredAPIWarnings(Set<DexMethod> tracked, String inner) {
@@ -596,10 +425,8 @@
return vivifiedType;
}
- public void registerWrappersForLibraryInvokeIfRequired(
- DexMethod invokedMethod, Type invokeType, ProgramMethod context) {
- // TODO(b/191656218): Once R8 support is done, use an unboxed boolean here.
- if (!shouldRewriteInvoke(invokedMethod, invokeType, null, context)) {
+ public void registerWrappersForLibraryInvokeIfRequired(DexMethod invokedMethod) {
+ if (!shouldRewriteInvoke(invokedMethod)) {
return;
}
if (trackedAPIs != null) {
@@ -616,120 +443,6 @@
}
}
- private DexMethod computeReturnConversion(
- DexMethod invokedMethod, CfInstructionDesugaringEventConsumer eventConsumer) {
- DexType returnType = invokedMethod.proto.returnType;
- if (!appView.rewritePrefix.hasRewrittenType(returnType, appView)) {
- return null;
- }
- if (canConvert(returnType)) {
- DexType newReturnType = DesugaredLibraryAPIConverter.vivifiedTypeFor(returnType, appView);
- return ensureConversionMethod(returnType, newReturnType, returnType, eventConsumer);
- }
- reportInvalidInvoke(returnType, invokedMethod, "return ");
- return null;
- }
-
- private DexMethod[] computeParameterConversions(
- DexMethod invokedMethod, CfInstructionDesugaringEventConsumer eventConsumer) {
- DexMethod[] parameterConversions = new DexMethod[invokedMethod.getArity()];
- DexType[] parameters = invokedMethod.proto.parameters.values;
- for (int i = 0; i < parameters.length; i++) {
- DexType argType = parameters[i];
- if (appView.rewritePrefix.hasRewrittenType(argType, appView)) {
- if (canConvert(argType)) {
- DexType argVivifiedType = vivifiedTypeFor(argType, appView);
- parameterConversions[i] =
- ensureConversionMethod(argType, argType, argVivifiedType, eventConsumer);
- } else {
- reportInvalidInvoke(argType, invokedMethod, "parameter ");
- }
- }
- }
- return parameterConversions;
- }
-
- private CfInvoke rewriteLibraryInvoke(
- CfInvoke invoke,
- MethodProcessingContext methodProcessingContext,
- CfInstructionDesugaringEventConsumer eventConsumer,
- ProgramMethod context) {
- DexMethod invokedMethod = invoke.getMethod();
- if (trackedAPIs != null) {
- trackedAPIs.add(invokedMethod);
- }
- DexProto newProto =
- invoke.isInvokeStatic()
- ? invokedMethod.proto
- : factory.prependTypeToProto(invokedMethod.getHolderType(), invokedMethod.getProto());
- DexMethod apiConversionMethod =
- invoke.isInvokeSuper(context.getHolderType())
- ? createSuperAPIConversion(
- invoke, methodProcessingContext, eventConsumer, newProto, context)
- : createOutlinedAPIConversion(invoke, methodProcessingContext, eventConsumer, newProto);
- return new CfInvoke(Opcodes.INVOKESTATIC, apiConversionMethod, false);
- }
-
- private DexMethod createSuperAPIConversion(
- CfInvoke invoke,
- MethodProcessingContext methodProcessingContext,
- CfInstructionDesugaringEventConsumer eventConsumer,
- DexProto newProto,
- ProgramMethod context) {
- DexMethod invokedMethod = invoke.getMethod();
- String uniqueSuffix = methodProcessingContext.createUniqueContext().getSyntheticSuffix();
- DexMethod method =
- factory.createMethod(
- context.getHolderType(), newProto, SUPER_CONVERSION_METHOD_PREFIX + uniqueSuffix);
- DexEncodedMethod apiConversion =
- new DexEncodedMethod(
- method,
- superAPIConversionMethodAccessFlags,
- MethodTypeSignature.noSignature(),
- DexAnnotationSet.empty(),
- ParameterAnnotationsList.empty(),
- new APIConversionCfCodeProvider(
- appView,
- method.holder,
- invoke,
- computeReturnConversion(invokedMethod, eventConsumer),
- computeParameterConversions(invokedMethod, eventConsumer))
- .generateCfCode(),
- true);
- eventConsumer.acceptSuperAPIConversion(new ProgramMethod(context.getHolder(), apiConversion));
- return method;
- }
-
- private DexMethod createOutlinedAPIConversion(
- CfInvoke invoke,
- MethodProcessingContext methodProcessingContext,
- CfInstructionDesugaringEventConsumer eventConsumer,
- DexProto newProto) {
- DexMethod invokedMethod = invoke.getMethod();
- ProgramMethod outline =
- appView
- .getSyntheticItems()
- .createMethod(
- SyntheticKind.API_CONVERSION,
- methodProcessingContext.createUniqueContext(),
- appView,
- builder ->
- builder
- .setProto(newProto)
- .setAccessFlags(MethodAccessFlags.createPublicStaticSynthetic())
- .setCode(
- methodSig ->
- new APIConversionCfCodeProvider(
- appView,
- methodSig.holder,
- invoke,
- computeReturnConversion(invokedMethod, eventConsumer),
- computeParameterConversions(invokedMethod, eventConsumer))
- .generateCfCode()));
- eventConsumer.acceptAPIConversion(outline);
- return outline.getReference();
- }
-
private void rewriteLibraryInvoke(
IRCode code,
InvokeMethod invokeMethod,
@@ -861,7 +574,7 @@
private Instruction createParameterConversion(
IRCode code, DexType argType, DexType argVivifiedType, Value inValue) {
- DexMethod conversionMethod = ensureConversionMethod(argType, argType, argVivifiedType, null);
+ DexMethod conversionMethod = ensureConversionMethod(argType, argType, argVivifiedType);
// The value is null only if the input is null.
Value convertedValue =
createConversionValue(code, inValue.getType().nullability(), argVivifiedType, null);
@@ -870,8 +583,7 @@
private Instruction createReturnConversionAndReplaceUses(
IRCode code, InvokeMethod invokeMethod, DexType returnType, DexType returnVivifiedType) {
- DexMethod conversionMethod =
- ensureConversionMethod(returnType, returnVivifiedType, returnType, null);
+ DexMethod conversionMethod = ensureConversionMethod(returnType, returnVivifiedType, returnType);
Value outValue = invokeMethod.outValue();
Value convertedValue =
createConversionValue(code, Nullability.maybeNull(), returnType, outValue.getLocalInfo());
@@ -888,11 +600,7 @@
}
}
- public DexMethod ensureConversionMethod(
- DexType type,
- DexType srcType,
- DexType destType,
- DesugaredLibraryAPIConverterEventConsumer eventConsumer) {
+ public DexMethod ensureConversionMethod(DexType type, DexType srcType, DexType destType) {
// ConversionType holds the methods "rewrittenType convert(type)" and the other way around.
// But everything is going to be rewritten, so we need to use vivifiedType and type".
DexType conversionHolder =
@@ -900,8 +608,8 @@
if (conversionHolder == null) {
conversionHolder =
type == srcType
- ? wrapperSynthesizor.ensureTypeWrapper(type, eventConsumer)
- : wrapperSynthesizor.ensureVivifiedTypeWrapper(type, eventConsumer);
+ ? wrapperSynthesizor.ensureTypeWrapper(type)
+ : wrapperSynthesizor.ensureVivifiedTypeWrapper(type);
}
assert conversionHolder != null;
return factory.createMethod(
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryAPIConverterEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryAPIConverterEventConsumer.java
deleted file mode 100644
index 65f5ece..0000000
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryAPIConverterEventConsumer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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.desugaredlibrary;
-
-import com.android.tools.r8.graph.DexClasspathClass;
-import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.ProgramMethod;
-
-public interface DesugaredLibraryAPIConverterEventConsumer {
-
- void acceptWrapperProgramClass(DexProgramClass clazz);
-
- void acceptWrapperClasspathClass(DexClasspathClass clazz);
-
- void acceptAPIConversion(ProgramMethod method);
-
- void acceptSuperAPIConversion(ProgramMethod method);
-
- interface DesugaredLibraryAPIConverterPostProcessingEventConsumer {
-
- void acceptAPIConversionCallback(ProgramMethod method);
- }
-}
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 dac3079..0b0039e 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,8 +23,6 @@
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
@@ -43,9 +41,7 @@
}
@Override
- public void postProcessingDesugaring(
- CfPostProcessingDesugaringEventConsumer eventConsumer, ExecutorService executorService)
- throws ExecutionException {
+ public void postProcessingDesugaring(CfPostProcessingDesugaringEventConsumer eventConsumer) {
if (appView.options().isDesugaredLibraryCompilation()) {
ensureEmulatedDispatchMethodsSynthesized(eventConsumer);
} else {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterSyntheticHelper.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterSyntheticHelper.java
index 02eb59b..1f8322f 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterSyntheticHelper.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterSyntheticHelper.java
@@ -150,7 +150,6 @@
.setCode(
methodSig ->
new EmulateInterfaceSyntheticCfCodeProvider(
- methodSig.getHolderType(),
emulatedDispatchMethod.getHolderType(),
desugarMethod,
itfMethod,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryWrapperSynthesizer.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryWrapperSynthesizer.java
index 7e2164f..6c1e889 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryWrapperSynthesizer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryWrapperSynthesizer.java
@@ -117,16 +117,14 @@
return appView.options().desugaredLibraryConfiguration.getWrapperConversions().contains(type);
}
- DexType ensureTypeWrapper(DexType type, DesugaredLibraryAPIConverterEventConsumer eventConsumer) {
- return ensureWrappers(type, eventConsumer).getWrapper().type;
+ DexType ensureTypeWrapper(DexType type) {
+ return ensureWrappers(type).getWrapper().type;
}
- DexType ensureVivifiedTypeWrapper(
- DexType type, DesugaredLibraryAPIConverterEventConsumer eventConsumer) {
- return ensureWrappers(type, eventConsumer).getVivifiedWrapper().type;
+ DexType ensureVivifiedTypeWrapper(DexType type) {
+ return ensureWrappers(type).getVivifiedWrapper().type;
}
-
public void registerWrapper(DexType type) {
wrappersToGenerate.add(type);
assert getValidClassToWrap(type) != null;
@@ -163,17 +161,13 @@
}
}
- private Wrappers ensureWrappers(
- DexType type, DesugaredLibraryAPIConverterEventConsumer eventConsumer) {
+ private Wrappers ensureWrappers(DexType type) {
assert canGenerateWrapper(type) : type;
DexClass dexClass = getValidClassToWrap(type);
- return ensureWrappers(dexClass, ignored -> {}, eventConsumer);
+ return ensureWrappers(dexClass, ignored -> {});
}
- private Wrappers ensureWrappers(
- DexClass context,
- Consumer<DexClasspathClass> creationCallback,
- DesugaredLibraryAPIConverterEventConsumer eventConsumer) {
+ private Wrappers ensureWrappers(DexClass context, Consumer<DexClasspathClass> creationCallback) {
DexType type = context.type;
DexClass wrapper;
DexClass vivifiedWrapper;
@@ -186,20 +180,15 @@
vivifiedTypeFor(type),
type,
programContext,
- eventConsumer,
- wrapperField ->
- synthesizeVirtualMethodsForTypeWrapper(
- programContext, wrapperField, eventConsumer));
+ wrapperField -> synthesizeVirtualMethodsForTypeWrapper(programContext, wrapperField));
vivifiedWrapper =
ensureProgramWrapper(
SyntheticKind.VIVIFIED_WRAPPER,
type,
vivifiedTypeFor(type),
programContext,
- eventConsumer,
wrapperField ->
- synthesizeVirtualMethodsForVivifiedTypeWrapper(
- programContext, wrapperField, eventConsumer));
+ synthesizeVirtualMethodsForVivifiedTypeWrapper(programContext, wrapperField));
DexField wrapperField = getWrapperUniqueField(wrapper);
DexField vivifiedWrapperField = getWrapperUniqueField(vivifiedWrapper);
ensureProgramConversionMethod(
@@ -216,9 +205,7 @@
type,
classpathOrLibraryContext,
creationCallback,
- eventConsumer,
- wrapperField ->
- synthesizeVirtualMethodsForTypeWrapper(context, wrapperField, eventConsumer));
+ wrapperField -> synthesizeVirtualMethodsForTypeWrapper(context, wrapperField));
vivifiedWrapper =
ensureClasspathWrapper(
SyntheticKind.VIVIFIED_WRAPPER,
@@ -226,10 +213,8 @@
vivifiedTypeFor(type),
classpathOrLibraryContext,
creationCallback,
- eventConsumer,
wrapperField ->
- synthesizeVirtualMethodsForVivifiedTypeWrapper(
- context, wrapperField, eventConsumer));
+ synthesizeVirtualMethodsForVivifiedTypeWrapper(context, wrapperField));
DexField wrapperField = getWrapperUniqueField(wrapper);
DexField vivifiedWrapperField = getWrapperUniqueField(vivifiedWrapper);
ensureClasspathConversionMethod(
@@ -257,7 +242,6 @@
DexType wrappingType,
DexType wrappedType,
DexProgramClass programContext,
- DesugaredLibraryAPIConverterEventConsumer eventConsumer,
Function<DexEncodedField, DexEncodedMethod[]> virtualMethodProvider) {
return appView
.getSyntheticItems()
@@ -268,13 +252,9 @@
builder -> buildWrapper(wrappingType, wrappedType, programContext, builder),
// The creation of virtual methods may require new wrappers, this needs to happen
// once the wrapper is created to avoid infinite recursion.
- wrapper -> {
- if (eventConsumer != null) {
- eventConsumer.acceptWrapperProgramClass(wrapper);
- }
- wrapper.setVirtualMethods(
- virtualMethodProvider.apply(getWrapperUniqueEncodedField(wrapper)));
- });
+ wrapper ->
+ wrapper.setVirtualMethods(
+ virtualMethodProvider.apply(getWrapperUniqueEncodedField(wrapper))));
}
private DexClasspathClass ensureClasspathWrapper(
@@ -283,7 +263,6 @@
DexType wrappedType,
ClasspathOrLibraryClass classpathOrLibraryContext,
Consumer<DexClasspathClass> creationCallback,
- DesugaredLibraryAPIConverterEventConsumer eventConsumer,
Function<DexEncodedField, DexEncodedMethod[]> virtualMethodProvider) {
return appView
.getSyntheticItems()
@@ -297,9 +276,6 @@
// The creation of virtual methods may require new wrappers, this needs to happen
// once the wrapper is created to avoid infinite recursion.
wrapper -> {
- if (eventConsumer != null) {
- eventConsumer.acceptWrapperClasspathClass(wrapper);
- }
wrapper.setVirtualMethods(
virtualMethodProvider.apply(getWrapperUniqueEncodedField(wrapper)));
creationCallback.accept(wrapper);
@@ -406,9 +382,7 @@
}
private DexEncodedMethod[] synthesizeVirtualMethodsForVivifiedTypeWrapper(
- DexClass dexClass,
- DexEncodedField wrapperField,
- DesugaredLibraryAPIConverterEventConsumer eventConsumer) {
+ DexClass dexClass, DexEncodedField wrapperField) {
List<DexEncodedMethod> dexMethods = allImplementedMethods(dexClass);
List<DexEncodedMethod> generatedMethods = new ArrayList<>();
// Each method should use only types in their signature, but each method the wrapper forwards
@@ -447,12 +421,7 @@
} else {
cfCode =
new APIConverterVivifiedWrapperCfCodeProvider(
- appView,
- methodToInstall,
- wrapperField.getReference(),
- converter,
- isInterface,
- eventConsumer)
+ appView, methodToInstall, wrapperField.getReference(), converter, isInterface)
.generateCfCode();
}
DexEncodedMethod newDexEncodedMethod =
@@ -463,9 +432,7 @@
}
private DexEncodedMethod[] synthesizeVirtualMethodsForTypeWrapper(
- DexClass dexClass,
- DexEncodedField wrapperField,
- DesugaredLibraryAPIConverterEventConsumer eventConsumer) {
+ DexClass dexClass, DexEncodedField wrapperField) {
List<DexEncodedMethod> dexMethods = allImplementedMethods(dexClass);
List<DexEncodedMethod> generatedMethods = new ArrayList<>();
// Each method should use only vivified types in their signature, but each method the wrapper
@@ -498,8 +465,7 @@
dexEncodedMethod.getReference(),
wrapperField.getReference(),
converter,
- isInterface,
- eventConsumer)
+ isInterface)
.generateCfCode();
}
DexEncodedMethod newDexEncodedMethod =
@@ -608,7 +574,7 @@
field, fieldAccessFlags, FieldTypeSignature.noSignature(), DexAnnotationSet.empty(), null);
}
- void ensureWrappersForL8(DesugaredLibraryAPIConverterEventConsumer eventConsumer) {
+ void finalizeWrappersForL8() {
DesugaredLibraryConfiguration conf = appView.options().desugaredLibraryConfiguration;
for (DexType type : conf.getWrapperConversions()) {
assert !conf.getCustomConversions().containsKey(type);
@@ -616,7 +582,7 @@
// In broken set-ups we can end up having a json files containing wrappers of non desugared
// classes. Such wrappers are not required since the class won't be rewritten.
if (validClassToWrap.isProgramClass()) {
- ensureWrappers(validClassToWrap, ignored -> {}, eventConsumer);
+ ensureWrappers(validClassToWrap, ignored -> {});
}
}
}
@@ -633,8 +599,7 @@
classpathWrapper -> {
changed.set(true);
synthesizedCallback.accept(classpathWrapper);
- },
- null);
+ });
}
}
}
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 14e5fea..d86d22c 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,8 +380,7 @@
}
@Override
- public void process(
- DexProgramClass clazz, InterfaceProcessingDesugaringEventConsumer eventConsumer) {
+ public void process(DexProgramClass clazz, ProgramMethodSet synthesizedMethods) {
if (!clazz.isInterface()) {
visitClassInfo(clazz, new ReportingContext(clazz, clazz));
}
@@ -390,11 +389,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(InterfaceProcessingDesugaringEventConsumer eventConsumer) {
+ public final void finalizeProcessing(ProgramMethodSet synthesizedMethods) {
newSyntheticMethods.forEach(
(clazz, newForwardingMethods) -> {
clazz.addVirtualMethods(newForwardingMethods.toDefinitionSet());
- newForwardingMethods.forEach(eventConsumer::acceptForwardingMethod);
+ newForwardingMethods.forEach(synthesizedMethods::add);
});
}
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 f0d298f..4ec0ef8 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,6 +19,7 @@
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;
@@ -88,7 +89,7 @@
}
DexProgramClass ensureEmulateInterfaceLibrary(
- DexProgramClass emulatedInterface, InterfaceProcessingDesugaringEventConsumer eventConsumer) {
+ DexProgramClass emulatedInterface, ProgramMethodSet synthesizedMethods) {
assert rewriter.isEmulatedInterface(emulatedInterface.type);
DexProgramClass emulateInterfaceClass =
appView
@@ -106,7 +107,7 @@
synthesizeEmulatedInterfaceMethod(
method, emulatedInterface, methodBuilder))),
ignored -> {});
- emulateInterfaceClass.forEachProgramMethod(eventConsumer::acceptEmulatedInterfaceMethod);
+ emulateInterfaceClass.forEachProgramMethod(synthesizedMethods::add);
assert emulateInterfaceClass.getType()
== InterfaceMethodRewriter.getEmulateLibraryInterfaceClassType(
emulatedInterface.type, appView.dexItemFactory());
@@ -130,10 +131,9 @@
.setProto(emulatedMethod.getProto())
.setAccessFlags(MethodAccessFlags.createPublicStaticSynthetic())
.setCode(
- emulatedInterfaceMethod ->
+ theMethod ->
new EmulateInterfaceSyntheticCfCodeProvider(
- emulatedInterfaceMethod.getHolderType(),
- method.getHolderType(),
+ theMethod.getHolderType(),
companionMethod,
libraryMethod,
extraDispatchCases,
@@ -217,15 +217,14 @@
}
@Override
- public void process(
- DexProgramClass emulatedInterface, InterfaceProcessingDesugaringEventConsumer eventConsumer) {
+ public void process(DexProgramClass emulatedInterface, ProgramMethodSet synthesizedMethods) {
if (!appView.options().isDesugaredLibraryCompilation()
|| !rewriter.isEmulatedInterface(emulatedInterface.type)
|| appView.isAlreadyLibraryDesugared(emulatedInterface)) {
return;
}
if (needsEmulateInterfaceLibrary(emulatedInterface)) {
- ensureEmulateInterfaceLibrary(emulatedInterface, eventConsumer);
+ ensureEmulateInterfaceLibrary(emulatedInterface, synthesizedMethods);
}
}
@@ -234,7 +233,7 @@
}
@Override
- public void finalizeProcessing(InterfaceProcessingDesugaringEventConsumer eventConsumer) {
+ public void finalizeProcessing(ProgramMethodSet synthesizedMethods) {
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 4f4ba32..7f3d047 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,6 +5,7 @@
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 {
@@ -13,11 +14,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, InterfaceProcessingDesugaringEventConsumer eventConsumer);
+ void process(DexProgramClass clazz, ProgramMethodSet synthesizedMethods);
// 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(InterfaceProcessingDesugaringEventConsumer eventConsumer);
+ void finalizeProcessing(ProgramMethodSet synthesizedMethods);
}
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 71844b0..731316f 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,10 +6,7 @@
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;
@@ -19,22 +16,21 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
-public class InterfaceMethodProcessorFacade implements CfPostProcessingDesugaring {
+class InterfaceMethodProcessorFacade {
private final AppView<?> appView;
- private final Flavor flavour;
- private final List<InterfaceDesugaringProcessor> interfaceDesugaringProcessors;
- InterfaceMethodProcessorFacade(
- AppView<?> appView, Flavor flavour, InterfaceMethodRewriter rewriter) {
+ InterfaceMethodProcessorFacade(AppView<?> appView) {
this.appView = appView;
- this.flavour = flavour;
- interfaceDesugaringProcessors = instantiateInterfaceDesugaringProcessors(appView, rewriter);
}
- private List<InterfaceDesugaringProcessor> instantiateInterfaceDesugaringProcessors(
- AppView<?> appView, InterfaceMethodRewriter rewriter) {
-
+ /** Runs the interfaceProcessor, the class processor and the emulated interface processor. */
+ void runInterfaceDesugaringProcessors(
+ InterfaceMethodRewriter rewriter,
+ IRConverter converter,
+ Flavor flavour,
+ ExecutorService executorService)
+ throws ExecutionException {
// 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 =
@@ -50,47 +46,17 @@
// classes if needed.
InterfaceProcessor interfaceProcessor = new InterfaceProcessor(appView, rewriter);
- // 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 {
+ // 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);
SortedProgramMethodSet sortedSynthesizedMethods = SortedProgramMethodSet.createConcurrent();
-
- @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;
- }
+ processClassesConcurrently(
+ orderedInterfaceDesugaringProcessors, sortedSynthesizedMethods, flavour, executorService);
+ assert converter != null;
+ converter.processMethodsConcurrently(sortedSynthesizedMethods, executorService);
}
private boolean shouldProcess(DexProgramClass clazz, Flavor flavour) {
@@ -101,28 +67,22 @@
}
private void processClassesConcurrently(
- InterfaceProcessingDesugaringEventConsumer eventConsumer, ExecutorService executorService)
+ List<InterfaceDesugaringProcessor> processors,
+ SortedProgramMethodSet sortedSynthesizedMethods,
+ Flavor flavour,
+ ExecutorService executorService)
throws ExecutionException {
ThreadUtils.processItems(
Iterables.filter(
appView.appInfo().classes(), (DexProgramClass clazz) -> shouldProcess(clazz, flavour)),
clazz -> {
- for (InterfaceDesugaringProcessor processor : interfaceDesugaringProcessors) {
- processor.process(clazz, eventConsumer);
+ for (InterfaceDesugaringProcessor processor : processors) {
+ processor.process(clazz, sortedSynthesizedMethods);
}
},
executorService);
- for (InterfaceDesugaringProcessor processor : interfaceDesugaringProcessors) {
- processor.finalizeProcessing(eventConsumer);
+ for (InterfaceDesugaringProcessor processor : processors) {
+ processor.finalizeProcessing(sortedSynthesizedMethods);
}
}
-
- @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 104efee..0e46288 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
@@ -1380,15 +1380,11 @@
this.synthesizedMethods.clear();
}
- public void runInterfaceDesugaringProcessorsForR8(
+ public void runInterfaceDesugaringProcessors(
IRConverter converter, Flavor flavour, ExecutorService executorService)
throws ExecutionException {
- getPostProcessingDesugaring(flavour)
- .runInterfaceDesugaringProcessorsForR8(converter, executorService);
- }
-
- public InterfaceMethodProcessorFacade getPostProcessingDesugaring(Flavor flavour) {
- return new InterfaceMethodProcessorFacade(appView, flavour, this);
+ new InterfaceMethodProcessorFacade(appView)
+ .runInterfaceDesugaringProcessors(this, converter, flavour, executorService);
}
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
deleted file mode 100644
index 2581364..0000000
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessingDesugaringEventConsumer.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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 2dd65a9..cb752ad 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,6 +47,7 @@
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;
@@ -79,13 +80,12 @@
}
@Override
- public void process(
- DexProgramClass iface, InterfaceProcessingDesugaringEventConsumer eventConsumer) {
+ public void process(DexProgramClass iface, ProgramMethodSet synthesizedMethods) {
if (!iface.isInterface()) {
return;
}
analyzeBridges(iface);
- ensureCompanionClassMethods(iface, eventConsumer);
+ ensureCompanionClassMethods(iface, synthesizedMethods);
}
private void analyzeBridges(DexProgramClass iface) {
@@ -99,8 +99,8 @@
}
private void ensureCompanionClassMethods(
- DexProgramClass iface, InterfaceProcessingDesugaringEventConsumer eventConsumer) {
- ensureCompanionClassInitializesInterface(iface, eventConsumer);
+ DexProgramClass iface, ProgramMethodSet synthesizedMethods) {
+ ensureCompanionClassInitializesInterface(iface, synthesizedMethods);
// 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, InterfaceProcessingDesugaringEventConsumer eventConsumer) {
+ DexProgramClass iface, ProgramMethodSet synthesizedMethods) {
if (!hasStaticMethodThatTriggersNonTrivialClassInitializer(iface)) {
return;
}
@@ -146,7 +146,7 @@
appView.dexItemFactory().createProto(appView.dexItemFactory().voidType),
appView,
methodBuilder -> createCompanionClassInitializer(iface, clinitField, methodBuilder));
- eventConsumer.acceptCompanionClassClinit(clinit);
+ synthesizedMethods.add(clinit);
}
private DexEncodedField ensureStaticClinitFieldToTriggerInterfaceInitialization(
@@ -441,7 +441,7 @@
}
@Override
- public void finalizeProcessing(InterfaceProcessingDesugaringEventConsumer eventConsumer) {
+ public void finalizeProcessing(ProgramMethodSet synthesizedMethods) {
InterfaceProcessorNestedGraphLens graphLens = postProcessInterfaces();
if (appView.enableWholeProgramOptimizations() && graphLens != null) {
appView.setGraphLens(graphLens);
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/DesugaredLibraryAPIConversionCfCodeProvider.java b/src/main/java/com/android/tools/r8/ir/synthetic/DesugaredLibraryAPIConversionCfCodeProvider.java
index 5680337..db93ced 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/DesugaredLibraryAPIConversionCfCodeProvider.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/DesugaredLibraryAPIConversionCfCodeProvider.java
@@ -32,8 +32,6 @@
import com.android.tools.r8.ir.code.If;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAPIConverter;
-import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAPIConverterEventConsumer;
-import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.collections.ImmutableDeque;
import com.android.tools.r8.utils.collections.ImmutableInt2ReferenceSortedMap;
import java.util.ArrayList;
@@ -64,25 +62,22 @@
public static class APIConverterVivifiedWrapperCfCodeProvider
extends DesugaredLibraryAPIConversionCfCodeProvider {
- private final DexField wrapperField;
- private final DexMethod forwardMethod;
- private final DesugaredLibraryAPIConverter converter;
- private final boolean itfCall;
- private final DesugaredLibraryAPIConverterEventConsumer eventConsumer;
+ DexField wrapperField;
+ DexMethod forwardMethod;
+ DesugaredLibraryAPIConverter converter;
+ boolean itfCall;
public APIConverterVivifiedWrapperCfCodeProvider(
AppView<?> appView,
DexMethod forwardMethod,
DexField wrapperField,
DesugaredLibraryAPIConverter converter,
- boolean itfCall,
- DesugaredLibraryAPIConverterEventConsumer eventConsumer) {
+ boolean itfCall) {
super(appView, wrapperField.holder);
this.forwardMethod = forwardMethod;
this.wrapperField = wrapperField;
this.converter = converter;
this.itfCall = itfCall;
- this.eventConsumer = eventConsumer;
}
@Override
@@ -103,8 +98,7 @@
instructions.add(
new CfInvoke(
Opcodes.INVOKESTATIC,
- converter.ensureConversionMethod(
- param, param, vivifiedTypeFor(param), eventConsumer),
+ converter.ensureConversionMethod(param, param, vivifiedTypeFor(param)),
false));
newParameters[index - 1] = vivifiedTypeFor(param);
}
@@ -136,7 +130,7 @@
new CfInvoke(
Opcodes.INVOKESTATIC,
converter.ensureConversionMethod(
- returnType, vivifiedTypeFor(returnType), returnType, eventConsumer),
+ returnType, vivifiedTypeFor(returnType), returnType),
false));
}
if (returnType == factory.voidType) {
@@ -155,22 +149,19 @@
DexMethod forwardMethod;
DesugaredLibraryAPIConverter converter;
boolean itfCall;
- private final DesugaredLibraryAPIConverterEventConsumer eventConsumer;
public APIConverterWrapperCfCodeProvider(
AppView<?> appView,
DexMethod forwardMethod,
DexField wrapperField,
DesugaredLibraryAPIConverter converter,
- boolean itfCall,
- DesugaredLibraryAPIConverterEventConsumer eventConsumer) {
+ boolean itfCall) {
// Var wrapperField is null if should forward to receiver.
super(appView, wrapperField == null ? forwardMethod.holder : wrapperField.holder);
this.forwardMethod = forwardMethod;
this.wrapperField = wrapperField;
this.converter = converter;
this.itfCall = itfCall;
- this.eventConsumer = eventConsumer;
}
@Override
@@ -194,8 +185,7 @@
instructions.add(
new CfInvoke(
Opcodes.INVOKESTATIC,
- converter.ensureConversionMethod(
- param, vivifiedTypeFor(param), param, eventConsumer),
+ converter.ensureConversionMethod(param, vivifiedTypeFor(param), param),
false));
}
if (param == factory.longType || param == factory.doubleType) {
@@ -216,7 +206,7 @@
new CfInvoke(
Opcodes.INVOKESTATIC,
converter.ensureConversionMethod(
- returnType, returnType, vivifiedTypeFor(returnType), eventConsumer),
+ returnType, returnType, vivifiedTypeFor(returnType)),
false));
returnType = vivifiedTypeFor(returnType);
}
@@ -292,105 +282,6 @@
}
}
- public static class APIConversionCfCodeProvider extends SyntheticCfCodeProvider {
-
- private final CfInvoke initialInvoke;
- private final DexMethod returnConversion;
- private final DexMethod[] parameterConversions;
-
- public APIConversionCfCodeProvider(
- AppView<?> appView,
- DexType holder,
- CfInvoke initialInvoke,
- DexMethod returnConversion,
- DexMethod[] parameterConversions) {
- super(appView, holder);
- this.initialInvoke = initialInvoke;
- this.returnConversion = returnConversion;
- this.parameterConversions = parameterConversions;
- }
-
- private DexType invalidType(DexMethod invokedMethod, DexMethod convertedMethod) {
- if (invokedMethod.getReturnType() != convertedMethod.getReturnType()
- && returnConversion == null) {
- return invokedMethod.getReturnType();
- }
- for (int i = 0; i < invokedMethod.getArity(); i++) {
- if (invokedMethod.getParameter(i) != convertedMethod.getParameter(i)
- && parameterConversions[i] == null) {
- return invokedMethod.getParameter(i);
- }
- }
- return null;
- }
-
- @Override
- public CfCode generateCfCode() {
- DexMethod invokedMethod = initialInvoke.getMethod();
- DexMethod convertedMethod =
- DesugaredLibraryAPIConverter.methodWithVivifiedTypeInSignature(
- invokedMethod, invokedMethod.holder, appView);
-
- DexType invalidType = invalidType(invokedMethod, convertedMethod);
- if (invalidType != null) {
- // This is true if the API conversion requires to convert a type which is impossible to
- // convert: no custom conversion and no wrapping possible. This is extremely rare and
- // should happen only with broken desugared library set-ups. A warning has already been
- // reported at this point.
- DexString message =
- appView
- .dexItemFactory()
- .createString(
- "The method "
- + invokedMethod
- + " requires API conversion, but conversion was impossible because of the"
- + " non convertible type "
- + invalidType
- + ".");
- return new APIConverterThrowRuntimeExceptionCfCodeProvider(
- appView, message, invokedMethod.getHolderType())
- .generateCfCode();
- }
-
- List<CfInstruction> instructions = new ArrayList<>();
-
- boolean isStatic = initialInvoke.getOpcode() == Opcodes.INVOKESTATIC;
- if (!isStatic) {
- instructions.add(new CfLoad(ValueType.fromDexType(invokedMethod.holder), 0));
- }
- int receiverShift = BooleanUtils.intValue(!isStatic);
- int stackIndex = 0;
- for (int i = 0; i < invokedMethod.getArity(); i++) {
- DexType param = invokedMethod.getParameter(i);
- instructions.add(new CfLoad(ValueType.fromDexType(param), stackIndex + receiverShift));
- if (parameterConversions[i] != null) {
- instructions.add(new CfInvoke(Opcodes.INVOKESTATIC, parameterConversions[i], false));
- }
- if (param == appView.dexItemFactory().longType
- || param == appView.dexItemFactory().doubleType) {
- stackIndex++;
- }
- stackIndex++;
- }
-
- // Actual call to converted value.
- instructions.add(
- new CfInvoke(initialInvoke.getOpcode(), convertedMethod, initialInvoke.isInterface()));
-
- // Return conversion.
- if (returnConversion != null) {
- instructions.add(new CfInvoke(Opcodes.INVOKESTATIC, returnConversion, false));
- }
-
- if (invokedMethod.getReturnType().isVoidType()) {
- instructions.add(new CfReturnVoid());
- } else {
- instructions.add(new CfReturn(ValueType.fromDexType(invokedMethod.getReturnType())));
- }
- return standardCfCodeFromInstructions(instructions);
- }
- }
-
public static class APIConverterConstructorCfCodeProvider extends SyntheticCfCodeProvider {
DexField wrapperField;
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/EmulateInterfaceSyntheticCfCodeProvider.java b/src/main/java/com/android/tools/r8/ir/synthetic/EmulateInterfaceSyntheticCfCodeProvider.java
index e1ba3b2..7f26a19 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/EmulateInterfaceSyntheticCfCodeProvider.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/EmulateInterfaceSyntheticCfCodeProvider.java
@@ -36,13 +36,12 @@
private final List<Pair<DexType, DexMethod>> extraDispatchCases;
public EmulateInterfaceSyntheticCfCodeProvider(
- DexType holder,
DexType interfaceType,
DexMethod companionMethod,
DexMethod libraryMethod,
List<Pair<DexType, DexMethod>> extraDispatchCases,
AppView<?> appView) {
- super(appView, holder);
+ super(appView, interfaceType);
this.interfaceType = interfaceType;
this.companionMethod = companionMethod;
this.libraryMethod = libraryMethod;
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 df5840b..822a7dc 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -3886,14 +3886,14 @@
}
}
- private void postProcessingDesugaring() throws ExecutionException {
+ private void postProcessingDesugaring() {
SyntheticAdditions syntheticAdditions =
new SyntheticAdditions(appView.createProcessorContext());
R8PostProcessingDesugaringEventConsumer eventConsumer =
CfPostProcessingDesugaringEventConsumer.createForR8(appView, syntheticAdditions);
- CfPostProcessingDesugaringCollection.create(appView, null, desugaring.getRetargetingInfo())
- .postProcessingDesugaring(eventConsumer, executorService);
+ CfPostProcessingDesugaringCollection.create(appView, desugaring.getRetargetingInfo())
+ .postProcessingDesugaring(eventConsumer);
if (syntheticAdditions.isEmpty()) {
return;
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
index 9f87beb..4c1ac7c 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
@@ -51,8 +51,7 @@
THROW_NSME("ThrowNSME", 16, true),
TWR_CLOSE_RESOURCE("TwrCloseResource", 17, true),
SERVICE_LOADER("ServiceLoad", 18, true),
- OUTLINE("Outline", 19, true),
- API_CONVERSION("APIConversion", 26, true);
+ OUTLINE("Outline", 19, true);
static {
assert verifyNoOverlappingIds();
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/BufferedReaderTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/BufferedReaderTest.java
index fdca331..ddebca5 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/BufferedReaderTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/BufferedReaderTest.java
@@ -126,7 +126,7 @@
Path desugaredLib =
getDesugaredLibraryInCF(parameters, this::configurationForLibraryCompilation);
- // Run on the JVM with desugared library on classpath.
+ // Run on the JVM with desuagred library on classpath.
testForJvm()
.addProgramFiles(jar)
.addRunClasspathFiles(desugaredLib)
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/APIConversionFinalClassTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/APIConversionFinalClassTest.java
index 131295c..f9d1828 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/APIConversionFinalClassTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/APIConversionFinalClassTest.java
@@ -68,9 +68,7 @@
.inspectDiagnosticMessages(this::assertDiagnosis)
.addRunClasspathFiles(customLib)
.run(parameters.getRuntime(), Executor.class)
- .assertFailureWithErrorThatMatches(
- containsString(
- "conversion was impossible because of the non convertible type java.time.Year"));
+ .assertFailureWithErrorThatMatches(containsString("NoSuchMethodError"));
}
private void assertDiagnosis(TestDiagnosticMessages d) {