Merge commit '5eddb3987a5140f150bf67a3476b197d9259ed6e' into dev-release
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
index c7b07d3..269dc23 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
@@ -112,16 +112,24 @@
private final AppView<? extends AppInfoWithClassHierarchy> appView;
private final EnumUnboxer enumUnboxer;
- private final LensCodeRewriterUtils helper;
+ private LensCodeRewriterUtils helper = null;
private final InternalOptions options;
LensCodeRewriter(AppView<? extends AppInfoWithClassHierarchy> appView, EnumUnboxer enumUnboxer) {
this.appView = appView;
this.enumUnboxer = enumUnboxer;
- this.helper = new LensCodeRewriterUtils(appView);
this.options = appView.options();
}
+ private LensCodeRewriterUtils getHelper() {
+ // The LensCodeRewriterUtils uses internal caches that are not valid if the graphLens changes.
+ if (helper != null && helper.hasGraphLens(appView.graphLens())) {
+ return helper;
+ }
+ helper = new LensCodeRewriterUtils(appView);
+ return helper;
+ }
+
private Value makeOutValue(Instruction insn, IRCode code) {
if (insn.hasOutValue()) {
TypeElement oldType = insn.getOutType();
@@ -170,7 +178,7 @@
{
InvokeCustom invokeCustom = current.asInvokeCustom();
DexCallSite callSite = invokeCustom.getCallSite();
- DexCallSite newCallSite = helper.rewriteCallSite(callSite, method);
+ DexCallSite newCallSite = getHelper().rewriteCallSite(callSite, method);
if (newCallSite != callSite) {
Value newOutValue = makeOutValue(invokeCustom, code);
InvokeCustom newInvokeCustom =
@@ -187,7 +195,8 @@
{
DexMethodHandle handle = current.asConstMethodHandle().getValue();
DexMethodHandle newHandle =
- helper.rewriteDexMethodHandle(handle, NOT_ARGUMENT_TO_LAMBDA_METAFACTORY, method);
+ getHelper()
+ .rewriteDexMethodHandle(handle, NOT_ARGUMENT_TO_LAMBDA_METAFACTORY, method);
if (newHandle != handle) {
Value newOutValue = makeOutValue(current, code);
iterator.replaceCurrentInstruction(new ConstMethodHandle(newOutValue, newHandle));
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriterUtils.java b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriterUtils.java
index b8a70f9..dd5b328 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriterUtils.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriterUtils.java
@@ -17,6 +17,7 @@
import com.android.tools.r8.graph.DexMethodHandle;
import com.android.tools.r8.graph.DexMethodHandle.MethodHandleType;
import com.android.tools.r8.graph.DexProto;
+import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexValue;
import com.android.tools.r8.graph.DexValue.DexValueMethodHandle;
@@ -26,6 +27,8 @@
import com.android.tools.r8.graph.GraphLens.MethodLookupResult;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.UseRegistry.MethodHandleUse;
+import com.android.tools.r8.ir.code.Invoke;
+import com.android.tools.r8.ir.desugar.LambdaDescriptor;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -33,7 +36,6 @@
public class LensCodeRewriterUtils {
- private final AppView<?> appView;
private final DexDefinitionSupplier definitions;
private final GraphLens graphLens;
@@ -44,27 +46,21 @@
private final Map<DexCallSite, DexCallSite> rewrittenCallSiteCache;
public LensCodeRewriterUtils(AppView<?> appView) {
- this(appView, false);
+ this(appView, appView.graphLens());
}
public LensCodeRewriterUtils(AppView<?> appView, boolean enableCallSiteCaching) {
- this.appView = appView;
this.definitions = appView;
- this.graphLens = null;
+ this.graphLens = appView.graphLens();
this.rewrittenCallSiteCache = enableCallSiteCaching ? new ConcurrentHashMap<>() : null;
}
public LensCodeRewriterUtils(DexDefinitionSupplier definitions, GraphLens graphLens) {
- this.appView = null;
this.definitions = definitions;
this.graphLens = graphLens;
this.rewrittenCallSiteCache = null;
}
- private GraphLens graphLens() {
- return appView != null ? appView.graphLens() : graphLens;
- }
-
public DexCallSite rewriteCallSite(DexCallSite callSite, ProgramMethod context) {
if (rewrittenCallSiteCache == null) {
return rewriteCallSiteInternal(callSite, context);
@@ -85,22 +81,41 @@
isLambdaMetaFactory ? ARGUMENT_TO_LAMBDA_METAFACTORY : NOT_ARGUMENT_TO_LAMBDA_METAFACTORY;
List<DexValue> newArgs =
rewriteBootstrapArguments(callSite.bootstrapArgs, methodHandleUse, context);
+ DexString newMethodName = computeNewMethodName(callSite, context, isLambdaMetaFactory);
if (!newMethodProto.equals(callSite.methodProto)
+ || newMethodName != callSite.methodName
|| newBootstrapMethod != callSite.bootstrapMethod
|| !newArgs.equals(callSite.bootstrapArgs)) {
return dexItemFactory.createCallSite(
- callSite.methodName, newMethodProto, newBootstrapMethod, newArgs);
+ newMethodName, newMethodProto, newBootstrapMethod, newArgs);
}
return callSite;
}
+ private DexString computeNewMethodName(
+ DexCallSite callSite, ProgramMethod context, boolean isLambdaMetaFactory) {
+ if (!isLambdaMetaFactory) {
+ return callSite.methodName;
+ }
+ assert callSite.getBootstrapArgs().size() > 0;
+ assert callSite.getBootstrapArgs().get(0).isDexValueMethodType();
+ // The targeted method may have been renamed, we need to update the name if that is the case.
+ DexMethod method =
+ LambdaDescriptor.getMainFunctionalInterfaceMethodReference(
+ callSite, definitions.dexItemFactory());
+ return graphLens
+ .lookupMethod(method, context.getReference(), Invoke.Type.INTERFACE)
+ .getReference()
+ .getName();
+ }
+
public DexMethodHandle rewriteDexMethodHandle(
DexMethodHandle methodHandle, MethodHandleUse use, ProgramMethod context) {
if (methodHandle.isMethodHandle()) {
DexMethod invokedMethod = methodHandle.asMethod();
MethodHandleType oldType = methodHandle.type;
MethodLookupResult lensLookup =
- graphLens().lookupMethod(invokedMethod, context.getReference(), oldType.toInvokeType());
+ graphLens.lookupMethod(invokedMethod, context.getReference(), oldType.toInvokeType());
DexMethod rewrittenTarget = lensLookup.getReference();
DexMethod actualTarget;
MethodHandleType newType;
@@ -120,7 +135,7 @@
definitions
.dexItemFactory()
.createMethod(
- graphLens().lookupType(invokedMethod.holder),
+ graphLens.lookupType(invokedMethod.holder),
rewrittenTarget.proto,
rewrittenTarget.name);
newType = oldType;
@@ -147,7 +162,7 @@
}
} else {
DexField field = methodHandle.asField();
- DexField actualField = graphLens().lookupField(field);
+ DexField actualField = graphLens.lookupField(field);
if (actualField != field) {
return definitions
.dexItemFactory()
@@ -192,7 +207,7 @@
return rewriteDexMethodType(value.asDexValueMethodType());
case TYPE:
DexType oldType = value.asDexValueType().value;
- DexType newType = graphLens().lookupType(oldType);
+ DexType newType = graphLens.lookupType(oldType);
return newType != oldType ? new DexValueType(newType) : value;
default:
return value;
@@ -202,7 +217,7 @@
public DexProto rewriteProto(DexProto proto) {
return definitions
.dexItemFactory()
- .applyClassMappingToProto(proto, graphLens()::lookupType, protoFixupCache);
+ .applyClassMappingToProto(proto, graphLens::lookupType, protoFixupCache);
}
private DexValueMethodHandle rewriteDexValueMethodHandle(
@@ -211,4 +226,8 @@
DexMethodHandle newHandle = rewriteDexMethodHandle(oldHandle, use, context);
return newHandle != oldHandle ? new DexValueMethodHandle(newHandle) : methodHandle;
}
+
+ public boolean hasGraphLens(GraphLens graphLens) {
+ return this.graphLens == graphLens;
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java
index ed967ef..bc7a544 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java
@@ -23,6 +23,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
+import java.util.function.BiConsumer;
import java.util.function.Consumer;
// Represents the lambda descriptor inferred from calls site.
@@ -182,6 +183,13 @@
return implHandle.asMethod().getName().startsWith(factory.javacLambdaMethodPrefix);
}
+ public void forEachErasedAndEnforcedTypes(BiConsumer<DexType, DexType> consumer) {
+ consumer.accept(erasedProto.returnType, enforcedProto.returnType);
+ for (int i = 0; i < enforcedProto.getArity(); i++) {
+ consumer.accept(erasedProto.getParameter(i), enforcedProto.getParameter(i));
+ }
+ }
+
public Iterable<DexType> getReferencedBaseTypes(DexItemFactory dexItemFactory) {
return enforcedProto.getBaseTypes(dexItemFactory);
}
@@ -259,6 +267,15 @@
return descriptor == MATCH_FAILED ? null : descriptor;
}
+ public static DexMethod getMainFunctionalInterfaceMethodReference(
+ DexCallSite callSite, DexItemFactory factory) {
+ DexProto proto = callSite.getBootstrapArgs().get(0).asDexValueMethodType().value;
+ DexProto lambdaFactoryProto = callSite.methodProto;
+ DexType mainInterface = lambdaFactoryProto.returnType;
+ DexString funcMethodName = callSite.methodName;
+ return factory.createMethod(mainInterface, proto, funcMethodName);
+ }
+
public static boolean isLambdaMetafactoryMethod(
DexCallSite callSite, DexDefinitionSupplier definitions) {
return callSite.bootstrapMethod.type.isInvokeStatic()
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxerImpl.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxerImpl.java
index 40627da..353d8b7 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxerImpl.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxerImpl.java
@@ -74,6 +74,7 @@
import com.android.tools.r8.ir.conversion.MethodConversionOptions.MutableMethodConversionOptions;
import com.android.tools.r8.ir.conversion.MethodProcessor;
import com.android.tools.r8.ir.conversion.PostMethodProcessor.Builder;
+import com.android.tools.r8.ir.desugar.LambdaDescriptor;
import com.android.tools.r8.ir.optimize.enums.EnumDataMap.EnumData;
import com.android.tools.r8.ir.optimize.enums.EnumInstanceFieldData.EnumInstanceFieldKnownData;
import com.android.tools.r8.ir.optimize.enums.EnumInstanceFieldData.EnumInstanceFieldMappingData;
@@ -265,7 +266,7 @@
analyzeCheckCast(instruction.asCheckCast(), eligibleEnums);
break;
case INVOKE_CUSTOM:
- analyzeInvokeCustom(instruction.asInvokeCustom(), eligibleEnums);
+ analyzeInvokeCustom(instruction.asInvokeCustom(), eligibleEnums, code.context());
break;
case INVOKE_STATIC:
analyzeInvokeStatic(instruction.asInvokeStatic(), eligibleEnums, code.context());
@@ -303,15 +304,45 @@
}
}
- private void analyzeInvokeCustom(InvokeCustom invoke, Set<DexType> eligibleEnums) {
- Consumer<DexType> typeReferenceConsumer =
- type -> {
- DexProgramClass enumClass = getEnumUnboxingCandidateOrNull(type);
- if (enumClass != null) {
- eligibleEnums.add(enumClass.getType());
+ private void markEnumEligible(DexType type, Set<DexType> eligibleEnums) {
+ DexProgramClass enumClass = getEnumUnboxingCandidateOrNull(type);
+ if (enumClass != null) {
+ eligibleEnums.add(enumClass.getType());
+ }
+ }
+
+ private void invalidateEnum(DexType type) {
+ DexProgramClass enumClass = getEnumUnboxingCandidateOrNull(type);
+ if (enumClass != null) {
+ markEnumAsUnboxable(Reason.INVALID_INVOKE_CUSTOM, enumClass);
+ }
+ }
+
+ private void analyzeInvokeCustom(
+ InvokeCustom invoke, Set<DexType> eligibleEnums, ProgramMethod context) {
+ invoke.getCallSite().getMethodProto().forEachType(t -> markEnumEligible(t, eligibleEnums));
+ LambdaDescriptor lambdaDescriptor =
+ LambdaDescriptor.tryInfer(invoke.getCallSite(), appView.appInfo(), context);
+ if (lambdaDescriptor == null) {
+ // Based on lambda we can see that enums cannot be unboxed if used in call site bootstrap
+ // arguments, since there might be expectations on overrides. Enums used directly in the
+ // method proto should be fine.
+ analyzeInvokeCustomParameters(invoke, this::invalidateEnum);
+ return;
+ }
+
+ analyzeInvokeCustomParameters(invoke, t -> markEnumEligible(t, eligibleEnums));
+
+ lambdaDescriptor.forEachErasedAndEnforcedTypes(
+ (erasedType, enforcedType) -> {
+ if (erasedType != enforcedType) {
+ invalidateEnum(erasedType);
+ invalidateEnum(enforcedType);
}
- };
- invoke.getCallSite().getMethodProto().forEachType(typeReferenceConsumer);
+ });
+ }
+
+ private void analyzeInvokeCustomParameters(InvokeCustom invoke, Consumer<DexType> nonHolder) {
invoke
.getCallSite()
.getBootstrapArgs()
@@ -322,26 +353,17 @@
bootstrapArgument.asDexValueMethodHandle().getValue();
if (methodHandle.isMethodHandle()) {
DexMethod method = methodHandle.asMethod();
- DexProgramClass enumClass =
- getEnumUnboxingCandidateOrNull(method.getHolderType());
- if (enumClass != null) {
- markEnumAsUnboxable(Reason.INVALID_INVOKE_CUSTOM, enumClass);
- } else {
- method.getProto().forEachType(typeReferenceConsumer);
- }
+ invalidateEnum(method.getHolderType());
+ method.getProto().forEachType(nonHolder);
} else {
assert methodHandle.isFieldHandle();
DexField field = methodHandle.asField();
- DexProgramClass enumClass = getEnumUnboxingCandidateOrNull(field.getHolderType());
- if (enumClass != null) {
- markEnumAsUnboxable(Reason.INVALID_INVOKE_CUSTOM, enumClass);
- } else {
- typeReferenceConsumer.accept(field.getType());
- }
+ invalidateEnum(field.getHolderType());
+ nonHolder.accept(field.type);
}
} else if (bootstrapArgument.isDexValueMethodType()) {
DexProto proto = bootstrapArgument.asDexValueMethodType().getValue();
- proto.forEachType(typeReferenceConsumer);
+ proto.forEachType(nonHolder);
}
});
}
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 494cf92..fb814c6 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -4626,38 +4626,38 @@
}
DexProgramClass clazz = asProgramClassOrNull(definitionFor(type, method));
- if (clazz != null) {
+ if (clazz != null && clazz.isInterface()) {
+ KeepReason reason = KeepReason.reflectiveUseIn(method);
+ markInterfaceAsInstantiated(clazz, graphReporter.registerClass(clazz, reason));
worklist.addIfNotSeen(clazz);
}
}
while (worklist.hasNext()) {
DexProgramClass clazz = worklist.next();
- if (!clazz.isInterface()) {
- continue;
- }
+ assert clazz.isInterface();
- // Add this interface to the set of pinned items to ensure that we do not merge the
- // interface into its unique subtype, if any.
- // TODO(b/145344105): This should be superseded by the unknown interface hierarchy.
+ // Keep this interface to ensure that we do not merge the interface into its unique subtype,
+ // or merge other interfaces into it horizontally.
keepInfo.joinClass(clazz, joiner -> joiner.disallowOptimization().disallowShrinking());
- KeepReason reason = KeepReason.reflectiveUseIn(method);
- markInterfaceAsInstantiated(clazz, graphReporter.registerClass(clazz, reason));
- // Also pin all of its virtual methods to ensure that the devirtualizer does not perform
+ // Also keep all of its virtual methods to ensure that the devirtualizer does not perform
// illegal rewritings of invoke-interface instructions into invoke-virtual instructions.
- clazz.forEachProgramVirtualMethod(
- virtualMethod -> {
- keepInfo.joinMethod(
- virtualMethod, joiner -> joiner.disallowOptimization().disallowShrinking());
- markVirtualMethodAsReachable(virtualMethod.getReference(), true, method, reason);
- });
+ if (mode.isInitialTreeShaking()) {
+ KeepReason reason = KeepReason.reflectiveUseIn(method);
+ clazz.forEachProgramVirtualMethod(
+ virtualMethod -> {
+ keepInfo.joinMethod(
+ virtualMethod, joiner -> joiner.disallowOptimization().disallowShrinking());
+ markVirtualMethodAsReachable(virtualMethod.getReference(), true, method, reason);
+ });
+ }
// Repeat for all super interfaces.
for (DexType implementedType : clazz.getInterfaces()) {
DexProgramClass implementedClass =
asProgramClassOrNull(definitionFor(implementedType, clazz));
- if (implementedClass != null) {
+ if (implementedClass != null && implementedClass.isInterface()) {
worklist.addIfNotSeen(implementedClass);
}
}
diff --git a/src/test/java/com/android/tools/r8/enumunboxing/LambdaEnumUnboxingEmptyEnumObjectTest.java b/src/test/java/com/android/tools/r8/enumunboxing/LambdaEnumUnboxingEmptyEnumObjectTest.java
new file mode 100644
index 0000000..284f8ac
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/enumunboxing/LambdaEnumUnboxingEmptyEnumObjectTest.java
@@ -0,0 +1,77 @@
+// 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.enumunboxing;
+
+import com.android.tools.r8.NeverClassInline;
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.NoVerticalClassMerging;
+import com.android.tools.r8.TestParameters;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class LambdaEnumUnboxingEmptyEnumObjectTest extends EnumUnboxingTestBase {
+
+ private final TestParameters parameters;
+ private final boolean enumValueOptimization;
+ private final EnumKeepRules enumKeepRules;
+
+ @Parameters(name = "{0} valueOpt: {1} keep: {2}")
+ public static List<Object[]> data() {
+ return enumUnboxingTestParameters(getTestParameters().withAllRuntimesAndApiLevels().build());
+ }
+
+ public LambdaEnumUnboxingEmptyEnumObjectTest(
+ TestParameters parameters, boolean enumValueOptimization, EnumKeepRules enumKeepRules) {
+ this.parameters = parameters;
+ this.enumValueOptimization = enumValueOptimization;
+ this.enumKeepRules = enumKeepRules;
+ }
+
+ @Test
+ public void testEnumUnboxing() throws Exception {
+ testForR8(parameters.getBackend())
+ .addInnerClasses(getClass())
+ .addKeepMainRule(Main.class)
+ .addKeepRules(enumKeepRules.getKeepRules())
+ .enableNeverClassInliningAnnotations()
+ .noMinification()
+ .enableNoVerticalClassMergingAnnotations()
+ .enableInliningAnnotations()
+ .addOptionsModification(opt -> enableEnumOptions(opt, enumValueOptimization))
+ .addEnumUnboxingInspector(
+ inspector ->
+ inspector.assertUnboxedIf(
+ enumKeepRules.isNone() && parameters.getBackend().isDex(), MyEnum.class))
+ .setMinApi(parameters.getApiLevel())
+ .compile()
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines("null");
+ }
+
+ @NeverClassInline
+ enum MyEnum {}
+
+ @NoVerticalClassMerging
+ interface ObjectConsumer<T> {
+
+ void accept(T o);
+ }
+
+ static class Main {
+
+ public static void main(String[] args) {
+ executeObject(e -> System.out.println(String.valueOf(e)));
+ }
+
+ @NeverInline
+ static void executeObject(ObjectConsumer<MyEnum> consumer) {
+ consumer.accept(null);
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/enumunboxing/LambdaEnumUnboxingEmptyEnumTest.java b/src/test/java/com/android/tools/r8/enumunboxing/LambdaEnumUnboxingEmptyEnumTest.java
new file mode 100644
index 0000000..288ace4
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/enumunboxing/LambdaEnumUnboxingEmptyEnumTest.java
@@ -0,0 +1,75 @@
+// 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.enumunboxing;
+
+import com.android.tools.r8.NeverClassInline;
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.NoVerticalClassMerging;
+import com.android.tools.r8.TestParameters;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class LambdaEnumUnboxingEmptyEnumTest extends EnumUnboxingTestBase {
+
+ private final TestParameters parameters;
+ private final boolean enumValueOptimization;
+ private final EnumKeepRules enumKeepRules;
+
+ @Parameters(name = "{0} valueOpt: {1} keep: {2}")
+ public static List<Object[]> data() {
+ return enumUnboxingTestParameters(getTestParameters().withAllRuntimesAndApiLevels().build());
+ }
+
+ public LambdaEnumUnboxingEmptyEnumTest(
+ TestParameters parameters, boolean enumValueOptimization, EnumKeepRules enumKeepRules) {
+ this.parameters = parameters;
+ this.enumValueOptimization = enumValueOptimization;
+ this.enumKeepRules = enumKeepRules;
+ }
+
+ @Test
+ public void testEnumUnboxing() throws Exception {
+ testForR8(parameters.getBackend())
+ .addInnerClasses(getClass())
+ .addKeepMainRule(Main.class)
+ .addKeepRules(enumKeepRules.getKeepRules())
+ .enableNeverClassInliningAnnotations()
+ .noMinification()
+ .enableNoVerticalClassMergingAnnotations()
+ .enableInliningAnnotations()
+ .addOptionsModification(opt -> enableEnumOptions(opt, enumValueOptimization))
+ .addEnumUnboxingInspector(
+ inspector -> inspector.assertUnboxedIf(enumKeepRules.isNone(), MyEnum.class))
+ .setMinApi(parameters.getApiLevel())
+ .compile()
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines("null");
+ }
+
+ @NeverClassInline
+ enum MyEnum {}
+
+ @NoVerticalClassMerging
+ interface MyEnumConsumer {
+
+ void accept(MyEnum e);
+ }
+
+ static class Main {
+
+ public static void main(String[] args) {
+ execute(e -> System.out.println(String.valueOf(e)));
+ }
+
+ @NeverInline
+ static void execute(MyEnumConsumer consumer) {
+ consumer.accept(null);
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/internal/CompilationTestBase.java b/src/test/java/com/android/tools/r8/internal/CompilationTestBase.java
index cec9053..0a19636 100644
--- a/src/test/java/com/android/tools/r8/internal/CompilationTestBase.java
+++ b/src/test/java/com/android/tools/r8/internal/CompilationTestBase.java
@@ -75,17 +75,6 @@
reporter = new Reporter(handler);
}
- public AndroidApp runAndCheckVerification(
- CompilerUnderTest compiler,
- CompilationMode mode,
- String referenceApk,
- List<String> pgConfs,
- String input)
- throws ExecutionException, IOException, CompilationFailedException {
- return runAndCheckVerification(
- compiler, mode, referenceApk, pgConfs, null, Collections.singletonList(input));
- }
-
public AndroidApp runAndCheckVerification(D8Command.Builder builder, String referenceApk)
throws IOException, ExecutionException, CompilationFailedException {
AndroidAppConsumers appSink = new AndroidAppConsumers(builder);
@@ -95,22 +84,6 @@
return result;
}
- public void assertIdenticalZipFiles(File file1, File file2) throws IOException {
- try (ZipFile zipFile1 = new ZipFile(file1); ZipFile zipFile2 = new ZipFile(file2)) {
- final Enumeration<? extends ZipEntry> entries1 = zipFile1.entries();
- final Enumeration<? extends ZipEntry> entries2 = zipFile2.entries();
-
- while (entries1.hasMoreElements()) {
- Assert.assertTrue(entries2.hasMoreElements());
- ZipEntry entry1 = entries1.nextElement();
- ZipEntry entry2 = entries2.nextElement();
- Assert.assertEquals(entry1.getName(), entry2.getName());
- Assert.assertEquals(entry1.getCrc(), entry2.getCrc());
- Assert.assertEquals(entry1.getSize(), entry2.getSize());
- }
- }
- }
-
public AndroidApp runAndCheckVerification(
CompilerUnderTest compiler,
CompilationMode mode,
diff --git a/src/test/java/com/android/tools/r8/internal/D8FrameworkDeterministicTest.java b/src/test/java/com/android/tools/r8/internal/D8FrameworkDeterministicTest.java
index ab430d5..0d6061a 100644
--- a/src/test/java/com/android/tools/r8/internal/D8FrameworkDeterministicTest.java
+++ b/src/test/java/com/android/tools/r8/internal/D8FrameworkDeterministicTest.java
@@ -9,7 +9,6 @@
import com.android.tools.r8.D8Command;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.AndroidAppConsumers;
-import java.io.IOException;
import java.nio.file.Paths;
import org.junit.Test;
@@ -17,8 +16,7 @@
private static final int MIN_SDK = 24;
private static final String JAR = "third_party/framework/framework_160115954.jar";
- private AndroidApp doRun(D8Command.Builder builder)
- throws IOException, CompilationFailedException {
+ private AndroidApp doRun(D8Command.Builder builder) throws CompilationFailedException {
builder.setProgramConsumer(null);
AndroidAppConsumers appSink = new AndroidAppConsumers(builder);
D8.run(builder.build());
diff --git a/src/test/java/com/android/tools/r8/internal/GMSCoreLatestTest.java b/src/test/java/com/android/tools/r8/internal/GMSCoreLatestTest.java
index 3beab34..3f5ad48 100644
--- a/src/test/java/com/android/tools/r8/internal/GMSCoreLatestTest.java
+++ b/src/test/java/com/android/tools/r8/internal/GMSCoreLatestTest.java
@@ -40,7 +40,7 @@
@Parameterized.Parameters(name = "{0}")
public static TestParametersCollection data() {
return getTestParameters()
- .withDexRuntime(Version.V9_0_0)
+ .withDexRuntime(Version.DEFAULT)
.withApiLevel(AndroidApiLevel.L)
.build();
}
@@ -125,9 +125,7 @@
containsString("Proguard configuration rule does not match anything")))
.assertAllWarningMessagesMatch(
anyOf(
- containsString(
- "Expected stack map table for method with non-linear control flow. "
- + "In later version of R8, the method may be assumed not reachable."),
+ containsString("Expected stack map table for method with non-linear control flow."),
containsString("Ignoring option: -outjars")));
}
}
diff --git a/src/test/java/com/android/tools/r8/internal/GMSCoreV10Test.java b/src/test/java/com/android/tools/r8/internal/GMSCoreV10Test.java
index 30716fb..4c9b99f 100644
--- a/src/test/java/com/android/tools/r8/internal/GMSCoreV10Test.java
+++ b/src/test/java/com/android/tools/r8/internal/GMSCoreV10Test.java
@@ -43,7 +43,7 @@
@Parameterized.Parameters(name = "{0}")
public static TestParametersCollection data() {
return getTestParameters()
- .withDexRuntime(Version.V9_0_0)
+ .withDexRuntime(Version.DEFAULT)
.withApiLevel(AndroidApiLevel.L)
.build();
}
diff --git a/src/test/java/com/android/tools/r8/internal/Gmail18082615TreeShakeJarVerificationTest.java b/src/test/java/com/android/tools/r8/internal/Gmail18082615TreeShakeJarVerificationTest.java
index 118bcce..4929cb2 100644
--- a/src/test/java/com/android/tools/r8/internal/Gmail18082615TreeShakeJarVerificationTest.java
+++ b/src/test/java/com/android/tools/r8/internal/Gmail18082615TreeShakeJarVerificationTest.java
@@ -24,16 +24,14 @@
public class Gmail18082615TreeShakeJarVerificationTest extends GmailCompilationBase {
private static final int MAX_SIZE = 20000000;
- private final TestParameters parameters;
-
@Parameters(name = "{0}")
public static TestParametersCollection data() {
- return getTestParameters().withDexRuntimes().build();
+ return getTestParameters().withNoneRuntime().build();
}
public Gmail18082615TreeShakeJarVerificationTest(TestParameters parameters) {
super(180826, 15);
- this.parameters = parameters;
+ parameters.assertNoneRuntime();
}
@Test
@@ -41,7 +39,7 @@
assumeTrue(isLocalDevelopment());
R8TestCompileResult compileResult =
- testForR8(parameters.getBackend())
+ testForR8(Backend.DEX)
.addKeepRuleFiles(
Paths.get(base).resolve(BASE_PG_CONF),
Paths.get(ToolHelper.PROGUARD_SETTINGS_FOR_INTERNAL_APPS, PG_CONF))
diff --git a/src/test/java/com/android/tools/r8/internal/Iosched2019Test.java b/src/test/java/com/android/tools/r8/internal/Iosched2019Test.java
deleted file mode 100644
index 0dbe71a..0000000
--- a/src/test/java/com/android/tools/r8/internal/Iosched2019Test.java
+++ /dev/null
@@ -1,69 +0,0 @@
-// 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.internal;
-
-import static org.hamcrest.CoreMatchers.anyOf;
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assume.assumeTrue;
-
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.ToolHelper;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.List;
-import java.util.stream.Collectors;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(Parameterized.class)
-public class Iosched2019Test extends TestBase {
-
- private final TestParameters parameters;
-
- @Parameterized.Parameters(name = "{0}")
- public static TestParametersCollection data() {
- return getTestParameters().withDexRuntimes().withAllApiLevels().build();
- }
-
- public Iosched2019Test(TestParameters parameters) {
- this.parameters = parameters;
- }
-
- @Test
- public void test() throws Exception {
- assumeTrue(ToolHelper.isLocalDevelopment());
-
- List<Path> programFiles =
- Files.list(Paths.get(ToolHelper.THIRD_PARTY_DIR, "iosched_2019"))
- .filter(path -> path.toString().endsWith(".jar"))
- .collect(Collectors.toList());
- assertEquals(155, programFiles.size());
-
- testForR8(parameters.getBackend())
- .addProgramFiles(programFiles)
- .addKeepRuleFiles(
- Paths.get(ToolHelper.THIRD_PARTY_DIR, "iosched_2019", "proguard-rules.pro"))
- .addLibraryFiles(ToolHelper.getMostRecentAndroidJar())
- .allowDiagnosticMessages()
- .allowUnusedProguardConfigurationRules()
- .setMinApi(parameters.getApiLevel())
- .compile()
- .assertAllInfoMessagesMatch(
- anyOf(
- containsString("Ignoring option: "),
- containsString("Proguard configuration rule does not match anything: ")))
- .assertAllWarningMessagesMatch(
- anyOf(
- containsString("Missing class "),
- containsString("required for default or static interface methods desugaring"),
- equalTo("Resource 'META-INF/MANIFEST.MF' already exists.")))
- .assertNoErrorMessages();
- }
-}
diff --git a/src/test/java/com/android/tools/r8/internal/Regression127524985.java b/src/test/java/com/android/tools/r8/internal/Regression127524985.java
index 4af8640..e5e6dcd 100644
--- a/src/test/java/com/android/tools/r8/internal/Regression127524985.java
+++ b/src/test/java/com/android/tools/r8/internal/Regression127524985.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.utils.StringUtils;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -26,7 +27,11 @@
@Parameters(name = "{0}")
public static TestParametersCollection data() {
- return getTestParameters().withAllRuntimes().build();
+ return getTestParameters()
+ .withCfRuntimes()
+ .withDexRuntime(Version.DEFAULT)
+ .withAllApiLevels()
+ .build();
}
private final TestParameters parameters;
@@ -52,7 +57,7 @@
.addKeepAllAttributes()
.addKeepRules("-dontwarn"))
.addProgramFiles(JAR)
- .setMinApi(parameters.getRuntime())
+ .setMinApi(parameters.getApiLevel())
.compile()
.run(parameters.getRuntime(), MAIN)
.assertSuccessWithOutput(EXPECTED);
diff --git a/src/test/java/com/android/tools/r8/internal/YouTubeV1612Test.java b/src/test/java/com/android/tools/r8/internal/YouTubeV1612Test.java
index 50442c9..b7ccb02 100644
--- a/src/test/java/com/android/tools/r8/internal/YouTubeV1612Test.java
+++ b/src/test/java/com/android/tools/r8/internal/YouTubeV1612Test.java
@@ -55,7 +55,7 @@
@Parameters(name = "{0}")
public static TestParametersCollection data() {
return getTestParameters()
- .withDexRuntime(Version.V9_0_0)
+ .withDexRuntime(Version.DEFAULT)
.withApiLevel(AndroidApiLevel.L)
.build();
}
diff --git a/src/test/java/com/android/tools/r8/internal/YouTubeV1620Test.java b/src/test/java/com/android/tools/r8/internal/YouTubeV1620Test.java
index 0c3abdd..2030032 100644
--- a/src/test/java/com/android/tools/r8/internal/YouTubeV1620Test.java
+++ b/src/test/java/com/android/tools/r8/internal/YouTubeV1620Test.java
@@ -55,7 +55,7 @@
@Parameters(name = "{0}")
public static TestParametersCollection data() {
return getTestParameters()
- .withDexRuntime(Version.V9_0_0)
+ .withDexRuntime(Version.DEFAULT)
.withApiLevel(AndroidApiLevel.L)
.build();
}
diff --git a/src/test/java/com/android/tools/r8/internal/proto/Proto2BuilderOnlyReferencedFromDynamicMethodTest.java b/src/test/java/com/android/tools/r8/internal/proto/Proto2BuilderOnlyReferencedFromDynamicMethodTest.java
index d603cc1..d6a04df 100644
--- a/src/test/java/com/android/tools/r8/internal/proto/Proto2BuilderOnlyReferencedFromDynamicMethodTest.java
+++ b/src/test/java/com/android/tools/r8/internal/proto/Proto2BuilderOnlyReferencedFromDynamicMethodTest.java
@@ -13,6 +13,7 @@
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableList;
@@ -34,7 +35,7 @@
@Parameterized.Parameters(name = "{0}")
public static TestParametersCollection data() {
- return getTestParameters().withAllRuntimesAndApiLevels().build();
+ return getTestParameters().withDexRuntime(Version.DEFAULT).withAllApiLevels().build();
}
public Proto2BuilderOnlyReferencedFromDynamicMethodTest(TestParameters parameters) {
diff --git a/src/test/java/com/android/tools/r8/internal/proto/Proto2BuilderShrinkingTest.java b/src/test/java/com/android/tools/r8/internal/proto/Proto2BuilderShrinkingTest.java
index 868c061..f8ae6c5 100644
--- a/src/test/java/com/android/tools/r8/internal/proto/Proto2BuilderShrinkingTest.java
+++ b/src/test/java/com/android/tools/r8/internal/proto/Proto2BuilderShrinkingTest.java
@@ -13,6 +13,7 @@
import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.utils.StringUtils;
@@ -57,7 +58,7 @@
"proto2.BuilderWithProtoSetterTestClass",
"proto2.BuilderWithReusedSettersTestClass",
"proto2.HasFlaggedOffExtensionBuilderTestClass")),
- getTestParameters().withAllRuntimesAndApiLevels().build());
+ getTestParameters().withDexRuntime(Version.DEFAULT).withAllApiLevels().build());
}
public Proto2BuilderShrinkingTest(List<String> mains, TestParameters parameters) {
diff --git a/src/test/java/com/android/tools/r8/internal/proto/Proto2ShrinkingTest.java b/src/test/java/com/android/tools/r8/internal/proto/Proto2ShrinkingTest.java
index dd056e1..5eda02a 100644
--- a/src/test/java/com/android/tools/r8/internal/proto/Proto2ShrinkingTest.java
+++ b/src/test/java/com/android/tools/r8/internal/proto/Proto2ShrinkingTest.java
@@ -16,6 +16,7 @@
import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
@@ -64,7 +65,7 @@
return buildParameters(
BooleanUtils.values(),
BooleanUtils.values(),
- getTestParameters().withAllRuntimesAndApiLevels().build());
+ getTestParameters().withDexRuntime(Version.DEFAULT).withAllApiLevels().build());
}
public Proto2ShrinkingTest(
diff --git a/src/test/java/com/android/tools/r8/internal/proto/Proto3ShrinkingTest.java b/src/test/java/com/android/tools/r8/internal/proto/Proto3ShrinkingTest.java
index a3c0705..f641510 100644
--- a/src/test/java/com/android/tools/r8/internal/proto/Proto3ShrinkingTest.java
+++ b/src/test/java/com/android/tools/r8/internal/proto/Proto3ShrinkingTest.java
@@ -13,6 +13,7 @@
import static org.junit.Assert.assertEquals;
import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
@@ -41,7 +42,7 @@
return buildParameters(
BooleanUtils.values(),
BooleanUtils.values(),
- getTestParameters().withAllRuntimesAndApiLevels().build());
+ getTestParameters().withDexRuntime(Version.DEFAULT).withAllApiLevels().build());
}
public Proto3ShrinkingTest(
diff --git a/third_party/chrome/chrome_180917_ffbaa8.tar.gz.sha1 b/third_party/chrome/chrome_180917_ffbaa8.tar.gz.sha1
index 104ad9d..3ac92ca 100644
--- a/third_party/chrome/chrome_180917_ffbaa8.tar.gz.sha1
+++ b/third_party/chrome/chrome_180917_ffbaa8.tar.gz.sha1
@@ -1 +1 @@
-e35ecc90931db82165b96f7b5f0e1c251ebe7347
\ No newline at end of file
+c32dc7f70022946c04bfe9316e35e60e8d2ee0cb
\ No newline at end of file