Always generate the big wrapper
Bug: 150442579
Change-Id: Ie96fce062232531f94864353275e923e74069520
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 c85439b..d8d48a2 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
@@ -121,9 +121,8 @@
registration.accept(virtualMethod);
}
DexProgramClass reverseWrapper = wrappersToReverseMap.get(wrapper);
- if (reverseWrapper != null) {
- registration.accept(getConvertMethod(reverseWrapper));
- }
+ assert reverseWrapper != null;
+ registration.accept(getConvertMethod(reverseWrapper));
return this;
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryWrapperSynthesizer.java b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryWrapperSynthesizer.java
index 069015f..3527f62 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryWrapperSynthesizer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryWrapperSynthesizer.java
@@ -20,7 +20,6 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexProgramClass.ChecksumSupplier;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
@@ -120,12 +119,6 @@
this.vivifiedSourceFile = appView.dexItemFactory().createString("vivified");
}
- public static boolean isSynthesizedWrapper(DexType type) {
- // Slow path, but more convenient since no instance is needed. Use hasSynthesized(DexType) when
- // possible.
- return type.descriptor.toString().startsWith("L" + WRAPPER_PREFIX);
- }
-
boolean hasSynthesized(DexType type) {
return type.descriptor.startsWith(dexWrapperPrefix);
}
@@ -139,10 +132,14 @@
}
DexType getTypeWrapper(DexType type) {
+ // Force create the reverse wrapper.
+ getWrapper(type, VIVIFIED_TYPE_WRAPPER_SUFFIX, vivifiedTypeWrappers);
return getWrapper(type, TYPE_WRAPPER_SUFFIX, typeWrappers);
}
DexType getVivifiedTypeWrapper(DexType type) {
+ // Force create the reverse wrapper.
+ getWrapper(type, TYPE_WRAPPER_SUFFIX, typeWrappers);
return getWrapper(type, VIVIFIED_TYPE_WRAPPER_SUFFIX, vivifiedTypeWrappers);
}
@@ -249,25 +246,10 @@
new DexEncodedMethod[] {synthesizeConstructor(wrapperField.field), conversionMethod},
virtualMethods,
factory.getSkipNameValidationForTesting(),
- getChecksumSupplier(this, clazz.type),
+ DexProgramClass::checksumFromType,
Collections.emptyList());
}
- private ChecksumSupplier getChecksumSupplier(
- DesugaredLibraryWrapperSynthesizer synthesizer, DexType keyType) {
- return clazz -> {
- // The synthesized type wrappers are constructed lazily, so their lookup must be delayed
- // until the point the checksum is requested (at write time). The presence of a wrapper
- // affects the implementation of the conversion functions, so they must be accounted for in
- // the checksum.
- boolean hasWrapper = synthesizer.typeWrappers.containsKey(keyType);
- boolean hasViviWrapper = synthesizer.vivifiedTypeWrappers.containsKey(keyType);
- return ((long) clazz.type.hashCode())
- + 7 * (long) Boolean.hashCode(hasWrapper)
- + 11 * (long) Boolean.hashCode(hasViviWrapper);
- };
- }
-
private DexEncodedMethod[] synthesizeVirtualMethodsForVivifiedTypeWrapper(
DexClass dexClass, DexEncodedField wrapperField) {
List<DexEncodedMethod> dexMethods = allImplementedMethods(dexClass);
@@ -284,7 +266,14 @@
Set<DexMethod> finalMethods = Sets.newIdentityHashSet();
for (DexEncodedMethod dexEncodedMethod : dexMethods) {
DexClass holderClass = appView.definitionFor(dexEncodedMethod.method.holder);
- assert holderClass != null;
+ boolean isInterface;
+ if (holderClass == null) {
+ assert appView.options().desugaredLibraryConfiguration.getEmulateLibraryInterface()
+ .containsValue(dexEncodedMethod.method.holder);
+ isInterface = true;
+ } else {
+ isInterface = holderClass.isInterface();
+ }
DexMethod methodToInstall =
factory.createMethod(
wrapperField.field.holder,
@@ -302,7 +291,7 @@
methodToInstall,
wrapperField.field,
converter,
- holderClass.isInterface())
+ isInterface)
.generateCfCode();
}
DexEncodedMethod newDexEncodedMethod =
@@ -585,23 +574,25 @@
private DexEncodedMethod generateTypeConversion(DexType type, DexType typeWrapperType) {
DexType reverse = vivifiedTypeWrappers.get(type);
+ assert reverse != null;
return synthesizeConversionMethod(
typeWrapperType,
type,
type,
vivifiedTypeFor(type),
- reverse == null ? null : wrappedValueField(reverse, vivifiedTypeFor(type)));
+ wrappedValueField(reverse, vivifiedTypeFor(type)));
}
private DexEncodedMethod generateVivifiedTypeConversion(
DexType type, DexType vivifiedTypeWrapperType) {
DexType reverse = typeWrappers.get(type);
+ assert reverse != null;
return synthesizeConversionMethod(
vivifiedTypeWrapperType,
type,
vivifiedTypeFor(type),
type,
- reverse == null ? null : wrappedValueField(reverse, type));
+ wrappedValueField(reverse, type));
}
private DexEncodedMethod synthesizeConversionMethod(
@@ -609,7 +600,7 @@
DexType type,
DexType argType,
DexType returnType,
- DexField reverseFieldOrNull) {
+ DexField reverseField) {
DexMethod method =
factory.createMethod(
holder, factory.createProto(returnType, argType), factory.convertMethodName);
@@ -629,7 +620,7 @@
new APIConverterWrapperConversionCfCodeProvider(
appView,
argType,
- reverseFieldOrNull,
+ reverseField,
factory.createField(holder, returnType, factory.wrapperFieldName))
.generateCfCode();
}
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 422bc2f..50885dc 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
@@ -253,20 +253,18 @@
instructions.add(new CfReturn(ValueType.OBJECT));
instructions.add(nullDest);
- // This part is skipped if there is no reverse wrapper.
// if (arg instanceOf ReverseWrapper) { return ((ReverseWrapper) arg).wrapperField};
- if (reverseWrapperField != null) {
- CfLabel unwrapDest = new CfLabel();
- instructions.add(new CfLoad(ValueType.fromDexType(argType), 0));
- instructions.add(new CfInstanceOf(reverseWrapperField.holder));
- instructions.add(new CfIf(If.Type.EQ, ValueType.INT, unwrapDest));
- instructions.add(new CfLoad(ValueType.fromDexType(argType), 0));
- instructions.add(new CfCheckCast(reverseWrapperField.holder));
- instructions.add(
- new CfFieldInstruction(Opcodes.GETFIELD, reverseWrapperField, reverseWrapperField));
- instructions.add(new CfReturn(ValueType.fromDexType(reverseWrapperField.type)));
- instructions.add(unwrapDest);
- }
+ assert reverseWrapperField != null;
+ CfLabel unwrapDest = new CfLabel();
+ instructions.add(new CfLoad(ValueType.fromDexType(argType), 0));
+ instructions.add(new CfInstanceOf(reverseWrapperField.holder));
+ instructions.add(new CfIf(If.Type.EQ, ValueType.INT, unwrapDest));
+ instructions.add(new CfLoad(ValueType.fromDexType(argType), 0));
+ instructions.add(new CfCheckCast(reverseWrapperField.holder));
+ instructions.add(
+ new CfFieldInstruction(Opcodes.GETFIELD, reverseWrapperField, reverseWrapperField));
+ instructions.add(new CfReturn(ValueType.fromDexType(reverseWrapperField.type)));
+ instructions.add(unwrapDest);
// return new Wrapper(wrappedValue);
instructions.add(new CfNew(wrapperField.holder));
@@ -317,6 +315,7 @@
public static class APIConverterThrowRuntimeExceptionCfCodeProvider
extends SyntheticCfCodeProvider {
+
DexString message;
public APIConverterThrowRuntimeExceptionCfCodeProvider(
diff --git a/src/main/java/com/android/tools/r8/utils/ProgramClassCollection.java b/src/main/java/com/android/tools/r8/utils/ProgramClassCollection.java
index d602a51..3681a77 100644
--- a/src/main/java/com/android/tools/r8/utils/ProgramClassCollection.java
+++ b/src/main/java/com/android/tools/r8/utils/ProgramClassCollection.java
@@ -4,13 +4,10 @@
package com.android.tools.r8.utils;
import com.android.tools.r8.dex.ApplicationReader.ProgramClassConflictResolver;
-import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.DuplicateTypesDiagnostic;
import com.android.tools.r8.graph.ClassKind;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.ir.desugar.DesugaredLibraryWrapperSynthesizer;
import com.android.tools.r8.references.Reference;
import com.google.common.collect.ImmutableList;
import java.util.List;
@@ -85,9 +82,6 @@
private static DexProgramClass mergeClasses(
Reporter reporter, DexProgramClass a, DexProgramClass b) {
- if (DesugaredLibraryWrapperSynthesizer.isSynthesizedWrapper(a.type)) {
- return mergeWrappers(a, b);
- }
if (a.type.isD8R8SynthesizedClassType()) {
assert assertEqualClasses(a, b);
return a;
@@ -100,22 +94,4 @@
assert a.directMethods().size() == b.directMethods().size();
return true;
}
-
- private static DexProgramClass mergeWrappers(DexProgramClass a, DexProgramClass b) {
- DexEncodedMethod aMethod = findConversionMethod(a);
- DexEncodedMethod bMethod = findConversionMethod(b);
- return aMethod.getCode().estimatedSizeForInlining()
- > bMethod.getCode().estimatedSizeForInlining()
- ? a
- : b;
- }
-
- private static DexEncodedMethod findConversionMethod(DexProgramClass clazz) {
- for (DexEncodedMethod dexEncodedMethod : clazz.directMethods()) {
- if (!dexEncodedMethod.isInstanceInitializer()) {
- return dexEncodedMethod;
- }
- }
- throw new CompilationError("A wrapper should have a conversion method.");
- }
}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/FunctionConversionTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/FunctionConversionTest.java
index 687a673..3d1b999 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/FunctionConversionTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/FunctionConversionTest.java
@@ -4,16 +4,12 @@
package com.android.tools.r8.desugar.desugaredlibrary.conversiontests;
-import static junit.framework.TestCase.assertEquals;
-
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
import com.android.tools.r8.ir.desugar.DesugaredLibraryWrapperSynthesizer;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.StringUtils;
-import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
import java.nio.file.Path;
import java.util.List;
import java.util.function.BiFunction;
@@ -25,7 +21,6 @@
import java.util.function.IntSupplier;
import java.util.function.LongConsumer;
import java.util.function.LongSupplier;
-import java.util.stream.Collectors;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.BeforeClass;
@@ -75,7 +70,6 @@
.addLibraryClasses(CustomLibClass.class)
.enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
.compile()
- .inspect(this::assertSingleWrappers)
.addDesugaredCoreLibraryRunClassPath(
this::buildDesugaredLibrary,
parameters.getApiLevel(),
@@ -107,26 +101,6 @@
.assertSuccessWithOutput(EXPECTED_RESULT);
}
- private void assertSingleWrappers(CodeInspector i) {
- List<FoundClassSubject> intSupplierWrapperClasses =
- i.allClasses().stream()
- .filter(c -> c.getOriginalName().contains("IntSupplier"))
- .collect(Collectors.toList());
- assertEquals(
- "Expected 1 IntSupplier wrapper but got " + intSupplierWrapperClasses,
- 1,
- intSupplierWrapperClasses.size());
-
- List<FoundClassSubject> doubleSupplierWrapperClasses =
- i.allClasses().stream()
- .filter(c -> c.getOriginalName().contains("DoubleSupplier"))
- .collect(Collectors.toList());
- assertEquals(
- "Expected 1 DoubleSupplier wrapper but got " + doubleSupplierWrapperClasses,
- 1,
- doubleSupplierWrapperClasses.size());
- }
-
@Test
public void testWrapperWithChecksum() throws Exception {
Assume.assumeTrue(
@@ -142,7 +116,7 @@
.inspect(
inspector -> {
Assert.assertEquals(
- 8,
+ 9,
inspector.allClasses().stream()
.filter(
clazz ->
@@ -151,7 +125,7 @@
.contains(DesugaredLibraryWrapperSynthesizer.TYPE_WRAPPER_SUFFIX))
.count());
Assert.assertEquals(
- 6,
+ 9,
inspector.allClasses().stream()
.filter(
clazz ->