Add static class initializer merging
Change-Id: I75d26e021aa50e39a71ca056cb62a6e1d1d3625d
diff --git a/src/main/java/com/android/tools/r8/D8Command.java b/src/main/java/com/android/tools/r8/D8Command.java
index e9dbc44..f720ee9 100644
--- a/src/main/java/com/android/tools/r8/D8Command.java
+++ b/src/main/java/com/android/tools/r8/D8Command.java
@@ -414,7 +414,7 @@
// Assert some of R8 optimizations are disabled.
assert !internal.enableInlining;
assert !internal.enableClassInlining;
- assert !internal.enableHorizontalClassMerging;
+ assert internal.horizontalClassMergerOptions().isDisabled();
assert !internal.enableStaticClassMerging;
assert !internal.enableVerticalClassMerging;
assert !internal.enableClassStaticizer;
diff --git a/src/main/java/com/android/tools/r8/L8Command.java b/src/main/java/com/android/tools/r8/L8Command.java
index dce2b21..fff3341 100644
--- a/src/main/java/com/android/tools/r8/L8Command.java
+++ b/src/main/java/com/android/tools/r8/L8Command.java
@@ -168,7 +168,7 @@
// Assert some of R8 optimizations are disabled.
assert !internal.enableInlining;
assert !internal.enableClassInlining;
- assert !internal.enableHorizontalClassMerging;
+ assert internal.horizontalClassMergerOptions().isDisabled();
assert !internal.enableStaticClassMerging;
assert !internal.enableVerticalClassMerging;
assert !internal.enableClassStaticizer;
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 1dc0468..5521ef9 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -583,7 +583,9 @@
timing.end();
}
}
- if (options.enableHorizontalClassMerging && options.enableInlining) {
+ if (options.horizontalClassMergerOptions().isEnabled()
+ && options.enableInlining
+ && options.isShrinking()) {
timing.begin("HorizontalClassMerger");
HorizontalClassMerger merger = new HorizontalClassMerger(appViewWithLiveness);
DirectMappedDexApplication.Builder appBuilder =
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index 40be618..29112ed 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -869,7 +869,8 @@
? LineNumberOptimization.ON
: LineNumberOptimization.OFF;
- assert proguardConfiguration.isOptimizing() || !internal.enableHorizontalClassMerging;
+ assert proguardConfiguration.isOptimizing()
+ || internal.horizontalClassMergerOptions().isDisabled();
assert internal.enableStaticClassMerging || !proguardConfiguration.isOptimizing();
assert !internal.enableTreeShakingOfLibraryMethodOverrides;
assert internal.enableVerticalClassMerging || !proguardConfiguration.isOptimizing();
@@ -879,7 +880,7 @@
internal.getProguardConfiguration().getKeepAttributes().localVariableTypeTable = true;
internal.enableInlining = false;
internal.enableClassInlining = false;
- internal.enableHorizontalClassMerging = false;
+ internal.horizontalClassMergerOptions().disable();
internal.enableStaticClassMerging = false;
internal.enableVerticalClassMerging = false;
internal.enableClassStaticizer = false;
@@ -891,7 +892,7 @@
// If R8 is not shrinking, there is no point in running various optimizations since the
// optimized classes will still remain in the program (the application size could increase).
internal.enableEnumUnboxing = false;
- internal.enableHorizontalClassMerging = false;
+ internal.horizontalClassMergerOptions().disable();
internal.enableLambdaMerging = false;
internal.enableStaticClassMerging = false;
internal.enableVerticalClassMerging = false;
@@ -900,7 +901,7 @@
if (!internal.enableInlining) {
// If R8 cannot perform inlining, then the synthetic constructors would not inline the called
// constructors, producing invalid code.
- internal.enableHorizontalClassMerging = false;
+ internal.horizontalClassMergerOptions().disable();
}
// Amend the proguard-map consumer with options from the proguard configuration.
@@ -958,7 +959,7 @@
if (internal.isGeneratingClassFiles()) {
internal.outline.enabled = false;
internal.enableEnumUnboxing = false;
- internal.enableHorizontalClassMerging = false;
+ internal.horizontalClassMergerOptions().disable();
}
// EXPERIMENTAL flags.
diff --git a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
index 9c22c36..ce97d08 100644
--- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
@@ -1927,6 +1927,10 @@
holder);
}
+ public DexMethod createClassInitializer(DexType holder) {
+ return createMethod(holder, createProto(voidType), classConstructorMethodName);
+ }
+
public DexMethod createInstanceInitializerWithFreshProto(
DexMethod method, List<DexType> extraTypes, Predicate<DexMethod> isFresh) {
assert method.isInstanceInitializer(this);
diff --git a/src/main/java/com/android/tools/r8/graph/GraphLens.java b/src/main/java/com/android/tools/r8/graph/GraphLens.java
index b2d04e8..0e3d784 100644
--- a/src/main/java/com/android/tools/r8/graph/GraphLens.java
+++ b/src/main/java/com/android/tools/r8/graph/GraphLens.java
@@ -4,9 +4,11 @@
package com.android.tools.r8.graph;
import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
+import static com.android.tools.r8.horizontalclassmerging.ClassMerger.CLASS_ID_FIELD_NAME;
+import static com.android.tools.r8.ir.desugar.LambdaRewriter.LAMBDA_CLASS_NAME_PREFIX;
+import static com.android.tools.r8.ir.desugar.LambdaRewriter.LAMBDA_INSTANCE_FIELD_NAME;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.horizontalclassmerging.ClassMerger;
import com.android.tools.r8.ir.code.Invoke.Type;
import com.android.tools.r8.ir.conversion.LensCodeRewriterUtils;
import com.android.tools.r8.ir.desugar.InterfaceProcessor.InterfaceProcessorNestedGraphLens;
@@ -614,21 +616,14 @@
continue;
}
for (DexEncodedField field : clazz.fields()) {
- // The field $r8$clinitField may be synthesized by R8 in order to trigger the initialization
- // of the enclosing class. It is not present in the input, and therefore we do not require
- // that it can be mapped back to the original program.
- if (field.field.match(dexItemFactory.objectMembers.clinitField)) {
- continue;
- }
-
- // TODO(b/167947782): Should be a general check to see if the field is D8/R8 synthesized.
- if (field.getReference().name.toSourceString().equals(ClassMerger.CLASS_ID_FIELD_NAME)) {
- continue;
- }
-
- DexField originalField = getOriginalFieldSignature(field.field);
+ // Fields synthesized by R8 are not present in the input, and therefore we do not require
+ // that they can be mapped back to the original program.
+ DexField originalField = getOriginalFieldSignature(field.getReference());
assert originalFields.contains(originalField)
- : "Unable to map field `" + field.field.toSourceString() + "` back to original program";
+ || isD8R8SynthesizedField(originalField, dexItemFactory)
+ : "Unable to map field `"
+ + field.getReference().toSourceString()
+ + "` back to original program";
}
for (DexEncodedMethod method : clazz.methods()) {
if (method.isD8R8Synthesized()) {
@@ -643,6 +638,22 @@
return true;
}
+ private boolean isD8R8SynthesizedField(DexField field, DexItemFactory dexItemFactory) {
+ // TODO(b/167947782): Should be a general check to see if the field is D8/R8 synthesized
+ // instead of relying on field names.
+ if (field.match(dexItemFactory.objectMembers.clinitField)) {
+ return true;
+ }
+ if (field.getName().toSourceString().equals(CLASS_ID_FIELD_NAME)) {
+ return true;
+ }
+ if (field.getHolderType().toSourceString().contains(LAMBDA_CLASS_NAME_PREFIX)
+ && field.getName().toSourceString().equals(LAMBDA_INSTANCE_FIELD_NAME)) {
+ return true;
+ }
+ return false;
+ }
+
public abstract static class NonIdentityGraphLens extends GraphLens {
private final DexItemFactory dexItemFactory;
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassInitializerSynthesizedCode.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassInitializerSynthesizedCode.java
new file mode 100644
index 0000000..c919e63
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassInitializerSynthesizedCode.java
@@ -0,0 +1,100 @@
+// 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.horizontalclassmerging;
+
+import static com.android.tools.r8.utils.ConsumerUtils.apply;
+import static java.lang.Integer.max;
+
+import com.android.tools.r8.cf.CfVersion;
+import com.android.tools.r8.cf.code.CfGoto;
+import com.android.tools.r8.cf.code.CfInstruction;
+import com.android.tools.r8.cf.code.CfLabel;
+import com.android.tools.r8.cf.code.CfReturnVoid;
+import com.android.tools.r8.graph.CfCode;
+import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.utils.CfVersionUtils;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class ClassInitializerSynthesizedCode {
+ private final List<DexEncodedMethod> staticClassInitializers;
+ private int maxStack = 0;
+ private int maxLocals = 0;
+
+ private ClassInitializerSynthesizedCode(List<DexEncodedMethod> staticClassInitializers) {
+ this.staticClassInitializers = staticClassInitializers;
+ }
+
+ public boolean isEmpty() {
+ return staticClassInitializers.isEmpty();
+ }
+
+ private void addCfCode(List<CfInstruction> newInstructions, DexEncodedMethod method) {
+ CfCode code = method.getCode().asCfCode();
+ maxStack = max(maxStack, code.getMaxStack());
+ maxLocals = max(maxLocals, code.getMaxLocals());
+
+ CfLabel endLabel = new CfLabel();
+ boolean requiresLabel = false;
+ int index = 1;
+ for (CfInstruction instruction : code.getInstructions()) {
+ if (instruction.isReturn()) {
+ if (code.getInstructions().size() != index) {
+ newInstructions.add(new CfGoto(endLabel));
+ requiresLabel = true;
+ }
+ } else {
+ newInstructions.add(instruction);
+ }
+
+ index++;
+ }
+ if (requiresLabel) {
+ newInstructions.add(endLabel);
+ }
+ }
+
+ public CfCode synthesizeCode(DexType originalHolder) {
+ return new CfCode(
+ originalHolder,
+ maxStack,
+ maxLocals,
+ buildInstructions(),
+ Collections.emptyList(),
+ Collections.emptyList());
+ }
+
+ private List<CfInstruction> buildInstructions() {
+ List<CfInstruction> newInstructions = new ArrayList<>();
+ staticClassInitializers.forEach(apply(this::addCfCode, newInstructions));
+ newInstructions.add(new CfReturnVoid());
+ return newInstructions;
+ }
+
+ public DexEncodedMethod getFirst() {
+ return staticClassInitializers.iterator().next();
+ }
+
+ public CfVersion getCfVersion() {
+ return CfVersionUtils.max(staticClassInitializers);
+ }
+
+ public static class Builder {
+ private final List<DexEncodedMethod> staticClassInitializers = new ArrayList<>();
+
+ public void add(DexEncodedMethod method) {
+ assert method.isClassInitializer();
+ assert method.hasCode();
+ assert method.getCode().isCfCode();
+ staticClassInitializers.add(method);
+ }
+
+ public ClassInitializerSynthesizedCode build() {
+ return new ClassInitializerSynthesizedCode(staticClassInitializers);
+ }
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java
index 04b4b68..950cf9a 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java
@@ -6,8 +6,10 @@
import static com.google.common.base.Predicates.not;
+import com.android.tools.r8.cf.CfVersion;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.DexAnnotationSet;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
@@ -19,6 +21,9 @@
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.FieldAccessFlags;
import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
+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.shaking.AppInfoWithLiveness;
import com.android.tools.r8.shaking.FieldAccessInfoCollectionModifier;
@@ -46,8 +51,10 @@
public static final String CLASS_ID_FIELD_NAME = "$r8$classId";
+ private final AppView<AppInfoWithLiveness> appView;
private final MergeGroup group;
private final DexItemFactory dexItemFactory;
+ private final ClassInitializerSynthesizedCode classInitializerSynthesizedCode;
private final HorizontalClassMergerGraphLens.Builder lensBuilder;
private final HorizontallyMergedClasses.Builder mergedClassesBuilder;
private final FieldAccessInfoCollectionModifier.Builder fieldAccessChangesBuilder;
@@ -66,7 +73,9 @@
FieldAccessInfoCollectionModifier.Builder fieldAccessChangesBuilder,
MergeGroup group,
Collection<VirtualMethodMerger> virtualMethodMergers,
- Collection<ConstructorMerger> constructorMergers) {
+ Collection<ConstructorMerger> constructorMergers,
+ ClassInitializerSynthesizedCode classInitializerSynthesizedCode) {
+ this.appView = appView;
this.lensBuilder = lensBuilder;
this.mergedClassesBuilder = mergedClassesBuilder;
this.fieldAccessChangesBuilder = fieldAccessChangesBuilder;
@@ -75,6 +84,7 @@
this.constructorMergers = constructorMergers;
this.dexItemFactory = appView.dexItemFactory();
+ this.classInitializerSynthesizedCode = classInitializerSynthesizedCode;
this.classStaticFieldsMerger = new ClassStaticFieldsMerger(appView, lensBuilder, group);
this.classInstanceFieldsMerger = new ClassInstanceFieldsMerger(lensBuilder, group);
@@ -91,18 +101,54 @@
}
void mergeDirectMethods(SyntheticArgumentClass syntheticArgumentClass) {
+ mergeStaticClassInitializers();
mergeDirectMethods(group.getTarget());
group.forEachSource(this::mergeDirectMethods);
mergeConstructors(syntheticArgumentClass);
}
+ void mergeStaticClassInitializers() {
+ if (classInitializerSynthesizedCode.isEmpty()) {
+ return;
+ }
+
+ DexMethod newClinit = dexItemFactory.createClassInitializer(group.getTarget().getType());
+
+ CfCode code = classInitializerSynthesizedCode.synthesizeCode(group.getTarget().getType());
+ if (!group.getTarget().hasClassInitializer()) {
+ classMethodsBuilder.addDirectMethod(
+ new DexEncodedMethod(
+ newClinit,
+ MethodAccessFlags.fromSharedAccessFlags(
+ Constants.ACC_SYNTHETIC | Constants.ACC_STATIC, true),
+ MethodTypeSignature.noSignature(),
+ DexAnnotationSet.empty(),
+ ParameterAnnotationsList.empty(),
+ code,
+ true,
+ classInitializerSynthesizedCode.getCfVersion()));
+ } else {
+ DexEncodedMethod clinit = group.getTarget().getClassInitializer();
+ clinit.setCode(code, appView);
+ CfVersion cfVersion = classInitializerSynthesizedCode.getCfVersion();
+ if (cfVersion != null) {
+ clinit.upgradeClassFileVersion(cfVersion);
+ } else {
+ assert appView.options().isGeneratingDex();
+ }
+ classMethodsBuilder.addDirectMethod(clinit);
+ }
+ }
+
void mergeDirectMethods(DexProgramClass toMerge) {
toMerge.forEachProgramDirectMethod(
method -> {
DexEncodedMethod definition = method.getDefinition();
- assert !definition.isClassInitializer();
-
- if (!definition.isInstanceInitializer()) {
+ if (definition.isClassInitializer()) {
+ lensBuilder.moveMethod(
+ method.getReference(),
+ dexItemFactory.createClassInitializer(group.getTarget().getType()));
+ } else if (!definition.isInstanceInitializer()) {
DexMethod newMethod =
method.getReference().withHolder(group.getTarget().getType(), dexItemFactory);
if (!classMethodsBuilder.isFresh(newMethod)) {
@@ -114,7 +160,6 @@
}
}
});
-
// Clear the members of the class to be merged since they have now been moved to the target.
toMerge.getMethodCollection().clearDirectMethods();
}
@@ -217,6 +262,8 @@
public static class Builder {
private final AppView<AppInfoWithLiveness> appView;
private final MergeGroup group;
+ private final ClassInitializerSynthesizedCode.Builder classInitializerSynthesizedCodeBuilder =
+ new ClassInitializerSynthesizedCode.Builder();
private final Map<DexProto, ConstructorMerger.Builder> constructorMergerBuilders =
new LinkedHashMap<>();
private final List<ConstructorMerger.Builder> unmergedConstructorBuilders = new ArrayList<>();
@@ -242,20 +289,17 @@
}
private void setupForMethodMerging(DexProgramClass toMerge) {
- toMerge.forEachProgramDirectMethod(
- method -> {
- DexEncodedMethod definition = method.getDefinition();
- assert !definition.isClassInitializer();
- if (definition.isInstanceInitializer()) {
- addConstructor(method);
- }
- });
+ if (toMerge.hasClassInitializer()) {
+ classInitializerSynthesizedCodeBuilder.add(toMerge.getClassInitializer());
+ }
+ toMerge.forEachProgramDirectMethodMatching(
+ DexEncodedMethod::isInstanceInitializer, this::addConstructor);
toMerge.forEachProgramVirtualMethod(this::addVirtualMethod);
}
private void addConstructor(ProgramMethod method) {
assert method.getDefinition().isInstanceInitializer();
- if (appView.options().enableHorizontalClassMergingConstructorMerging) {
+ if (appView.options().horizontalClassMergerOptions().isConstructorMergingEnabled()) {
constructorMergerBuilders
.computeIfAbsent(
method.getDefinition().getProto(), ignore -> new ConstructorMerger.Builder(appView))
@@ -276,7 +320,7 @@
}
private Collection<ConstructorMerger.Builder> getConstructorMergerBuilders() {
- return appView.options().enableHorizontalClassMergingConstructorMerging
+ return appView.options().horizontalClassMergerOptions().isConstructorMergingEnabled()
? constructorMergerBuilders.values()
: unmergedConstructorBuilders;
}
@@ -313,7 +357,8 @@
fieldAccessChangesBuilder,
group,
virtualMethodMergers,
- constructorMergers);
+ constructorMergers,
+ classInitializerSynthesizedCodeBuilder.build());
}
}
}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/ConstructorMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/ConstructorMerger.java
index 297dcad..01d5771 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/ConstructorMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/ConstructorMerger.java
@@ -30,7 +30,6 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.LinkedList;
import java.util.List;
public class ConstructorMerger {
@@ -154,7 +153,7 @@
}
DexMethod movedConstructor = moveConstructor(classMethodsBuilder, constructor);
lensBuilder.mapMethod(movedConstructor, movedConstructor);
- lensBuilder.mapMethodInverse(constructor.method, movedConstructor);
+ lensBuilder.recordNewMethodSignature(constructor.getReference(), movedConstructor);
typeConstructorClassMap.put(
classIdentifiers.getInt(constructor.getHolderType()), movedConstructor);
}
@@ -167,13 +166,29 @@
classMethodsBuilder::isFresh);
int extraNulls = newConstructorReference.getArity() - methodReferenceTemplate.getArity();
- DexMethod representativeConstructorReference = constructors.iterator().next().method;
+ DexEncodedMethod representative = constructors.iterator().next();
+ DexMethod originalConstructorReference =
+ appView.graphLens().getOriginalMethodSignature(representative.getReference());
+
+ // Create a special original method signature for the synthesized constructor that did not exist
+ // prior to horizontal class merging. Otherwise we might accidentally think that the synthesized
+ // constructor corresponds to the previous <init>() method on the target class, which could have
+ // unintended side-effects such as leading to unused argument removal being applied to the
+ // synthesized constructor all-though it by construction doesn't have any unused arguments.
+ DexMethod bridgeConstructorReference =
+ dexItemFactory.createFreshMethodName(
+ "$r8$init$bridge",
+ null,
+ originalConstructorReference.getProto(),
+ originalConstructorReference.getHolderType(),
+ classMethodsBuilder::isFresh);
+
ConstructorEntryPointSynthesizedCode synthesizedCode =
new ConstructorEntryPointSynthesizedCode(
typeConstructorClassMap,
newConstructorReference,
group.getClassIdField(),
- appView.graphLens().getOriginalMethodSignature(representativeConstructorReference));
+ bridgeConstructorReference);
DexEncodedMethod newConstructor =
new DexEncodedMethod(
newConstructorReference,
@@ -185,34 +200,20 @@
true,
classFileVersion);
- if (isTrivialMerge()) {
- // The constructor does not require the additional argument, just map it like a regular
- // method.
- DexEncodedMethod oldConstructor = constructors.iterator().next();
- if (extraNulls > 0) {
- List<ExtraParameter> extraParameters = new LinkedList<>();
- extraParameters.addAll(Collections.nCopies(extraNulls, new ExtraUnusedNullParameter()));
- lensBuilder.moveMergedConstructor(
- oldConstructor.method, newConstructorReference, extraParameters);
- } else {
- lensBuilder.moveMethod(oldConstructor.method, newConstructorReference);
- }
- } else {
- // Map each old constructor to the newly synthesized constructor in the graph lens.
- for (DexEncodedMethod oldConstructor : constructors) {
+ // Map each old constructor to the newly synthesized constructor in the graph lens.
+ for (DexEncodedMethod oldConstructor : constructors) {
+ List<ExtraParameter> extraParameters = new ArrayList<>();
+ if (constructors.size() > 1) {
int classIdentifier = classIdentifiers.getInt(oldConstructor.getHolderType());
-
- List<ExtraParameter> extraParameters = new LinkedList<>();
extraParameters.add(new ExtraConstantIntParameter(classIdentifier));
- extraParameters.addAll(Collections.nCopies(extraNulls, new ExtraUnusedNullParameter()));
-
- lensBuilder.moveMergedConstructor(
- oldConstructor.method, newConstructorReference, extraParameters);
}
+ extraParameters.addAll(Collections.nCopies(extraNulls, new ExtraUnusedNullParameter()));
+ lensBuilder.mapMergedConstructor(
+ oldConstructor.getReference(), newConstructorReference, extraParameters);
}
- // Map the first constructor to the newly synthesized constructor.
- lensBuilder.recordExtraOriginalSignature(
- representativeConstructorReference, newConstructorReference);
+
+ // Add a mapping from a synthetic name to the synthetic constructor.
+ lensBuilder.recordNewMethodSignature(bridgeConstructorReference, newConstructorReference);
classMethodsBuilder.addDirectMethod(newConstructor);
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
index 0821a4c..5983618 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
@@ -15,6 +15,7 @@
import com.android.tools.r8.horizontalclassmerging.policies.IgnoreSynthetics;
import com.android.tools.r8.horizontalclassmerging.policies.LimitGroups;
import com.android.tools.r8.horizontalclassmerging.policies.NoAnnotations;
+import com.android.tools.r8.horizontalclassmerging.policies.NoClassInitializerWithObservableSideEffects;
import com.android.tools.r8.horizontalclassmerging.policies.NoClassesOrMembersWithAnnotations;
import com.android.tools.r8.horizontalclassmerging.policies.NoDirectRuntimeTypeChecks;
import com.android.tools.r8.horizontalclassmerging.policies.NoEnums;
@@ -26,7 +27,6 @@
import com.android.tools.r8.horizontalclassmerging.policies.NoKotlinMetadata;
import com.android.tools.r8.horizontalclassmerging.policies.NoNativeMethods;
import com.android.tools.r8.horizontalclassmerging.policies.NoServiceLoaders;
-import com.android.tools.r8.horizontalclassmerging.policies.NoStaticClassInitializer;
import com.android.tools.r8.horizontalclassmerging.policies.NotMatchedByNoHorizontalClassMerging;
import com.android.tools.r8.horizontalclassmerging.policies.NotVerticallyMergedIntoSubtype;
import com.android.tools.r8.horizontalclassmerging.policies.PreserveMethodCharacteristics;
@@ -64,11 +64,9 @@
MergeGroup initialGroup = new MergeGroup(appView.appInfo().classesWithDeterministicOrder());
// Run the policies on all program classes to produce a final grouping.
+ List<Policy> policies = getPolicies(mainDexTracingResult, runtimeTypeCheckInfo);
Collection<MergeGroup> groups =
- new SimplePolicyExecutor()
- .run(
- Collections.singletonList(initialGroup),
- getPolicies(mainDexTracingResult, runtimeTypeCheckInfo));
+ new SimplePolicyExecutor().run(Collections.singletonList(initialGroup), policies);
// If there are no groups, then end horizontal class merging.
if (groups.isEmpty()) {
@@ -116,7 +114,7 @@
new IgnoreSynthetics(appView),
new NoClassesOrMembersWithAnnotations(),
new NoInnerClasses(),
- new NoStaticClassInitializer(),
+ new NoClassInitializerWithObservableSideEffects(),
new NoNativeMethods(),
new NoKeepRules(appView),
new NoKotlinMetadata(),
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMergerGraphLens.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMergerGraphLens.java
index 9b472a4..3adad2e 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMergerGraphLens.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMergerGraphLens.java
@@ -8,30 +8,26 @@
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.GraphLens;
import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
-import com.android.tools.r8.graph.RewrittenPrototypeDescription;
import com.android.tools.r8.ir.conversion.ExtraParameter;
import com.android.tools.r8.utils.IterableUtils;
+import com.android.tools.r8.utils.collections.BidirectionalManyToOneHashMap;
import com.android.tools.r8.utils.collections.BidirectionalManyToOneRepresentativeHashMap;
import com.android.tools.r8.utils.collections.BidirectionalManyToOneRepresentativeMap;
-import com.android.tools.r8.utils.collections.BidirectionalOneToOneMap;
+import com.android.tools.r8.utils.collections.BidirectionalOneToManyRepresentativeHashMap;
+import com.android.tools.r8.utils.collections.BidirectionalOneToManyRepresentativeMap;
import com.android.tools.r8.utils.collections.MutableBidirectionalManyToOneRepresentativeMap;
-import com.google.common.collect.BiMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Streams;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.function.Function;
public class HorizontalClassMergerGraphLens extends NestedGraphLens {
private final Map<DexMethod, List<ExtraParameter>> methodExtraParameters;
- private final Map<DexMethod, DexMethod> extraOriginalMethodSignatures;
private final HorizontallyMergedClasses mergedClasses;
private HorizontalClassMergerGraphLens(
@@ -40,48 +36,23 @@
Map<DexMethod, List<ExtraParameter>> methodExtraParameters,
BidirectionalManyToOneRepresentativeMap<DexField, DexField> fieldMap,
Map<DexMethod, DexMethod> methodMap,
- BidirectionalOneToOneMap<DexMethod, DexMethod> originalMethodSignatures,
- Map<DexMethod, DexMethod> extraOriginalMethodSignatures,
- GraphLens previousLens) {
+ BidirectionalOneToManyRepresentativeMap<DexMethod, DexMethod> originalMethodSignatures) {
super(
mergedClasses.getForwardMap(),
methodMap,
fieldMap,
originalMethodSignatures,
- previousLens,
+ appView.graphLens(),
appView.dexItemFactory());
this.methodExtraParameters = methodExtraParameters;
- this.extraOriginalMethodSignatures = extraOriginalMethodSignatures;
this.mergedClasses = mergedClasses;
}
- private boolean isSynthesizedByHorizontalClassMerging(DexMethod method) {
- return methodExtraParameters.containsKey(method);
- }
-
@Override
protected Iterable<DexType> internalGetOriginalTypes(DexType previous) {
return IterableUtils.prependSingleton(previous, mergedClasses.getSourcesFor(previous));
}
- @Override
- public RewrittenPrototypeDescription lookupPrototypeChangesForMethodDefinition(DexMethod method) {
- if (isSynthesizedByHorizontalClassMerging(method)) {
- // If we are processing the call site, the arguments should be removed.
- return RewrittenPrototypeDescription.none();
- }
- return super.lookupPrototypeChangesForMethodDefinition(method);
- }
-
- @Override
- public DexMethod getOriginalMethodSignature(DexMethod method) {
- DexMethod originalConstructor = extraOriginalMethodSignatures.get(method);
- if (originalConstructor == null) {
- return super.getOriginalMethodSignature(method);
- }
- return getPrevious().getOriginalMethodSignature(originalConstructor);
- }
-
/**
* If an overloaded constructor is requested, add the constructor id as a parameter to the
* constructor. Otherwise return the lookup on the underlying graph lens.
@@ -102,39 +73,55 @@
}
public static class Builder {
- private MutableBidirectionalManyToOneRepresentativeMap<DexField, DexField> fieldMap =
+
+ private final MutableBidirectionalManyToOneRepresentativeMap<DexField, DexField> fieldMap =
new BidirectionalManyToOneRepresentativeHashMap<>();
- private ManyToOneMap<DexMethod, DexMethod> methodMap = new ManyToOneMap<>();
+ private final BidirectionalManyToOneHashMap<DexMethod, DexMethod> methodMap =
+ new BidirectionalManyToOneHashMap<>();
+ private final BidirectionalOneToManyRepresentativeHashMap<DexMethod, DexMethod>
+ originalMethodSignatures = new BidirectionalOneToManyRepresentativeHashMap<>();
private final Map<DexMethod, List<ExtraParameter>> methodExtraParameters =
new IdentityHashMap<>();
+ private final BidirectionalManyToOneHashMap<DexMethod, DexMethod> pendingMethodMapUpdates =
+ new BidirectionalManyToOneHashMap<>();
+ private final BidirectionalOneToManyRepresentativeHashMap<DexMethod, DexMethod>
+ pendingOriginalMethodSignatureUpdates = new BidirectionalOneToManyRepresentativeHashMap<>();
+
Builder() {}
- public HorizontalClassMergerGraphLens build(
+ HorizontalClassMergerGraphLens build(
AppView<?> appView, HorizontallyMergedClasses mergedClasses) {
- ManyToOneInverseMap<DexMethod, DexMethod> inverseMethodMap =
- methodMap.inverse(
- group -> {
- // Every group should have a representative. Fail in debug mode.
- assert false;
- return group.iterator().next();
- });
+ assert pendingMethodMapUpdates.isEmpty();
+ assert pendingOriginalMethodSignatureUpdates.isEmpty();
return new HorizontalClassMergerGraphLens(
appView,
mergedClasses,
methodExtraParameters,
fieldMap,
methodMap.getForwardMap(),
- inverseMethodMap.getBiMap(),
- inverseMethodMap.getExtraMap(),
- appView.graphLens());
+ originalMethodSignatures);
}
- public void remapMethods(BiMap<DexMethod, DexMethod> remapMethods) {
- methodMap = methodMap.remap(remapMethods, Function.identity(), Function.identity());
+ void recordNewFieldSignature(DexField oldFieldSignature, DexField newFieldSignature) {
+ fieldMap.put(oldFieldSignature, newFieldSignature);
}
- Builder recordNewFieldSignature(DexField oldFieldSignature, DexField newFieldSignature) {
+ void recordNewFieldSignature(
+ Iterable<DexField> oldFieldSignatures,
+ DexField newFieldSignature,
+ DexField representative) {
+ assert Streams.stream(oldFieldSignatures)
+ .anyMatch(oldFieldSignature -> oldFieldSignature != newFieldSignature);
+ assert Streams.stream(oldFieldSignatures).noneMatch(fieldMap::containsValue);
+ assert Iterables.contains(oldFieldSignatures, representative);
+ for (DexField oldFieldSignature : oldFieldSignatures) {
+ recordNewFieldSignature(oldFieldSignature, newFieldSignature);
+ }
+ fieldMap.setRepresentative(newFieldSignature, representative);
+ }
+
+ void fixupField(DexField oldFieldSignature, DexField newFieldSignature) {
Set<DexField> originalFieldSignatures = fieldMap.removeValue(oldFieldSignature);
if (originalFieldSignatures.isEmpty()) {
fieldMap.put(oldFieldSignature, newFieldSignature);
@@ -148,44 +135,59 @@
assert representative != null;
fieldMap.setRepresentative(newFieldSignature, representative);
}
- return this;
}
- Builder recordNewFieldSignature(
- Iterable<DexField> oldFieldSignatures,
- DexField newFieldSignature,
- DexField representative) {
- assert Streams.stream(oldFieldSignatures).noneMatch(fieldMap::containsValue);
- assert Iterables.contains(oldFieldSignatures, representative);
- for (DexField oldFieldSignature : oldFieldSignatures) {
- fieldMap.put(oldFieldSignature, newFieldSignature);
- }
- fieldMap.setRepresentative(newFieldSignature, representative);
- return this;
+ void mapMethod(DexMethod oldMethodSignature, DexMethod newMethodSignature) {
+ methodMap.put(oldMethodSignature, newMethodSignature);
}
- /** Unidirectional mapping from one method to another. */
- public Builder recordExtraOriginalSignature(DexMethod from, DexMethod to) {
- methodMap.setRepresentative(from, to);
- return this;
- }
-
- /** Unidirectional mapping from one method to another. */
- public Builder mapMethod(DexMethod from, DexMethod to) {
- methodMap.put(from, to);
- return this;
- }
-
- /** Unidirectional mapping from one method to another. */
- public Builder mapMethodInverse(DexMethod from, DexMethod to) {
- methodMap.putInverse(from, to);
- return this;
- }
-
- public Builder moveMethod(DexMethod from, DexMethod to) {
+ void moveMethod(DexMethod from, DexMethod to) {
mapMethod(from, to);
- mapMethodInverse(from, to);
- return this;
+ recordNewMethodSignature(from, to);
+ }
+
+ void recordNewMethodSignature(DexMethod oldMethodSignature, DexMethod newMethodSignature) {
+ originalMethodSignatures.put(newMethodSignature, oldMethodSignature);
+ }
+
+ void fixupMethod(DexMethod oldMethodSignature, DexMethod newMethodSignature) {
+ fixupMethodMap(oldMethodSignature, newMethodSignature);
+ fixupOriginalMethodSignatures(oldMethodSignature, newMethodSignature);
+ }
+
+ private void fixupMethodMap(DexMethod oldMethodSignature, DexMethod newMethodSignature) {
+ Set<DexMethod> originalMethodSignatures = methodMap.getKeys(oldMethodSignature);
+ if (originalMethodSignatures.isEmpty()) {
+ pendingMethodMapUpdates.put(oldMethodSignature, newMethodSignature);
+ } else {
+ for (DexMethod originalMethodSignature : originalMethodSignatures) {
+ pendingMethodMapUpdates.put(originalMethodSignature, newMethodSignature);
+ }
+ }
+ }
+
+ private void fixupOriginalMethodSignatures(
+ DexMethod oldMethodSignature, DexMethod newMethodSignature) {
+ Set<DexMethod> oldMethodSignatures = originalMethodSignatures.getValues(oldMethodSignature);
+ if (oldMethodSignatures.isEmpty()) {
+ pendingOriginalMethodSignatureUpdates.put(newMethodSignature, oldMethodSignature);
+ } else {
+ for (DexMethod originalMethodSignature : oldMethodSignatures) {
+ pendingOriginalMethodSignatureUpdates.put(newMethodSignature, originalMethodSignature);
+ }
+ }
+ }
+
+ void commitPendingUpdates() {
+ // Commit pending method map updates.
+ methodMap.removeAll(pendingMethodMapUpdates.keySet());
+ pendingMethodMapUpdates.forEachManyToOneMapping(methodMap::put);
+ pendingMethodMapUpdates.clear();
+
+ // Commit pending original method signatures updates.
+ originalMethodSignatures.removeAll(pendingOriginalMethodSignatureUpdates.keySet());
+ pendingOriginalMethodSignatureUpdates.forEachOneToManyMapping(originalMethodSignatures::put);
+ pendingOriginalMethodSignatureUpdates.clear();
}
/**
@@ -193,24 +195,27 @@
* where many constructors are merged into a single constructor. The synthesized constructor
* therefore does not have a unique reverse constructor.
*/
- public Builder moveMergedConstructor(
- DexMethod from, DexMethod to, List<ExtraParameter> extraParameters) {
- moveMethod(from, to);
- methodExtraParameters.put(from, extraParameters);
- return this;
+ void mapMergedConstructor(DexMethod from, DexMethod to, List<ExtraParameter> extraParameters) {
+ mapMethod(from, to);
+ if (extraParameters.size() > 0) {
+ methodExtraParameters.put(from, extraParameters);
+ }
}
- public Builder addExtraParameters(DexMethod to, List<ExtraParameter> extraParameters) {
- Set<DexMethod> mapsFrom = methodMap.lookupReverse(to);
- if (mapsFrom == null) {
- mapsFrom = Collections.singleton(to);
+ void addExtraParameters(DexMethod methodSignature, List<ExtraParameter> extraParameters) {
+ Set<DexMethod> originalMethodSignatures = methodMap.getKeys(methodSignature);
+ if (originalMethodSignatures.isEmpty()) {
+ methodExtraParameters
+ .computeIfAbsent(methodSignature, ignore -> new ArrayList<>(extraParameters.size()))
+ .addAll(extraParameters);
+ } else {
+ for (DexMethod originalMethodSignature : originalMethodSignatures) {
+ methodExtraParameters
+ .computeIfAbsent(
+ originalMethodSignature, ignore -> new ArrayList<>(extraParameters.size()))
+ .addAll(extraParameters);
+ }
}
- mapsFrom.forEach(
- originalFrom ->
- methodExtraParameters
- .computeIfAbsent(originalFrom, ignore -> new ArrayList<>(extraParameters.size()))
- .addAll(extraParameters));
- return this;
}
}
}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/ManyToOneInverseMap.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/ManyToOneInverseMap.java
deleted file mode 100644
index 8cf8b2a..0000000
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/ManyToOneInverseMap.java
+++ /dev/null
@@ -1,27 +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.horizontalclassmerging;
-
-import com.android.tools.r8.utils.collections.BidirectionalOneToOneMap;
-import java.util.Map;
-
-/** The inverse of a {@link ManyToOneMap} used for generating graph lens maps. */
-public class ManyToOneInverseMap<K, V> {
- private final BidirectionalOneToOneMap<V, K> biMap;
- private final Map<V, K> extraMap;
-
- ManyToOneInverseMap(BidirectionalOneToOneMap<V, K> biMap, Map<V, K> extraMap) {
- this.biMap = biMap;
- this.extraMap = extraMap;
- }
-
- public BidirectionalOneToOneMap<V, K> getBiMap() {
- return biMap;
- }
-
- public Map<V, K> getExtraMap() {
- return extraMap;
- }
-}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/ManyToOneMap.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/ManyToOneMap.java
deleted file mode 100644
index f51dfd2..0000000
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/ManyToOneMap.java
+++ /dev/null
@@ -1,122 +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.horizontalclassmerging;
-
-import com.android.tools.r8.utils.collections.BidirectionalOneToOneHashMap;
-import com.android.tools.r8.utils.collections.MutableBidirectionalOneToOneMap;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.HashBiMap;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.function.Function;
-
-/**
- * This mapping class is used to track method mappings for horizontal class merging. Essentially it
- * is a bidirectional many to one map, but with support for having unidirectional mappings and with
- * support for remapping the values to new values using {@link ManyToOneMap#remap(BiMap, Function,
- * Function)}. It also supports generating an inverse mapping {@link ManyToOneInverseMap} that can
- * be used by the graph lens using {@link ManyToOneMap#inverse(Function)}. The inverse map is a
- * bidirectional one to one map with additional non-bidirectional representative entries.
- */
-public class ManyToOneMap<K, V> {
- private final Map<K, V> forwardMap = new IdentityHashMap<>();
- private final Map<V, Set<K>> inverseMap = new IdentityHashMap<>();
- private final Map<V, K> representativeMap = new IdentityHashMap<>();
-
- public Map<K, V> getForwardMap() {
- return forwardMap;
- }
-
- public Set<K> lookupReverse(V to) {
- return inverseMap.get(to);
- }
-
- public V put(K from, V to) {
- return forwardMap.put(from, to);
- }
-
- public void putInverse(K from, V to) {
- inverseMap.computeIfAbsent(to, ignore -> new HashSet<>()).add(from);
- }
-
- public K setRepresentative(K from, V to) {
- putInverse(from, to);
- return representativeMap.put(to, from);
- }
-
- public ManyToOneInverseMap<K, V> inverse(Function<Set<K>, K> pickRepresentative) {
- MutableBidirectionalOneToOneMap<V, K> biMap = new BidirectionalOneToOneHashMap<>();
- Map<V, K> extraMap = new HashMap<>();
- for (Entry<V, Set<K>> entry : inverseMap.entrySet()) {
- K representative = representativeMap.get(entry.getKey());
- if (entry.getValue().size() == 1) {
- K singleton = entry.getValue().iterator().next();
- assert representative == null || singleton == representative;
- if (representative == null) {
- biMap.put(entry.getKey(), singleton);
- } else {
- extraMap.put(entry.getKey(), singleton);
- }
- } else {
- if (representative == null) {
- representative = pickRepresentative.apply(entry.getValue());
- } else {
- assert representative == entry.getKey() || entry.getValue().contains(representative);
- }
- extraMap.put(entry.getKey(), representative);
- }
- }
-
- return new ManyToOneInverseMap<>(biMap, extraMap);
- }
-
- public <NewV> ManyToOneMap<K, NewV> remap(
- BiMap<V, NewV> biMap, Function<V, NewV> notInBiMap, Function<V, K> notInForwardMap) {
- ManyToOneMap<K, NewV> newMap = new ManyToOneMap<>();
-
- // All entries that should be remapped and are already in the forward and/or inverse mappings
- // should only be remapped in the directions they are already mapped in.
- BiMap<V, NewV> biMapCopy = HashBiMap.create(biMap);
- for (Entry<V, Set<K>> entry : inverseMap.entrySet()) {
- NewV to = biMapCopy.remove(entry.getKey());
- if (to == null) {
- to = biMap.getOrDefault(entry.getKey(), notInBiMap.apply(entry.getKey()));
- }
- newMap.inverseMap.put(to, entry.getValue());
- }
- for (Entry<K, V> entry : forwardMap.entrySet()) {
- NewV newTo = biMapCopy.remove(entry.getValue());
- if (newTo == null) {
- newTo = biMap.getOrDefault(entry.getValue(), notInBiMap.apply(entry.getValue()));
- }
- newMap.forwardMap.put(entry.getKey(), newTo);
- }
-
- // All new entries should be mapped in both directions.
- for (Entry<V, NewV> entry : biMapCopy.entrySet()) {
- newMap.forwardMap.put(notInForwardMap.apply(entry.getKey()), entry.getValue());
- newMap
- .inverseMap
- .computeIfAbsent(entry.getValue(), ignore -> new HashSet<>())
- .add(notInForwardMap.apply(entry.getKey()));
- }
-
- // Representatives are always in the inverse mapping, so they should always be remapped as new
- // representatives.
- for (Entry<V, K> entry : representativeMap.entrySet()) {
- NewV newTo = biMap.get(entry.getKey());
- if (newTo == null) {
- newTo = notInBiMap.apply(entry.getKey());
- }
- newMap.representativeMap.put(newTo, entry.getValue());
- }
-
- return newMap;
- }
-}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/Policy.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/Policy.java
index f6b86a3..4642229 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/Policy.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/Policy.java
@@ -12,6 +12,8 @@
/** Counter keeping track of how many classes this policy has removed. For debugging only. */
public int numberOfRemovedClasses;
+ public void clear() {}
+
public boolean shouldSkipPolicy() {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/SimplePolicyExecutor.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/SimplePolicyExecutor.java
index b2fdb3d..14b249a 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/SimplePolicyExecutor.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/SimplePolicyExecutor.java
@@ -70,6 +70,8 @@
linkedGroups = applyMultiClassPolicy((MultiClassPolicy) policy, linkedGroups);
}
+ policy.clear();
+
// Any policy should not return any trivial groups.
assert linkedGroups.stream().allMatch(group -> group.size() >= 2);
}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/SyntheticArgumentClass.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/SyntheticArgumentClass.java
index b6e1f53..c3aa3c0 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/SyntheticArgumentClass.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/SyntheticArgumentClass.java
@@ -107,7 +107,9 @@
boolean requiresMainDex = appView.appInfo().getMainDexClasses().containsAnyOf(mergeClasses);
List<DexType> syntheticArgumentTypes = new ArrayList<>();
- for (int i = 0; i < appView.options().horizontalClassMergingSyntheticArgumentCount; i++) {
+ for (int i = 0;
+ i < appView.options().horizontalClassMergerOptions().getSyntheticArgumentCount();
+ i++) {
syntheticArgumentTypes.add(
synthesizeClass(appView, appBuilder, context, requiresMainDex, i));
}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/TreeFixer.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/TreeFixer.java
index 045a8b1..0f85054 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/TreeFixer.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/TreeFixer.java
@@ -45,7 +45,6 @@
private final FieldAccessInfoCollectionModifier.Builder fieldAccessChangesBuilder;
private final AppView<AppInfoWithLiveness> appView;
private final DexItemFactory dexItemFactory;
- private final BiMap<DexMethod, DexMethod> movedMethods = HashBiMap.create();
private final SyntheticArgumentClass syntheticArgumentClass;
private final BiMap<DexMethodSignature, DexMethodSignature> reservedInterfaceSignatures =
HashBiMap.create();
@@ -127,9 +126,6 @@
for (DexProgramClass root : subtypingForrest.getProgramRoots()) {
subtypingForrest.traverseNodeDepthFirst(root, HashBiMap.create(), this::fixupProgramClass);
}
-
- lensBuilder.remapMethods(movedMethods);
-
HorizontalClassMergerGraphLens lens = lensBuilder.build(appView, mergedClasses);
fieldAccessChangesBuilder.build(this::fixupMethodReference).modify(appView);
new AnnotationFixer(lens).run(appView.appInfo().classes());
@@ -162,6 +158,8 @@
fixupFields(clazz.staticFields(), clazz::setStaticField);
fixupFields(clazz.instanceFields(), clazz::setInstanceField);
+ lensBuilder.commitPendingUpdates();
+
return remappedClassVirtualMethods;
}
@@ -171,7 +169,7 @@
// Don't process this method if it does not refer to a merge class type.
boolean referencesMergeClass =
Iterables.any(
- originalMethodReference.proto.getBaseTypes(dexItemFactory),
+ originalMethodReference.getProto().getBaseTypes(dexItemFactory),
mergedClasses::hasBeenMergedOrIsMergeTarget);
if (!referencesMergeClass) {
return method;
@@ -198,8 +196,7 @@
DexMethod newMethodReference =
newMethodSignature.withHolder(originalMethodReference, dexItemFactory);
- movedMethods.put(originalMethodReference, newMethodReference);
-
+ lensBuilder.fixupMethod(originalMethodReference, newMethodReference);
return method.toTypeSubstitutedMethod(newMethodReference);
}
@@ -215,17 +212,17 @@
iface.getMethodCollection().replaceVirtualMethods(this::fixupVirtualInterfaceMethod);
fixupFields(iface.staticFields(), iface::setStaticField);
fixupFields(iface.instanceFields(), iface::setInstanceField);
+ lensBuilder.commitPendingUpdates();
}
private DexEncodedMethod fixupProgramMethod(
DexMethod newMethodReference, DexEncodedMethod method) {
DexMethod originalMethodReference = method.getReference();
-
if (newMethodReference == originalMethodReference) {
return method;
}
- movedMethods.put(originalMethodReference, newMethodReference);
+ lensBuilder.fixupMethod(originalMethodReference, newMethodReference);
DexEncodedMethod newMethod = method.toTypeSubstitutedMethod(newMethodReference);
if (newMethod.isNonPrivateVirtualMethod()) {
@@ -381,7 +378,7 @@
}
if (newFieldReference != oldFieldReference) {
- lensBuilder.recordNewFieldSignature(oldFieldReference, newFieldReference);
+ lensBuilder.fixupField(oldFieldReference, newFieldReference);
setter.setField(i, oldField.toTypeSubstitutedField(newFieldReference));
}
}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java
index fe3a898..9a44de7 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java
@@ -229,8 +229,7 @@
classFileVersion = Ordered.maxIgnoreNull(classFileVersion, methodVersion);
}
DexMethod newMethod = moveMethod(classMethodsBuilder, method);
- lensBuilder.mapMethod(newMethod, newMethod);
- lensBuilder.mapMethodInverse(method.getReference(), newMethod);
+ lensBuilder.recordNewMethodSignature(method.getReference(), newMethod);
classIdToMethodMap.put(classIdentifiers.getInt(method.getHolderType()), newMethod);
if (representative == null) {
representative = method;
@@ -274,16 +273,14 @@
// Map each old non-abstract method to the newly synthesized method in the graph lens.
for (ProgramMethod oldMethod : methods) {
- if (oldMethod.getDefinition().isAbstract()) {
- lensBuilder.mapMethod(oldMethod.getReference(), newMethodReference);
- } else {
- lensBuilder.moveMethod(oldMethod.getReference(), newMethodReference);
- }
+ lensBuilder.mapMethod(oldMethod.getReference(), newMethodReference);
}
- lensBuilder.recordExtraOriginalSignature(bridgeMethodReference, newMethodReference);
+
+ // Add a mapping from a synthetic name to the synthetic merged method.
+ lensBuilder.recordNewMethodSignature(bridgeMethodReference, newMethodReference);
classMethodsBuilder.addVirtualMethod(newMethod);
- fieldAccessChangesBuilder.fieldReadByMethod(group.getClassIdField(), newMethod.method);
+ fieldAccessChangesBuilder.fieldReadByMethod(group.getClassIdField(), newMethodReference);
}
}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/IgnoreSynthetics.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/IgnoreSynthetics.java
index 78875fd..e45e2d3 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/IgnoreSynthetics.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/IgnoreSynthetics.java
@@ -19,6 +19,10 @@
@Override
public boolean canMerge(DexProgramClass program) {
- return !appView.getSyntheticItems().isSyntheticClass(program);
+ if (appView.getSyntheticItems().isSyntheticClass(program)) {
+ return appView.options().horizontalClassMergerOptions().isJavaLambdaMergingEnabled()
+ && appView.getSyntheticItems().isLegacySyntheticClass(program);
+ }
+ return true;
}
}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/LimitGroups.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/LimitGroups.java
index f2800aa..33de8f3 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/LimitGroups.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/LimitGroups.java
@@ -18,7 +18,7 @@
private final int maxGroupSize;
public LimitGroups(AppView<AppInfoWithLiveness> appView) {
- maxGroupSize = appView.options().horizontalClassMergingMaxGroupSize;
+ maxGroupSize = appView.options().horizontalClassMergerOptions().getMaxGroupSize();
assert maxGroupSize >= 2;
}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoClassInitializerWithObservableSideEffects.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoClassInitializerWithObservableSideEffects.java
new file mode 100644
index 0000000..f10d78c
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoClassInitializerWithObservableSideEffects.java
@@ -0,0 +1,31 @@
+// 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.horizontalclassmerging.policies;
+
+import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.horizontalclassmerging.SingleClassPolicy;
+
+/**
+ * Prevent merging of classes with static initializers, as merging these causes side effects. It is
+ * okay for superclasses to have static initializers as all classes are expected to have the same
+ * super class.
+ */
+public class NoClassInitializerWithObservableSideEffects extends SingleClassPolicy {
+
+ @Override
+ public boolean canMerge(DexProgramClass program) {
+ if (!program.hasClassInitializer()) {
+ return true;
+ }
+ DexEncodedMethod clinit = program.getClassInitializer();
+ return clinit.getOptimizationInfo().classInitializerMayBePostponed() || isKotlinLambda(program);
+ }
+
+ private boolean isKotlinLambda(DexProgramClass program) {
+ return program.getKotlinInfo().isSyntheticClass()
+ && program.getKotlinInfo().asSyntheticClass().isLambda();
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoEnums.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoEnums.java
index 2da0177..c8a0aab 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoEnums.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoEnums.java
@@ -22,8 +22,19 @@
}
@Override
+ public void clear() {
+ cache.clear();
+ }
+
+ @Override
public boolean canMerge(DexProgramClass program) {
- return !program.isEnum() && !isEnumSubtype(program);
+ if (program.isEnum()) {
+ return false;
+ }
+ if (isEnumSubtype(program)) {
+ return false;
+ }
+ return true;
}
private boolean isEnumSubtype(DexClass clazz) {
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoKotlinLambdas.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoKotlinLambdas.java
index a137e88..dee7a4a 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoKotlinLambdas.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoKotlinLambdas.java
@@ -18,7 +18,7 @@
@Override
public boolean shouldSkipPolicy() {
- return appView.options().enableHorizontalClassMergingOfKotlinLambdas;
+ return appView.options().horizontalClassMergerOptions().isKotlinLambdaMergingEnabled();
}
@Override
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoStaticClassInitializer.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoStaticClassInitializer.java
deleted file mode 100644
index aeca6c0..0000000
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoStaticClassInitializer.java
+++ /dev/null
@@ -1,20 +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.horizontalclassmerging.policies;
-
-import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.horizontalclassmerging.SingleClassPolicy;
-
-/**
- * Prevent merging of classes with static initializers, as merging these causes side effects. It is
- * okay for superclasses to have static initializers as all classes are expected to have the same
- * super class.
- */
-public class NoStaticClassInitializer extends SingleClassPolicy {
- @Override
- public boolean canMerge(DexProgramClass program) {
- return !program.hasClassInitializer();
- }
-}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
index c9e47c2..a50581e 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
@@ -33,6 +33,8 @@
import com.android.tools.r8.graph.ResolutionResult.SingleResolutionResult;
import com.android.tools.r8.ir.code.Invoke;
import com.android.tools.r8.ir.code.Invoke.Type;
+import com.android.tools.r8.ir.optimize.info.OptimizationFeedback;
+import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple;
import com.android.tools.r8.ir.synthetic.ForwardMethodSourceCode;
import com.android.tools.r8.ir.synthetic.SynthesizedCode;
import com.android.tools.r8.origin.SynthesizedOrigin;
@@ -65,6 +67,8 @@
*/
public final class LambdaClass {
+ private static final OptimizationFeedback feedback = OptimizationFeedbackSimple.getInstance();
+
final AppView<?> appView;
final LambdaRewriter rewriter;
public final DexType type;
@@ -293,6 +297,7 @@
ParameterAnnotationsList.empty(),
LambdaClassConstructorSourceCode.build(this),
true);
+ feedback.classInitializerMayBePostponed(methods[1]);
}
return methods;
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
index d27fb16..f464fdd 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
@@ -72,7 +72,7 @@
public static final String LAMBDA_CLASS_NAME_PREFIX = "-$$Lambda$";
public static final String LAMBDA_GROUP_CLASS_NAME_PREFIX = "-$$LambdaGroup$";
static final String EXPECTED_LAMBDA_METHOD_PREFIX = "lambda$";
- private static final String LAMBDA_INSTANCE_FIELD_NAME = "INSTANCE";
+ public static final String LAMBDA_INSTANCE_FIELD_NAME = "INSTANCE";
private final AppView<?> appView;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
index 09c4a5d..4e3fb01 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
@@ -1076,6 +1076,7 @@
assert !context.getHolderType().isD8R8SynthesizedLambdaClassType()
|| options.debug
|| appView.appInfo().hasPinnedInstanceInitializer(context.getHolderType())
+ || appView.options().horizontalClassMergerOptions().isJavaLambdaMergingEnabled()
: "Unexpected observable side effects from lambda `" + context.toSourceString() + "`";
}
return;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackSimple.java b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackSimple.java
index 5840ea6..f0d7c28 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackSimple.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackSimple.java
@@ -195,6 +195,6 @@
@Override
public void classInitializerMayBePostponed(DexEncodedMethod method) {
- // Ignored.
+ method.getMutableOptimizationInfo().markClassInitializerMayBePostponed();
}
}
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
index 764fc9c..bc7d42e 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
@@ -224,10 +224,18 @@
return nonLecacySyntheticItems.containsKey(type) || legacySyntheticTypes.contains(type);
}
+ private boolean isLegacyCommittedSynthetic(DexType type) {
+ return legacySyntheticTypes.contains(type);
+ }
+
public boolean isPendingSynthetic(DexType type) {
return pendingDefinitions.containsKey(type) || legacyPendingClasses.containsKey(type);
}
+ public boolean isLegacyPendingSynthetic(DexType type) {
+ return legacyPendingClasses.containsKey(type);
+ }
+
public boolean isSyntheticClass(DexType type) {
return isCommittedSynthetic(type)
|| isPendingSynthetic(type)
@@ -239,6 +247,14 @@
return isSyntheticClass(clazz.type);
}
+ public boolean isLegacySyntheticClass(DexType type) {
+ return isLegacyCommittedSynthetic(type) || isLegacyPendingSynthetic(type);
+ }
+
+ public boolean isLegacySyntheticClass(DexProgramClass clazz) {
+ return isLegacySyntheticClass(clazz.getType());
+ }
+
public Collection<DexProgramClass> getLegacyPendingClasses() {
return Collections.unmodifiableCollection(legacyPendingClasses.values());
}
diff --git a/src/main/java/com/android/tools/r8/utils/CfVersionUtils.java b/src/main/java/com/android/tools/r8/utils/CfVersionUtils.java
new file mode 100644
index 0000000..dadf460
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/utils/CfVersionUtils.java
@@ -0,0 +1,23 @@
+// Copyright (c) 2016, 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.utils;
+
+import com.android.tools.r8.cf.CfVersion;
+import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.utils.structural.Ordered;
+import java.util.List;
+
+public class CfVersionUtils {
+
+ public static CfVersion max(List<DexEncodedMethod> methods) {
+ CfVersion result = null;
+ for (DexEncodedMethod method : methods) {
+ if (method.hasClassFileVersion()) {
+ result = Ordered.maxIgnoreNull(result, method.getClassFileVersion());
+ }
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index cd3a2db..fb8655a 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -202,7 +202,7 @@
enableClassStaticizer = false;
enableDevirtualization = false;
enableLambdaMerging = false;
- enableHorizontalClassMerging = false;
+ horizontalClassMergerOptions.disable();
enableStaticClassMerging = false;
enableVerticalClassMerging = false;
enableEnumUnboxing = false;
@@ -238,11 +238,6 @@
public boolean enableFieldBitAccessAnalysis =
System.getProperty("com.android.tools.r8.fieldBitAccessAnalysis") != null;
public boolean enableStaticClassMerging = true;
- public boolean enableHorizontalClassMerging = true;
- public boolean enableHorizontalClassMergingConstructorMerging = true;
- public int horizontalClassMergingMaxGroupSize = 30;
- public int horizontalClassMergingSyntheticArgumentCount = 3;
- public boolean enableHorizontalClassMergingOfKotlinLambdas = true;
public boolean enableVerticalClassMerging = true;
public boolean enableArgumentRemoval = true;
public boolean enableUnusedInterfaceRemoval = true;
@@ -582,7 +577,7 @@
* and check cast instructions needs to be collected.
*/
public boolean isClassMergingExtensionRequired() {
- return enableHorizontalClassMerging || enableVerticalClassMerging;
+ return horizontalClassMergerOptions.isEnabled() || enableVerticalClassMerging;
}
@Override
@@ -615,6 +610,8 @@
private final CallSiteOptimizationOptions callSiteOptimizationOptions =
new CallSiteOptimizationOptions();
+ private final HorizontalClassMergerOptions horizontalClassMergerOptions =
+ new HorizontalClassMergerOptions();
private final ProtoShrinkingOptions protoShrinking = new ProtoShrinkingOptions();
private final KotlinOptimizationOptions kotlinOptimizationOptions =
new KotlinOptimizationOptions();
@@ -638,6 +635,10 @@
return callSiteOptimizationOptions;
}
+ public HorizontalClassMergerOptions horizontalClassMergerOptions() {
+ return horizontalClassMergerOptions;
+ }
+
public ProtoShrinkingOptions protoShrinking() {
return protoShrinking;
}
@@ -1243,6 +1244,70 @@
}
}
+ public static class HorizontalClassMergerOptions {
+
+ public boolean enable = true;
+ public boolean enableConstructorMerging = true;
+ public boolean enableJavaLambdaMerging = false;
+ public boolean enableKotlinLambdaMerging = true;
+
+ public int syntheticArgumentCount = 3;
+ public int maxGroupSize = 30;
+
+ public void disable() {
+ enable = false;
+ }
+
+ @Deprecated
+ public void disableKotlinLambdaMerging() {
+ enableKotlinLambdaMerging = false;
+ }
+
+ public void enable() {
+ enable = true;
+ }
+
+ public void enableIf(boolean enable) {
+ this.enable = enable;
+ }
+
+ public void enableJavaLambdaMerging() {
+ enableJavaLambdaMerging = true;
+ }
+
+ public void enableKotlinLambdaMergingIf(boolean enableKotlinLambdaMerging) {
+ this.enableKotlinLambdaMerging = enableKotlinLambdaMerging;
+ }
+
+ public int getMaxGroupSize() {
+ return maxGroupSize;
+ }
+
+ public int getSyntheticArgumentCount() {
+ return syntheticArgumentCount;
+ }
+
+ public boolean isConstructorMergingEnabled() {
+ return enableConstructorMerging;
+ }
+
+ public boolean isDisabled() {
+ return !isEnabled();
+ }
+
+ public boolean isEnabled() {
+ return enable;
+ }
+
+ public boolean isJavaLambdaMergingEnabled() {
+ return enableJavaLambdaMerging;
+ }
+
+ public boolean isKotlinLambdaMergingEnabled() {
+ return enableKotlinLambdaMerging;
+ }
+ }
+
public static class ProtoShrinkingOptions {
public boolean enableGeneratedExtensionRegistryShrinking = false;
diff --git a/src/test/examplesAndroidO/lambdadesugaring/LambdaDesugaring.java b/src/test/examplesAndroidO/lambdadesugaring/LambdaDesugaring.java
index b54be6b..627d255 100644
--- a/src/test/examplesAndroidO/lambdadesugaring/LambdaDesugaring.java
+++ b/src/test/examplesAndroidO/lambdadesugaring/LambdaDesugaring.java
@@ -398,7 +398,15 @@
try {
testEnforcedSignatureHelper();
} catch (Exception e) {
- System.out.println(e.getMessage());
+ if (e.getMessage().contains("cannot be cast to lambdadesugaring.LambdaDesugaring$B")
+ || e.getMessage()
+ .contains("cannot be cast to class lambdadesugaring.LambdaDesugaring$B")) {
+ System.out.println(
+ "lambdadesugaring.LambdaDesugaring$A cannot be cast to"
+ + " lambdadesugaring.LambdaDesugaring$B");
+ } else {
+ System.out.println(e.getMessage());
+ }
}
atA(t -> new LambdaDesugaring().reorder(t));
diff --git a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
index abdfb83..f196151 100644
--- a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
@@ -47,7 +47,7 @@
options -> {
options.testing.allowClassInlinerGracefulExit = false;
options.testing.reportUnusedProguardConfigurationRules = true;
- options.enableHorizontalClassMerging = true;
+ options.horizontalClassMergerOptions().enable();
};
final Backend backend;
@@ -130,7 +130,6 @@
public T addHorizontallyMergedClassesInspectorIf(
boolean condition, Consumer<HorizontallyMergedClassesInspector> inspector) {
-
if (condition) {
return addHorizontallyMergedClassesInspector(inspector);
}
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/AbstractMethodMergingNonTrivialTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/AbstractMethodMergingNonTrivialTest.java
index 4d7d7fe..42df5c0 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/AbstractMethodMergingNonTrivialTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/AbstractMethodMergingNonTrivialTest.java
@@ -23,7 +23,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.addHorizontallyMergedClassesInspectorIf(
enableHorizontalClassMerging, inspector -> inspector.assertMergedInto(B.class, A.class))
.enableInliningAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/AbstractMethodMergingTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/AbstractMethodMergingTest.java
index cc092e9..3b0af4f 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/AbstractMethodMergingTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/AbstractMethodMergingTest.java
@@ -23,7 +23,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.addHorizontallyMergedClassesInspectorIf(
enableHorizontalClassMerging, inspector -> inspector.assertMergedInto(B.class, A.class))
.enableInliningAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/AdaptResourceFileContentsTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/AdaptResourceFileContentsTest.java
index 2c4ac9d..db8d4c7 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/AdaptResourceFileContentsTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/AdaptResourceFileContentsTest.java
@@ -36,7 +36,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.addOptionsModification(options -> options.dataResourceConsumer = dataResourceConsumer)
.enableNeverClassInliningAnnotations()
.addDataEntryResources(
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/AdaptVerticallyMergedResourceFileContentsTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/AdaptVerticallyMergedResourceFileContentsTest.java
index ea50082..0ebbb9d 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/AdaptVerticallyMergedResourceFileContentsTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/AdaptVerticallyMergedResourceFileContentsTest.java
@@ -35,7 +35,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.addOptionsModification(options -> options.dataResourceConsumer = dataResourceConsumer)
.enableNeverClassInliningAnnotations()
.addDataEntryResources(
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassWithInstanceFieldsTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassWithInstanceFieldsTest.java
index 25bb4ec..31a49cc 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassWithInstanceFieldsTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassWithInstanceFieldsTest.java
@@ -25,7 +25,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableNeverClassInliningAnnotations()
.enableInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesDistinguishedByDirectCheckCastTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesDistinguishedByDirectCheckCastTest.java
index 745fc26..bc5380e 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesDistinguishedByDirectCheckCastTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesDistinguishedByDirectCheckCastTest.java
@@ -24,7 +24,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesDistinguishedByDirectInstanceOfTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesDistinguishedByDirectInstanceOfTest.java
index 6a61d2f..6551ad2 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesDistinguishedByDirectInstanceOfTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesDistinguishedByDirectInstanceOfTest.java
@@ -24,7 +24,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesDistinguishedByIndirectCheckCastToInterfaceTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesDistinguishedByIndirectCheckCastToInterfaceTest.java
index 5eb49b1..6017cbe 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesDistinguishedByIndirectCheckCastToInterfaceTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesDistinguishedByIndirectCheckCastToInterfaceTest.java
@@ -26,7 +26,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableNoVerticalClassMergingAnnotations()
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesDistuingishedByIndirectInstanceOfInterfaceCheckCast.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesDistuingishedByIndirectInstanceOfInterfaceCheckCast.java
index 70e7c0d..cf05da6 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesDistuingishedByIndirectInstanceOfInterfaceCheckCast.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesDistuingishedByIndirectInstanceOfInterfaceCheckCast.java
@@ -26,7 +26,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNoVerticalClassMergingAnnotations()
.enableNeverClassInliningAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithDifferentInterfacesTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithDifferentInterfacesTest.java
index 3c9d066..5abdc09 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithDifferentInterfacesTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithDifferentInterfacesTest.java
@@ -26,7 +26,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.enableNoVerticalClassMergingAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithDifferentVisibilityFieldsTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithDifferentVisibilityFieldsTest.java
index 90e407e..68a81b1 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithDifferentVisibilityFieldsTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithDifferentVisibilityFieldsTest.java
@@ -32,7 +32,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithFeatureSplitTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithFeatureSplitTest.java
index 5907c150..9ac569b 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithFeatureSplitTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithFeatureSplitTest.java
@@ -42,7 +42,8 @@
.addKeepFeatureMainRule(Feature1Main.class)
.addKeepFeatureMainRule(Feature2Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
.compile()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithIdenticalInterfacesTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithIdenticalInterfacesTest.java
index 2bab975..6714388 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithIdenticalInterfacesTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithIdenticalInterfacesTest.java
@@ -25,7 +25,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithNativeMethodsTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithNativeMethodsTest.java
index 5ee01b3..1f0e3e6 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithNativeMethodsTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithNativeMethodsTest.java
@@ -26,7 +26,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithOverlappingVisibilitiesTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithOverlappingVisibilitiesTest.java
index 565c1bd..608f6fe 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithOverlappingVisibilitiesTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithOverlappingVisibilitiesTest.java
@@ -29,7 +29,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithStaticFields.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithStaticFields.java
index f00e07e..2810ce8 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithStaticFields.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithStaticFields.java
@@ -23,7 +23,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
.addHorizontallyMergedClassesInspectorIf(
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/CompanionClassMergingTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/CompanionClassMergingTest.java
index b14763f..9aca9fe 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/CompanionClassMergingTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/CompanionClassMergingTest.java
@@ -27,7 +27,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.addOptionsModification(options -> options.enableClassInlining = false)
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/CompatKeepConstructorLiveTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/CompatKeepConstructorLiveTest.java
index 9ccc2d4..c03361f 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/CompatKeepConstructorLiveTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/CompatKeepConstructorLiveTest.java
@@ -25,7 +25,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
.run(parameters.getRuntime(), Main.class)
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorCantInlineTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorCantInlineTest.java
index 2383a03..935e75e 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorCantInlineTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorCantInlineTest.java
@@ -27,7 +27,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingAfterUnusedArgumentRemovalTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingAfterUnusedArgumentRemovalTest.java
index 32f7454..d38efb3 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingAfterUnusedArgumentRemovalTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingAfterUnusedArgumentRemovalTest.java
@@ -22,7 +22,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
.addHorizontallyMergedClassesInspectorIf(
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingOverlapTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingOverlapTest.java
index 185e090..8936dc1 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingOverlapTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingOverlapTest.java
@@ -32,7 +32,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingPreoptimizedTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingPreoptimizedTest.java
index f658909..f878fd5 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingPreoptimizedTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingPreoptimizedTest.java
@@ -33,7 +33,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.addHorizontallyMergedClassesInspectorIf(
enableHorizontalClassMerging,
inspector ->
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingTest.java
index b1d77c2..21c3486 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingTest.java
@@ -23,7 +23,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
.run(parameters.getRuntime(), Main.class)
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingTrivialOverlapTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingTrivialOverlapTest.java
index f6def29..50da81e 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingTrivialOverlapTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingTrivialOverlapTest.java
@@ -32,7 +32,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingWithArgumentsTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingWithArgumentsTest.java
index a4a0fd9..7891de2 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingWithArgumentsTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingWithArgumentsTest.java
@@ -26,7 +26,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
.run(parameters.getRuntime(), Main.class)
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/DistinguishExceptionClassesTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/DistinguishExceptionClassesTest.java
index c751735..749ae58 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/DistinguishExceptionClassesTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/DistinguishExceptionClassesTest.java
@@ -22,7 +22,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.setMinApi(parameters.getApiLevel())
.run(parameters.getRuntime(), Main.class)
.assertSuccessWithOutputLines("test success")
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/EmptyClassTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/EmptyClassTest.java
index 4cdca16..5d63188 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/EmptyClassTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/EmptyClassTest.java
@@ -25,7 +25,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
.addHorizontallyMergedClassesInspectorIf(
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/FieldTypeMergedTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/FieldTypeMergedTest.java
index 616c88a..58434a9 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/FieldTypeMergedTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/FieldTypeMergedTest.java
@@ -29,7 +29,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/GenericStaticFieldTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/GenericStaticFieldTest.java
index 9b86b43..af72afe 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/GenericStaticFieldTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/GenericStaticFieldTest.java
@@ -20,7 +20,8 @@
.addKeepMainRule(Main.class)
.addKeepRules("-keepattributes Signatures")
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
// .addHorizontallyMergedClassesInspectorIf(
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/IdenticalFieldMembersTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/IdenticalFieldMembersTest.java
index 6968e1a..9dae7a2 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/IdenticalFieldMembersTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/IdenticalFieldMembersTest.java
@@ -23,7 +23,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/InheritInterfaceWithDefaultTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/InheritInterfaceWithDefaultTest.java
index 9bdaca6..b069bb1 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/InheritInterfaceWithDefaultTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/InheritInterfaceWithDefaultTest.java
@@ -30,7 +30,8 @@
.addKeepMainRule(Main.class)
.allowStdoutMessages()
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/InheritOverrideInterfaceTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/InheritOverrideInterfaceTest.java
index cedee87..8c7644d 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/InheritOverrideInterfaceTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/InheritOverrideInterfaceTest.java
@@ -24,7 +24,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNoVerticalClassMergingAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/InheritsFromLibraryClassTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/InheritsFromLibraryClassTest.java
index cfafb12..575c2cd 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/InheritsFromLibraryClassTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/InheritsFromLibraryClassTest.java
@@ -30,7 +30,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/InnerOuterClassesTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/InnerOuterClassesTest.java
index 075448a..98e74e4 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/InnerOuterClassesTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/InnerOuterClassesTest.java
@@ -22,7 +22,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableNeverClassInliningAnnotations()
.addKeepAttributes("InnerClasses", "EnclosingMethod")
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/InstantiatedAndUninstantiatedClassMergingTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/InstantiatedAndUninstantiatedClassMergingTest.java
index a27fdbd..59e77dd 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/InstantiatedAndUninstantiatedClassMergingTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/InstantiatedAndUninstantiatedClassMergingTest.java
@@ -36,7 +36,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(TestClass.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.addHorizontallyMergedClassesInspector(
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/JavaLambdaMergingTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/JavaLambdaMergingTest.java
new file mode 100644
index 0000000..adabb3e
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/JavaLambdaMergingTest.java
@@ -0,0 +1,91 @@
+// 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.classmerging.horizontal;
+
+import static com.android.tools.r8.ir.desugar.LambdaRewriter.LAMBDA_CLASS_NAME_PREFIX;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.utils.codeinspector.VerticallyMergedClassesInspector;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.junit.Test;
+
+public class JavaLambdaMergingTest extends HorizontalClassMergingTestBase {
+
+ public JavaLambdaMergingTest(TestParameters parameters, boolean enableHorizontalClassMerging) {
+ super(parameters, enableHorizontalClassMerging);
+ }
+
+ @Test
+ public void test() throws Exception {
+ testForR8(parameters.getBackend())
+ .addInnerClasses(getClass())
+ .addKeepMainRule(Main.class)
+ .addOptionsModification(
+ options -> {
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging);
+ assertFalse(options.horizontalClassMergerOptions().isJavaLambdaMergingEnabled());
+ options.horizontalClassMergerOptions().enableJavaLambdaMerging();
+ })
+ .addHorizontallyMergedClassesInspectorIf(
+ enableHorizontalClassMerging && parameters.isDexRuntime(),
+ inspector -> {
+ Set<DexType> lambdaSources =
+ inspector.getSources().stream()
+ .filter(x -> x.toSourceString().contains(LAMBDA_CLASS_NAME_PREFIX))
+ .collect(Collectors.toSet());
+ assertEquals(3, lambdaSources.size());
+ DexType firstTarget = inspector.getTarget(lambdaSources.iterator().next());
+ for (DexType lambdaSource : lambdaSources) {
+ assertTrue(
+ inspector
+ .getTarget(lambdaSource)
+ .toSourceString()
+ .contains(LAMBDA_CLASS_NAME_PREFIX));
+ assertEquals(firstTarget, inspector.getTarget(lambdaSource));
+ }
+ })
+ .addVerticallyMergedClassesInspector(
+ VerticallyMergedClassesInspector::assertNoClassesMerged)
+ .setMinApi(parameters.getApiLevel())
+ .compile()
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines("Hello world!");
+ }
+
+ public static class Main {
+
+ public static void main(String[] args) {
+ HelloGreeter helloGreeter =
+ System.currentTimeMillis() > 0
+ ? () -> System.out.print("Hello")
+ : () -> {
+ throw new RuntimeException();
+ };
+ WorldGreeter worldGreeter =
+ System.currentTimeMillis() > 0
+ ? () -> System.out.println(" world!")
+ : () -> {
+ throw new RuntimeException();
+ };
+ helloGreeter.hello();
+ worldGreeter.world();
+ }
+ }
+
+ interface HelloGreeter {
+
+ void hello();
+ }
+
+ interface WorldGreeter {
+
+ void world();
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/LargeConstructorsMergingTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/LargeConstructorsMergingTest.java
index 847db55..a553abe 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/LargeConstructorsMergingTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/LargeConstructorsMergingTest.java
@@ -26,7 +26,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.addOptionsModification(options -> options.testing.verificationSizeLimitInBytesOverride = 4)
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergeNonFinalAndFinalClassTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergeNonFinalAndFinalClassTest.java
index a5eb885..c8a36b6 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergeNonFinalAndFinalClassTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergeNonFinalAndFinalClassTest.java
@@ -25,7 +25,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.addHorizontallyMergedClassesInspectorIf(
enableHorizontalClassMerging, inspector -> inspector.assertMergedInto(B.class, A.class))
.enableNeverClassInliningAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergePackagePrivateWithPublicClassTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergePackagePrivateWithPublicClassTest.java
index a1c8faa..04d69b1d 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergePackagePrivateWithPublicClassTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergePackagePrivateWithPublicClassTest.java
@@ -27,7 +27,8 @@
PackagePrivateClassRunner.class, PackagePrivateClassRunner.getPrivateClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorForwardingTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorForwardingTest.java
index 2256e5d..f913560 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorForwardingTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorForwardingTest.java
@@ -32,7 +32,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorStackTraceTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorStackTraceTest.java
index fc4f076..a11a7d6 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorStackTraceTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorStackTraceTest.java
@@ -46,7 +46,8 @@
.addKeepAttributeLineNumberTable()
.addKeepAttributeSourceFile()
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableNoVerticalClassMergingAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
@@ -63,7 +64,9 @@
2,
StackTraceLine.builder()
.setClassName(A.class.getTypeName())
- .setMethodName("<init>")
+ // TODO(b/124483578): The synthetic method should not be part of the
+ // retraced stack trace.
+ .setMethodName("$r8$init$bridge")
.setFileName(getClass().getSimpleName() + ".java")
.setLineNumber(0)
.build())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedVirtualMethodStackTraceTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedVirtualMethodStackTraceTest.java
index 00d6e59..8c9d11d 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedVirtualMethodStackTraceTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedVirtualMethodStackTraceTest.java
@@ -46,7 +46,8 @@
.addKeepAttributeSourceFile()
.addDontWarn(C.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
@@ -64,7 +65,6 @@
StackTrace expectedStackTraceWithMergedMethod =
StackTrace.builder()
.add(expectedStackTrace)
-
.add(
1,
StackTraceLine.builder()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergingProducesFieldCollisionTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergingProducesFieldCollisionTest.java
index d25d516..34972f6 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergingProducesFieldCollisionTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergingProducesFieldCollisionTest.java
@@ -31,7 +31,8 @@
.addProgramClassFileData(transformedC)
.addProgramClasses(Parent.class, A.class, B.class, Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/NestClassTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/NestClassTest.java
index 5edc29f..b416826 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/NestClassTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/NestClassTest.java
@@ -58,7 +58,8 @@
.addKeepMainRule(examplesTypeName(BasicNestHostHorizontalClassMerging.class))
.addExamplesProgramFiles(R.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.compile()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/NoAbstractClassesWithNonAbstractClassesTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/NoAbstractClassesWithNonAbstractClassesTest.java
index 2bc2c97..5566f45 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/NoAbstractClassesWithNonAbstractClassesTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/NoAbstractClassesWithNonAbstractClassesTest.java
@@ -26,7 +26,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.enableNoVerticalClassMergingAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/NoClassesOrMembersWithAnnotationsTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/NoClassesOrMembersWithAnnotationsTest.java
index d17fa75..74d0ad6 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/NoClassesOrMembersWithAnnotationsTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/NoClassesOrMembersWithAnnotationsTest.java
@@ -31,7 +31,8 @@
.addKeepMainRule(Main.class)
.addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableNeverClassInliningAnnotations()
.enableInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/NoHorizontalClassMergingTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/NoHorizontalClassMergingTest.java
index dc513c3..5c0e207 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/NoHorizontalClassMergingTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/NoHorizontalClassMergingTest.java
@@ -24,7 +24,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableNoHorizontalClassMergingAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/NonReboundFieldAccessOnMergedClassTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/NonReboundFieldAccessOnMergedClassTest.java
index e357250..671f740 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/NonReboundFieldAccessOnMergedClassTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/NonReboundFieldAccessOnMergedClassTest.java
@@ -26,7 +26,8 @@
.addInnerClasses(NonReboundFieldAccessOnMergedClassTestClasses.class)
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.addHorizontallyMergedClassesInspector(
inspector -> {
if (enableHorizontalClassMerging) {
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/NonReboundFieldAccessWithMergedTypeTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/NonReboundFieldAccessWithMergedTypeTest.java
index 3afcfb2..b6183a3 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/NonReboundFieldAccessWithMergedTypeTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/NonReboundFieldAccessWithMergedTypeTest.java
@@ -27,7 +27,8 @@
.addInnerClasses(NonReboundFieldAccessWithMergedTypeTestClasses.class)
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.addHorizontallyMergedClassesInspector(
inspector -> {
if (enableHorizontalClassMerging) {
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/OverlappingConstructorsTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/OverlappingConstructorsTest.java
index fbd587d..c97e384 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/OverlappingConstructorsTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/OverlappingConstructorsTest.java
@@ -25,7 +25,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
.run(parameters.getRuntime(), Main.class)
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/PackagePrivateMemberAccessTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/PackagePrivateMemberAccessTest.java
index a1b0951..2732240 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/PackagePrivateMemberAccessTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/PackagePrivateMemberAccessTest.java
@@ -28,7 +28,8 @@
.addProgramClasses(B.class)
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.allowAccessModification(false)
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/PackagePrivateMembersAccessedTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/PackagePrivateMembersAccessedTest.java
index cdaeee7..4d7c0c4 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/PackagePrivateMembersAccessedTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/PackagePrivateMembersAccessedTest.java
@@ -27,7 +27,8 @@
.addProgramClasses(D.class)
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.allowAccessModification(false)
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/PinnedClassMemberReferenceTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/PinnedClassMemberReferenceTest.java
index 4a22fe3..2f01f90 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/PinnedClassMemberReferenceTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/PinnedClassMemberReferenceTest.java
@@ -28,7 +28,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.noMinification()
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/PinnedClassMemberTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/PinnedClassMemberTest.java
index 444d573..1e09a5a 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/PinnedClassMemberTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/PinnedClassMemberTest.java
@@ -23,7 +23,8 @@
.addKeepMainRule(Main.class)
.addKeepRules("-keepclassmembers class " + B.class.getTypeName() + " { void foo(); }")
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
.run(parameters.getRuntime(), Main.class)
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/PinnedClassTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/PinnedClassTest.java
index a2b36f3..0ba06e6 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/PinnedClassTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/PinnedClassTest.java
@@ -23,7 +23,8 @@
.addKeepMainRule(Main.class)
.addKeepClassRules(B.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
.run(parameters.getRuntime(), Main.class)
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/PreventMergeMainDexListTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/PreventMergeMainDexListTest.java
index 4a50200..e3e1b85 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/PreventMergeMainDexListTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/PreventMergeMainDexListTest.java
@@ -48,7 +48,7 @@
.addMainDexListClasses(A.class, Main.class)
.addOptionsModification(
options -> {
- options.enableHorizontalClassMerging = enableHorizontalClassMerging;
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging);
options.minimalMainDex = true;
})
.enableNeverClassInliningAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/PreventMergeMainDexTracingTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/PreventMergeMainDexTracingTest.java
index 9e81bc6..6a31a5e 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/PreventMergeMainDexTracingTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/PreventMergeMainDexTracingTest.java
@@ -48,7 +48,7 @@
.addMainDexClassRules(Main.class)
.addOptionsModification(
options -> {
- options.enableHorizontalClassMerging = enableHorizontalClassMerging;
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging);
options.minimalMainDex = true;
})
.enableNeverClassInliningAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/PrivateAndInterfaceMethodCollisionTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/PrivateAndInterfaceMethodCollisionTest.java
index af37199..4553469 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/PrivateAndInterfaceMethodCollisionTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/PrivateAndInterfaceMethodCollisionTest.java
@@ -25,7 +25,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.addHorizontallyMergedClassesInspector(
HorizontallyMergedClassesInspector::assertNoClassesMerged)
.enableInliningAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/PrivateAndStaticMethodCollisionTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/PrivateAndStaticMethodCollisionTest.java
index df03d8a..3c7b799 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/PrivateAndStaticMethodCollisionTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/PrivateAndStaticMethodCollisionTest.java
@@ -22,7 +22,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.addHorizontallyMergedClassesInspectorIf(
enableHorizontalClassMerging, inspector -> inspector.assertMergedInto(B.class, A.class))
.enableInliningAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ReferencedInAnnotationTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ReferencedInAnnotationTest.java
index 620f948..385d782 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ReferencedInAnnotationTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ReferencedInAnnotationTest.java
@@ -38,7 +38,8 @@
.addKeepMainRule(TestClass.class)
.addKeepClassAndMembersRules(Annotation.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.addKeepRuntimeVisibleAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/RemapFieldTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/RemapFieldTest.java
index 33c8a85..168d6ee 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/RemapFieldTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/RemapFieldTest.java
@@ -24,7 +24,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/RemapMethodTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/RemapMethodTest.java
index a531860..c640ffc 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/RemapMethodTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/RemapMethodTest.java
@@ -24,7 +24,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ServiceLoaderParentTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ServiceLoaderParentTest.java
index 4e89fb8..5eab9c9 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ServiceLoaderParentTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ServiceLoaderParentTest.java
@@ -38,7 +38,8 @@
Origin.unknown()))
.enableNoVerticalClassMergingAnnotations()
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.setMinApi(parameters.getApiLevel())
.run(parameters.getRuntime(), Main.class)
.assertSuccess()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ServiceLoaderTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ServiceLoaderTest.java
index ee6dc18..f9ae4bd 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ServiceLoaderTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ServiceLoaderTest.java
@@ -36,7 +36,8 @@
"META-INF/services/" + A.class.getTypeName(),
Origin.unknown()))
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.setMinApi(parameters.getApiLevel())
.run(parameters.getRuntime(), Main.class)
.assertSuccess()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/StaticAndInterfaceMethodCollisionTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/StaticAndInterfaceMethodCollisionTest.java
index ebbfd86..e76dd447 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/StaticAndInterfaceMethodCollisionTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/StaticAndInterfaceMethodCollisionTest.java
@@ -25,7 +25,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.addHorizontallyMergedClassesInspector(
HorizontallyMergedClassesInspector::assertNoClassesMerged)
.enableInliningAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/StaticAndVirtualMethodCollisionTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/StaticAndVirtualMethodCollisionTest.java
index edca180..35a15e5 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/StaticAndVirtualMethodCollisionTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/StaticAndVirtualMethodCollisionTest.java
@@ -23,7 +23,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.addHorizontallyMergedClassesInspectorIf(
enableHorizontalClassMerging, inspector -> inspector.assertMergedInto(B.class, A.class))
.enableInliningAnnotations()
@@ -36,10 +37,10 @@
static class Main {
public static void main(String[] args) {
- new A().foo();
+ A.foo();
new A().bar();
new B().foo();
- new B().bar();
+ B.bar();
}
}
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/SuperConstructorCallsVirtualMethodTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/SuperConstructorCallsVirtualMethodTest.java
index 119913b..ecbd84b 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/SuperConstructorCallsVirtualMethodTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/SuperConstructorCallsVirtualMethodTest.java
@@ -25,7 +25,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/SynchronizedClassesTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/SynchronizedClassesTest.java
index e5c77a3..6f458b7 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/SynchronizedClassesTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/SynchronizedClassesTest.java
@@ -26,7 +26,7 @@
.addKeepMainRule(Main.class)
.addOptionsModification(
options -> {
- options.enableHorizontalClassMerging = enableHorizontalClassMerging;
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging);
})
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/SyntheticConstructorArgumentsMerged.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/SyntheticConstructorArgumentsMerged.java
index 59ea0b2..6567764 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/SyntheticConstructorArgumentsMerged.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/SyntheticConstructorArgumentsMerged.java
@@ -26,7 +26,7 @@
.addKeepMainRule(Main.class)
.addOptionsModification(
options -> {
- options.enableHorizontalClassMerging = enableHorizontalClassMerging;
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging);
})
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerCollisionTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerCollisionTest.java
index b603f66..97e41db 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerCollisionTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerCollisionTest.java
@@ -26,7 +26,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.enableNoVerticalClassMergingAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerConstructorCollisionTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerConstructorCollisionTest.java
index a5c5555..c7a7d9c 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerConstructorCollisionTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerConstructorCollisionTest.java
@@ -30,7 +30,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.enableNoHorizontalClassMergingAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerInterfaceCollisionTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerInterfaceCollisionTest.java
index f1301a0..946e113 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerInterfaceCollisionTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerInterfaceCollisionTest.java
@@ -36,7 +36,8 @@
.addKeepMainRule(Main.class)
.noMinification()
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.enableNoVerticalClassMergingAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerInterfaceFixedCollisionTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerInterfaceFixedCollisionTest.java
index 2f6895a..1d3290a 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerInterfaceFixedCollisionTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerInterfaceFixedCollisionTest.java
@@ -38,7 +38,8 @@
.addKeepMainRule(Main.class)
.noMinification()
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.enableNoVerticalClassMergingAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerInterfaceImplementedByParentTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerInterfaceImplementedByParentTest.java
index b6a320c..afee32c 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerInterfaceImplementedByParentTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerInterfaceImplementedByParentTest.java
@@ -34,7 +34,8 @@
.addKeepMainRule(Main.class)
.noMinification()
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.enableNoVerticalClassMergingAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerSubClassCollisionTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerSubClassCollisionTest.java
index aad0efa..b68f291 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerSubClassCollisionTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/TreeFixerSubClassCollisionTest.java
@@ -29,7 +29,8 @@
.addKeepMainRule(Main.class)
.noMinification()
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.enableNoVerticalClassMergingAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/VerticalMergingPreoptimizedTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/VerticalMergingPreoptimizedTest.java
index 7731d5e..b1c0b4a 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/VerticalMergingPreoptimizedTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/VerticalMergingPreoptimizedTest.java
@@ -28,7 +28,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.enableNoHorizontalClassMergingAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/VerticallyMergedClassDistinguishedByCheckCastTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/VerticallyMergedClassDistinguishedByCheckCastTest.java
index 9ecbf5a..366800a 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/VerticallyMergedClassDistinguishedByCheckCastTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/VerticallyMergedClassDistinguishedByCheckCastTest.java
@@ -23,7 +23,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
.run(parameters.getRuntime(), Main.class)
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/VerticallyMergedClassDistinguishedByInstanceOfTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/VerticallyMergedClassDistinguishedByInstanceOfTest.java
index bba42bb..c8ad21d 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/VerticallyMergedClassDistinguishedByInstanceOfTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/VerticallyMergedClassDistinguishedByInstanceOfTest.java
@@ -23,7 +23,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
.run(parameters.getRuntime(), Main.class)
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/VerticallyMergedClassTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/VerticallyMergedClassTest.java
index e40ff51..a40b387 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/VerticallyMergedClassTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/VerticallyMergedClassTest.java
@@ -27,7 +27,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableNoHorizontalClassMergingAnnotations()
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/VirtualMethodMergingOfFinalAndNonFinalMethodTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/VirtualMethodMergingOfFinalAndNonFinalMethodTest.java
index f9eff69..6399f3e 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/VirtualMethodMergingOfFinalAndNonFinalMethodTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/VirtualMethodMergingOfFinalAndNonFinalMethodTest.java
@@ -28,7 +28,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(TestClass.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.enableNoVerticalClassMergingAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/VirtualMethodMergingOfPublicizedMethodsTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/VirtualMethodMergingOfPublicizedMethodsTest.java
index 8178138..5e23840 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/VirtualMethodMergingOfPublicizedMethodsTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/VirtualMethodMergingOfPublicizedMethodsTest.java
@@ -25,7 +25,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(TestClass.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.allowAccessModification()
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/NotOverlappingTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/NotOverlappingTest.java
index 8742e67..e405aa9 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/NotOverlappingTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/NotOverlappingTest.java
@@ -23,7 +23,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/OverrideAbstractMethodWithDefaultTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/OverrideAbstractMethodWithDefaultTest.java
index 87f4dc3..e456600 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/OverrideAbstractMethodWithDefaultTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/OverrideAbstractMethodWithDefaultTest.java
@@ -25,7 +25,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNoVerticalClassMergingAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/OverrideDefaultMethodTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/OverrideDefaultMethodTest.java
index dd8183d..0e3a098 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/OverrideDefaultMethodTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/OverrideDefaultMethodTest.java
@@ -26,7 +26,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNoVerticalClassMergingAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/OverrideDefaultOnSuperMethodTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/OverrideDefaultOnSuperMethodTest.java
index bd41f8f..fa2dcb2 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/OverrideDefaultOnSuperMethodTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/OverrideDefaultOnSuperMethodTest.java
@@ -27,7 +27,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNoUnusedInterfaceRemovalAnnotations()
.enableNoVerticalClassMergingAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/OverrideMergeAbsentTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/OverrideMergeAbsentTest.java
index fe0bc23..526aa00 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/OverrideMergeAbsentTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/OverrideMergeAbsentTest.java
@@ -25,7 +25,8 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.enableNoVerticalClassMergingAnnotations()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/OverrideParentCollisionTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/OverrideParentCollisionTest.java
index 94b643a..639cf19 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/OverrideParentCollisionTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/OverrideParentCollisionTest.java
@@ -27,7 +27,8 @@
.addInnerClasses(this.getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/SuperMethodMergedTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/SuperMethodMergedTest.java
index 228223f..44973bc 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/SuperMethodMergedTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/dispatch/SuperMethodMergedTest.java
@@ -26,7 +26,8 @@
.addInnerClasses(this.getClass())
.addKeepMainRule(Main.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.enableNoVerticalClassMergingAnnotations()
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineSynthesizedLambdaClass.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineSynthesizedLambdaClass.java
index 117a18c..1bd8db6 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineSynthesizedLambdaClass.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineSynthesizedLambdaClass.java
@@ -23,7 +23,7 @@
@Parameterized.Parameters(name = "{0}")
public static TestParametersCollection data() {
- return getTestParameters().withDexRuntimes().build();
+ return getTestParameters().withDexRuntimes().withAllApiLevels().build();
}
public InlineSynthesizedLambdaClass(TestParameters parameters) {
@@ -42,7 +42,7 @@
.addKeepMainRule(Lambda.class)
.allowAccessModification()
.noMinification()
- .setMinApi(parameters.getRuntime())
+ .setMinApi(parameters.getApiLevel())
.run(parameters.getRuntime(), Lambda.class)
.assertSuccessWithOutput(javaOutput)
.inspector();
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/lambda/LambdaMethodInliningTest.java b/src/test/java/com/android/tools/r8/ir/optimize/lambda/LambdaMethodInliningTest.java
index 8bdea50..a63addb 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/lambda/LambdaMethodInliningTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/lambda/LambdaMethodInliningTest.java
@@ -43,6 +43,8 @@
.enableInliningAnnotations()
.enableNoVerticalClassMergingAnnotations()
.addOptionsModification(options -> options.enableClassInlining = false)
+ // TODO(b/173398086): Horizontal class merging breaks uniqueMethodWithName().
+ .noMinification()
.setMinApi(parameters.getApiLevel())
.compile()
.inspect(this::inspect)
diff --git a/src/test/java/com/android/tools/r8/kotlin/KotlinClassInlinerTest.java b/src/test/java/com/android/tools/r8/kotlin/KotlinClassInlinerTest.java
index 0f5b195..a949213 100644
--- a/src/test/java/com/android/tools/r8/kotlin/KotlinClassInlinerTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/KotlinClassInlinerTest.java
@@ -335,7 +335,7 @@
// condition.
options.testing.addCallEdgesForLibraryInvokes = true;
- options.enableHorizontalClassMergingOfKotlinLambdas = false;
+ options.horizontalClassMergerOptions().disableKotlinLambdaMerging();
})
.apply(configuration));
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingTest.java b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingTest.java
index 08f4398..b9e0546 100644
--- a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingTest.java
@@ -42,7 +42,7 @@
// Ensure that enclosing method and inner class attributes are kept even on classes that are
// not explicitly mentioned by a keep rule.
options.forceProguardCompatibility = true;
- options.enableHorizontalClassMergingOfKotlinLambdas = false;
+ options.horizontalClassMergerOptions().disableKotlinLambdaMerging();
}
private final boolean enableUnusedInterfaceRemoval;
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/b148525512/B148525512.java b/src/test/java/com/android/tools/r8/kotlin/lambda/b148525512/B148525512.java
index 1f73d0e..0dd8a62 100644
--- a/src/test/java/com/android/tools/r8/kotlin/lambda/b148525512/B148525512.java
+++ b/src/test/java/com/android/tools/r8/kotlin/lambda/b148525512/B148525512.java
@@ -126,7 +126,7 @@
.addKeepClassAndMembersRules(featureKtClassNamet)
.addKeepClassAndMembersRules(FeatureAPI.class)
.addOptionsModification(
- options -> options.enableHorizontalClassMergingOfKotlinLambdas = false)
+ options -> options.horizontalClassMergerOptions().disableKotlinLambdaMerging())
.setMinApi(parameters.getApiLevel())
.noMinification() // The check cast inspection above relies on original names.
.addFeatureSplit(
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/b159688129/LambdaGroupGCLimitTest.java b/src/test/java/com/android/tools/r8/kotlin/lambda/b159688129/LambdaGroupGCLimitTest.java
index 323b533..57cdae7 100644
--- a/src/test/java/com/android/tools/r8/kotlin/lambda/b159688129/LambdaGroupGCLimitTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/lambda/b159688129/LambdaGroupGCLimitTest.java
@@ -8,15 +8,17 @@
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.R8FullTestBuilder;
import com.android.tools.r8.R8TestCompileResult;
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 com.android.tools.r8.ToolHelper.ProcessResult;
+import com.android.tools.r8.utils.BooleanUtils;
+import com.android.tools.r8.utils.InternalOptions.HorizontalClassMergerOptions;
import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
import java.io.IOException;
import java.nio.file.Path;
@@ -32,16 +34,20 @@
@RunWith(Parameterized.class)
public class LambdaGroupGCLimitTest extends TestBase {
+ private final boolean enableHorizontalClassMergingOfKotlinLambdas;
private final TestParameters parameters;
private final int LAMBDA_HOLDER_LIMIT = 50;
private final int LAMBDAS_PER_CLASS_LIMIT = 100;
- @Parameters(name = "{0}")
- public static TestParametersCollection data() {
- return getTestParameters().withDexRuntimes().withAllApiLevels().build();
+ @Parameters(name = "{1}, horizontal class merging: {0}")
+ public static List<Object[]> data() {
+ return buildParameters(
+ BooleanUtils.values(), getTestParameters().withDexRuntimes().withAllApiLevels().build());
}
- public LambdaGroupGCLimitTest(TestParameters parameters) {
+ public LambdaGroupGCLimitTest(
+ boolean enableHorizontalClassMergingOfKotlinLambdas, TestParameters parameters) {
+ this.enableHorizontalClassMergingOfKotlinLambdas = enableHorizontalClassMergingOfKotlinLambdas;
this.parameters = parameters;
}
@@ -51,6 +57,11 @@
R8FullTestBuilder testBuilder =
testForR8(parameters.getBackend())
.addProgramFiles(ToolHelper.getKotlinStdlibJar(ToolHelper.getKotlinC_1_3_72()))
+ .addOptionsModification(
+ options ->
+ options
+ .horizontalClassMergerOptions()
+ .enableKotlinLambdaMergingIf(enableHorizontalClassMergingOfKotlinLambdas))
.setMinApi(parameters.getApiLevel())
.noMinification();
Path classFiles = temp.newFile("classes.jar").toPath();
@@ -63,7 +74,27 @@
testBuilder.addKeepClassAndMembersRules(PKG_NAME + ".MainKt" + mainId);
}
writeClassFileDataToJar(classFiles, classFileData);
- R8TestCompileResult compileResult = testBuilder.addProgramFiles(classFiles).compile();
+ R8TestCompileResult compileResult =
+ testBuilder
+ .addProgramFiles(classFiles)
+ .addHorizontallyMergedClassesInspector(
+ inspector -> {
+ if (enableHorizontalClassMergingOfKotlinLambdas) {
+ HorizontalClassMergerOptions defaultHorizontalClassMergerOptions =
+ new HorizontalClassMergerOptions();
+ assertEquals(4833, inspector.getSources().size());
+ assertEquals(167, inspector.getTargets().size());
+ assertTrue(
+ inspector.getMergeGroups().stream()
+ .allMatch(
+ mergeGroup ->
+ mergeGroup.size()
+ <= defaultHorizontalClassMergerOptions.getMaxGroupSize()));
+ } else {
+ inspector.assertNoClassesMerged();
+ }
+ })
+ .compile();
Path path = compileResult.writeToZip();
compileResult
.run(parameters.getRuntime(), PKG_NAME + ".MainKt0")
@@ -74,7 +105,9 @@
codeInspector.allClasses().stream()
.filter(c -> c.getFinalName().contains("LambdaGroup"))
.collect(Collectors.toList());
- assertEquals(1, lambdaGroups.size());
+ assertEquals(
+ 1 - BooleanUtils.intValue(enableHorizontalClassMergingOfKotlinLambdas),
+ lambdaGroups.size());
});
Path oatFile = temp.newFile("out.oat").toPath();
ProcessResult processResult =
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/b159688129/LambdaSplitByCodeCorrectnessTest.java b/src/test/java/com/android/tools/r8/kotlin/lambda/b159688129/LambdaSplitByCodeCorrectnessTest.java
index 4d3f823..c261c25 100644
--- a/src/test/java/com/android/tools/r8/kotlin/lambda/b159688129/LambdaSplitByCodeCorrectnessTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/lambda/b159688129/LambdaSplitByCodeCorrectnessTest.java
@@ -67,6 +67,8 @@
testForR8(parameters.getBackend())
.addProgramFiles(ToolHelper.getKotlinStdlibJar(kotlinc))
.addProgramFiles(ktClasses)
+ .addOptionsModification(
+ options -> options.horizontalClassMergerOptions().disableKotlinLambdaMerging())
.setMinApi(parameters.getApiLevel())
.addKeepMainRule(PKG_NAME + ".SimpleKt")
.applyIf(
@@ -75,8 +77,7 @@
b.addOptionsModification(
internalOptions ->
// Setting verificationSizeLimitInBytesOverride = 1 will force a a chain
- // having
- // only a single implementation method in each.
+ // having only a single implementation method in each.
internalOptions.testing.verificationSizeLimitInBytesOverride =
splitGroup ? 1 : -1))
.noMinification()
diff --git a/src/test/java/com/android/tools/r8/shaking/assumenosideeffects/AssumenosideeffectsPropagationTest.java b/src/test/java/com/android/tools/r8/shaking/assumenosideeffects/AssumenosideeffectsPropagationTest.java
index 4f65b48..1c7f6ac 100644
--- a/src/test/java/com/android/tools/r8/shaking/assumenosideeffects/AssumenosideeffectsPropagationTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/assumenosideeffects/AssumenosideeffectsPropagationTest.java
@@ -157,7 +157,8 @@
.addKeepMainRule(MAIN)
.addKeepRules(config.getKeepRules())
.addOptionsModification(
- options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ options ->
+ options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
.enableInliningAnnotations()
.noMinification()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/HorizontallyMergedClassesInspector.java b/src/test/java/com/android/tools/r8/utils/codeinspector/HorizontallyMergedClassesInspector.java
index 37dbe19..7cfc3fe 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/HorizontallyMergedClassesInspector.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/HorizontallyMergedClassesInspector.java
@@ -12,6 +12,8 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.horizontalclassmerging.HorizontallyMergedClasses;
+import com.android.tools.r8.utils.SetUtils;
+import com.google.common.collect.Sets;
import java.util.Set;
import java.util.function.BiConsumer;
@@ -30,10 +32,29 @@
horizontallyMergedClasses.forEachMergeGroup(consumer);
}
+ public Set<Set<DexType>> getMergeGroups() {
+ Set<Set<DexType>> mergeGroups = Sets.newLinkedHashSet();
+ forEachMergeGroup(
+ (sources, target) -> {
+ Set<DexType> mergeGroup = SetUtils.newIdentityHashSet(sources);
+ mergeGroup.add(target);
+ mergeGroups.add(mergeGroup);
+ });
+ return mergeGroups;
+ }
+
+ public Set<DexType> getSources() {
+ return horizontallyMergedClasses.getSources();
+ }
+
public DexType getTarget(DexType clazz) {
return horizontallyMergedClasses.getMergeTargetOrDefault(clazz);
}
+ public Set<DexType> getTargets() {
+ return horizontallyMergedClasses.getTargets();
+ }
+
public HorizontallyMergedClassesInspector assertMergedInto(Class<?> from, Class<?> target) {
assertEquals(
horizontallyMergedClasses.getMergeTargetOrDefault(toDexType(from, dexItemFactory)),