Merge commit 'a8cb578796218b723389a026531566e3519aba5e' into dev-release
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index 46cc30f..7f17170 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -256,12 +256,9 @@
InspectorImpl.runInspections(options.outputInspections, appView.appInfo().classes());
NamingLens namingLens = NamingLens.getIdentityLens();
- if (appView.rewritePrefix.isRewriting()) {
- namingLens = PrefixRewritingNamingLens.createPrefixRewritingNamingLens(appView, namingLens);
- }
- if (appView.options().shouldDesugarRecords()) {
- namingLens = RecordRewritingNamingLens.createRecordRewritingNamingLens(appView, namingLens);
- }
+ namingLens = PrefixRewritingNamingLens.createPrefixRewritingNamingLens(appView, namingLens);
+ namingLens = RecordRewritingNamingLens.createRecordRewritingNamingLens(appView, namingLens);
+
if (options.isGeneratingClassFiles()) {
ProguardMapSupplier proguardMapSupplier =
finalizeApplication(inputApp, appView, namingLens);
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index d3c617c..02ef891 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -71,6 +71,7 @@
import com.android.tools.r8.naming.PrefixRewritingNamingLens;
import com.android.tools.r8.naming.ProguardMapMinifier;
import com.android.tools.r8.naming.ProguardMapSupplier;
+import com.android.tools.r8.naming.RecordRewritingNamingLens;
import com.android.tools.r8.naming.SeedMapper;
import com.android.tools.r8.naming.SourceFileRewriter;
import com.android.tools.r8.naming.signature.GenericSignatureRewriter;
@@ -842,15 +843,14 @@
options.syntheticProguardRulesConsumer.accept(synthesizedProguardRules);
}
- NamingLens prefixRewritingNamingLens =
- PrefixRewritingNamingLens.createPrefixRewritingNamingLens(appView, namingLens);
+ namingLens = PrefixRewritingNamingLens.createPrefixRewritingNamingLens(appView, namingLens);
+ namingLens = RecordRewritingNamingLens.createRecordRewritingNamingLens(appView, namingLens);
timing.begin("MinifyKotlinMetadata");
- new KotlinMetadataRewriter(appView, prefixRewritingNamingLens).runForR8(executorService);
+ new KotlinMetadataRewriter(appView, namingLens).runForR8(executorService);
timing.end();
- new GenericSignatureRewriter(
- appView, prefixRewritingNamingLens, genericContextBuilderBeforeFinalMerging)
+ new GenericSignatureRewriter(appView, namingLens, genericContextBuilderBeforeFinalMerging)
.run(appView.appInfo().classes(), executorService);
assert appView.checkForTesting(
@@ -862,8 +862,7 @@
.isValid())
: "Could not validate generic signatures";
- new DesugaredLibraryKeepRuleGenerator(appView, prefixRewritingNamingLens)
- .runIfNecessary(timing);
+ new DesugaredLibraryKeepRuleGenerator(appView, namingLens).runIfNecessary(timing);
// Generate the resulting application resources.
writeApplication(
@@ -871,7 +870,7 @@
appView,
appView.graphLens(),
appView.initClassLens(),
- prefixRewritingNamingLens,
+ namingLens,
options,
ProguardMapSupplier.create(classNameMapper, options));
diff --git a/src/main/java/com/android/tools/r8/graph/ApplicationReaderMap.java b/src/main/java/com/android/tools/r8/graph/ApplicationReaderMap.java
index 82b9d7f..5ce8224 100644
--- a/src/main/java/com/android/tools/r8/graph/ApplicationReaderMap.java
+++ b/src/main/java/com/android/tools/r8/graph/ApplicationReaderMap.java
@@ -12,7 +12,7 @@
public static Map<String, String> getDescriptorMap(InternalOptions options) {
ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
- if (options.shouldDesugarRecords()) {
+ if (options.shouldDesugarRecords() && !options.testing.disableRecordApplicationReaderMap) {
builder.put(DexItemFactory.recordTagDescriptorString, DexItemFactory.recordDescriptorString);
}
return builder.build();
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 5d05028..b4a382f 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -48,6 +48,8 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexAnnotation.AnnotatedKind;
import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.RemovedArgumentInfo;
import com.android.tools.r8.ir.analysis.inlining.SimpleInliningConstraint;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.NumericType;
@@ -57,9 +59,9 @@
import com.android.tools.r8.ir.optimize.Inliner.Reason;
import com.android.tools.r8.ir.optimize.NestUtils;
import com.android.tools.r8.ir.optimize.info.CallSiteOptimizationInfo;
-import com.android.tools.r8.ir.optimize.info.ConcreteCallSiteOptimizationInfo;
import com.android.tools.r8.ir.optimize.info.DefaultMethodOptimizationInfo;
import com.android.tools.r8.ir.optimize.info.MethodOptimizationInfo;
+import com.android.tools.r8.ir.optimize.info.MethodOptimizationInfoFixer;
import com.android.tools.r8.ir.optimize.info.MutableMethodOptimizationInfo;
import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple;
import com.android.tools.r8.ir.optimize.inliner.WhyAreYouNotInliningReporter;
@@ -1287,11 +1289,16 @@
public DexEncodedMethod toStaticMethodWithoutThis(AppView<AppInfoWithLiveness> appView) {
checkIfObsolete();
assert !accessFlags.isStatic();
+
+ ArgumentInfoCollection prototypeChanges =
+ ArgumentInfoCollection.builder()
+ .addArgumentInfo(0, RemovedArgumentInfo.builder().setType(getHolderType()).build())
+ .build();
Builder builder =
builder(this)
.promoteToStatic()
.withoutThisParameter()
- .adjustOptimizationInfoAfterRemovingThisParameter(appView)
+ .fixupOptimizationInfo(appView, prototypeChanges.createMethodOptimizationInfoFixer())
.setGenericSignature(MethodTypeSignature.noSignature());
DexEncodedMethod method = builder.build();
method.copyMetadata(this);
@@ -1525,15 +1532,22 @@
return this;
}
- public Builder fixupCallSiteOptimizationInfo(
- Function<ConcreteCallSiteOptimizationInfo, ? extends CallSiteOptimizationInfo> fn) {
+ public Builder fixupCallSiteOptimizationInfo(MethodOptimizationInfoFixer fixer) {
if (callSiteOptimizationInfo.isConcreteCallSiteOptimizationInfo()) {
callSiteOptimizationInfo =
- fn.apply(callSiteOptimizationInfo.asConcreteCallSiteOptimizationInfo());
+ fixer.fixupCallSiteOptimizationInfo(
+ callSiteOptimizationInfo.asConcreteCallSiteOptimizationInfo());
}
return this;
}
+ public Builder fixupOptimizationInfo(
+ AppView<AppInfoWithLiveness> appView, MethodOptimizationInfoFixer fixer) {
+ return fixupCallSiteOptimizationInfo(fixer)
+ .modifyOptimizationInfo(
+ (newMethod, optimizationInfo) -> optimizationInfo.fixup(appView, fixer));
+ }
+
public Builder setSimpleInliningConstraint(
DexProgramClass holder, SimpleInliningConstraint simpleInliningConstraint) {
return addBuildConsumer(
@@ -1661,15 +1675,6 @@
return this;
}
- public Builder adjustOptimizationInfoAfterRemovingThisParameter(
- AppView<AppInfoWithLiveness> appView) {
- return fixupCallSiteOptimizationInfo(
- callSiteOptimizationInfo -> callSiteOptimizationInfo.fixupAfterParameterRemoval(0))
- .modifyOptimizationInfo(
- (newMethod, optimizationInfo) ->
- optimizationInfo.adjustOptimizationInfoAfterRemovingThisParameter(appView));
- }
-
public Builder modifyOptimizationInfo(
BiConsumer<DexEncodedMethod, MutableMethodOptimizationInfo> consumer) {
return addBuildConsumer(
diff --git a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
index b9563fa..4c6c165 100644
--- a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
+++ b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
@@ -515,10 +515,6 @@
if (!accessFlags.isRecord()) {
return;
}
- // TODO(b/169645628): Support records in all compilation.
- if (!application.options.enableExperimentalRecordDesugaring()) {
- throw new CompilationError("Records are not supported", origin);
- }
// TODO(b/169645628): Change this logic if we start stripping the record components.
// Another approach would be to mark a bit in fields that are record components instead.
String message = "Records are expected to have one record component per instance field.";
diff --git a/src/main/java/com/android/tools/r8/graph/RewrittenPrototypeDescription.java b/src/main/java/com/android/tools/r8/graph/RewrittenPrototypeDescription.java
index dffe2a3..1133b65 100644
--- a/src/main/java/com/android/tools/r8/graph/RewrittenPrototypeDescription.java
+++ b/src/main/java/com/android/tools/r8/graph/RewrittenPrototypeDescription.java
@@ -11,10 +11,10 @@
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.conversion.ExtraParameter;
import com.android.tools.r8.ir.conversion.ExtraUnusedNullParameter;
-import com.android.tools.r8.ir.optimize.info.CallSiteOptimizationInfo;
-import com.android.tools.r8.ir.optimize.info.ConcreteCallSiteOptimizationInfo;
+import com.android.tools.r8.ir.optimize.info.MethodOptimizationInfoFixer;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.ConsumerUtils;
+import com.android.tools.r8.utils.IntObjConsumer;
import com.android.tools.r8.utils.IteratorUtils;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Ordering;
@@ -32,7 +32,6 @@
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
-import java.util.function.Function;
public class RewrittenPrototypeDescription {
@@ -201,6 +200,12 @@
assert newType == rewrittenTypeInfo.oldType;
return new RewrittenTypeInfo(oldType, rewrittenTypeInfo.newType);
}
+
+ public boolean verifyIsDueToUnboxing(DexItemFactory dexItemFactory) {
+ assert oldType.toBaseType(dexItemFactory).isClassType();
+ assert newType.toBaseType(dexItemFactory).isIntType();
+ return true;
+ }
}
public static class ArgumentInfoCollection {
@@ -224,6 +229,12 @@
return EMPTY;
}
+ public void forEach(IntObjConsumer<ArgumentInfo> consumer) {
+ for (Entry<ArgumentInfo> entry : argumentInfos.int2ReferenceEntrySet()) {
+ consumer.accept(entry.getIntKey(), entry.getValue());
+ }
+ }
+
public IntSortedSet getKeys() {
return argumentInfos.keySet();
}
@@ -247,6 +258,10 @@
return removedParameterIndices;
}
+ public boolean isArgumentRemoved(int argumentIndex) {
+ return getArgumentInfo(argumentIndex).isRemovedArgumentInfo();
+ }
+
public boolean isEmpty() {
return this == EMPTY;
}
@@ -274,6 +289,10 @@
return removed;
}
+ public boolean hasArgumentInfo(int argumentIndex) {
+ return argumentInfos.containsKey(argumentIndex);
+ }
+
public ArgumentInfo getArgumentInfo(int argumentIndex) {
return argumentInfos.getOrDefault(argumentIndex, ArgumentInfo.NO_INFO);
}
@@ -290,12 +309,13 @@
private Int2ReferenceSortedMap<ArgumentInfo> argumentInfos;
- public void addArgumentInfo(int argIndex, ArgumentInfo argInfo) {
+ public Builder addArgumentInfo(int argIndex, ArgumentInfo argInfo) {
if (argumentInfos == null) {
argumentInfos = new Int2ReferenceRBTreeMap<>();
}
assert !argumentInfos.containsKey(argIndex);
argumentInfos.put(argIndex, argInfo);
+ return this;
}
public ArgumentInfoCollection build() {
@@ -392,12 +412,16 @@
return Integer.MAX_VALUE;
}
- public Function<ConcreteCallSiteOptimizationInfo, ? extends CallSiteOptimizationInfo>
- createCallSiteOptimizationInfoFixer() {
- return callSiteOptimizationInfo ->
- callSiteOptimizationInfo.fixupAfterParameterRemoval(getRemovedParameterIndices());
+ public MethodOptimizationInfoFixer createMethodOptimizationInfoFixer() {
+ RewrittenPrototypeDescription prototypeChanges =
+ RewrittenPrototypeDescription.create(Collections.emptyList(), null, this);
+ return prototypeChanges.createMethodOptimizationInfoFixer();
}
+ /**
+ * Returns a function for rewriting the parameter annotations on a method info after prototype
+ * changes were made.
+ */
public Consumer<DexEncodedMethod.Builder> createParameterAnnotationsRemover(
DexEncodedMethod method) {
if (numberOfRemovedArguments() > 0 && !method.parameterAnnotationsList.isEmpty()) {
@@ -483,6 +507,10 @@
return NONE;
}
+ public MethodOptimizationInfoFixer createMethodOptimizationInfoFixer() {
+ return new RewrittenPrototypeDescriptionMethodOptimizationInfoFixer(this);
+ }
+
public RewrittenPrototypeDescription combine(RewrittenPrototypeDescription other) {
if (isEmpty()) {
return other;
@@ -514,6 +542,10 @@
&& argumentInfoCollection.isEmpty();
}
+ public boolean hasExtraParameters() {
+ return !extraParameters.isEmpty();
+ }
+
public List<ExtraParameter> getExtraParameters() {
return extraParameters;
}
diff --git a/src/main/java/com/android/tools/r8/graph/RewrittenPrototypeDescriptionMethodOptimizationInfoFixer.java b/src/main/java/com/android/tools/r8/graph/RewrittenPrototypeDescriptionMethodOptimizationInfoFixer.java
new file mode 100644
index 0000000..265d050
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/graph/RewrittenPrototypeDescriptionMethodOptimizationInfoFixer.java
@@ -0,0 +1,170 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.graph;
+
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfo;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
+import com.android.tools.r8.ir.analysis.inlining.SimpleInliningConstraint;
+import com.android.tools.r8.ir.analysis.inlining.SimpleInliningConstraintFactory;
+import com.android.tools.r8.ir.optimize.classinliner.constraint.ClassInlinerMethodConstraint;
+import com.android.tools.r8.ir.optimize.enums.classification.EnumUnboxerMethodClassification;
+import com.android.tools.r8.ir.optimize.info.CallSiteOptimizationInfo;
+import com.android.tools.r8.ir.optimize.info.ConcreteCallSiteOptimizationInfo;
+import com.android.tools.r8.ir.optimize.info.MethodOptimizationInfoFixer;
+import com.android.tools.r8.ir.optimize.info.bridge.BridgeInfo;
+import com.android.tools.r8.ir.optimize.info.bridge.VirtualBridgeInfo;
+import com.android.tools.r8.ir.optimize.info.initializer.InstanceInitializerInfoCollection;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import java.util.BitSet;
+
+public class RewrittenPrototypeDescriptionMethodOptimizationInfoFixer
+ extends MethodOptimizationInfoFixer {
+
+ private final RewrittenPrototypeDescription prototypeChanges;
+
+ public RewrittenPrototypeDescriptionMethodOptimizationInfoFixer(
+ RewrittenPrototypeDescription prototypeChanges) {
+ this.prototypeChanges = prototypeChanges;
+ }
+
+ private ArgumentInfoCollection getArgumentInfoCollection() {
+ return prototypeChanges.getArgumentInfoCollection();
+ }
+
+ /**
+ * Function for rewriting the bridge info on a piece of method optimization info after prototype
+ * changes were made.
+ */
+ @Override
+ public BridgeInfo fixupBridgeInfo(VirtualBridgeInfo bridgeInfo) {
+ if (getArgumentInfoCollection().isEmpty()) {
+ return bridgeInfo;
+ }
+ return null;
+ }
+
+ /**
+ * Function for rewriting the call site optimization info on a method after prototype changes were
+ * made.
+ */
+ @Override
+ public CallSiteOptimizationInfo fixupCallSiteOptimizationInfo(
+ ConcreteCallSiteOptimizationInfo callSiteOptimizationInfo) {
+ if (prototypeChanges.isEmpty()) {
+ return callSiteOptimizationInfo;
+ }
+ return callSiteOptimizationInfo.fixupAfterParametersChanged(prototypeChanges);
+ }
+
+ /**
+ * Function for rewriting the class inliner method constraint on a piece of method optimization
+ * info after prototype changes were made.
+ */
+ @Override
+ public ClassInlinerMethodConstraint fixupClassInlinerMethodConstraint(
+ AppView<AppInfoWithLiveness> appView,
+ ClassInlinerMethodConstraint classInlinerMethodConstraint) {
+ if (getArgumentInfoCollection().isEmpty()) {
+ return classInlinerMethodConstraint;
+ }
+ return classInlinerMethodConstraint.fixupAfterParametersChanged(
+ appView, getArgumentInfoCollection());
+ }
+
+ /**
+ * Function for rewriting the enum unboxer method classification on a piece of method optimization
+ * info after prototype changes were made.
+ */
+ @Override
+ public EnumUnboxerMethodClassification fixupEnumUnboxerMethodClassification(
+ EnumUnboxerMethodClassification classification) {
+ if (getArgumentInfoCollection().isEmpty()) {
+ return classification;
+ }
+ return classification.fixupAfterParametersChanged(getArgumentInfoCollection());
+ }
+
+ /**
+ * Function for rewriting the instance initializer information on a piece of method optimization
+ * info after prototype changes were made.
+ */
+ @Override
+ public InstanceInitializerInfoCollection fixupInstanceInitializerInfo(
+ AppView<AppInfoWithLiveness> appView,
+ InstanceInitializerInfoCollection instanceInitializerInfo) {
+ if (getArgumentInfoCollection().isEmpty()) {
+ return instanceInitializerInfo;
+ }
+ return instanceInitializerInfo.fixupAfterParametersChanged(
+ appView, getArgumentInfoCollection());
+ }
+
+ /**
+ * Function for rewriting the non-null-param-on-normal-exits information on a piece of method
+ * optimization info after prototype changes were made.
+ */
+ @Override
+ public BitSet fixupNonNullParamOnNormalExits(BitSet nonNullParamOnNormalExits) {
+ return fixupNonNullParamInfo(nonNullParamOnNormalExits);
+ }
+
+ /**
+ * Function for rewriting the non-null-param-or-throw information on a piece of method
+ * optimization info after prototype changes were made.
+ */
+ @Override
+ public BitSet fixupNonNullParamOrThrow(BitSet nonNullParamOrThrow) {
+ return fixupNonNullParamInfo(nonNullParamOrThrow);
+ }
+
+ private BitSet fixupNonNullParamInfo(BitSet nonNullParamInfo) {
+ if (getArgumentInfoCollection().isEmpty() || nonNullParamInfo == null) {
+ return nonNullParamInfo;
+ }
+ int n = nonNullParamInfo.length();
+ BitSet rewrittenNonNullParamOnNormalExits = new BitSet(n);
+ for (int argumentIndex = 0; argumentIndex < n; argumentIndex++) {
+ if (!nonNullParamInfo.get(argumentIndex)) {
+ continue;
+ }
+ ArgumentInfo argumentInfo = getArgumentInfoCollection().getArgumentInfo(argumentIndex);
+ if (argumentInfo.isRemovedArgumentInfo() || argumentInfo.isRewrittenTypeInfo()) {
+ continue;
+ }
+ rewrittenNonNullParamOnNormalExits.set(
+ getArgumentInfoCollection().getNewArgumentIndex(argumentIndex));
+ }
+ return rewrittenNonNullParamOnNormalExits.isEmpty() ? null : rewrittenNonNullParamOnNormalExits;
+ }
+
+ /**
+ * Function for rewriting the returned argument information on a piece of method optimization info
+ * after prototype changes were made.
+ */
+ @Override
+ public int fixupReturnedArgumentIndex(int returnedArgumentIndex) {
+ if (getArgumentInfoCollection().isEmpty() || returnedArgumentIndex < 0) {
+ return returnedArgumentIndex;
+ }
+ return getArgumentInfoCollection().isArgumentRemoved(returnedArgumentIndex)
+ ? -1
+ : getArgumentInfoCollection().getNewArgumentIndex(returnedArgumentIndex);
+ }
+
+ /**
+ * Function for rewriting the simple inlining constraint on a piece of method optimization info
+ * after prototype changes were made.
+ */
+ @Override
+ public SimpleInliningConstraint fixupSimpleInliningConstraint(
+ AppView<AppInfoWithLiveness> appView,
+ SimpleInliningConstraint constraint,
+ SimpleInliningConstraintFactory factory) {
+ if (getArgumentInfoCollection().isEmpty()) {
+ return constraint;
+ }
+ return constraint.fixupAfterParametersChanged(appView, getArgumentInfoCollection(), factory);
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/AbstractFieldSet.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/AbstractFieldSet.java
index a5977df..b6ac534 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/AbstractFieldSet.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/AbstractFieldSet.java
@@ -8,6 +8,8 @@
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.PrunedItems;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
/**
* Implements a lifted subset lattice for fields.
@@ -71,6 +73,9 @@
return lessThanOrEqual(other) && !equals(other);
}
+ public abstract AbstractFieldSet fixupReadSetAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView, ArgumentInfoCollection argumentInfoCollection);
+
public abstract AbstractFieldSet rewrittenWithLens(
AppView<?> appView, GraphLens lens, PrunedItems prunedItems);
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/ConcreteMutableFieldSet.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/ConcreteMutableFieldSet.java
index cdb9eb9..757e426 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/ConcreteMutableFieldSet.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/ConcreteMutableFieldSet.java
@@ -10,6 +10,8 @@
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.PrunedItems;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.SetUtils;
import com.google.common.collect.Sets;
@@ -70,6 +72,22 @@
}
@Override
+ public AbstractFieldSet fixupReadSetAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView, ArgumentInfoCollection argumentInfoCollection) {
+ assert !isEmpty();
+
+ if (argumentInfoCollection.isEmpty()) {
+ return this;
+ }
+
+ // Find the new field gets that are introduced as a result of constant parameter removal.
+ AbstractFieldSet newReadSet =
+ EmptyFieldSet.getInstance()
+ .fixupReadSetAfterParametersChanged(appView, argumentInfoCollection);
+ return newReadSet.isEmpty() ? this : newReadSet.asConcreteFieldSet().addAll(this);
+ }
+
+ @Override
public AbstractFieldSet rewrittenWithLens(
AppView<?> appView, GraphLens lens, PrunedItems prunedItems) {
assert !isEmpty();
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/EmptyFieldSet.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/EmptyFieldSet.java
index d5d694f..78fa9c0 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/EmptyFieldSet.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/EmptyFieldSet.java
@@ -8,6 +8,9 @@
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.PrunedItems;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.RemovedArgumentInfo;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
public class EmptyFieldSet extends AbstractFieldSet implements KnownFieldSet {
@@ -40,6 +43,35 @@
}
@Override
+ public AbstractFieldSet fixupReadSetAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView, ArgumentInfoCollection argumentInfoCollection) {
+ if (argumentInfoCollection.isEmpty()) {
+ return this;
+ }
+
+ // Find the new field gets that are introduced as a result of constant parameter removal.
+ ConcreteMutableFieldSet newReadSet = new ConcreteMutableFieldSet();
+ argumentInfoCollection.forEach(
+ (argumentIndex, argumentInfo) -> {
+ if (argumentInfo.isRemovedArgumentInfo()) {
+ RemovedArgumentInfo removedArgumentInfo = argumentInfo.asRemovedArgumentInfo();
+ if (removedArgumentInfo.hasSingleValue()
+ && removedArgumentInfo.getSingleValue().isSingleFieldValue()) {
+ DexEncodedField definition =
+ removedArgumentInfo.getSingleValue().asSingleFieldValue().getField(appView);
+ if (definition != null) {
+ newReadSet.add(definition);
+ } else {
+ assert false;
+ }
+ }
+ }
+ });
+
+ return newReadSet.isEmpty() ? this : newReadSet;
+ }
+
+ @Override
public AbstractFieldSet rewrittenWithLens(
AppView<?> appView, GraphLens lens, PrunedItems prunedItems) {
return this;
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/UnknownFieldSet.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/UnknownFieldSet.java
index 32ddba9..5de960d 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/UnknownFieldSet.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/UnknownFieldSet.java
@@ -8,6 +8,8 @@
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.PrunedItems;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
public class UnknownFieldSet extends AbstractFieldSet {
@@ -35,6 +37,12 @@
}
@Override
+ public AbstractFieldSet fixupReadSetAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView, ArgumentInfoCollection argumentInfoCollection) {
+ return this;
+ }
+
+ @Override
public AbstractFieldSet rewrittenWithLens(
AppView<?> appView, GraphLens lens, PrunedItems prunedItems) {
return this;
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/inlining/AlwaysSimpleInliningConstraint.java b/src/main/java/com/android/tools/r8/ir/analysis/inlining/AlwaysSimpleInliningConstraint.java
index 93cdb16..9180568 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/inlining/AlwaysSimpleInliningConstraint.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/inlining/AlwaysSimpleInliningConstraint.java
@@ -4,8 +4,10 @@
package com.android.tools.r8.ir.analysis.inlining;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.code.InvokeMethod;
-import it.unimi.dsi.fastutil.ints.IntList;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
/** Constraint that is always satisfied. */
public class AlwaysSimpleInliningConstraint extends SimpleInliningConstraint {
@@ -30,14 +32,10 @@
}
@Override
- public SimpleInliningConstraint fixupAfterRemovingThisParameter(
+ public SimpleInliningConstraint fixupAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView,
+ ArgumentInfoCollection changes,
SimpleInliningConstraintFactory factory) {
return this;
}
-
- @Override
- public SimpleInliningConstraint rewrittenWithUnboxedArguments(
- IntList unboxedArgumentIndices, SimpleInliningConstraintFactory factory) {
- return this;
- }
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/inlining/EqualToBooleanSimpleInliningConstraint.java b/src/main/java/com/android/tools/r8/ir/analysis/inlining/EqualToBooleanSimpleInliningConstraint.java
index dae3231..9a400ae 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/inlining/EqualToBooleanSimpleInliningConstraint.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/inlining/EqualToBooleanSimpleInliningConstraint.java
@@ -4,10 +4,14 @@
package com.android.tools.r8.ir.analysis.inlining;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.RemovedArgumentInfo;
+import com.android.tools.r8.ir.analysis.value.SingleValue;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InvokeMethod;
import com.android.tools.r8.ir.code.Value;
-import it.unimi.dsi.fastutil.ints.IntList;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
/** Constraint that is satisfied if a specific argument is always true. */
public class EqualToBooleanSimpleInliningConstraint extends SimpleInliningArgumentConstraint {
@@ -26,6 +30,30 @@
}
@Override
+ public SimpleInliningConstraint fixupAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView,
+ ArgumentInfoCollection changes,
+ SimpleInliningConstraintFactory factory) {
+ if (changes.isArgumentRemoved(getArgumentIndex())) {
+ RemovedArgumentInfo removedArgumentInfo =
+ changes.getArgumentInfo(getArgumentIndex()).asRemovedArgumentInfo();
+ if (!removedArgumentInfo.hasSingleValue()) {
+ // We should never have constraints for unused arguments.
+ assert false;
+ return NeverSimpleInliningConstraint.getInstance();
+ }
+ SingleValue singleValue = removedArgumentInfo.getSingleValue();
+ return singleValue.isSingleNumberValue()
+ && singleValue.asSingleNumberValue().getBooleanValue() == value
+ ? AlwaysSimpleInliningConstraint.getInstance()
+ : NeverSimpleInliningConstraint.getInstance();
+ } else {
+ assert !changes.hasArgumentInfo(getArgumentIndex());
+ }
+ return withArgumentIndex(changes.getNewArgumentIndex(getArgumentIndex()), factory);
+ }
+
+ @Override
public boolean isSatisfied(InvokeMethod invoke) {
Value argumentRoot = getArgument(invoke).getAliasedValue();
return argumentRoot.isDefinedByInstructionSatisfying(Instruction::isConstNumber)
@@ -33,12 +61,6 @@
}
@Override
- public SimpleInliningConstraint rewrittenWithUnboxedArguments(
- IntList unboxedArgumentIndices, SimpleInliningConstraintFactory factory) {
- return this;
- }
-
- @Override
SimpleInliningArgumentConstraint withArgumentIndex(
int argumentIndex, SimpleInliningConstraintFactory factory) {
return factory.createEqualToBooleanConstraint(argumentIndex, value);
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/inlining/NeverSimpleInliningConstraint.java b/src/main/java/com/android/tools/r8/ir/analysis/inlining/NeverSimpleInliningConstraint.java
index 809dbb9..d786e67 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/inlining/NeverSimpleInliningConstraint.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/inlining/NeverSimpleInliningConstraint.java
@@ -4,8 +4,10 @@
package com.android.tools.r8.ir.analysis.inlining;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.code.InvokeMethod;
-import it.unimi.dsi.fastutil.ints.IntList;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
/** Constraint that is never satisfied. */
public class NeverSimpleInliningConstraint extends SimpleInliningConstraint {
@@ -29,14 +31,10 @@
}
@Override
- public SimpleInliningConstraint fixupAfterRemovingThisParameter(
+ public SimpleInliningConstraint fixupAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView,
+ ArgumentInfoCollection changes,
SimpleInliningConstraintFactory factory) {
return this;
}
-
- @Override
- public SimpleInliningConstraint rewrittenWithUnboxedArguments(
- IntList unboxedArgumentIndices, SimpleInliningConstraintFactory factory) {
- return this;
- }
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/inlining/NullSimpleInliningConstraint.java b/src/main/java/com/android/tools/r8/ir/analysis/inlining/NullSimpleInliningConstraint.java
index 13cc5b9..bb4f505 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/inlining/NullSimpleInliningConstraint.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/inlining/NullSimpleInliningConstraint.java
@@ -4,12 +4,17 @@
package com.android.tools.r8.ir.analysis.inlining;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfo;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.RemovedArgumentInfo;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.RewrittenTypeInfo;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InvokeMethod;
import com.android.tools.r8.ir.code.Value;
-import it.unimi.dsi.fastutil.ints.IntList;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
/** Constraint that is satisfied if a specific argument is always null. */
public class NullSimpleInliningConstraint extends SimpleInliningArgumentConstraint {
@@ -29,6 +34,35 @@
}
@Override
+ public SimpleInliningConstraint fixupAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView,
+ ArgumentInfoCollection changes,
+ SimpleInliningConstraintFactory factory) {
+ ArgumentInfo argumentInfo = changes.getArgumentInfo(getArgumentIndex());
+ if (argumentInfo.isRemovedArgumentInfo()) {
+ RemovedArgumentInfo removedArgumentInfo =
+ changes.getArgumentInfo(getArgumentIndex()).asRemovedArgumentInfo();
+ if (!removedArgumentInfo.hasSingleValue()) {
+ // We should never have constraints for unused arguments.
+ assert false;
+ return NeverSimpleInliningConstraint.getInstance();
+ }
+ return removedArgumentInfo.getSingleValue().isNull() && nullability.isDefinitelyNull()
+ ? AlwaysSimpleInliningConstraint.getInstance()
+ : NeverSimpleInliningConstraint.getInstance();
+ } else if (argumentInfo.isRewrittenTypeInfo()) {
+ RewrittenTypeInfo rewrittenTypeInfo = argumentInfo.asRewrittenTypeInfo();
+ // We should only get here as a result of enum unboxing.
+ assert rewrittenTypeInfo.verifyIsDueToUnboxing(appView.dexItemFactory());
+ // Rewrite definitely-null constraints to definitely-zero constraints.
+ return nullability.isDefinitelyNull()
+ ? factory.createEqualToNumberConstraint(getArgumentIndex(), 0)
+ : factory.createNotEqualToNumberConstraint(getArgumentIndex(), 0);
+ }
+ return withArgumentIndex(changes.getNewArgumentIndex(getArgumentIndex()), factory);
+ }
+
+ @Override
public final boolean isSatisfied(InvokeMethod invoke) {
Value argument = getArgument(invoke);
TypeElement argumentType = argument.getType();
@@ -47,17 +81,6 @@
}
@Override
- public SimpleInliningConstraint rewrittenWithUnboxedArguments(
- IntList unboxedArgumentIndices, SimpleInliningConstraintFactory factory) {
- if (unboxedArgumentIndices.contains(getArgumentIndex())) {
- return nullability.isDefinitelyNull()
- ? factory.createEqualToNumberConstraint(getArgumentIndex(), 0)
- : factory.createNotEqualToNumberConstraint(getArgumentIndex(), 0);
- }
- return this;
- }
-
- @Override
SimpleInliningArgumentConstraint withArgumentIndex(
int argumentIndex, SimpleInliningConstraintFactory factory) {
return factory.createNullConstraint(argumentIndex, nullability);
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/inlining/NumberSimpleInliningConstraint.java b/src/main/java/com/android/tools/r8/ir/analysis/inlining/NumberSimpleInliningConstraint.java
index 4f6ee2c..23b6233 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/inlining/NumberSimpleInliningConstraint.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/inlining/NumberSimpleInliningConstraint.java
@@ -4,10 +4,14 @@
package com.android.tools.r8.ir.analysis.inlining;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.RemovedArgumentInfo;
+import com.android.tools.r8.ir.analysis.value.SingleValue;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InvokeMethod;
import com.android.tools.r8.ir.code.Value;
-import it.unimi.dsi.fastutil.ints.IntList;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
public abstract class NumberSimpleInliningConstraint extends SimpleInliningArgumentConstraint {
@@ -23,6 +27,29 @@
}
@Override
+ public SimpleInliningConstraint fixupAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView,
+ ArgumentInfoCollection changes,
+ SimpleInliningConstraintFactory factory) {
+ if (changes.isArgumentRemoved(getArgumentIndex())) {
+ RemovedArgumentInfo removedArgumentInfo =
+ changes.getArgumentInfo(getArgumentIndex()).asRemovedArgumentInfo();
+ if (!removedArgumentInfo.hasSingleValue()) {
+ // We should never have constraints for unused arguments.
+ assert false;
+ return NeverSimpleInliningConstraint.getInstance();
+ }
+ SingleValue singleValue = removedArgumentInfo.getSingleValue();
+ return singleValue.isSingleNumberValue() && test(singleValue.asSingleNumberValue().getValue())
+ ? AlwaysSimpleInliningConstraint.getInstance()
+ : NeverSimpleInliningConstraint.getInstance();
+ } else {
+ assert !changes.hasArgumentInfo(getArgumentIndex());
+ }
+ return withArgumentIndex(changes.getNewArgumentIndex(getArgumentIndex()), factory);
+ }
+
+ @Override
public final boolean isSatisfied(InvokeMethod invoke) {
Value argumentRoot = getArgument(invoke).getAliasedValue();
return argumentRoot.isDefinedByInstructionSatisfying(Instruction::isConstNumber)
@@ -30,10 +57,4 @@
}
abstract boolean test(long argumentValue);
-
- @Override
- public final SimpleInliningConstraint rewrittenWithUnboxedArguments(
- IntList unboxedArgumentIndices, SimpleInliningConstraintFactory factory) {
- return this;
- }
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningArgumentConstraint.java b/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningArgumentConstraint.java
index 78bf329..8583b96 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningArgumentConstraint.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningArgumentConstraint.java
@@ -15,13 +15,6 @@
this.argumentIndex = argumentIndex;
}
- @Override
- public final SimpleInliningConstraint fixupAfterRemovingThisParameter(
- SimpleInliningConstraintFactory factory) {
- assert getArgumentIndex() > 0;
- return withArgumentIndex(getArgumentIndex() - 1, factory);
- }
-
Value getArgument(InvokeMethod invoke) {
return invoke.getArgument(argumentIndex);
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraint.java b/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraint.java
index c9978cb..64e6f44 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraint.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraint.java
@@ -4,9 +4,11 @@
package com.android.tools.r8.ir.analysis.inlining;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.code.InvokeMethod;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.google.common.collect.ImmutableList;
-import it.unimi.dsi.fastutil.ints.IntList;
import java.util.function.Supplier;
public abstract class SimpleInliningConstraint {
@@ -90,9 +92,8 @@
return new SimpleInliningConstraintDisjunction(ImmutableList.of(this, other));
}
- public abstract SimpleInliningConstraint fixupAfterRemovingThisParameter(
+ public abstract SimpleInliningConstraint fixupAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView,
+ ArgumentInfoCollection changes,
SimpleInliningConstraintFactory factory);
-
- public abstract SimpleInliningConstraint rewrittenWithUnboxedArguments(
- IntList unboxedArgumentIndices, SimpleInliningConstraintFactory factory);
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraintConjunction.java b/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraintConjunction.java
index ae2e07b..55da1c0 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraintConjunction.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraintConjunction.java
@@ -4,10 +4,13 @@
package com.android.tools.r8.ir.analysis.inlining;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.code.InvokeMethod;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.ListUtils;
import com.google.common.collect.ImmutableList;
-import it.unimi.dsi.fastutil.ints.IntList;
+import com.google.common.collect.Iterables;
import java.util.List;
public class SimpleInliningConstraintConjunction extends SimpleInliningConstraint {
@@ -66,26 +69,40 @@
}
@Override
- public SimpleInliningConstraint fixupAfterRemovingThisParameter(
+ public SimpleInliningConstraint fixupAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView,
+ ArgumentInfoCollection changes,
SimpleInliningConstraintFactory factory) {
List<SimpleInliningConstraint> rewrittenConstraints =
ListUtils.mapOrElse(
- constraints, constraint -> constraint.fixupAfterRemovingThisParameter(factory), null);
- return rewrittenConstraints != null
- ? new SimpleInliningConstraintConjunction(rewrittenConstraints)
- : this;
- }
-
- @Override
- public SimpleInliningConstraint rewrittenWithUnboxedArguments(
- IntList unboxedArgumentIndices, SimpleInliningConstraintFactory factory) {
- List<SimpleInliningConstraint> rewrittenConstraints =
- ListUtils.mapOrElse(
constraints,
- constraint -> constraint.rewrittenWithUnboxedArguments(unboxedArgumentIndices, factory),
+ constraint -> {
+ SimpleInliningConstraint rewrittenConstraint =
+ constraint.fixupAfterParametersChanged(appView, changes, factory);
+ if (rewrittenConstraint.isAlways()) {
+ // Remove 'always' from conjunctions.
+ return null;
+ }
+ return rewrittenConstraint;
+ },
null);
- return rewrittenConstraints != null
- ? new SimpleInliningConstraintConjunction(rewrittenConstraints)
- : this;
+
+ if (rewrittenConstraints == null) {
+ return this;
+ }
+
+ if (rewrittenConstraints.isEmpty()) {
+ return AlwaysSimpleInliningConstraint.getInstance();
+ }
+
+ if (rewrittenConstraints.size() == 1) {
+ return ListUtils.first(rewrittenConstraints);
+ }
+
+ if (Iterables.any(rewrittenConstraints, SimpleInliningConstraint::isNever)) {
+ return NeverSimpleInliningConstraint.getInstance();
+ }
+
+ return new SimpleInliningConstraintConjunction(rewrittenConstraints);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraintDisjunction.java b/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraintDisjunction.java
index 42bcaf6..0ac0ced 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraintDisjunction.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraintDisjunction.java
@@ -4,10 +4,13 @@
package com.android.tools.r8.ir.analysis.inlining;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.code.InvokeMethod;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.ListUtils;
import com.google.common.collect.ImmutableList;
-import it.unimi.dsi.fastutil.ints.IntList;
+import com.google.common.collect.Iterables;
import java.util.List;
public class SimpleInliningConstraintDisjunction extends SimpleInliningConstraint {
@@ -66,26 +69,40 @@
}
@Override
- public SimpleInliningConstraint fixupAfterRemovingThisParameter(
+ public SimpleInliningConstraint fixupAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView,
+ ArgumentInfoCollection changes,
SimpleInliningConstraintFactory factory) {
List<SimpleInliningConstraint> rewrittenConstraints =
ListUtils.mapOrElse(
- constraints, constraint -> constraint.fixupAfterRemovingThisParameter(factory), null);
- return rewrittenConstraints != null
- ? new SimpleInliningConstraintDisjunction(rewrittenConstraints)
- : this;
- }
-
- @Override
- public SimpleInliningConstraint rewrittenWithUnboxedArguments(
- IntList unboxedArgumentIndices, SimpleInliningConstraintFactory factory) {
- List<SimpleInliningConstraint> rewrittenConstraints =
- ListUtils.mapOrElse(
constraints,
- constraint -> constraint.rewrittenWithUnboxedArguments(unboxedArgumentIndices, factory),
+ constraint -> {
+ SimpleInliningConstraint rewrittenConstraint =
+ constraint.fixupAfterParametersChanged(appView, changes, factory);
+ if (rewrittenConstraint.isNever()) {
+ // Remove 'never' from disjunctions.
+ return null;
+ }
+ return rewrittenConstraint;
+ },
null);
- return rewrittenConstraints != null
- ? new SimpleInliningConstraintDisjunction(rewrittenConstraints)
- : this;
+
+ if (rewrittenConstraints == null) {
+ return this;
+ }
+
+ if (rewrittenConstraints.isEmpty()) {
+ return NeverSimpleInliningConstraint.getInstance();
+ }
+
+ if (rewrittenConstraints.size() == 1) {
+ return ListUtils.first(rewrittenConstraints);
+ }
+
+ if (Iterables.any(rewrittenConstraints, SimpleInliningConstraint::isAlways)) {
+ return AlwaysSimpleInliningConstraint.getInstance();
+ }
+
+ return new SimpleInliningConstraintDisjunction(rewrittenConstraints);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleConstClassValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleConstClassValue.java
index 3352cf7..c9bcee0 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleConstClassValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleConstClassValue.java
@@ -15,12 +15,14 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.ConstClass;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.NumberGenerator;
import com.android.tools.r8.ir.code.TypeAndLocalInfoSupplier;
import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfo;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
public class SingleConstClassValue extends SingleConstValue {
@@ -109,6 +111,12 @@
}
@Override
+ public InstanceFieldInitializationInfo fixupAfterParametersChanged(
+ ArgumentInfoCollection argumentInfoCollection) {
+ return this;
+ }
+
+ @Override
public SingleValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLens lens) {
assert lens.lookupType(type) == type;
return this;
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleDexItemBasedStringValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleDexItemBasedStringValue.java
index a537863..f1fac36 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleDexItemBasedStringValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleDexItemBasedStringValue.java
@@ -13,12 +13,14 @@
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.DexItemBasedConstString;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.NumberGenerator;
import com.android.tools.r8.ir.code.TypeAndLocalInfoSupplier;
import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfo;
import com.android.tools.r8.naming.dexitembasedstring.NameComputationInfo;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.Objects;
@@ -106,6 +108,12 @@
}
@Override
+ public InstanceFieldInitializationInfo fixupAfterParametersChanged(
+ ArgumentInfoCollection argumentInfoCollection) {
+ return this;
+ }
+
+ @Override
public SingleValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLens lens) {
return appView
.abstractValueFactory()
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleFieldValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleFieldValue.java
index de0be6d..530bfc4 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleFieldValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleFieldValue.java
@@ -9,12 +9,14 @@
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.FieldResolutionResult.SuccessfulFieldResolutionResult;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.Instruction;
@@ -23,6 +25,7 @@
import com.android.tools.r8.ir.code.TypeAndLocalInfoSupplier;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.ir.optimize.enums.EnumDataMap;
+import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfo;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
public abstract class SingleFieldValue extends SingleValue {
@@ -37,6 +40,11 @@
return field;
}
+ public DexEncodedField getField(DexDefinitionSupplier definitions) {
+ DexClass holder = definitions.definitionFor(field.getHolderType());
+ return field.lookupOnClass(holder);
+ }
+
public abstract ObjectState getState();
public boolean mayHaveFinalizeMethodDirectlyOrIndirectly(AppView<AppInfoWithLiveness> appView) {
@@ -105,6 +113,12 @@
}
@Override
+ public InstanceFieldInitializationInfo fixupAfterParametersChanged(
+ ArgumentInfoCollection argumentInfoCollection) {
+ return this;
+ }
+
+ @Override
public SingleValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLens lens) {
AbstractValueFactory factory = appView.abstractValueFactory();
if (field.holder == field.type) {
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleNumberValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleNumberValue.java
index c01133e..264bec5 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleNumberValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleNumberValue.java
@@ -9,12 +9,14 @@
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.ConstNumber;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.NumberGenerator;
import com.android.tools.r8.ir.code.TypeAndLocalInfoSupplier;
import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfo;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.ArrayUtils;
import com.android.tools.r8.utils.OptionalBool;
@@ -152,6 +154,12 @@
}
@Override
+ public InstanceFieldInitializationInfo fixupAfterParametersChanged(
+ ArgumentInfoCollection argumentInfoCollection) {
+ return this;
+ }
+
+ @Override
public SingleValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLens lens) {
return this;
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleStringValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleStringValue.java
index 35acae4..f346b24 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleStringValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleStringValue.java
@@ -13,12 +13,14 @@
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.ConstString;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.NumberGenerator;
import com.android.tools.r8.ir.code.TypeAndLocalInfoSupplier;
import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfo;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
public class SingleStringValue extends SingleConstValue {
@@ -93,6 +95,12 @@
}
@Override
+ public InstanceFieldInitializationInfo fixupAfterParametersChanged(
+ ArgumentInfoCollection argumentInfoCollection) {
+ return this;
+ }
+
+ @Override
public SingleValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLens lens) {
return this;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Value.java b/src/main/java/com/android/tools/r8/ir/code/Value.java
index 0c58032..7b97131 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Value.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Value.java
@@ -832,6 +832,10 @@
return UnknownValue.getInstance();
}
+ if (getType().nullability().isDefinitelyNull()) {
+ return appView.abstractValueFactory().createNullValue();
+ }
+
Value root = getAliasedValue();
if (root.isPhi()) {
return UnknownValue.getInstance();
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CallGraphBuilderBase.java b/src/main/java/com/android/tools/r8/ir/conversion/CallGraphBuilderBase.java
index 1e5a344..2be47ca 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CallGraphBuilderBase.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CallGraphBuilderBase.java
@@ -144,10 +144,11 @@
// We don't care about calls to native methods.
return;
}
- if (appView.appInfo().isPinned(callee.getReference())) {
- // Since the callee is kept, we cannot inline it into the caller, and we also cannot collect
- // any optimization info for the method. Therefore, we drop the call edge to reduce the
- // total number of call graph edges, which should lead to fewer call graph cycles.
+ if (!appView.getKeepInfo(callee).isInliningAllowed(appView.options())) {
+ // Since the callee is kept and optimizations are disallowed, we cannot inline it into the
+ // caller, and we also cannot collect any optimization info for the method. Therefore, we
+ // drop the call edge to reduce the total number of call graph edges, which should lead to
+ // fewer call graph cycles.
return;
}
getOrCreateNode(callee).addCallerConcurrently(currentMethod, likelySpuriousCallEdge);
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index 0235660..5bde78e 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -1288,6 +1288,7 @@
.libraryMethodOptimizer()
.optimize(code, feedback, methodProcessor, methodProcessingContext);
timing.end();
+ previous = printMethod(code, "IR after class library method optimizer (SSA)", previous);
assert code.isConsistentSSA();
}
@@ -1298,6 +1299,7 @@
timing.begin("Devirtualize invoke interface");
devirtualizer.devirtualizeInvokeInterface(code);
timing.end();
+ previous = printMethod(code, "IR after devirtualizer (SSA)", previous);
}
assert code.verifyTypes(appView);
@@ -1374,12 +1376,14 @@
timing.begin("Rewrite throw NPE");
codeRewriter.rewriteThrowNullPointerException(code);
timing.end();
+ previous = printMethod(code, "IR after rewrite throw null (SSA)", previous);
}
timing.begin("Optimize class initializers");
ClassInitializerDefaultsResult classInitializerDefaultsResult =
classInitializerDefaultsOptimization.optimize(code, feedback);
timing.end();
+ previous = printMethod(code, "IR after class initializer optimisation (SSA)", previous);
if (Log.ENABLED) {
Log.debug(getClass(), "Intermediate (SSA) flow graph for %s:\n%s",
@@ -1391,7 +1395,7 @@
deadCodeRemover.run(code, timing);
assert code.isConsistentSSA();
- previous = printMethod(code, "IR after lambda desugaring (SSA)", previous);
+ previous = printMethod(code, "IR after dead code removal (SSA)", previous);
assert code.verifyTypes(appView);
@@ -1572,7 +1576,7 @@
timing.end();
}
- if (appView.getKeepInfo().getMethodInfo(code.context()).isPinned(options)) {
+ if (appView.getKeepInfo(code.context()).isPinned(options)) {
return;
}
@@ -1694,8 +1698,7 @@
|| definition.getOptimizationInfo().isReachabilitySensitive()) {
return false;
}
- if (appView.appInfo().hasLiveness()
- && appView.appInfo().withLiveness().isPinned(method.getReference())) {
+ if (!appView.getKeepInfo(method).isInliningAllowed(options)) {
return false;
}
return true;
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/MethodOptimizationFeedback.java b/src/main/java/com/android/tools/r8/ir/conversion/MethodOptimizationFeedback.java
index 53bb277..13b7140 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/MethodOptimizationFeedback.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/MethodOptimizationFeedback.java
@@ -66,8 +66,6 @@
void setEnumUnboxerMethodClassification(
ProgramMethod method, EnumUnboxerMethodClassification enumUnboxerMethodClassification);
- void unsetEnumUnboxerMethodClassification(ProgramMethod method);
-
void setInstanceInitializerInfoCollection(
DexEncodedMethod method, InstanceInitializerInfoCollection instanceInitializerInfoCollection);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
index c4c281d..9ee3f54 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
@@ -315,9 +315,11 @@
// If the target holder does not resolve we may want to issue diagnostics.
DexClass holder = appView.definitionForHolder(invoke.getMethod(), context);
if (holder == null) {
- // NOTE: leave unchanged those calls to undefined targets. This may lead to runtime
- // exception but we can not report it as error since it can also be the intended
- // behavior.
+ if (invoke.isInvokeVirtual() || invoke.isInvokeInterface()) {
+ // For virtual targets we should not report anything as any virtual dispatch just remains.
+ return DesugarDescription.nothing();
+ }
+ // For static, private and special invokes, they may require desugaring and should warn.
return DesugarDescription.builder()
.addScanEffect(
() -> {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
index 0ddc915..7bf0e38 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
@@ -118,7 +118,7 @@
WhyAreYouNotInliningReporter whyAreYouNotInliningReporter) {
AppInfoWithLiveness appInfo = appView.appInfo();
DexMethod singleTargetReference = singleTarget.getReference();
- if (appInfo.isPinned(singleTargetReference)) {
+ if (!appView.getKeepInfo(singleTarget).isInliningAllowed(appView.options())) {
whyAreYouNotInliningReporter.reportPinned();
return true;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/constraint/AlwaysFalseClassInlinerMethodConstraint.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/constraint/AlwaysFalseClassInlinerMethodConstraint.java
index 6ddae8d..0ceb39e 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/constraint/AlwaysFalseClassInlinerMethodConstraint.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/constraint/AlwaysFalseClassInlinerMethodConstraint.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.analysis.value.ObjectState;
import com.android.tools.r8.ir.optimize.classinliner.analysis.ParameterUsage;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -22,7 +23,8 @@
}
@Override
- public ClassInlinerMethodConstraint fixupAfterRemovingThisParameter() {
+ public ClassInlinerMethodConstraint fixupAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView, ArgumentInfoCollection changes) {
return this;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/constraint/AlwaysTrueClassInlinerMethodConstraint.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/constraint/AlwaysTrueClassInlinerMethodConstraint.java
index dc89cf4..4b8a513 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/constraint/AlwaysTrueClassInlinerMethodConstraint.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/constraint/AlwaysTrueClassInlinerMethodConstraint.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.analysis.value.ObjectState;
import com.android.tools.r8.ir.optimize.classinliner.analysis.ParameterUsage;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -22,7 +23,8 @@
}
@Override
- public ClassInlinerMethodConstraint fixupAfterRemovingThisParameter() {
+ public ClassInlinerMethodConstraint fixupAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView, ArgumentInfoCollection changes) {
return this;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/constraint/ClassInlinerMethodConstraint.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/constraint/ClassInlinerMethodConstraint.java
index 22079fe..ebe34b8 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/constraint/ClassInlinerMethodConstraint.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/constraint/ClassInlinerMethodConstraint.java
@@ -6,13 +6,15 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.analysis.value.ObjectState;
import com.android.tools.r8.ir.optimize.classinliner.analysis.ParameterUsage;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
public interface ClassInlinerMethodConstraint {
- ClassInlinerMethodConstraint fixupAfterRemovingThisParameter();
+ ClassInlinerMethodConstraint fixupAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView, ArgumentInfoCollection changes);
ParameterUsage getParameterUsage(int parameter);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/constraint/ConditionalClassInlinerMethodConstraint.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/constraint/ConditionalClassInlinerMethodConstraint.java
index eb743cb..09a482d 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/constraint/ConditionalClassInlinerMethodConstraint.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/constraint/ConditionalClassInlinerMethodConstraint.java
@@ -9,6 +9,9 @@
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfo;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.RewrittenTypeInfo;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.analysis.value.ObjectState;
import com.android.tools.r8.ir.analysis.value.SingleConstValue;
@@ -32,7 +35,8 @@
}
@Override
- public ClassInlinerMethodConstraint fixupAfterRemovingThisParameter() {
+ public ClassInlinerMethodConstraint fixupAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView, ArgumentInfoCollection changes) {
if (usages.isBottom()) {
return this;
}
@@ -40,10 +44,21 @@
usages
.asNonEmpty()
.forEach(
- (parameter, usagePerContext) -> {
- if (parameter > 0) {
- backing.put(parameter - 1, usagePerContext);
+ (argumentIndex, usagePerContext) -> {
+ ArgumentInfo argumentInfo = changes.getArgumentInfo(argumentIndex);
+ if (argumentInfo.isRemovedArgumentInfo()) {
+ // When removing a parameter from a method, we no longer need information about the
+ // usages of that parameter for class inlining.
+ return;
}
+ if (argumentInfo.isRewrittenTypeInfo()) {
+ // This is due to enum unboxing. After enum unboxing, we no longer need information
+ // about the usages of this parameter for class inlining.
+ RewrittenTypeInfo rewrittenTypeInfo = argumentInfo.asRewrittenTypeInfo();
+ assert rewrittenTypeInfo.verifyIsDueToUnboxing(appView.dexItemFactory());
+ return;
+ }
+ backing.put(changes.getNewArgumentIndex(argumentIndex), usagePerContext);
});
return new ConditionalClassInlinerMethodConstraint(NonEmptyParameterUsages.create(backing));
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingLens.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingLens.java
index c9c7c40..da704c1 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingLens.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingLens.java
@@ -100,7 +100,7 @@
move(from, to, fromStatic, toStatic, 0);
}
- public void move(
+ public RewrittenPrototypeDescription move(
DexMethod from,
DexMethod to,
boolean fromStatic,
@@ -134,10 +134,11 @@
? null
: new RewrittenPrototypeDescription.RewrittenTypeInfo(
from.proto.returnType, to.proto.returnType);
- prototypeChangesPerMethod.put(
- to,
+ RewrittenPrototypeDescription prototypeChanges =
RewrittenPrototypeDescription.createForRewrittenTypes(returnInfo, builder.build())
- .withExtraUnusedNullParameters(numberOfExtraNullParameters));
+ .withExtraUnusedNullParameters(numberOfExtraNullParameters);
+ prototypeChangesPerMethod.put(to, prototypeChanges);
+ return prototypeChanges;
}
void recordCheckNotZeroMethod(
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingTreeFixer.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingTreeFixer.java
index 09dc715..c7bcc37 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingTreeFixer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingTreeFixer.java
@@ -24,7 +24,7 @@
import com.android.tools.r8.graph.ProgramField;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.PrunedItems;
-import com.android.tools.r8.ir.analysis.inlining.SimpleInliningConstraint;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription;
import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.BasicBlock;
@@ -48,7 +48,6 @@
import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfo;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
-import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.ImmutableArrayUtils;
import com.android.tools.r8.utils.OptionalBool;
import com.android.tools.r8.utils.SetUtils;
@@ -56,8 +55,6 @@
import com.android.tools.r8.utils.Timing;
import com.android.tools.r8.utils.collections.ProgramMethodMap;
import com.google.common.collect.Sets;
-import it.unimi.dsi.fastutil.ints.IntArrayList;
-import it.unimi.dsi.fastutil.ints.IntList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.IdentityHashMap;
@@ -516,38 +513,18 @@
newMethod = ensureUniqueMethod(method, newMethod);
int numberOfExtraNullParameters = newMethod.getArity() - method.getReference().getArity();
boolean isStatic = method.isStatic();
- lensBuilder.move(
- method.getReference(), newMethod, isStatic, isStatic, numberOfExtraNullParameters);
+ RewrittenPrototypeDescription prototypeChanges =
+ lensBuilder.move(
+ method.getReference(), newMethod, isStatic, isStatic, numberOfExtraNullParameters);
return method.toTypeSubstitutedMethod(
newMethod,
builder ->
builder
- .fixupCallSiteOptimizationInfo(
- callSiteOptimizationInfo ->
- callSiteOptimizationInfo.fixupAfterExtraNullParameters(
- numberOfExtraNullParameters))
+ .fixupOptimizationInfo(
+ appView, prototypeChanges.createMethodOptimizationInfoFixer())
.setCompilationState(method.getCompilationState())
.setIsLibraryMethodOverrideIf(
- method.isNonPrivateVirtualMethod(), OptionalBool.FALSE)
- .setSimpleInliningConstraint(
- holder, getRewrittenSimpleInliningConstraint(method, oldProto, newProto)));
- }
-
- private SimpleInliningConstraint getRewrittenSimpleInliningConstraint(
- DexEncodedMethod method, DexProto oldProto, DexProto newProto) {
- IntList unboxedArgumentIndices = new IntArrayList();
- int offset = BooleanUtils.intValue(method.isInstance());
- for (int i = 0; i < method.getReference().getArity(); i++) {
- if (oldProto.getParameter(i).isReferenceType()
- && newProto.getParameter(i).isPrimitiveType()) {
- unboxedArgumentIndices.add(i + offset);
- }
- }
- return method
- .getOptimizationInfo()
- .getSimpleInliningConstraint()
- .rewrittenWithUnboxedArguments(
- unboxedArgumentIndices, appView.simpleInliningConstraintFactory());
+ method.isNonPrivateVirtualMethod(), OptionalBool.FALSE));
}
private DexMethod ensureUniqueMethod(DexEncodedMethod encodedMethod, DexMethod newMethod) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/classification/CheckNotNullEnumUnboxerMethodClassification.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/classification/CheckNotNullEnumUnboxerMethodClassification.java
index 1a466ed..e9f1bdb 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/classification/CheckNotNullEnumUnboxerMethodClassification.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/classification/CheckNotNullEnumUnboxerMethodClassification.java
@@ -32,7 +32,7 @@
}
@Override
- public EnumUnboxerMethodClassification fixupAfterParameterRemoval(
+ public EnumUnboxerMethodClassification fixupAfterParametersChanged(
ArgumentInfoCollection removedParameters) {
if (removedParameters.getArgumentInfo(argumentIndex).isRemovedArgumentInfo()) {
// If the null-checked argument is removed from the parameters of the method, then we can no
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/classification/EnumUnboxerMethodClassification.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/classification/EnumUnboxerMethodClassification.java
index 5c93c36..f9192b9 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/classification/EnumUnboxerMethodClassification.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/classification/EnumUnboxerMethodClassification.java
@@ -12,15 +12,9 @@
return UnknownEnumUnboxerMethodClassification.getInstance();
}
- public abstract EnumUnboxerMethodClassification fixupAfterParameterRemoval(
+ public abstract EnumUnboxerMethodClassification fixupAfterParametersChanged(
ArgumentInfoCollection removedParameters);
- public EnumUnboxerMethodClassification fixupAfterRemovingThisParameter() {
- // Only static methods are currently classified by the enum unboxer.
- assert isUnknownClassification();
- return unknown();
- }
-
public boolean isCheckNotNullClassification() {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/classification/UnknownEnumUnboxerMethodClassification.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/classification/UnknownEnumUnboxerMethodClassification.java
index e88239b..04529b4 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/classification/UnknownEnumUnboxerMethodClassification.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/classification/UnknownEnumUnboxerMethodClassification.java
@@ -18,7 +18,7 @@
}
@Override
- public EnumUnboxerMethodClassification fixupAfterParameterRemoval(
+ public EnumUnboxerMethodClassification fixupAfterParametersChanged(
ArgumentInfoCollection removedParameters) {
return this;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/ConcreteCallSiteOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/ConcreteCallSiteOptimizationInfo.java
index a82770c..d598935 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/ConcreteCallSiteOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/ConcreteCallSiteOptimizationInfo.java
@@ -13,6 +13,8 @@
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.analysis.type.DynamicType;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
@@ -26,9 +28,6 @@
import it.unimi.dsi.fastutil.ints.Int2ReferenceArrayMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceMaps;
-import it.unimi.dsi.fastutil.ints.IntArrayList;
-import it.unimi.dsi.fastutil.ints.IntCollection;
-import it.unimi.dsi.fastutil.ints.IntList;
import java.util.List;
// Accumulated optimization info from call sites.
@@ -76,33 +75,37 @@
: this;
}
- public CallSiteOptimizationInfo fixupAfterParameterRemoval(int removedParameterIndex) {
- IntList removedParameterIndices = new IntArrayList(1);
- removedParameterIndices.add(removedParameterIndex);
- return fixupAfterParameterRemoval(removedParameterIndices);
- }
-
- public CallSiteOptimizationInfo fixupAfterParameterRemoval(
- IntCollection removedParameterIndices) {
- if (removedParameterIndices.isEmpty()) {
+ public CallSiteOptimizationInfo fixupAfterParametersChanged(
+ RewrittenPrototypeDescription prototypeChanges) {
+ if (prototypeChanges.isEmpty()) {
return this;
}
- assert removedParameterIndices.stream()
+ ArgumentInfoCollection parameterChanges = prototypeChanges.getArgumentInfoCollection();
+ if (parameterChanges.isEmpty()) {
+ if (prototypeChanges.hasExtraParameters()) {
+ return new ConcreteCallSiteOptimizationInfo(
+ size + prototypeChanges.numberOfExtraParameters(), dynamicUpperBoundTypes, constants);
+ }
+ return this;
+ }
+
+ assert parameterChanges.getRemovedParameterIndices().stream()
.allMatch(removedParameterIndex -> removedParameterIndex < size);
- int newSize = size - removedParameterIndices.size();
- if (newSize == 0) {
+ int newSizeAfterParameterRemoval = size - parameterChanges.numberOfRemovedArguments();
+ if (newSizeAfterParameterRemoval == 0) {
return top();
}
- Int2ReferenceMap<AbstractValue> rewrittenConstants = new Int2ReferenceArrayMap<>(newSize);
+ Int2ReferenceMap<AbstractValue> rewrittenConstants =
+ new Int2ReferenceArrayMap<>(newSizeAfterParameterRemoval);
Int2ReferenceMap<TypeElement> rewrittenDynamicUpperBoundTypes =
- new Int2ReferenceArrayMap<>(newSize);
+ new Int2ReferenceArrayMap<>(newSizeAfterParameterRemoval);
for (int parameterIndex = 0, rewrittenParameterIndex = 0;
parameterIndex < size;
parameterIndex++) {
- if (!removedParameterIndices.contains(parameterIndex)) {
+ if (!parameterChanges.isArgumentRemoved(parameterIndex)) {
AbstractValue abstractValue =
constants.getOrDefault(parameterIndex, AbstractValue.unknown());
if (!abstractValue.isUnknown()) {
@@ -116,7 +119,9 @@
}
}
return ConcreteCallSiteOptimizationInfo.create(
- newSize, rewrittenDynamicUpperBoundTypes, rewrittenConstants);
+ newSizeAfterParameterRemoval + prototypeChanges.numberOfExtraParameters(),
+ rewrittenDynamicUpperBoundTypes,
+ rewrittenConstants);
}
CallSiteOptimizationInfo join(
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoFixer.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoFixer.java
new file mode 100644
index 0000000..58c0f9b
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoFixer.java
@@ -0,0 +1,46 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir.optimize.info;
+
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.ir.analysis.inlining.SimpleInliningConstraint;
+import com.android.tools.r8.ir.analysis.inlining.SimpleInliningConstraintFactory;
+import com.android.tools.r8.ir.optimize.classinliner.constraint.ClassInlinerMethodConstraint;
+import com.android.tools.r8.ir.optimize.enums.classification.EnumUnboxerMethodClassification;
+import com.android.tools.r8.ir.optimize.info.bridge.BridgeInfo;
+import com.android.tools.r8.ir.optimize.info.bridge.VirtualBridgeInfo;
+import com.android.tools.r8.ir.optimize.info.initializer.InstanceInitializerInfoCollection;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import java.util.BitSet;
+
+public abstract class MethodOptimizationInfoFixer {
+
+ public abstract BridgeInfo fixupBridgeInfo(VirtualBridgeInfo bridgeInfo);
+
+ public abstract CallSiteOptimizationInfo fixupCallSiteOptimizationInfo(
+ ConcreteCallSiteOptimizationInfo callSiteOptimizationInfo);
+
+ public abstract ClassInlinerMethodConstraint fixupClassInlinerMethodConstraint(
+ AppView<AppInfoWithLiveness> appView,
+ ClassInlinerMethodConstraint classInlinerMethodConstraint);
+
+ public abstract EnumUnboxerMethodClassification fixupEnumUnboxerMethodClassification(
+ EnumUnboxerMethodClassification classification);
+
+ public abstract InstanceInitializerInfoCollection fixupInstanceInitializerInfo(
+ AppView<AppInfoWithLiveness> appView,
+ InstanceInitializerInfoCollection instanceInitializerInfo);
+
+ public abstract BitSet fixupNonNullParamOnNormalExits(BitSet nonNullParamOnNormalExits);
+
+ public abstract BitSet fixupNonNullParamOrThrow(BitSet nonNullParamOrThrow);
+
+ public abstract int fixupReturnedArgumentIndex(int returnedArgumentIndex);
+
+ public abstract SimpleInliningConstraint fixupSimpleInliningConstraint(
+ AppView<AppInfoWithLiveness> appView,
+ SimpleInliningConstraint constraint,
+ SimpleInliningConstraintFactory factory);
+}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MutableMethodOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MutableMethodOptimizationInfo.java
index 4263b35..c4a08f4 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MutableMethodOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MutableMethodOptimizationInfo.java
@@ -156,6 +156,18 @@
enumUnboxerMethodClassification = template.enumUnboxerMethodClassification;
}
+ public MutableMethodOptimizationInfo fixup(
+ AppView<AppInfoWithLiveness> appView, MethodOptimizationInfoFixer fixer) {
+ return fixupBridgeInfo(fixer)
+ .fixupClassInlinerMethodConstraint(appView, fixer)
+ .fixupEnumUnboxerMethodClassification(fixer)
+ .fixupInstanceInitializerInfo(appView, fixer)
+ .fixupNonNullParamOnNormalExits(fixer)
+ .fixupNonNullParamOrThrow(fixer)
+ .fixupReturnedArgumentIndex(fixer)
+ .fixupSimpleInliningConstraint(appView, fixer);
+ }
+
public MutableMethodOptimizationInfo fixupClassTypeReferences(
AppView<? extends AppInfoWithClassHierarchy> appView, GraphLens lens) {
return fixupClassTypeReferences(appView, lens, emptySet());
@@ -240,6 +252,13 @@
return classInlinerConstraint;
}
+ public MutableMethodOptimizationInfo fixupClassInlinerMethodConstraint(
+ AppView<AppInfoWithLiveness> appView, MethodOptimizationInfoFixer fixer) {
+ classInlinerConstraint =
+ fixer.fixupClassInlinerMethodConstraint(appView, classInlinerConstraint);
+ return this;
+ }
+
void setClassInlinerMethodConstraint(ClassInlinerMethodConstraint classInlinerConstraint) {
this.classInlinerConstraint = classInlinerConstraint;
}
@@ -261,8 +280,11 @@
this.enumUnboxerMethodClassification = enumUnboxerMethodClassification;
}
- void unsetEnumUnboxerMethodClassification() {
- this.enumUnboxerMethodClassification = EnumUnboxerMethodClassification.unknown();
+ public MutableMethodOptimizationInfo fixupEnumUnboxerMethodClassification(
+ MethodOptimizationInfoFixer fixer) {
+ enumUnboxerMethodClassification =
+ fixer.fixupEnumUnboxerMethodClassification(enumUnboxerMethodClassification);
+ return this;
}
@Override
@@ -290,16 +312,42 @@
return instanceInitializerInfoCollection.get(invoke);
}
+ public MutableMethodOptimizationInfo fixupInstanceInitializerInfo(
+ AppView<AppInfoWithLiveness> appView, MethodOptimizationInfoFixer fixer) {
+ instanceInitializerInfoCollection =
+ fixer.fixupInstanceInitializerInfo(appView, instanceInitializerInfoCollection);
+ return this;
+ }
+
@Override
public BitSet getNonNullParamOrThrow() {
return nonNullParamOrThrow;
}
+ public MutableMethodOptimizationInfo fixupNonNullParamOrThrow(MethodOptimizationInfoFixer fixer) {
+ nonNullParamOrThrow = fixer.fixupNonNullParamOrThrow(nonNullParamOrThrow);
+ return this;
+ }
+
+ void setNonNullParamOrThrow(BitSet facts) {
+ this.nonNullParamOrThrow = facts;
+ }
+
@Override
public BitSet getNonNullParamOnNormalExits() {
return nonNullParamOnNormalExits;
}
+ public MutableMethodOptimizationInfo fixupNonNullParamOnNormalExits(
+ MethodOptimizationInfoFixer fixer) {
+ nonNullParamOnNormalExits = fixer.fixupNonNullParamOnNormalExits(nonNullParamOnNormalExits);
+ return this;
+ }
+
+ void setNonNullParamOnNormalExits(BitSet facts) {
+ this.nonNullParamOnNormalExits = facts;
+ }
+
@Override
public boolean hasBeenInlinedIntoSingleCallSite() {
return isFlagSet(HAS_BEEN_INLINED_INTO_SINGLE_CALL_SITE_FLAG);
@@ -335,6 +383,14 @@
return bridgeInfo;
}
+ public MutableMethodOptimizationInfo fixupBridgeInfo(MethodOptimizationInfoFixer fixer) {
+ if (bridgeInfo != null) {
+ assert bridgeInfo.isVirtualBridgeInfo();
+ bridgeInfo = fixer.fixupBridgeInfo(bridgeInfo.asVirtualBridgeInfo());
+ }
+ return this;
+ }
+
void setBridgeInfo(BridgeInfo bridgeInfo) {
this.bridgeInfo = bridgeInfo;
}
@@ -408,14 +464,6 @@
return isFlagSet(RETURN_VALUE_ONLY_DEPENDS_ON_ARGUMENTS_FLAG);
}
- void setNonNullParamOrThrow(BitSet facts) {
- this.nonNullParamOrThrow = facts;
- }
-
- void setNonNullParamOnNormalExits(BitSet facts) {
- this.nonNullParamOnNormalExits = facts;
- }
-
public void setReachabilitySensitive(boolean reachabilitySensitive) {
setFlag(REACHABILITY_SENSITIVE_FLAG, reachabilitySensitive);
}
@@ -424,6 +472,14 @@
this.simpleInliningConstraint = constraint;
}
+ public MutableMethodOptimizationInfo fixupSimpleInliningConstraint(
+ AppView<AppInfoWithLiveness> appView, MethodOptimizationInfoFixer fixer) {
+ simpleInliningConstraint =
+ fixer.fixupSimpleInliningConstraint(
+ appView, simpleInliningConstraint, appView.simpleInliningConstraintFactory());
+ return this;
+ }
+
void setInstanceInitializerInfoCollection(
InstanceInitializerInfoCollection instanceInitializerInfoCollection) {
this.instanceInitializerInfoCollection = instanceInitializerInfoCollection;
@@ -437,10 +493,16 @@
this.initializedClassesOnNormalExit = initializedClassesOnNormalExit;
}
- void markReturnsArgument(int argument) {
- assert argument >= 0;
- assert returnedArgument == -1 || returnedArgument == argument;
- returnedArgument = argument;
+ void markReturnsArgument(int returnedArgumentIndex) {
+ assert returnedArgumentIndex >= 0;
+ assert returnedArgument == -1 || returnedArgument == returnedArgumentIndex;
+ returnedArgument = returnedArgumentIndex;
+ }
+
+ public MutableMethodOptimizationInfo fixupReturnedArgumentIndex(
+ MethodOptimizationInfoFixer fixer) {
+ returnedArgument = fixer.fixupReturnedArgumentIndex(returnedArgument);
+ return this;
}
void markMayNotHaveSideEffects() {
@@ -550,64 +612,4 @@
public MutableMethodOptimizationInfo mutableCopy() {
return new MutableMethodOptimizationInfo(this);
}
-
- public void adjustOptimizationInfoAfterRemovingThisParameter(
- AppView<AppInfoWithLiveness> appView) {
- classInlinerConstraint = classInlinerConstraint.fixupAfterRemovingThisParameter();
- enumUnboxerMethodClassification =
- enumUnboxerMethodClassification.fixupAfterRemovingThisParameter();
- simpleInliningConstraint =
- simpleInliningConstraint.fixupAfterRemovingThisParameter(
- appView.simpleInliningConstraintFactory());
- // cannotBeKept: doesn't depend on `this`
- // classInitializerMayBePostponed: `this` could trigger <clinit> of the previous holder.
- clearFlag(CLASS_INITIALIZER_MAY_BE_POSTPONED_FLAG);
- // hasBeenInlinedIntoSingleCallSite: then it should not be staticized.
- clearFlag(HAS_BEEN_INLINED_INTO_SINGLE_CALL_SITE_FLAG);
- // initializedClassesOnNormalExit: `this` could trigger <clinit> of the previous holder.
- initializedClassesOnNormalExit =
- DefaultMethodOptimizationInfo.UNKNOWN_INITIALIZED_CLASSES_ON_NORMAL_EXIT;
- // At least, `this` pointer is not used in `returnedArgument`.
- assert returnedArgument == DefaultMethodOptimizationInfo.UNKNOWN_RETURNED_ARGUMENT
- || returnedArgument > 0;
- returnedArgument =
- returnedArgument == DefaultMethodOptimizationInfo.UNKNOWN_RETURNED_ARGUMENT
- ? DefaultMethodOptimizationInfo.UNKNOWN_RETURNED_ARGUMENT
- : returnedArgument - 1;
- // mayHaveSideEffects: `this` Argument didn't have side effects, so removing it doesn't affect
- // whether or not the method may have side effects.
- // returnValueOnlyDependsOnArguments:
- // if the method did before, so it does even after removing `this` Argument
- // code is not changed, and thus the following *return* info is not changed either.
- // * neverReturnsNull
- // * neverReturnsNormally
- // * constantValue
- // * returnsObjectWithUpperBoundType
- // * returnsObjectWithLowerBoundType
- // inlining: it is not inlined, and thus staticized. No more chance of inlining, though.
- inlining = InlinePreference.Default;
- // checksNullReceiverBeforeAnySideEffect: no more receiver.
- markCheckNullReceiverBeforeAnySideEffect(
- DefaultMethodOptimizationInfo.UNKNOWN_CHECKS_NULL_RECEIVER_BEFORE_ANY_SIDE_EFFECT);
- // triggersClassInitBeforeAnySideEffect: code is not changed.
- markTriggerClassInitBeforeAnySideEffect(
- DefaultMethodOptimizationInfo.UNKNOWN_TRIGGERS_CLASS_INIT_BEFORE_ANY_SIDE_EFFECT);
- // initializerInfo: the computed initializer info may become invalid.
- instanceInitializerInfoCollection = InstanceInitializerInfoCollection.empty();
- // initializerEnablingJavaAssertions: `this` could trigger <clinit> of the previous holder.
- setFlag(
- INITIALIZER_ENABLING_JAVA_ASSERTIONS_FLAG,
- DefaultMethodOptimizationInfo.UNKNOWN_INITIALIZER_ENABLING_JAVA_ASSERTIONS);
- nonNullParamOrThrow =
- nonNullParamOrThrow == DefaultMethodOptimizationInfo.NO_NULL_PARAMETER_OR_THROW_FACTS
- ? DefaultMethodOptimizationInfo.NO_NULL_PARAMETER_OR_THROW_FACTS
- : nonNullParamOrThrow.get(1, nonNullParamOrThrow.length());
- nonNullParamOnNormalExits =
- nonNullParamOnNormalExits
- == DefaultMethodOptimizationInfo.NO_NULL_PARAMETER_ON_NORMAL_EXITS_FACTS
- ? DefaultMethodOptimizationInfo.NO_NULL_PARAMETER_ON_NORMAL_EXITS_FACTS
- : nonNullParamOnNormalExits.get(1, nonNullParamOnNormalExits.length());
- // reachabilitySensitive: doesn't depend on `this`
- // returnValueHasBeenPropagated: doesn't depend on `this`
- }
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackDelayed.java b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackDelayed.java
index bd275db..c9390d7 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackDelayed.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackDelayed.java
@@ -272,11 +272,6 @@
}
@Override
- public synchronized void unsetEnumUnboxerMethodClassification(ProgramMethod method) {
- getMethodOptimizationInfoForUpdating(method).unsetEnumUnboxerMethodClassification();
- }
-
- @Override
public synchronized void setInstanceInitializerInfoCollection(
DexEncodedMethod method,
InstanceInitializerInfoCollection instanceInitializerInfoCollection) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackIgnore.java b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackIgnore.java
index 1894532..623d8d2 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackIgnore.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackIgnore.java
@@ -122,9 +122,6 @@
ProgramMethod method, EnumUnboxerMethodClassification enumUnboxerMethodClassification) {}
@Override
- public void unsetEnumUnboxerMethodClassification(ProgramMethod method) {}
-
- @Override
public void setInstanceInitializerInfoCollection(
DexEncodedMethod method,
InstanceInitializerInfoCollection instanceInitializerInfoCollection) {}
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 10649fb..47f1b8e 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
@@ -194,11 +194,6 @@
}
@Override
- public void unsetEnumUnboxerMethodClassification(ProgramMethod method) {
- method.getDefinition().getMutableOptimizationInfo().unsetEnumUnboxerMethodClassification();
- }
-
- @Override
public void setInstanceInitializerInfoCollection(
DexEncodedMethod method,
InstanceInitializerInfoCollection instanceInitializerInfoCollection) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/EmptyInstanceFieldInitializationInfoCollection.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/EmptyInstanceFieldInitializationInfoCollection.java
index 9c7d07c..16a86a4 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/EmptyInstanceFieldInitializationInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/EmptyInstanceFieldInitializationInfoCollection.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.function.BiConsumer;
@@ -52,6 +53,12 @@
}
@Override
+ public InstanceFieldInitializationInfoCollection fixupAfterParametersChanged(
+ ArgumentInfoCollection argumentInfoCollection) {
+ return this;
+ }
+
+ @Override
public InstanceFieldInitializationInfoCollection rewrittenWithLens(
AppView<AppInfoWithLiveness> appView, GraphLens lens) {
return this;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldArgumentInitializationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldArgumentInitializationInfo.java
index 0447d5d..46255f1 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldArgumentInitializationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldArgumentInitializationInfo.java
@@ -6,6 +6,9 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfo;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.RemovedArgumentInfo;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
/**
@@ -36,6 +39,28 @@
}
@Override
+ public InstanceFieldInitializationInfo fixupAfterParametersChanged(
+ ArgumentInfoCollection argumentInfoCollection) {
+ ArgumentInfo argumentInfo = argumentInfoCollection.getArgumentInfo(argumentIndex);
+ if (argumentInfo.isRemovedArgumentInfo()) {
+ RemovedArgumentInfo removedArgumentInfo = argumentInfo.asRemovedArgumentInfo();
+ if (!removedArgumentInfo.hasSingleValue()) {
+ // This should only happen if the argument is unused, but here the argument is used to
+ // initialize an instance field on the enclosing class.
+ assert false;
+ return UnknownInstanceFieldInitializationInfo.getInstance();
+ }
+ // Now the constant is used to initialize the field instead of the argument.
+ return removedArgumentInfo.getSingleValue();
+ }
+
+ int newArgumentIndex = argumentInfoCollection.getNewArgumentIndex(argumentIndex);
+ return newArgumentIndex != argumentIndex
+ ? new InstanceFieldArgumentInitializationInfo(newArgumentIndex)
+ : this;
+ }
+
+ @Override
public InstanceFieldInitializationInfo rewrittenWithLens(
AppView<AppInfoWithLiveness> appView, GraphLens lens) {
// We don't have the context here to determine what should happen. It is the responsibility of
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfo.java
index aa3ab9b..94e5ea5 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfo.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.analysis.value.SingleValue;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -46,6 +47,9 @@
return false;
}
+ InstanceFieldInitializationInfo fixupAfterParametersChanged(
+ ArgumentInfoCollection argumentInfoCollection);
+
InstanceFieldInitializationInfo rewrittenWithLens(
AppView<AppInfoWithLiveness> appView, GraphLens lens);
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfoCollection.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfoCollection.java
index aca1f76..ef40285 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfoCollection.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.TreeMap;
import java.util.function.BiConsumer;
@@ -38,6 +39,9 @@
public abstract boolean isEmpty();
+ public abstract InstanceFieldInitializationInfoCollection fixupAfterParametersChanged(
+ ArgumentInfoCollection argumentInfoCollection);
+
public abstract InstanceFieldInitializationInfoCollection rewrittenWithLens(
AppView<AppInfoWithLiveness> appView, GraphLens lens);
@@ -52,7 +56,9 @@
public Builder recordInitializationInfo(DexField field, InstanceFieldInitializationInfo info) {
assert !infos.containsKey(field);
- infos.put(field, info);
+ if (!info.isUnknown()) {
+ infos.put(field, info);
+ }
return this;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldTypeInitializationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldTypeInitializationInfo.java
index 708c84a..39a72ba 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldTypeInitializationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldTypeInitializationInfo.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.optimize.enums.EnumDataMap;
@@ -47,6 +48,12 @@
}
@Override
+ public InstanceFieldInitializationInfo fixupAfterParametersChanged(
+ ArgumentInfoCollection argumentInfoCollection) {
+ return this;
+ }
+
+ @Override
public InstanceFieldInitializationInfo rewrittenWithLens(
AppView<AppInfoWithLiveness> appView, GraphLens lens) {
EnumDataMap enumDataMap = appView.unboxedEnums();
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/NonTrivialInstanceFieldInitializationInfoCollection.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/NonTrivialInstanceFieldInitializationInfoCollection.java
index 2081721..2e34bcd 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/NonTrivialInstanceFieldInitializationInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/NonTrivialInstanceFieldInitializationInfoCollection.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.StringUtils;
import java.util.ArrayList;
@@ -67,17 +68,24 @@
}
@Override
+ public InstanceFieldInitializationInfoCollection fixupAfterParametersChanged(
+ ArgumentInfoCollection argumentInfoCollection) {
+ Builder builder = InstanceFieldInitializationInfoCollection.builder();
+ infos.forEach(
+ (field, info) ->
+ builder.recordInitializationInfo(
+ field, info.fixupAfterParametersChanged(argumentInfoCollection)));
+ return builder.build();
+ }
+
+ @Override
public InstanceFieldInitializationInfoCollection rewrittenWithLens(
AppView<AppInfoWithLiveness> appView, GraphLens lens) {
Builder builder = InstanceFieldInitializationInfoCollection.builder();
infos.forEach(
- (field, info) -> {
- DexField rewrittenField = lens.lookupField(field);
- InstanceFieldInitializationInfo rewrittenInfo = info.rewrittenWithLens(appView, lens);
- if (!rewrittenInfo.isUnknown()) {
- builder.recordInitializationInfo(rewrittenField, rewrittenInfo);
- }
- });
+ (field, info) ->
+ builder.recordInitializationInfo(
+ lens.lookupField(field), info.rewrittenWithLens(appView, lens)));
return builder.build();
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/UnknownInstanceFieldInitializationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/UnknownInstanceFieldInitializationInfo.java
index 13d4944..f0353a4 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/UnknownInstanceFieldInitializationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/UnknownInstanceFieldInitializationInfo.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
/**
@@ -29,6 +30,12 @@
}
@Override
+ public InstanceFieldInitializationInfo fixupAfterParametersChanged(
+ ArgumentInfoCollection argumentInfoCollection) {
+ return this;
+ }
+
+ @Override
public InstanceFieldInitializationInfo rewrittenWithLens(
AppView<AppInfoWithLiveness> appView, GraphLens lens) {
return this;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/ContextInsensitiveInstanceInitializerInfoCollection.java b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/ContextInsensitiveInstanceInitializerInfoCollection.java
index 537bda3..1feccf6 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/ContextInsensitiveInstanceInitializerInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/ContextInsensitiveInstanceInitializerInfoCollection.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.PrunedItems;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.code.InvokeDirect;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -35,6 +36,17 @@
}
@Override
+ public InstanceInitializerInfoCollection fixupAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView, ArgumentInfoCollection argumentInfoCollection) {
+ NonTrivialInstanceInitializerInfo rewrittenInfo =
+ info.fixupAfterParametersChanged(appView, argumentInfoCollection);
+ if (rewrittenInfo != info) {
+ return new ContextInsensitiveInstanceInitializerInfoCollection(rewrittenInfo);
+ }
+ return this;
+ }
+
+ @Override
public ContextInsensitiveInstanceInitializerInfoCollection rewrittenWithLens(
AppView<AppInfoWithLiveness> appView, GraphLens lens, PrunedItems prunedItems) {
NonTrivialInstanceInitializerInfo rewrittenInfo =
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/ContextSensitiveInstanceInitializerInfoCollection.java b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/ContextSensitiveInstanceInitializerInfoCollection.java
index acaeef9..f281892 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/ContextSensitiveInstanceInitializerInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/ContextSensitiveInstanceInitializerInfoCollection.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.PrunedItems;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.code.InvokeDirect;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.google.common.collect.ImmutableMap;
@@ -49,6 +50,17 @@
}
@Override
+ public InstanceInitializerInfoCollection fixupAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView, ArgumentInfoCollection argumentInfoCollection) {
+ Builder builder = builder();
+ infos.forEach(
+ (context, info) ->
+ builder.put(
+ context, info.fixupAfterParametersChanged(appView, argumentInfoCollection)));
+ return builder.build();
+ }
+
+ @Override
public InstanceInitializerInfoCollection rewrittenWithLens(
AppView<AppInfoWithLiveness> appView, GraphLens lens, PrunedItems prunedItems) {
Builder builder = builder();
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/DefaultInstanceInitializerInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/DefaultInstanceInitializerInfo.java
index 8391de8..678489b 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/DefaultInstanceInitializerInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/DefaultInstanceInitializerInfo.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.PrunedItems;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.AbstractFieldSet;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.UnknownFieldSet;
import com.android.tools.r8.ir.optimize.info.field.EmptyInstanceFieldInitializationInfoCollection;
@@ -66,6 +67,12 @@
}
@Override
+ public InstanceInitializerInfo fixupAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView, ArgumentInfoCollection argumentInfoCollection) {
+ return this;
+ }
+
+ @Override
public InstanceInitializerInfo rewrittenWithLens(
AppView<AppInfoWithLiveness> appView, GraphLens lens, PrunedItems prunedItems) {
return this;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/EmptyInstanceInitializerInfoCollection.java b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/EmptyInstanceInitializerInfoCollection.java
index 7100e35..c3742a5 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/EmptyInstanceInitializerInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/EmptyInstanceInitializerInfoCollection.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.PrunedItems;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.code.InvokeDirect;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -37,6 +38,12 @@
}
@Override
+ public InstanceInitializerInfoCollection fixupAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView, ArgumentInfoCollection argumentInfoCollection) {
+ return this;
+ }
+
+ @Override
public EmptyInstanceInitializerInfoCollection rewrittenWithLens(
AppView<AppInfoWithLiveness> appView, GraphLens lens, PrunedItems prunedItems) {
return this;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/InstanceInitializerInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/InstanceInitializerInfo.java
index edd78e5..e89b738 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/InstanceInitializerInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/InstanceInitializerInfo.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.PrunedItems;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.AbstractFieldSet;
import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfoCollection;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -71,6 +72,9 @@
return !receiverNeverEscapesOutsideConstructorChain();
}
+ public abstract InstanceInitializerInfo fixupAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView, ArgumentInfoCollection argumentInfoCollection);
+
public abstract InstanceInitializerInfo rewrittenWithLens(
AppView<AppInfoWithLiveness> appView, GraphLens lens, PrunedItems prunedItems);
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/InstanceInitializerInfoCollection.java b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/InstanceInitializerInfoCollection.java
index 0139cf0..f228922 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/InstanceInitializerInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/InstanceInitializerInfoCollection.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.PrunedItems;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.code.InvokeDirect;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.MapUtils;
@@ -36,6 +37,9 @@
public abstract boolean isEmpty();
+ public abstract InstanceInitializerInfoCollection fixupAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView, ArgumentInfoCollection argumentInfoCollection);
+
public abstract InstanceInitializerInfoCollection rewrittenWithLens(
AppView<AppInfoWithLiveness> appView, GraphLens lens, PrunedItems prunedItems);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/NonTrivialInstanceInitializerInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/NonTrivialInstanceInitializerInfo.java
index 7066531..99cb83b 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/NonTrivialInstanceInitializerInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/NonTrivialInstanceInitializerInfo.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.PrunedItems;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.AbstractFieldSet;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.ConcreteMutableFieldSet;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.EmptyFieldSet;
@@ -99,6 +100,16 @@
}
@Override
+ public NonTrivialInstanceInitializerInfo fixupAfterParametersChanged(
+ AppView<AppInfoWithLiveness> appView, ArgumentInfoCollection argumentInfoCollection) {
+ return new NonTrivialInstanceInitializerInfo(
+ data,
+ fieldInitializationInfos.fixupAfterParametersChanged(argumentInfoCollection),
+ readSet.fixupReadSetAfterParametersChanged(appView, argumentInfoCollection),
+ parent);
+ }
+
+ @Override
public NonTrivialInstanceInitializerInfo rewrittenWithLens(
AppView<AppInfoWithLiveness> appView, GraphLens lens, PrunedItems prunedItems) {
return new NonTrivialInstanceInitializerInfo(
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/string/StringOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/string/StringOptimizer.java
index 48f2199..1d0e301 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/string/StringOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/string/StringOptimizer.java
@@ -143,7 +143,10 @@
continue;
}
DexMethod invokedMethod = invoke.getInvokedMethod();
- if (invokedMethod.name == factory.substringName) {
+ if (invokedMethod.getHolderType() != factory.stringType) {
+ continue;
+ }
+ if (invokedMethod.getName() == factory.substringName) {
assert invoke.inValues().size() == 2 || invoke.inValues().size() == 3;
Value rcv = invoke.getReceiver().getAliasedValue();
if (rcv.definition == null
diff --git a/src/main/java/com/android/tools/r8/kotlin/Kotlin.java b/src/main/java/com/android/tools/r8/kotlin/Kotlin.java
index 2bbd2b3..9470367 100644
--- a/src/main/java/com/android/tools/r8/kotlin/Kotlin.java
+++ b/src/main/java/com/android/tools/r8/kotlin/Kotlin.java
@@ -9,8 +9,10 @@
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
+import com.google.common.collect.ImmutableSet;
import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -33,8 +35,59 @@
public static final class ClassClassifiers {
public static final String arrayBinaryName = NAME + "/Array";
+ public static final String arrayDescriptor = PACKAGE_PREFIX + "Array;";
public static final String anyDescriptor = PACKAGE_PREFIX + "Any;";
+ public static final String unitDescriptor = PACKAGE_PREFIX + "Unit;";
+ public static final String booleanDescriptor = PACKAGE_PREFIX + "Boolean";
+ public static final String charDescriptor = PACKAGE_PREFIX + "Char";
+ public static final String byteDescriptor = PACKAGE_PREFIX + "Byte";
+ public static final String uByteDescriptor = PACKAGE_PREFIX + "UByte";
+ public static final String shortDescriptor = PACKAGE_PREFIX + "Short;";
+ public static final String uShortDescriptor = PACKAGE_PREFIX + "UShort;";
+ public static final String intDescriptor = PACKAGE_PREFIX + "Int;";
+ public static final String uIntDescriptor = PACKAGE_PREFIX + "UInt;";
+ public static final String floatDescriptor = PACKAGE_PREFIX + "Float;";
+ public static final String longDescriptor = PACKAGE_PREFIX + "Long;";
+ public static final String uLongDescriptor = PACKAGE_PREFIX + "ULong;";
+ public static final String doubleDescriptor = PACKAGE_PREFIX + "Double;";
+ public static final String functionDescriptor = PACKAGE_PREFIX + "Function;";
+ public static final String kFunctionDescriptor = PACKAGE_PREFIX + "KFunction;";
public static final String anyName = NAME + "/Any";
+
+ public static final Set<String> kotlinPrimitivesDescriptors =
+ ImmutableSet.<String>builder()
+ .add(booleanDescriptor)
+ .add(charDescriptor)
+ .add(byteDescriptor)
+ .add(uByteDescriptor)
+ .add(shortDescriptor)
+ .add(uShortDescriptor)
+ .add(intDescriptor)
+ .add(uIntDescriptor)
+ .add(floatDescriptor)
+ .add(longDescriptor)
+ .add(uLongDescriptor)
+ .add(doubleDescriptor)
+ .build();
+
+ // Kotlin static known types is a possible not complete collection of descriptors that kotlinc
+ // and kotlin reflect know and expect the existence of.
+ public static final Set<String> kotlinStaticallyKnownTypes;
+
+ static {
+ ImmutableSet.Builder<String> builder = ImmutableSet.builder();
+ kotlinPrimitivesDescriptors.forEach(
+ primitive -> {
+ builder.add(primitive);
+ builder.add(primitive.substring(0, primitive.length() - 1) + "Array;");
+ });
+ builder.add(unitDescriptor);
+ builder.add(anyDescriptor);
+ builder.add(arrayDescriptor);
+ builder.add(functionDescriptor);
+ builder.add(kFunctionDescriptor);
+ kotlinStaticallyKnownTypes = builder.build();
+ }
}
public Kotlin(DexItemFactory factory) {
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinTypeReference.java b/src/main/java/com/android/tools/r8/kotlin/KotlinTypeReference.java
index 8cea528..4fd93a0 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinTypeReference.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinTypeReference.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.kotlin.Kotlin.ClassClassifiers;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.EnqueuerMetadataTraceable;
import com.android.tools.r8.utils.DescriptorUtils;
@@ -79,8 +80,16 @@
}
DexType rewrittenType = toRewrittenTypeOrNull(appView, known);
if (rewrittenType == null) {
- rewrittenConsumer.accept(defaultValue);
- return true;
+ String knownDescriptor = known.toDescriptorString();
+ // Static known kotlin types can be pruned without rewriting to Any since the types are known
+ // by kotlinc and kotlin reflect.
+ if (ClassClassifiers.kotlinStaticallyKnownTypes.contains(knownDescriptor)) {
+ rewrittenConsumer.accept(knownDescriptor);
+ return false;
+ } else {
+ rewrittenConsumer.accept(defaultValue);
+ return true;
+ }
}
String renamedString = namingLens.lookupDescriptor(rewrittenType).toString();
rewrittenConsumer.accept(renamedString);
diff --git a/src/main/java/com/android/tools/r8/naming/ProguardMapReader.java b/src/main/java/com/android/tools/r8/naming/ProguardMapReader.java
index 1dcd902..6dd1fa3 100644
--- a/src/main/java/com/android/tools/r8/naming/ProguardMapReader.java
+++ b/src/main/java/com/android/tools/r8/naming/ProguardMapReader.java
@@ -8,7 +8,6 @@
import com.android.tools.r8.naming.MemberNaming.FieldSignature;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.naming.MemberNaming.Signature;
-import com.android.tools.r8.naming.ProguardMap.Builder;
import com.android.tools.r8.naming.mappinginformation.MapVersionMappingInformation;
import com.android.tools.r8.naming.mappinginformation.MappingInformation;
import com.android.tools.r8.naming.mappinginformation.MappingInformationDiagnostics;
@@ -231,11 +230,13 @@
if (isCommentLineWithJsonBrace()) {
parseMappingInformation(
info -> {
- assert info.isMetaInfMappingInformation();
+ assert info.isMapVersionMappingInformation()
+ || info.isUnknownJsonMappingInformation();
});
// Skip reading the rest of the line.
lineOffset = line.length();
nextLine();
+ continue;
}
String before = parseType(false);
skipWhitespace();
@@ -257,7 +258,7 @@
mapBuilder.classNamingBuilder(after, before, getPosition());
skipWhitespace();
if (nextLine()) {
- parseMemberMappings(mapBuilder, currentClassBuilder);
+ parseMemberMappings(currentClassBuilder);
}
}
}
@@ -269,7 +270,7 @@
diagnosticsHandler,
lineNo,
info -> {
- MapVersionMappingInformation generatorInfo = info.asMetaInfMappingInformation();
+ MapVersionMappingInformation generatorInfo = info.asMapVersionMappingInformation();
if (generatorInfo != null) {
if (generatorInfo.getMapVersion().equals(MapVersion.MAP_VERSION_EXPERIMENTAL)) {
// A mapping file that is marked "experimental" will be treated as an unversioned
@@ -286,8 +287,7 @@
});
}
- private void parseMemberMappings(Builder mapBuilder, ClassNaming.Builder classNamingBuilder)
- throws IOException {
+ private void parseMemberMappings(ClassNaming.Builder classNamingBuilder) throws IOException {
MemberNaming lastAddedNaming = null;
MemberNaming activeMemberNaming = null;
MappedRange activeMappedRange = null;
diff --git a/src/main/java/com/android/tools/r8/naming/RecordRewritingNamingLens.java b/src/main/java/com/android/tools/r8/naming/RecordRewritingNamingLens.java
index e809317..f48cfc7 100644
--- a/src/main/java/com/android/tools/r8/naming/RecordRewritingNamingLens.java
+++ b/src/main/java/com/android/tools/r8/naming/RecordRewritingNamingLens.java
@@ -21,16 +21,16 @@
final NamingLens namingLens;
private final DexItemFactory factory;
- public static NamingLens createRecordRewritingNamingLens(AppView<?> appView) {
- return createRecordRewritingNamingLens(appView, NamingLens.getIdentityLens());
- }
-
public static NamingLens createRecordRewritingNamingLens(
AppView<?> appView, NamingLens namingLens) {
- if (!appView.options().shouldDesugarRecords()) {
- return namingLens;
+ if (appView.options().shouldDesugarRecords()
+ && appView
+ .appInfo()
+ .definitionForWithoutExistenceAssert(appView.dexItemFactory().recordType)
+ != null) {
+ return new RecordRewritingNamingLens(namingLens, appView);
}
- return new RecordRewritingNamingLens(namingLens, appView);
+ return namingLens;
}
public RecordRewritingNamingLens(NamingLens namingLens, AppView<?> appView) {
@@ -83,6 +83,16 @@
}
@Override
+ public boolean hasPrefixRewritingLogic() {
+ return namingLens.hasPrefixRewritingLogic();
+ }
+
+ @Override
+ public DexString prefixRewrittenType(DexType type) {
+ return namingLens.prefixRewrittenType(type);
+ }
+
+ @Override
public String lookupPackageName(String packageName) {
return namingLens.lookupPackageName(packageName);
}
diff --git a/src/main/java/com/android/tools/r8/naming/mappinginformation/CompilerSynthesizedMappingInformation.java b/src/main/java/com/android/tools/r8/naming/mappinginformation/CompilerSynthesizedMappingInformation.java
index d26d9a8..7f82be1 100644
--- a/src/main/java/com/android/tools/r8/naming/mappinginformation/CompilerSynthesizedMappingInformation.java
+++ b/src/main/java/com/android/tools/r8/naming/mappinginformation/CompilerSynthesizedMappingInformation.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.naming.mappinginformation;
-import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.naming.MapVersion;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
@@ -61,9 +60,6 @@
public static void deserialize(
MapVersion version,
- JsonObject object,
- DiagnosticsHandler diagnosticsHandler,
- int lineNumber,
Consumer<MappingInformation> onMappingInfo) {
if (isSupported(version)) {
onMappingInfo.accept(builder().build());
diff --git a/src/main/java/com/android/tools/r8/naming/mappinginformation/MapVersionMappingInformation.java b/src/main/java/com/android/tools/r8/naming/mappinginformation/MapVersionMappingInformation.java
index cd72831..357be56 100644
--- a/src/main/java/com/android/tools/r8/naming/mappinginformation/MapVersionMappingInformation.java
+++ b/src/main/java/com/android/tools/r8/naming/mappinginformation/MapVersionMappingInformation.java
@@ -20,7 +20,6 @@
private final MapVersion mapVersion;
public MapVersionMappingInformation(MapVersion mapVersion) {
- super();
this.mapVersion = mapVersion;
}
@@ -30,12 +29,12 @@
}
@Override
- public boolean isMetaInfMappingInformation() {
+ public boolean isMapVersionMappingInformation() {
return true;
}
@Override
- public MapVersionMappingInformation asMetaInfMappingInformation() {
+ public MapVersionMappingInformation asMapVersionMappingInformation() {
return this;
}
diff --git a/src/main/java/com/android/tools/r8/naming/mappinginformation/MappingInformation.java b/src/main/java/com/android/tools/r8/naming/mappinginformation/MappingInformation.java
index f8f1e53..13bcfe9 100644
--- a/src/main/java/com/android/tools/r8/naming/mappinginformation/MappingInformation.java
+++ b/src/main/java/com/android/tools/r8/naming/mappinginformation/MappingInformation.java
@@ -18,30 +18,38 @@
public abstract String serialize();
- public boolean isMetaInfMappingInformation() {
+ public boolean isMapVersionMappingInformation() {
return false;
}
- public MapVersionMappingInformation asMetaInfMappingInformation() {
- return null;
+ public boolean isUnknownJsonMappingInformation() {
+ return false;
}
public boolean isFileNameInformation() {
return false;
}
- public FileNameInformation asFileNameInformation() {
- return null;
- }
-
public boolean isCompilerSynthesizedMappingInformation() {
return false;
}
+ public MapVersionMappingInformation asMapVersionMappingInformation() {
+ return null;
+ }
+
+ public FileNameInformation asFileNameInformation() {
+ return null;
+ }
+
public CompilerSynthesizedMappingInformation asCompilerSynthesizedMappingInformation() {
return null;
}
+ public UnknownJsonMappingInformation asUnknownJsonMappingInformation() {
+ return null;
+ }
+
public abstract boolean allowOther(MappingInformation information);
public static void fromJsonObject(
@@ -92,11 +100,11 @@
version, object, diagnosticsHandler, lineNumber, onMappingInfo);
return;
case CompilerSynthesizedMappingInformation.ID:
- CompilerSynthesizedMappingInformation.deserialize(
- version, object, diagnosticsHandler, lineNumber, onMappingInfo);
+ CompilerSynthesizedMappingInformation.deserialize(version, onMappingInfo);
return;
default:
diagnosticsHandler.info(MappingInformationDiagnostics.noHandlerFor(lineNumber, id));
+ UnknownJsonMappingInformation.deserialize(id, object, onMappingInfo);
}
}
diff --git a/src/main/java/com/android/tools/r8/naming/mappinginformation/UnknownJsonMappingInformation.java b/src/main/java/com/android/tools/r8/naming/mappinginformation/UnknownJsonMappingInformation.java
new file mode 100644
index 0000000..848919b
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/naming/mappinginformation/UnknownJsonMappingInformation.java
@@ -0,0 +1,54 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.naming.mappinginformation;
+
+import com.android.tools.r8.errors.Unreachable;
+import com.google.gson.JsonObject;
+import java.util.function.Consumer;
+
+public class UnknownJsonMappingInformation extends MappingInformation {
+
+ private final String id;
+ private final String payload;
+
+ public UnknownJsonMappingInformation(String id, String payload) {
+ this.id = id;
+ this.payload = payload;
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ public String getPayload() {
+ return payload;
+ }
+
+ @Override
+ public String serialize() {
+ throw new Unreachable("We should not at this point serialize unknown information");
+ }
+
+ @Override
+ public boolean allowOther(MappingInformation information) {
+ return true;
+ }
+
+ @Override
+ public boolean isUnknownJsonMappingInformation() {
+ return true;
+ }
+
+ @Override
+ public UnknownJsonMappingInformation asUnknownJsonMappingInformation() {
+ return this;
+ }
+
+ public static void deserialize(
+ String id, JsonObject object, Consumer<MappingInformation> onMappingInfo) {
+ onMappingInfo.accept(new UnknownJsonMappingInformation(id, object.toString()));
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java
index 227851f..36719be 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java
@@ -128,10 +128,12 @@
timing.begin("Argument propagator");
// Compute the strongly connected program components for parallel execution.
+ timing.begin("Compute components");
ImmediateProgramSubtypingInfo immediateSubtypingInfo =
ImmediateProgramSubtypingInfo.create(appView);
List<Set<DexProgramClass>> stronglyConnectedProgramComponents =
computeStronglyConnectedProgramClasses(appView, immediateSubtypingInfo);
+ timing.end();
// Set the optimization info on each method.
populateParameterOptimizationInfo(
@@ -142,16 +144,17 @@
Set<DexProgramClass> affectedClasses = Sets.newConcurrentHashSet();
ArgumentPropagatorGraphLens graphLens =
new ArgumentPropagatorProgramOptimizer(appView, immediateSubtypingInfo)
- .run(stronglyConnectedProgramComponents, affectedClasses::add, executorService);
+ .run(stronglyConnectedProgramComponents, affectedClasses::add, executorService, timing);
// Find all the code objects that need reprocessing.
new ArgumentPropagatorMethodReprocessingEnqueuer(appView)
- .enqueueMethodForReprocessing(graphLens, postMethodProcessorBuilder, executorService);
+ .enqueueMethodForReprocessing(
+ graphLens, postMethodProcessorBuilder, executorService, timing);
// Finally, apply the graph lens to the program (i.e., remove constant parameters from method
// definitions).
new ArgumentPropagatorApplicationFixer(appView, graphLens)
- .fixupApplication(affectedClasses, executorService);
+ .fixupApplication(affectedClasses, executorService, timing);
timing.end();
}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorApplicationFixer.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorApplicationFixer.java
index b3e2027..beb3003 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorApplicationFixer.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorApplicationFixer.java
@@ -8,13 +8,10 @@
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.MethodCollection;
-import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
-import com.android.tools.r8.ir.optimize.enums.classification.EnumUnboxerMethodClassification;
-import com.android.tools.r8.ir.optimize.info.OptimizationFeedback;
-import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.ThreadUtils;
+import com.android.tools.r8.utils.Timing;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
@@ -35,7 +32,7 @@
}
public void fixupApplication(
- Set<DexProgramClass> affectedClasses, ExecutorService executorService)
+ Set<DexProgramClass> affectedClasses, ExecutorService executorService, Timing timing)
throws ExecutionException {
// If the graph lens is null, argument propagation did not lead to any parameter removals. In
// this case there is no needed to fixup the program.
@@ -46,8 +43,13 @@
assert !affectedClasses.isEmpty();
+ timing.begin("Fixup application");
ThreadUtils.processItems(affectedClasses, this::fixupClass, executorService);
+ timing.end();
+
+ timing.begin("Rewrite AppView");
appView.rewriteWithLens(graphLens);
+ timing.end();
}
private void fixupClass(DexProgramClass clazz) {
@@ -64,30 +66,12 @@
return method.toTypeSubstitutedMethod(
methodReferenceAfterParameterRemoval,
builder -> {
- // TODO(b/190154391): fixup parameter annotations, if any.
ArgumentInfoCollection removedParameters =
graphLens.getRemovedParameters(methodReferenceAfterParameterRemoval);
builder
- .fixupCallSiteOptimizationInfo(
- removedParameters.createCallSiteOptimizationInfoFixer())
- .modifyOptimizationInfo(
- (newMethod, optimizationInfo) -> {
- OptimizationFeedback feedback = OptimizationFeedbackSimple.getInstance();
- ProgramMethod programMethod = new ProgramMethod(clazz, newMethod);
- // TODO(b/190154391): test this.
- EnumUnboxerMethodClassification rewrittenEnumUnboxerMethodClassification =
- optimizationInfo
- .getEnumUnboxerMethodClassification()
- .fixupAfterParameterRemoval(removedParameters);
- if (rewrittenEnumUnboxerMethodClassification
- .isCheckNotNullClassification()) {
- feedback.setEnumUnboxerMethodClassification(
- programMethod, rewrittenEnumUnboxerMethodClassification);
- } else {
- // Bypass monotonicity check.
- feedback.unsetEnumUnboxerMethodClassification(programMethod);
- }
- });
+ .apply(removedParameters.createParameterAnnotationsRemover(method))
+ .fixupOptimizationInfo(
+ appView, removedParameters.createMethodOptimizationInfoFixer());
});
});
}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorMethodReprocessingEnqueuer.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorMethodReprocessingEnqueuer.java
index 37adcfa..68c7d12 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorMethodReprocessingEnqueuer.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorMethodReprocessingEnqueuer.java
@@ -19,6 +19,7 @@
import com.android.tools.r8.ir.optimize.info.CallSiteOptimizationInfo;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.ThreadUtils;
+import com.android.tools.r8.utils.Timing;
import com.android.tools.r8.utils.collections.LongLivedProgramMethodSetBuilder;
import com.android.tools.r8.utils.collections.ProgramMethodSet;
import java.util.ArrayList;
@@ -43,18 +44,31 @@
public void enqueueMethodForReprocessing(
ArgumentPropagatorGraphLens graphLens,
PostMethodProcessor.Builder postMethodProcessorBuilder,
- ExecutorService executorService)
+ ExecutorService executorService,
+ Timing timing)
throws ExecutionException {
+ timing.begin("Enqueue methods for reprocessing");
+
// Bring the methods to reprocess set up-to-date with the current graph lens (i.e., the one
// prior to the argument propagator lens, which has not yet been installed!).
+ timing.begin("Rewrite methods to reprocess");
LongLivedProgramMethodSetBuilder<ProgramMethodSet> methodsToReprocessBuilder =
postMethodProcessorBuilder
.getMethodsToReprocessBuilder()
.rewrittenWithLens(appView.graphLens());
+ timing.end();
+
+ timing.begin("Enqueue methods with non-trivial info");
enqueueMethodsWithNonTrivialOptimizationInfo(methodsToReprocessBuilder);
+ timing.end();
+
+ timing.begin("Enqueue affected methods");
if (graphLens != null) {
enqueueAffectedCallers(graphLens, methodsToReprocessBuilder, executorService);
}
+ timing.end();
+
+ timing.end();
}
private void enqueueMethodsWithNonTrivialOptimizationInfo(
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java
index 41e2e9c..76845cc 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java
@@ -27,6 +27,7 @@
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Pair;
import com.android.tools.r8.utils.ThreadUtils;
+import com.android.tools.r8.utils.Timing;
import com.android.tools.r8.utils.collections.DexMethodSignatureSet;
import com.android.tools.r8.utils.collections.ProgramMethodSet;
import com.google.common.collect.Iterables;
@@ -64,20 +65,27 @@
public ArgumentPropagatorGraphLens run(
List<Set<DexProgramClass>> stronglyConnectedProgramComponents,
Consumer<DexProgramClass> affectedClassConsumer,
- ExecutorService executorService)
+ ExecutorService executorService,
+ Timing timing)
throws ExecutionException {
+ timing.begin("Optimize components");
Collection<Builder> partialGraphLensBuilders =
ThreadUtils.processItemsWithResults(
stronglyConnectedProgramComponents,
classes ->
new StronglyConnectedComponentOptimizer().optimize(classes, affectedClassConsumer),
executorService);
+ timing.end();
// Merge all the partial, disjoint graph lens builders into a single graph lens.
+ timing.begin("Build graph lens");
ArgumentPropagatorGraphLens.Builder graphLensBuilder =
ArgumentPropagatorGraphLens.builder(appView);
partialGraphLensBuilders.forEach(graphLensBuilder::mergeDisjoint);
- return graphLensBuilder.build();
+ ArgumentPropagatorGraphLens graphLens = graphLensBuilder.build();
+ timing.end();
+
+ return graphLens;
}
private DexMethodSignatureSet getOrComputeLibraryMethods(DexClass clazz) {
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceClassElement.java b/src/main/java/com/android/tools/r8/retrace/RetraceClassElement.java
index 0615725..35380e4 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceClassElement.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceClassElement.java
@@ -24,4 +24,6 @@
RetraceFrameResult lookupFrame(
String methodName, int position, List<TypeReference> formalTypes, TypeReference returnType);
+
+ RetraceUnknownJsonMappingInformationResult getUnknownJsonMappingInformation();
}
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceUnknownJsonMappingInformationResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceUnknownJsonMappingInformationResult.java
new file mode 100644
index 0000000..2afa333
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceUnknownJsonMappingInformationResult.java
@@ -0,0 +1,21 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.retrace;
+
+import com.android.tools.r8.Keep;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
+
+@Keep
+public interface RetraceUnknownJsonMappingInformationResult {
+
+ /** Basic operation over 'elements' which represent a possible non-ambiguous retracing. */
+ Stream<RetraceUnknownMappingInformationElement> stream();
+
+ /** Short-hand for iterating the elements. */
+ default void forEach(Consumer<RetraceUnknownMappingInformationElement> action) {
+ stream().forEach(action);
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceUnknownMappingInformationElement.java b/src/main/java/com/android/tools/r8/retrace/RetraceUnknownMappingInformationElement.java
new file mode 100644
index 0000000..3bba032
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceUnknownMappingInformationElement.java
@@ -0,0 +1,17 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.retrace;
+
+import com.android.tools.r8.Keep;
+
+@Keep
+public interface RetraceUnknownMappingInformationElement {
+
+ String getIdentifier();
+
+ String getPayLoad();
+
+ RetraceUnknownJsonMappingInformationResult getRetraceResultContext();
+}
diff --git a/src/main/java/com/android/tools/r8/retrace/StringRetrace.java b/src/main/java/com/android/tools/r8/retrace/StringRetrace.java
index f6636c1..4bdb42c 100644
--- a/src/main/java/com/android/tools/r8/retrace/StringRetrace.java
+++ b/src/main/java/com/android/tools/r8/retrace/StringRetrace.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.Keep;
import com.android.tools.r8.retrace.internal.StackTraceElementStringProxy;
+import com.android.tools.r8.utils.ListUtils;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -97,28 +98,29 @@
// The result is empty, likely it maps to compiler synthesized items.
return;
}
- List<String> initialResult = retracedResult.get(0);
- initialResult.forEach(joinedConsumer);
- if (retracedResult.size() <= 1) {
- // The result is not ambiguous.
- return;
- }
- Set<String> reportedFrames = new HashSet<>(initialResult);
- for (int i = 1; i < retracedResult.size(); i++) {
- List<String> ambiguousResult = retracedResult.get(i);
- assert !ambiguousResult.isEmpty();
- String topFrame = ambiguousResult.get(0);
- if (reportedFrames.add(topFrame)) {
- ambiguousResult.forEach(
- retracedString -> {
- int firstCharIndex = firstNonWhiteSpaceCharacterFromIndex(retracedString, 0);
- retracedString =
- retracedString.substring(0, firstCharIndex)
- + "<OR> "
- + retracedString.substring(firstCharIndex);
- joinedConsumer.accept(retracedString);
- });
- }
- }
+ Set<String> reportedFrames = new HashSet<>();
+ ListUtils.forEachWithIndex(
+ retracedResult,
+ (potentialResults, index) -> {
+ assert !potentialResults.isEmpty();
+ // Check if we already reported position.
+ if (reportedFrames.add(potentialResults.get(0))) {
+ boolean isAmbiguous = potentialResults != retracedResult.get(0);
+ potentialResults.forEach(
+ retracedString -> {
+ if (isAmbiguous) {
+ int firstCharIndex = firstNonWhiteSpaceCharacterFromIndex(retracedString, 0);
+ joinedConsumer.accept(
+ retracedString.substring(0, firstCharIndex)
+ + "<OR #"
+ + (index)
+ + "> "
+ + retracedString.substring(firstCharIndex));
+ } else {
+ joinedConsumer.accept(retracedString);
+ }
+ });
+ }
+ });
}
}
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceClassResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceClassResultImpl.java
index 5dace5b..55ed4db 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceClassResultImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceClassResultImpl.java
@@ -17,6 +17,7 @@
import com.android.tools.r8.retrace.RetraceClassResult;
import com.android.tools.r8.retrace.RetraceFrameResult;
import com.android.tools.r8.retrace.RetraceSourceFileResult;
+import com.android.tools.r8.retrace.RetraceUnknownJsonMappingInformationResult;
import com.android.tools.r8.retrace.Retracer;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.Pair;
@@ -344,6 +345,12 @@
position);
}
+ @Override
+ public RetraceUnknownJsonMappingInformationResult getUnknownJsonMappingInformation() {
+ return RetraceUnknownJsonMappingInformationResultImpl.build(
+ mapper.getAdditionalMappingInfo());
+ }
+
private RetraceFrameResultImpl lookupFrame(MethodDefinition definition, int position) {
MethodDefinition methodDefinition =
MethodDefinition.create(classReference.getClassReference(), definition.getName());
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java
index 82717b1..edde5ab 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java
@@ -17,6 +17,7 @@
import com.android.tools.r8.retrace.Retracer;
import com.android.tools.r8.retrace.internal.RetraceClassResultImpl.RetraceClassElementImpl;
import com.android.tools.r8.utils.ListUtils;
+import com.android.tools.r8.utils.OptionalBool;
import com.android.tools.r8.utils.Pair;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
@@ -34,6 +35,8 @@
private final List<Pair<RetraceClassElementImpl, List<MappedRange>>> mappedRanges;
private final Retracer retracer;
+ private OptionalBool isAmbiguousCache = OptionalBool.UNKNOWN;
+
public RetraceFrameResultImpl(
RetraceClassResultImpl classResult,
List<Pair<RetraceClassElementImpl, List<MappedRange>>> mappedRanges,
@@ -49,22 +52,27 @@
@Override
public boolean isAmbiguous() {
- if (mappedRanges.size() > 1) {
- return true;
- }
- List<MappedRange> methodRanges = mappedRanges.get(0).getSecond();
- if (methodRanges == null || methodRanges.isEmpty()) {
- return false;
- }
- MappedRange lastRange = methodRanges.get(0);
- for (MappedRange mappedRange : methodRanges) {
- if (mappedRange != lastRange
- && (mappedRange.minifiedRange == null
- || !mappedRange.minifiedRange.equals(lastRange.minifiedRange))) {
+ if (isAmbiguousCache.isUnknown()) {
+ if (mappedRanges.size() > 1) {
+ isAmbiguousCache = OptionalBool.TRUE;
return true;
}
+ List<MappedRange> methodRanges = mappedRanges.get(0).getSecond();
+ if (methodRanges != null && !methodRanges.isEmpty()) {
+ MappedRange lastRange = methodRanges.get(0);
+ for (MappedRange mappedRange : methodRanges) {
+ if (mappedRange != lastRange
+ && (mappedRange.minifiedRange == null
+ || !mappedRange.minifiedRange.equals(lastRange.minifiedRange))) {
+ isAmbiguousCache = OptionalBool.TRUE;
+ return true;
+ }
+ }
+ }
+ isAmbiguousCache = OptionalBool.FALSE;
}
- return false;
+ assert !isAmbiguousCache.isUnknown();
+ return isAmbiguousCache.isTrue();
}
@Override
@@ -120,12 +128,12 @@
private RetracedMethodReferenceImpl getRetracedMethod(
MethodReference methodReference, MappedRange mappedRange, int obfuscatedPosition) {
- if (mappedRange.minifiedRange == null) {
+ if (mappedRange.minifiedRange == null || (obfuscatedPosition == -1 && !isAmbiguous())) {
int originalLineNumber = mappedRange.getFirstLineNumberOfOriginalRange();
return RetracedMethodReferenceImpl.create(
methodReference, originalLineNumber > 0 ? originalLineNumber : obfuscatedPosition);
}
- if (obfuscatedPosition == -1 || !mappedRange.minifiedRange.contains(obfuscatedPosition)) {
+ if (!mappedRange.minifiedRange.contains(obfuscatedPosition)) {
return RetracedMethodReferenceImpl.create(methodReference);
}
return RetracedMethodReferenceImpl.create(
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceUnknownJsonMappingInformationResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceUnknownJsonMappingInformationResultImpl.java
new file mode 100644
index 0000000..4a681a3
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceUnknownJsonMappingInformationResultImpl.java
@@ -0,0 +1,45 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.retrace.internal;
+
+import com.android.tools.r8.naming.mappinginformation.MappingInformation;
+import com.android.tools.r8.naming.mappinginformation.UnknownJsonMappingInformation;
+import com.android.tools.r8.retrace.RetraceUnknownJsonMappingInformationResult;
+import com.android.tools.r8.retrace.RetraceUnknownMappingInformationElement;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import java.util.stream.Stream;
+
+public class RetraceUnknownJsonMappingInformationResultImpl
+ implements RetraceUnknownJsonMappingInformationResult {
+
+ private final List<UnknownJsonMappingInformation> elements;
+
+ private RetraceUnknownJsonMappingInformationResultImpl(
+ List<UnknownJsonMappingInformation> elements) {
+ this.elements = elements;
+ }
+
+ @Override
+ public Stream<RetraceUnknownMappingInformationElement> stream() {
+ return elements.stream()
+ .map(
+ unknownJsonMappingInformation ->
+ new RetraceUnknownMappingInformationElementImpl(
+ this, unknownJsonMappingInformation));
+ }
+
+ static RetraceUnknownJsonMappingInformationResult build(
+ List<MappingInformation> mappingInformations) {
+ ImmutableList.Builder<UnknownJsonMappingInformation> unknownBuilder = ImmutableList.builder();
+ mappingInformations.forEach(
+ info -> {
+ if (info.isUnknownJsonMappingInformation()) {
+ unknownBuilder.add(info.asUnknownJsonMappingInformation());
+ }
+ });
+ return new RetraceUnknownJsonMappingInformationResultImpl(unknownBuilder.build());
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceUnknownMappingInformationElementImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceUnknownMappingInformationElementImpl.java
new file mode 100644
index 0000000..5615408
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceUnknownMappingInformationElementImpl.java
@@ -0,0 +1,38 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.retrace.internal;
+
+import com.android.tools.r8.naming.mappinginformation.UnknownJsonMappingInformation;
+import com.android.tools.r8.retrace.RetraceUnknownJsonMappingInformationResult;
+import com.android.tools.r8.retrace.RetraceUnknownMappingInformationElement;
+
+public class RetraceUnknownMappingInformationElementImpl
+ implements RetraceUnknownMappingInformationElement {
+
+ private final RetraceUnknownJsonMappingInformationResult result;
+ private final UnknownJsonMappingInformation mappingInformation;
+
+ RetraceUnknownMappingInformationElementImpl(
+ RetraceUnknownJsonMappingInformationResult result,
+ UnknownJsonMappingInformation mappingInformation) {
+ this.result = result;
+ this.mappingInformation = mappingInformation;
+ }
+
+ @Override
+ public String getIdentifier() {
+ return mappingInformation.getId();
+ }
+
+ @Override
+ public String getPayLoad() {
+ return mappingInformation.getPayload();
+ }
+
+ @Override
+ public RetraceUnknownJsonMappingInformationResult getRetraceResultContext() {
+ return result;
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementStringProxy.java b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementStringProxy.java
index 33a0ea1..5f512f4 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementStringProxy.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementStringProxy.java
@@ -114,7 +114,11 @@
return -1;
}
try {
- return Integer.parseInt(getEntryInLine(lineNumber));
+ String lineNumberString = getEntryInLine(lineNumber);
+ if (lineNumberString.isEmpty()) {
+ return -1;
+ }
+ return Integer.parseInt(lineNumberString);
} catch (NumberFormatException nfe) {
return -1;
}
@@ -226,15 +230,16 @@
return this;
}
- public StackTraceElementStringProxyBuilder registerLineNumber(int startIndex, int endIndex) {
+ public StackTraceElementStringProxyBuilder registerLineNumber(
+ int startIndex, int endIndex, boolean insertSeparatorForRetraced) {
lineNumber =
new StringIndex(
startIndex,
endIndex,
(retraced, original, verbose) ->
- retraced.hasLineNumber()
- ? retraced.getLineNumber() + ""
- : original.lineNumberAsString());
+ (retraced.hasLineNumber()
+ ? ((insertSeparatorForRetraced ? ":" : "") + retraced.getLineNumber())
+ : original.lineNumberAsString()));
orderedIndices.add(lineNumber);
return this;
}
@@ -296,6 +301,9 @@
}
public StackTraceElementStringProxy build() {
+ if (!lineNumber.hasIndex() && sourceFile.hasIndex()) {
+ registerLineNumber(sourceFile.endIndex, sourceFile.endIndex, true);
+ }
return new StackTraceElementStringProxy(
line,
orderedIndices,
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceRegularExpressionParser.java b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceRegularExpressionParser.java
index fc8d5d9..e26e351 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceRegularExpressionParser.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceRegularExpressionParser.java
@@ -309,7 +309,7 @@
if (startOfGroup == NO_MATCH) {
return false;
}
- builder.registerLineNumber(startOfGroup, matcher.end(captureGroup));
+ builder.registerLineNumber(startOfGroup, matcher.end(captureGroup), false);
return true;
};
}
diff --git a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
index a46bf38..242a08c 100644
--- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
+++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
@@ -937,7 +937,8 @@
if (!options().enableValuePropagation || neverPropagateValue.contains(method)) {
return false;
}
- if (isPinned(method) && !method.getReturnType().isAlwaysNull(this)) {
+ if (!method.getReturnType().isAlwaysNull(this)
+ && !getKeepInfo().getMethodInfo(method, this).isInliningAllowed(options())) {
return false;
}
return true;
@@ -1319,7 +1320,11 @@
if (refinedReceiverClass.isProgramClass()) {
DexClassAndMethod clazzAndMethod =
resolution.lookupVirtualDispatchTarget(refinedReceiverClass.asProgramClass(), this);
- if (clazzAndMethod == null || isPinned(clazzAndMethod.getDefinition().getReference())) {
+ if (clazzAndMethod == null
+ || (clazzAndMethod.isProgramMethod()
+ && !getKeepInfo()
+ .getMethodInfo(clazzAndMethod.asProgramMethod())
+ .isOptimizationAllowed(options()))) {
// TODO(b/150640456): We should maybe only consider program methods.
return DexEncodedMethod.SENTINEL;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 68fc3dc..c4e0518 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -564,8 +564,10 @@
}
public void addDeadProtoTypeCandidate(DexType type) {
- assert type.isProgramType(appView);
- addDeadProtoTypeCandidate(appView.definitionFor(type).asProgramClass());
+ DexProgramClass clazz = asProgramClassOrNull(appView.definitionFor(type));
+ if (clazz != null) {
+ addDeadProtoTypeCandidate(clazz);
+ }
}
public void addDeadProtoTypeCandidate(DexProgramClass clazz) {
diff --git a/src/main/java/com/android/tools/r8/shaking/KeepMethodInfo.java b/src/main/java/com/android/tools/r8/shaking/KeepMethodInfo.java
index dd4226c..9938bbc 100644
--- a/src/main/java/com/android/tools/r8/shaking/KeepMethodInfo.java
+++ b/src/main/java/com/android/tools/r8/shaking/KeepMethodInfo.java
@@ -36,7 +36,7 @@
}
public boolean isArgumentPropagationAllowed(GlobalKeepInfoConfiguration configuration) {
- return isOptimizationAllowed(configuration);
+ return isParameterRemovalAllowed(configuration);
}
public Joiner joiner() {
@@ -54,6 +54,10 @@
return this.equals(bottom());
}
+ public boolean isInliningAllowed(GlobalKeepInfoConfiguration configuration) {
+ return isOptimizationAllowed(configuration);
+ }
+
public static class Builder extends KeepInfo.Builder<Builder, KeepMethodInfo> {
private Builder() {
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 9694a13..860860b 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -520,15 +520,7 @@
return !canUseNestBasedAccess();
}
- public boolean enableExperimentalRecordDesugaring() {
- // TODO(b/169645628): Remove when records are supported.
- return testing.enableExperimentalRecordDesugaring;
- }
-
public boolean shouldDesugarRecords() {
- if (!enableExperimentalRecordDesugaring()) {
- return false;
- }
return desugarState.isOn() && !canUseRecords();
}
@@ -1553,7 +1545,6 @@
public boolean enableEnumUnboxingDebugLogs = false;
public boolean forceRedundantConstNumberRemoval = false;
public boolean enableExperimentalDesugaredLibraryKeepRuleGenerator = false;
- public boolean enableExperimentalRecordDesugaring = false;
public boolean invertConditionals = false;
public boolean placeExceptionalBlocksLast = false;
public boolean dontCreateMarkerInD8 = false;
@@ -1566,6 +1557,7 @@
public Consumer<IRCode> inlineeIrModifier = null;
public int basicBlockMuncherIterationLimit = NO_LIMIT;
public boolean dontReportFailingCheckDiscarded = false;
+ public boolean disableRecordApplicationReaderMap = false;
public PrintStream whyAreYouNotInliningConsumer = System.out;
public boolean trackDesugaredAPIConversions =
System.getProperty("com.android.tools.r8.trackDesugaredAPIConversions") != null;
diff --git a/src/test/examplesAndroidP/invokecustom/InvokeCustom.java b/src/test/examplesAndroidP/invokecustom/InvokeCustom.java
index c3cb86f..76fed75 100644
--- a/src/test/examplesAndroidP/invokecustom/InvokeCustom.java
+++ b/src/test/examplesAndroidP/invokecustom/InvokeCustom.java
@@ -35,8 +35,6 @@
}
}
-// TODO(116283747): Add the same test where the interface method is not overriden but inherited
-// from the interface. Currently, that works on the reference implementation but fails on Art.
class Impl implements I2 {
@Override
public ReturnType targetMethodTest5(ArgumentType arg) {
diff --git a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
index 2af9e9a..c81cdfc 100644
--- a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
@@ -1901,6 +1901,7 @@
.setDisableTreeShaking(true)
.setDisableMinification(true)
.setDisableDesugaring(compilationOptions.disableDesugaring)
+ .addProguardConfiguration(ImmutableList.of("-dontoptimize"), Origin.unknown())
.addProguardConfiguration(ImmutableList.of("-keepattributes *"), Origin.unknown())
.addProguardConfiguration(compilationOptions.keepRules, Origin.unknown())
.setOutput(
diff --git a/src/test/java/com/android/tools/r8/TestBase.java b/src/test/java/com/android/tools/r8/TestBase.java
index 2ccb378..1fda6a4 100644
--- a/src/test/java/com/android/tools/r8/TestBase.java
+++ b/src/test/java/com/android/tools/r8/TestBase.java
@@ -1776,6 +1776,10 @@
return AndroidApiLevel.O;
}
+ public static AndroidApiLevel apiLevelWithConstMethodHandleSupport() {
+ return AndroidApiLevel.P;
+ }
+
public static AndroidApiLevel apiLevelWithNativeMultiDexSupport() {
return AndroidApiLevel.L;
}
diff --git a/src/test/java/com/android/tools/r8/TestCompileResult.java b/src/test/java/com/android/tools/r8/TestCompileResult.java
index b80c482..69bf834 100644
--- a/src/test/java/com/android/tools/r8/TestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/TestCompileResult.java
@@ -283,6 +283,14 @@
return self();
}
+ public CR enableJVMPreview() {
+ assert getBackend() == Backend.CF;
+ if (!vmArguments.contains("--enable-preview")) {
+ vmArguments.add("--enable-preview");
+ }
+ return self();
+ }
+
public CR enableRuntimeAssertions(boolean enable) {
if (getBackend() == Backend.CF) {
if (enable) {
@@ -360,6 +368,13 @@
return self();
}
+ public <E extends Throwable> CR inspectWithOptions(
+ ThrowingConsumer<CodeInspector, E> consumer, Consumer<InternalOptions> debugOptionsConsumer)
+ throws IOException, E {
+ consumer.accept(inspector(debugOptionsConsumer));
+ return self();
+ }
+
public CR assertNoMessages() {
getDiagnosticMessages().assertNoMessages();
return self();
diff --git a/src/test/java/com/android/tools/r8/desugar/DesugarMissingTypeClassTest.java b/src/test/java/com/android/tools/r8/desugar/DesugarMissingTypeClassTest.java
index a0838e8..1269b34 100644
--- a/src/test/java/com/android/tools/r8/desugar/DesugarMissingTypeClassTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/DesugarMissingTypeClassTest.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.desugar;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.D8TestBuilder;
@@ -79,10 +78,8 @@
InterfaceDesugarMissingTypeDiagnostic desugarWarning = (InterfaceDesugarMissingTypeDiagnostic) diagnostic;
assertEquals(
Reference.classFromClass(MissingInterface.class), desugarWarning.getMissingType());
- // The type is both missing from the interface referenced invoke and from the implements.
- // The diagnostics should likely include all contexts akin to the R8 missing types.
- assertEquals(Reference.classFromClass(TestClass.class), desugarWarning.getContextType());
- assertNotEquals(Position.UNKNOWN, desugarWarning.getPosition());
+ assertEquals(Reference.classFromClass(MyClass.class), desugarWarning.getContextType());
+ assertEquals(Position.UNKNOWN, desugarWarning.getPosition());
}
}
}
diff --git a/src/test/java/com/android/tools/r8/desugar/DesugarMissingTypeLambdaTest.java b/src/test/java/com/android/tools/r8/desugar/DesugarMissingTypeLambdaTest.java
index bd50527..875ead2 100644
--- a/src/test/java/com/android/tools/r8/desugar/DesugarMissingTypeLambdaTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/DesugarMissingTypeLambdaTest.java
@@ -3,10 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.desugar;
-import static com.android.tools.r8.references.Reference.classFromClass;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.D8TestBuilder;
@@ -19,6 +16,7 @@
import com.android.tools.r8.errors.DesugarDiagnostic;
import com.android.tools.r8.errors.InterfaceDesugarMissingTypeDiagnostic;
import com.android.tools.r8.position.Position;
+import com.android.tools.r8.references.Reference;
import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.StringUtils;
@@ -77,12 +75,12 @@
assertTrue(diagnostic instanceof DesugarDiagnostic);
assertTrue(diagnostic instanceof InterfaceDesugarMissingTypeDiagnostic);
InterfaceDesugarMissingTypeDiagnostic desugarWarning = (InterfaceDesugarMissingTypeDiagnostic) diagnostic;
- assertEquals(classFromClass(MissingInterface.class), desugarWarning.getMissingType());
- // TODO(b/132671303): The diagnostics should also contain the lambda context, but it should
- // not be the synthesized lambda class.
- assertFalse(SyntheticItemsTestUtils.isInternalLambda(desugarWarning.getContextType()));
- assertEquals(classFromClass(TestClass.class), desugarWarning.getContextType());
- assertNotEquals(Position.UNKNOWN, desugarWarning.getPosition());
+ assertEquals(
+ Reference.classFromClass(MissingInterface.class), desugarWarning.getMissingType());
+ // TODO(b/132671303): The context class should not be the synthesized lambda class.
+ assertTrue(SyntheticItemsTestUtils.isInternalLambda(desugarWarning.getContextType()));
+ // TODO(b/132671303): The position info should be the method context.
+ assertEquals(Position.UNKNOWN, desugarWarning.getPosition());
}
}
}
diff --git a/src/test/java/com/android/tools/r8/desugar/lambdas/LambdaInStacktraceTest.java b/src/test/java/com/android/tools/r8/desugar/lambdas/LambdaInStacktraceTest.java
index 640796d..31f87d9 100644
--- a/src/test/java/com/android/tools/r8/desugar/lambdas/LambdaInStacktraceTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/lambdas/LambdaInStacktraceTest.java
@@ -102,6 +102,7 @@
.addKeepAttributeSourceFile()
.addKeepRules("-renamesourcefileattribute SourceFile")
.noTreeShaking()
+ .addDontOptimize()
.run(parameters.getRuntime(), TestRunner.class, Boolean.toString(isDalvik))
.assertSuccess()
.getStdOut();
diff --git a/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordTest.java b/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordTest.java
index 389744e..817114e 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordTest.java
@@ -11,7 +11,6 @@
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRuntime.CfRuntime;
import com.android.tools.r8.utils.StringUtils;
-import java.nio.file.Path;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -55,7 +54,6 @@
.addProgramClassFileData(PROGRAM_DATA)
.setMinApi(parameters.getApiLevel())
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
.compile()
.run(parameters.getRuntime(), MAIN_TYPE)
.assertSuccessWithOutput(EXPECTED_RESULT);
@@ -64,21 +62,16 @@
@Test
public void testR8() throws Exception {
if (parameters.isCfRuntime()) {
- Path output =
- testForR8(parameters.getBackend())
- .addProgramClassFileData(PROGRAM_DATA)
- .setMinApi(parameters.getApiLevel())
- .addKeepRules(RECORD_KEEP_RULE)
- .addKeepMainRule(MAIN_TYPE)
- .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
- .addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
- .compile()
- .writeToZip();
- RecordTestUtils.assertRecordsAreRecords(output);
- testForJvm()
- .addRunClasspathFiles(output)
- .enablePreview()
+ testForR8(parameters.getBackend())
+ .addProgramClassFileData(PROGRAM_DATA)
+ .setMinApi(parameters.getApiLevel())
+ .addKeepRules(RECORD_KEEP_RULE)
+ .addKeepMainRule(MAIN_TYPE)
+ .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
+ .addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
+ .compile()
+ .inspect(RecordTestUtils::assertRecordsAreRecords)
+ .enableJVMPreview()
.run(parameters.getRuntime(), MAIN_TYPE)
.assertSuccessWithOutput(EXPECTED_RESULT);
return;
@@ -89,7 +82,6 @@
.addKeepRules(RECORD_KEEP_RULE)
.addKeepMainRule(MAIN_TYPE)
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
.compile()
.run(parameters.getRuntime(), MAIN_TYPE)
.assertSuccessWithOutput(EXPECTED_RESULT);
diff --git a/src/test/java/com/android/tools/r8/desugar/records/InvalidRecordAttributeTest.java b/src/test/java/com/android/tools/r8/desugar/records/InvalidRecordAttributeTest.java
deleted file mode 100644
index 7064af6..0000000
--- a/src/test/java/com/android/tools/r8/desugar/records/InvalidRecordAttributeTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.desugar.records;
-
-import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.junit.Assert.assertThrows;
-
-import com.android.tools.r8.CompilationFailedException;
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestDiagnosticMessages;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestRuntime.CfRuntime;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import java.util.List;
-import org.junit.Assume;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-/** Remove this test when Records are supported by default. */
-@RunWith(Parameterized.class)
-public class InvalidRecordAttributeTest extends TestBase {
-
- private final TestParameters parameters;
- private final Backend backend;
-
- private static final String EMPTY_RECORD = "EmptyRecord";
- private static final byte[][] EMPTY_RECORD_PROGRAM_DATA =
- RecordTestUtils.getProgramData(EMPTY_RECORD);
- private static final String SIMPLE_RECORD = "SimpleRecord";
- private static final byte[][] SIMPLE_RECORD_PROGRAM_DATA =
- RecordTestUtils.getProgramData(SIMPLE_RECORD);
-
- @Parameters(name = "{0} back: {1}")
- public static List<Object[]> data() {
- // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk16).
- return buildParameters(
- getTestParameters().withCustomRuntime(CfRuntime.getCheckedInJdk16()).build(),
- Backend.values());
- }
-
- public InvalidRecordAttributeTest(TestParameters parameters, Backend backend) {
- this.parameters = parameters;
- this.backend = backend;
- }
-
- @Test
- public void testD8EmptyRecord() throws Exception {
- Assume.assumeTrue(backend.isDex());
- assertThrows(
- CompilationFailedException.class,
- () -> {
- testForD8(backend)
- .addProgramClassFileData(EMPTY_RECORD_PROGRAM_DATA)
- .setMinApi(AndroidApiLevel.B)
- .compileWithExpectedDiagnostics(
- InvalidRecordAttributeTest::assertUnsupportedRecordError);
- });
- }
-
- @Test
- public void testD8SimpleRecord() throws Exception {
- Assume.assumeTrue(backend.isDex());
- assertThrows(
- CompilationFailedException.class,
- () -> {
- testForD8(backend)
- .addProgramClassFileData(RecordTestUtils.getProgramData(SIMPLE_RECORD))
- .setMinApi(AndroidApiLevel.B)
- .compileWithExpectedDiagnostics(
- InvalidRecordAttributeTest::assertUnsupportedRecordError);
- });
- }
-
- @Test
- public void testR8EmptyRecord() throws Exception {
- assertThrows(
- CompilationFailedException.class,
- () -> {
- testForR8(backend)
- .addProgramClassFileData(EMPTY_RECORD_PROGRAM_DATA)
- .setMinApi(AndroidApiLevel.B)
- .addKeepMainRule(RecordTestUtils.getMainType(EMPTY_RECORD))
- .compileWithExpectedDiagnostics(
- InvalidRecordAttributeTest::assertUnsupportedRecordError);
- });
- }
-
- @Test
- public void testR8SimpleRecord() throws Exception {
- assertThrows(
- CompilationFailedException.class,
- () -> {
- testForR8(backend)
- .addProgramClassFileData(SIMPLE_RECORD_PROGRAM_DATA)
- .setMinApi(AndroidApiLevel.B)
- .addKeepMainRule(RecordTestUtils.getMainType(SIMPLE_RECORD))
- .compileWithExpectedDiagnostics(
- InvalidRecordAttributeTest::assertUnsupportedRecordError);
- });
- }
-
- private static void assertUnsupportedRecordError(TestDiagnosticMessages diagnostics) {
- diagnostics.assertErrorThatMatches(
- diagnosticMessage(containsString("Records are not supported")));
- }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordInstanceOfTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordInstanceOfTest.java
index 08b0e85..6d0f1a3 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordInstanceOfTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordInstanceOfTest.java
@@ -11,7 +11,6 @@
import com.android.tools.r8.TestRuntime.CfRuntime;
import com.android.tools.r8.utils.InternalOptions.TestingOptions;
import com.android.tools.r8.utils.StringUtils;
-import java.nio.file.Path;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -55,7 +54,6 @@
.addProgramClassFileData(PROGRAM_DATA)
.setMinApi(parameters.getApiLevel())
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
.compile()
.run(parameters.getRuntime(), MAIN_TYPE)
.assertSuccessWithOutput(EXPECTED_RESULT);
@@ -64,21 +62,16 @@
@Test
public void testR8() throws Exception {
if (parameters.isCfRuntime()) {
- Path output =
- testForR8(parameters.getBackend())
- .addProgramClassFileData(PROGRAM_DATA)
- .setMinApi(parameters.getApiLevel())
- .addKeepRules(RECORD_KEEP_RULE)
- .addKeepMainRule(MAIN_TYPE)
- .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
- .addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
- .compile()
- .writeToZip();
- RecordTestUtils.assertRecordsAreRecords(output);
- testForJvm()
- .addRunClasspathFiles(output)
- .enablePreview()
+ testForR8(parameters.getBackend())
+ .addProgramClassFileData(PROGRAM_DATA)
+ .setMinApi(parameters.getApiLevel())
+ .addKeepRules(RECORD_KEEP_RULE)
+ .addKeepMainRule(MAIN_TYPE)
+ .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
+ .addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
+ .compile()
+ .inspect(RecordTestUtils::assertRecordsAreRecords)
+ .enableJVMPreview()
.run(parameters.getRuntime(), MAIN_TYPE)
.assertSuccessWithOutput(EXPECTED_RESULT);
return;
@@ -89,7 +82,6 @@
.addKeepRules(RECORD_KEEP_RULE)
.addKeepMainRule(MAIN_TYPE)
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
.compile()
.run(parameters.getRuntime(), MAIN_TYPE)
.assertSuccessWithOutput(EXPECTED_RESULT);
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomSplitDesugaringTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomSplitDesugaringTest.java
index 206fc03..0383285 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomSplitDesugaringTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomSplitDesugaringTest.java
@@ -56,14 +56,12 @@
.addProgramClassFileData(PROGRAM_DATA)
.setMinApi(parameters.getApiLevel())
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
.compile()
.writeToZip();
testForD8(parameters.getBackend())
.addProgramFiles(desugared)
.setMinApi(parameters.getApiLevel())
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
.compile()
.run(parameters.getRuntime(), MAIN_TYPE)
.assertSuccessWithOutput(EXPECTED_RESULT);
@@ -76,7 +74,6 @@
.addProgramClassFileData(PROGRAM_DATA)
.setMinApi(parameters.getApiLevel())
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
.compile()
.writeToZip();
testForR8(parameters.getBackend())
@@ -85,7 +82,6 @@
.addKeepRules(RECORD_KEEP_RULE)
.addKeepMainRule(MAIN_TYPE)
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
.compile()
.run(parameters.getRuntime(), MAIN_TYPE)
.assertSuccessWithOutput(EXPECTED_RESULT);
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomTest.java
index 9bf3327..3326483 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomTest.java
@@ -11,7 +11,6 @@
import com.android.tools.r8.TestRuntime.CfRuntime;
import com.android.tools.r8.utils.InternalOptions.TestingOptions;
import com.android.tools.r8.utils.StringUtils;
-import java.nio.file.Path;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -68,7 +67,6 @@
.addProgramClassFileData(PROGRAM_DATA)
.setMinApi(parameters.getApiLevel())
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
.compile()
.run(parameters.getRuntime(), MAIN_TYPE)
.assertSuccessWithOutput(EXPECTED_RESULT);
@@ -77,21 +75,16 @@
@Test
public void testR8() throws Exception {
if (parameters.isCfRuntime()) {
- Path output =
- testForR8(parameters.getBackend())
- .addProgramClassFileData(PROGRAM_DATA)
- .setMinApi(parameters.getApiLevel())
- .addKeepRules(RECORD_KEEP_RULE)
- .addKeepMainRule(MAIN_TYPE)
- .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
- .addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
- .compile()
- .writeToZip();
- RecordTestUtils.assertRecordsAreRecords(output);
- testForJvm()
- .addRunClasspathFiles(output)
- .enablePreview()
+ testForR8(parameters.getBackend())
+ .addProgramClassFileData(PROGRAM_DATA)
+ .setMinApi(parameters.getApiLevel())
+ .addKeepRules(RECORD_KEEP_RULE)
+ .addKeepMainRule(MAIN_TYPE)
+ .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
+ .addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
+ .compile()
+ .inspect(RecordTestUtils::assertRecordsAreRecords)
+ .enableJVMPreview()
.run(parameters.getRuntime(), MAIN_TYPE)
.assertSuccessWithOutput(EXPECTED_RESULT);
return;
@@ -102,7 +95,6 @@
.addKeepRules(RECORD_KEEP_RULE)
.addKeepMainRule(MAIN_TYPE)
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
.compile()
.run(parameters.getRuntime(), MAIN_TYPE)
.assertSuccessWithOutput(EXPECTED_RESULT);
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java
index 240e128..ef11ef4 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java
@@ -56,7 +56,6 @@
.addProgramClassFileData(PROGRAM_DATA_1)
.setMinApi(parameters.getApiLevel())
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
.compile()
.writeToZip();
Path output2 =
@@ -64,7 +63,6 @@
.addProgramClassFileData(PROGRAM_DATA_2)
.setMinApi(parameters.getApiLevel())
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
.compile()
.writeToZip();
D8TestCompileResult result =
@@ -84,7 +82,6 @@
.addProgramClassFileData(PROGRAM_DATA_1)
.setMinApi(parameters.getApiLevel())
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
.compile()
.writeToZip();
D8TestCompileResult result =
@@ -93,7 +90,6 @@
.addProgramClassFileData(PROGRAM_DATA_2)
.setMinApi(parameters.getApiLevel())
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
.compile();
result.run(parameters.getRuntime(), MAIN_TYPE_1).assertSuccessWithOutput(EXPECTED_RESULT_1);
result.run(parameters.getRuntime(), MAIN_TYPE_2).assertSuccessWithOutput(EXPECTED_RESULT_2);
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordReflectionTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordReflectionTest.java
index 9663f43..cad3c5b 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordReflectionTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordReflectionTest.java
@@ -11,7 +11,6 @@
import com.android.tools.r8.TestRuntime.CfRuntime;
import com.android.tools.r8.utils.InternalOptions.TestingOptions;
import com.android.tools.r8.utils.StringUtils;
-import java.nio.file.Path;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -59,21 +58,16 @@
@Test
public void testR8Cf() throws Exception {
- Path output =
- testForR8(parameters.getBackend())
- .addProgramClassFileData(PROGRAM_DATA)
- .setMinApi(parameters.getApiLevel())
- .addKeepRules(RECORD_KEEP_RULE)
- .addKeepMainRule(MAIN_TYPE)
- .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
- .addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
- .compile()
- .writeToZip();
- RecordTestUtils.assertRecordsAreRecords(output);
- testForJvm()
- .addRunClasspathFiles(output)
- .enablePreview()
+ testForR8(parameters.getBackend())
+ .addProgramClassFileData(PROGRAM_DATA)
+ .setMinApi(parameters.getApiLevel())
+ .addKeepRules(RECORD_KEEP_RULE)
+ .addKeepMainRule(MAIN_TYPE)
+ .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
+ .addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
+ .compile()
+ .inspect(RecordTestUtils::assertRecordsAreRecords)
+ .enableJVMPreview()
.run(parameters.getRuntime(), MAIN_TYPE)
.assertSuccessWithOutput(EXPECTED_RESULT);
}
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordTestUtils.java b/src/test/java/com/android/tools/r8/desugar/records/RecordTestUtils.java
index 86e30a6..224a873 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordTestUtils.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordTestUtils.java
@@ -5,6 +5,8 @@
package com.android.tools.r8.desugar.records;
import static com.android.tools.r8.TestRuntime.getCheckedInJdk8;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsent;
+import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.JavaCompilerTool;
@@ -98,13 +100,15 @@
return result.toArray(new byte[0][0]);
}
- public static void assertRecordsAreRecords(Path output) throws IOException {
- CodeInspector inspector =
- new CodeInspector(output, opt -> opt.testing.enableExperimentalRecordDesugaring = true);
+ public static void assertRecordsAreRecords(CodeInspector inspector) {
for (FoundClassSubject clazz : inspector.allClasses()) {
if (clazz.getDexProgramClass().superType.toString().equals("java.lang.Record")) {
assertTrue(clazz.getDexProgramClass().isRecord());
}
}
}
+
+ public static void assertNoJavaLangRecord(CodeInspector inspector) {
+ assertThat(inspector.clazz("java.lang.Record"), isAbsent());
+ }
}
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordWithMembersTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordWithMembersTest.java
index 36b2377..4b2c62a 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordWithMembersTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordWithMembersTest.java
@@ -11,7 +11,6 @@
import com.android.tools.r8.TestRuntime.CfRuntime;
import com.android.tools.r8.utils.InternalOptions.TestingOptions;
import com.android.tools.r8.utils.StringUtils;
-import java.nio.file.Path;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -57,7 +56,6 @@
.addProgramClassFileData(PROGRAM_DATA)
.setMinApi(parameters.getApiLevel())
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
.compile()
.run(parameters.getRuntime(), MAIN_TYPE)
.assertSuccessWithOutput(EXPECTED_RESULT);
@@ -66,21 +64,16 @@
@Test
public void testR8() throws Exception {
if (parameters.isCfRuntime()) {
- Path output =
- testForR8(parameters.getBackend())
- .addProgramClassFileData(PROGRAM_DATA)
- .setMinApi(parameters.getApiLevel())
- .addKeepRules(RECORD_KEEP_RULE)
- .addKeepMainRule(MAIN_TYPE)
- .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
- .addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
- .compile()
- .writeToZip();
- RecordTestUtils.assertRecordsAreRecords(output);
- testForJvm()
- .addRunClasspathFiles(output)
- .enablePreview()
+ testForR8(parameters.getBackend())
+ .addProgramClassFileData(PROGRAM_DATA)
+ .setMinApi(parameters.getApiLevel())
+ .addKeepRules(RECORD_KEEP_RULE)
+ .addKeepMainRule(MAIN_TYPE)
+ .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
+ .addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
+ .compile()
+ .inspect(RecordTestUtils::assertRecordsAreRecords)
+ .enableJVMPreview()
.run(parameters.getRuntime(), MAIN_TYPE)
.assertSuccessWithOutput(EXPECTED_RESULT);
return;
@@ -91,7 +84,6 @@
.addKeepRules(RECORD_KEEP_RULE)
.addKeepMainRule(MAIN_TYPE)
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
.compile()
.run(parameters.getRuntime(), MAIN_TYPE)
.assertSuccessWithOutput(EXPECTED_RESULT);
diff --git a/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java b/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
index 08c9468..ad338ed 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
@@ -11,7 +11,6 @@
import com.android.tools.r8.TestRuntime.CfRuntime;
import com.android.tools.r8.utils.InternalOptions.TestingOptions;
import com.android.tools.r8.utils.StringUtils;
-import java.nio.file.Path;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -56,8 +55,10 @@
.addProgramClassFileData(PROGRAM_DATA)
.setMinApi(parameters.getApiLevel())
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
.compile()
+ .inspectWithOptions(
+ RecordTestUtils::assertNoJavaLangRecord,
+ options -> options.testing.disableRecordApplicationReaderMap = true)
.run(parameters.getRuntime(), MAIN_TYPE)
.assertSuccessWithOutput(EXPECTED_RESULT);
}
@@ -65,21 +66,16 @@
@Test
public void testR8() throws Exception {
if (parameters.isCfRuntime()) {
- Path output =
- testForR8(parameters.getBackend())
- .addProgramClassFileData(PROGRAM_DATA)
- .setMinApi(parameters.getApiLevel())
- .addKeepRules(RECORD_KEEP_RULE)
- .addKeepMainRule(MAIN_TYPE)
- .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
- .addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
- .compile()
- .writeToZip();
- RecordTestUtils.assertRecordsAreRecords(output);
- testForJvm()
- .addRunClasspathFiles(output)
- .enablePreview()
+ testForR8(parameters.getBackend())
+ .addProgramClassFileData(PROGRAM_DATA)
+ .setMinApi(parameters.getApiLevel())
+ .addKeepRules(RECORD_KEEP_RULE)
+ .addKeepMainRule(MAIN_TYPE)
+ .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
+ .addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
+ .compile()
+ .inspect(RecordTestUtils::assertRecordsAreRecords)
+ .enableJVMPreview()
.run(parameters.getRuntime(), MAIN_TYPE)
.assertSuccessWithOutput(EXPECTED_RESULT);
return;
@@ -90,8 +86,43 @@
.addKeepRules(RECORD_KEEP_RULE)
.addKeepMainRule(MAIN_TYPE)
.addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
- .addOptionsModification(opt -> opt.testing.enableExperimentalRecordDesugaring = true)
.compile()
+ .inspectWithOptions(
+ RecordTestUtils::assertNoJavaLangRecord,
+ options -> options.testing.disableRecordApplicationReaderMap = true)
+ .run(parameters.getRuntime(), MAIN_TYPE)
+ .assertSuccessWithOutput(EXPECTED_RESULT);
+ }
+
+ @Test
+ public void testR8NoMinification() throws Exception {
+ if (parameters.isCfRuntime()) {
+ testForR8(parameters.getBackend())
+ .addProgramClassFileData(PROGRAM_DATA)
+ .noMinification()
+ .setMinApi(parameters.getApiLevel())
+ .addKeepRules(RECORD_KEEP_RULE)
+ .addKeepMainRule(MAIN_TYPE)
+ .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
+ .addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
+ .compile()
+ .inspect(RecordTestUtils::assertRecordsAreRecords)
+ .enableJVMPreview()
+ .run(parameters.getRuntime(), MAIN_TYPE)
+ .assertSuccessWithOutput(EXPECTED_RESULT);
+ return;
+ }
+ testForR8(parameters.getBackend())
+ .addProgramClassFileData(PROGRAM_DATA)
+ .noMinification()
+ .setMinApi(parameters.getApiLevel())
+ .addKeepRules(RECORD_KEEP_RULE)
+ .addKeepMainRule(MAIN_TYPE)
+ .addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
+ .compile()
+ .inspectWithOptions(
+ RecordTestUtils::assertNoJavaLangRecord,
+ options -> options.testing.disableRecordApplicationReaderMap = true)
.run(parameters.getRuntime(), MAIN_TYPE)
.assertSuccessWithOutput(EXPECTED_RESULT);
}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningOptimize.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningOptimize.java
new file mode 100644
index 0000000..0c0bac6
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningOptimize.java
@@ -0,0 +1,47 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.ir.optimize.inliner;
+
+import static org.junit.Assert.assertFalse;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.utils.codeinspector.InstructionSubject;
+import org.junit.Test;
+
+class Foobar {
+ public static void main(String[] args) {
+ System.out.println("Value: " + (new Bar()).returnPlusConstant(42));
+ }
+}
+
+class Bar {
+ public int returnPlusConstant(int value) {
+ return value + 42;
+ }
+}
+
+public class InliningOptimize extends TestBase {
+
+ @Test
+ public void test() throws Exception {
+ testForR8(Backend.DEX)
+ .addProgramClasses(Bar.class, Foobar.class)
+ .addKeepRules("-keep,allowoptimization class ** {\n" + "*;\n" + "}")
+ .compile()
+ .inspect(
+ inspector -> {
+ inspector
+ .clazz(Foobar.class)
+ .mainMethod()
+ .iterateInstructions(InstructionSubject::isInvoke)
+ .forEachRemaining(
+ invoke -> {
+ assertFalse(
+ invoke.getMethod().name.toString().contains("returnPlusConstant"));
+ });
+ })
+ .run(Foobar.class)
+ .assertSuccessWithOutputLines("Value: 84");
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataPrunedFieldsTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataPrunedFieldsTest.java
index 09c2a9d..505169e 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataPrunedFieldsTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataPrunedFieldsTest.java
@@ -54,6 +54,13 @@
.allowDiagnosticWarningMessages()
.setMinApi(parameters.getApiLevel())
.addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS)
+ .addOptionsModification(
+ internalOptions -> {
+ // When checking for metadata being equal if not rewritten, we parse the original data
+ // again. However, for this particular test, a field of the metadata has been removed
+ // and we cannot parse the metadata again.
+ internalOptions.testing.keepMetadataInR8IfNotRewritten = false;
+ })
.compile()
.inspect(
codeInspector -> {
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewritePassThroughTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewritePassThroughTest.java
index 717bf12..b175132 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewritePassThroughTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewritePassThroughTest.java
@@ -75,9 +75,6 @@
testForD8(Backend.DEX)
.addProgramFiles(getKotlinStdlibJar(kotlinc), getKotlinAnnotationJar(kotlinc))
.setMinApi(AndroidApiLevel.B)
- // Enable record desugaring support to force a non-identity naming lens
- .addOptionsModification(
- options -> options.testing.enableExperimentalRecordDesugaring = true)
.compile()
.inspect(
inspector ->
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteUnitPrimitiveTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteUnitPrimitiveTest.java
new file mode 100644
index 0000000..fafb083
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteUnitPrimitiveTest.java
@@ -0,0 +1,158 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.kotlin.metadata;
+
+import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MIN_SUPPORTED_VERSION;
+import static com.android.tools.r8.ToolHelper.KotlinTargetVersion.JAVA_8;
+import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar;
+import static com.android.tools.r8.ToolHelper.getKotlinReflectJar;
+import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertNull;
+
+import com.android.tools.r8.KotlinTestParameters;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.kotlin.KotlinMetadataWriter;
+import com.android.tools.r8.shaking.ProguardKeepAttributes;
+import com.android.tools.r8.utils.DescriptorUtils;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Collection;
+import junit.framework.TestCase;
+import kotlinx.metadata.jvm.KotlinClassHeader;
+import kotlinx.metadata.jvm.KotlinClassMetadata;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class MetadataRewriteUnitPrimitiveTest extends KotlinMetadataTestBase {
+
+ private static final String PKG_LIB = PKG + ".unit_primitive_lib";
+ private static final String PKG_APP = PKG + ".unit_primitive_app";
+ private final TestParameters parameters;
+
+ private static final String EXPECTED =
+ StringUtils.lines(
+ "fun " + PKG_LIB + ".Lib.testInt(): kotlin.Int",
+ "42",
+ "fun " + PKG_LIB + ".Lib.testIntArray(): kotlin.IntArray",
+ "42",
+ "fun " + PKG_LIB + ".Lib.testUInt(): kotlin.UInt",
+ "42",
+ "fun " + PKG_LIB + ".Lib.testUIntArray(): kotlin.UIntArray",
+ "UIntArray(storage=[42])",
+ "fun " + PKG_LIB + ".Lib.testUnit(): kotlin.Unit",
+ "testUnit",
+ "kotlin.Unit");
+
+ @Parameterized.Parameters(name = "{0}, {1}")
+ public static Collection<Object[]> data() {
+ return buildParameters(
+ getTestParameters().withCfRuntimes().build(),
+ getKotlinTestParameters()
+ .withCompilersStartingFromIncluding(MIN_SUPPORTED_VERSION)
+ .withTargetVersion(JAVA_8)
+ .build());
+ }
+
+ public MetadataRewriteUnitPrimitiveTest(
+ TestParameters parameters, KotlinTestParameters kotlinParameters) {
+ super(kotlinParameters);
+ this.parameters = parameters;
+ }
+
+ private static final KotlinCompileMemoizer kotlincLibJar =
+ getCompileMemoizer(
+ getKotlinFileInTest(DescriptorUtils.getBinaryNameFromJavaType(PKG_LIB), "lib"));
+
+ @Test
+ public void smokeTest() throws Exception {
+ Path output =
+ kotlinc(parameters.getRuntime().asCf(), kotlinc, targetVersion)
+ .addClasspathFiles(kotlincLibJar.getForConfiguration(kotlinc, targetVersion))
+ .addSourceFiles(
+ getKotlinFileInTest(DescriptorUtils.getBinaryNameFromJavaType(PKG_APP), "main"))
+ .setOutputPath(temp.newFolder().toPath())
+ .compile();
+ testForJvm()
+ .addRunClasspathFiles(
+ getKotlinStdlibJar(kotlinc),
+ getKotlinReflectJar(kotlinc),
+ kotlincLibJar.getForConfiguration(kotlinc, targetVersion))
+ .addClasspath(output)
+ .run(parameters.getRuntime(), PKG_APP + ".MainKt")
+ .assertSuccessWithOutput(EXPECTED);
+ }
+
+ @Test
+ public void testMetadataForLib() throws Exception {
+ Path libJar =
+ testForR8(parameters.getBackend())
+ .addClasspathFiles(getKotlinAnnotationJar(kotlinc))
+ .addProgramFiles(
+ kotlincLibJar.getForConfiguration(kotlinc, targetVersion),
+ getKotlinStdlibJar(kotlinc))
+ .addKeepClassAndMembersRules(PKG_LIB + ".*")
+ .addKeepAttributes(
+ ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS,
+ ProguardKeepAttributes.SIGNATURE,
+ ProguardKeepAttributes.INNER_CLASSES,
+ ProguardKeepAttributes.ENCLOSING_METHOD)
+ .addKeepKotlinMetadata()
+ .allowDiagnosticWarningMessages()
+ .compile()
+ .assertAllWarningMessagesMatch(
+ equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
+ .inspect(this::inspect)
+ .writeToZip();
+ Path main =
+ kotlinc(parameters.getRuntime().asCf(), kotlinc, targetVersion)
+ .addClasspathFiles(libJar)
+ .addSourceFiles(
+ getKotlinFileInTest(DescriptorUtils.getBinaryNameFromJavaType(PKG_APP), "main"))
+ .setOutputPath(temp.newFolder().toPath())
+ .compile();
+ testForJvm()
+ .addRunClasspathFiles(
+ getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinReflectJar(kotlinc), libJar)
+ .addClasspath(main)
+ .run(parameters.getRuntime(), PKG_APP + ".MainKt")
+ .assertSuccessWithOutput(EXPECTED);
+ }
+
+ private void inspect(CodeInspector inspector) throws IOException {
+ CodeInspector stdLibInspector =
+ new CodeInspector(kotlincLibJar.getForConfiguration(kotlinc, targetVersion));
+ for (FoundClassSubject clazzSubject : stdLibInspector.allClasses()) {
+ ClassSubject r8Clazz = inspector.clazz(clazzSubject.getOriginalName());
+ assertThat(r8Clazz, isPresent());
+ KotlinClassMetadata originalMetadata = clazzSubject.getKotlinClassMetadata();
+ KotlinClassMetadata rewrittenMetadata = r8Clazz.getKotlinClassMetadata();
+ if (originalMetadata == null) {
+ assertNull(rewrittenMetadata);
+ continue;
+ }
+ TestCase.assertNotNull(rewrittenMetadata);
+ KotlinClassHeader originalHeader = originalMetadata.getHeader();
+ KotlinClassHeader rewrittenHeader = rewrittenMetadata.getHeader();
+ TestCase.assertEquals(originalHeader.getKind(), rewrittenHeader.getKind());
+ TestCase.assertEquals(originalHeader.getPackageName(), rewrittenHeader.getPackageName());
+ Assert.assertArrayEquals(originalHeader.getData1(), rewrittenHeader.getData1());
+ Assert.assertArrayEquals(originalHeader.getData2(), rewrittenHeader.getData2());
+ String expected = KotlinMetadataWriter.kotlinMetadataToString("", originalMetadata);
+ String actual = KotlinMetadataWriter.kotlinMetadataToString("", rewrittenMetadata);
+ TestCase.assertEquals(expected, actual);
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/unit_primitive_app/main.kt b/src/test/java/com/android/tools/r8/kotlin/metadata/unit_primitive_app/main.kt
new file mode 100644
index 0000000..b3d5d3c
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/unit_primitive_app/main.kt
@@ -0,0 +1,21 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.kotlin.metadata.unit_primitive_app
+
+import com.android.tools.r8.kotlin.metadata.unit_primitive_lib.Lib
+import kotlin.reflect.full.declaredFunctions
+
+fun main() {
+ var lib = Lib();
+ lib::class.declaredFunctions.forEach({
+ println(it)
+ var msg = it.call(lib)
+ if (msg is IntArray) {
+ println(msg[0])
+ } else {
+ println(msg)
+ }
+ })
+}
\ No newline at end of file
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/unit_primitive_lib/lib.kt b/src/test/java/com/android/tools/r8/kotlin/metadata/unit_primitive_lib/lib.kt
new file mode 100644
index 0000000..65ae861
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/unit_primitive_lib/lib.kt
@@ -0,0 +1,26 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.kotlin.metadata.unit_primitive_lib
+
+class Lib {
+ fun testUnit() : Unit {
+ println("testUnit")
+ }
+
+ fun testInt() : Int {
+ return 42
+ }
+
+ fun testIntArray() : IntArray {
+ return intArrayOf(42)
+ }
+
+ fun testUInt() : UInt {
+ return 42u
+ }
+
+ fun testUIntArray() : UIntArray {
+ return uintArrayOf(42u)
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
index bcea2fe..42cd647 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
@@ -391,6 +391,7 @@
.setMinApi(minSdk)
.noMinification()
.noTreeShaking()
+ .addDontOptimize()
.setMainDexListConsumer(ToolHelper.consumeString(r8MainDexListOutput::set))
.allowDiagnosticMessages()
.compileWithExpectedDiagnostics(
diff --git a/src/test/java/com/android/tools/r8/resolution/InvokeCustomOnNonOverriddenInterfaceMethodTest.java b/src/test/java/com/android/tools/r8/resolution/InvokeCustomOnNonOverriddenInterfaceMethodTest.java
new file mode 100644
index 0000000..eaf6a35
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/resolution/InvokeCustomOnNonOverriddenInterfaceMethodTest.java
@@ -0,0 +1,115 @@
+// 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.resolution;
+
+import static com.android.tools.r8.references.Reference.classFromClass;
+import static com.android.tools.r8.references.Reference.methodFromMethod;
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.SingleTestRunResult;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
+import com.android.tools.r8.references.ClassReference;
+import com.android.tools.r8.references.MethodReference;
+import com.android.tools.r8.utils.structural.Ordered;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.WrongMethodTypeException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Opcodes;
+
+/** Regression for b/116283747. */
+@RunWith(Parameterized.class)
+public class InvokeCustomOnNonOverriddenInterfaceMethodTest extends TestBase {
+
+ private static final String[] EXPECTED = new String[] {"I.target"};
+
+ private final TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters()
+ .withAllRuntimes()
+ .withApiLevelsStartingAtIncluding(
+ Ordered.max(apiLevelWithInvokeCustomSupport(), apiLevelWithConstMethodHandleSupport()))
+ .build();
+ }
+
+ public InvokeCustomOnNonOverriddenInterfaceMethodTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
+
+ @Test
+ public void testRuntime() throws Throwable {
+ testForRuntime(parameters)
+ .addProgramClasses(Main.class, I.class, Super.class)
+ .addProgramClassFileData(getInvokeCustomTransform())
+ .run(parameters.getRuntime(), Main.class)
+ .apply(this::checkRunResult);
+ }
+
+ private void checkRunResult(SingleTestRunResult<?> result) {
+ if (parameters.isCfRuntime()
+ || parameters.asDexRuntime().getVersion().isNewerThanOrEqual(Version.V10_0_0)) {
+ result.assertSuccessWithOutputLines(EXPECTED);
+ } else {
+ // Fails due to b/115964401.
+ assertEquals(Version.V9_0_0, parameters.getDexRuntimeVersion());
+ result.assertFailureWithErrorThatThrows(WrongMethodTypeException.class);
+ }
+ }
+
+ private static byte[] getInvokeCustomTransform() throws Throwable {
+ ClassReference symbolicHolder = classFromClass(InvokeCustom.class);
+ MethodReference method = methodFromMethod(InvokeCustom.class.getMethod("target"));
+ return transformer(InvokeCustom.class)
+ .transformMethodInsnInMethod(
+ "test",
+ (opcode, owner, name, descriptor, isInterface, visitor) -> {
+ // Replace null argument by a const method handle.
+ visitor.visitInsn(Opcodes.POP);
+ visitor.visitLdcInsn(
+ new Handle(
+ Opcodes.H_INVOKEVIRTUAL,
+ symbolicHolder.getBinaryName(),
+ method.getMethodName(),
+ method.getMethodDescriptor(),
+ false));
+ visitor.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
+ })
+ .transform();
+ }
+
+ interface I {
+ default void target() {
+ System.out.println("I.target");
+ }
+ }
+
+ static class Super implements I {}
+
+ static class InvokeCustom extends Super {
+
+ public static void doInvokeExact(MethodHandle handle) throws Throwable {
+ handle.invokeExact(new InvokeCustom());
+ }
+
+ public static void test() throws Throwable {
+ doInvokeExact(null /* will be const method handle */);
+ }
+ }
+
+ static class Main {
+
+ public static void main(String[] args) throws Throwable {
+ InvokeCustom.test();
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/resolution/InvokePolymorphicResolutionTest.java b/src/test/java/com/android/tools/r8/resolution/InvokePolymorphicResolutionTest.java
new file mode 100644
index 0000000..1b0af62
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/resolution/InvokePolymorphicResolutionTest.java
@@ -0,0 +1,70 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.resolution;
+
+import static com.android.tools.r8.references.Reference.classFromClass;
+import static com.android.tools.r8.references.Reference.methodFromMethod;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import com.android.tools.r8.TestAppViewBuilder;
+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.graph.AppInfoWithClassHierarchy;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.MethodResolutionResult;
+import com.android.tools.r8.references.MethodReference;
+import com.android.tools.r8.references.Reference;
+import java.lang.invoke.MethodHandle;
+import java.util.Collections;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class InvokePolymorphicResolutionTest extends TestBase {
+
+ @Parameterized.Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withNoneRuntime().build();
+ }
+
+ public InvokePolymorphicResolutionTest(TestParameters parameters) {
+ parameters.assertNoneRuntime();
+ }
+
+ @Test
+ public void testResolution() throws Exception {
+ // Note: this could just as well resolve without liveness.
+ AppView<? extends AppInfoWithClassHierarchy> appView =
+ TestAppViewBuilder.builder()
+ .addLibraryFiles(ToolHelper.getJava8RuntimeJar())
+ .buildWithLiveness();
+
+ // An exact resolution will find invokeExact.
+ MethodReference invokeExact =
+ methodFromMethod(MethodHandle.class.getMethod("invokeExact", Object[].class));
+ MethodResolutionResult resolution1 =
+ appView.appInfo().resolveMethod(buildMethod(invokeExact, appView.dexItemFactory()), false);
+ assertFalse(resolution1.isFailedResolution());
+
+ // An inexact signature should also find invokeExact.
+ MethodReference inexactInvokeExact =
+ Reference.method(
+ invokeExact.getHolderClass(),
+ invokeExact.getMethodName(),
+ Collections.singletonList(Reference.array(classFromClass(getClass()), 1)),
+ invokeExact.getReturnType());
+ MethodResolutionResult resolution2 =
+ appView
+ .appInfo()
+ .resolveMethod(buildMethod(inexactInvokeExact, appView.dexItemFactory()), false);
+ assertFalse(resolution2.isFailedResolution());
+
+ // The should both be the same MethodHandle.invokeExact method.
+ assertEquals(resolution1.getSingleTarget(), resolution2.getSingleTarget());
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/resolution/interfacetargets/MissingInterfaceVirtualTargetsTest.java b/src/test/java/com/android/tools/r8/resolution/interfacetargets/MissingInterfaceVirtualTargetsTest.java
new file mode 100644
index 0000000..afb96e2
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/resolution/interfacetargets/MissingInterfaceVirtualTargetsTest.java
@@ -0,0 +1,77 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.resolution.interfacetargets;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.StringUtils;
+import java.nio.file.Path;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class MissingInterfaceVirtualTargetsTest extends TestBase {
+
+ static final String EXPECTED = StringUtils.lines("I.foo", "I.foo");
+
+ private final TestParameters parameters;
+
+ @Parameterized.Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters()
+ .withAllRuntimes()
+ .withApiLevel(AndroidApiLevel.B)
+ .enableApiLevelsForCf()
+ .build();
+ }
+
+ public MissingInterfaceVirtualTargetsTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
+
+ @Test
+ public void test() throws Exception {
+ Path out =
+ testForD8(parameters.getBackend())
+ .addProgramClasses(TestClass.class)
+ .setMinApi(parameters.getApiLevel())
+ .compile()
+ .assertNoMessages()
+ .writeToZip();
+ testForD8(parameters.getBackend())
+ .addProgramClasses(I.class, A.class)
+ .setMinApi(parameters.getApiLevel())
+ .addRunClasspathFiles(out)
+ .run(parameters.getRuntime(), TestClass.class)
+ .assertSuccessWithOutput(EXPECTED);
+ }
+
+ interface I {
+ default void foo() {
+ System.out.println("I.foo");
+ }
+ }
+
+ static class A implements I {
+ // No override.
+ }
+
+ static class TestClass {
+
+ static void targetI(I i) {
+ // This invoke-interface target should not cause missing class warnings.
+ i.foo();
+ }
+
+ public static void main(String[] args) {
+ A a = new A();
+ targetI(a);
+ // This invoke-virtual target should not cause missing class warnings.
+ a.foo();
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/retrace/RetraceLambdaTest.java b/src/test/java/com/android/tools/r8/retrace/RetraceLambdaTest.java
index 252dcc5..d68447d 100644
--- a/src/test/java/com/android/tools/r8/retrace/RetraceLambdaTest.java
+++ b/src/test/java/com/android/tools/r8/retrace/RetraceLambdaTest.java
@@ -105,6 +105,7 @@
.addKeepMainRule(Main.class)
.addKeepPackageNamesRule(getClass().getPackage())
.noTreeShaking()
+ .addDontOptimize()
.addKeepAttributeSourceFile()
.addKeepAttributeLineNumberTable()
.setMinApi(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/retrace/RetraceTests.java b/src/test/java/com/android/tools/r8/retrace/RetraceTests.java
index 4506755..8cc0883 100644
--- a/src/test/java/com/android/tools/r8/retrace/RetraceTests.java
+++ b/src/test/java/com/android/tools/r8/retrace/RetraceTests.java
@@ -35,6 +35,7 @@
import com.android.tools.r8.retrace.stacktraces.InvalidStackTrace;
import com.android.tools.r8.retrace.stacktraces.MemberFieldOverlapStackTrace;
import com.android.tools.r8.retrace.stacktraces.MultipleDotsInFileNameStackTrace;
+import com.android.tools.r8.retrace.stacktraces.MultipleLinesNoLineNumberStackTrace;
import com.android.tools.r8.retrace.stacktraces.NamedModuleStackTrace;
import com.android.tools.r8.retrace.stacktraces.NoObfuscatedLineNumberWithOverrideTest;
import com.android.tools.r8.retrace.stacktraces.NoObfuscationRangeMappingWithStackTrace;
@@ -276,6 +277,11 @@
runRetraceTest(new SingleLineNoLineNumberStackTrace());
}
+ @Test
+ public void testMultipleLinesNoLineNumberStackTrace() throws Exception {
+ runRetraceTest(new MultipleLinesNoLineNumberStackTrace());
+ }
+
private void inspectRetraceTest(
StackTraceForTest stackTraceForTest, Consumer<Retracer> inspection) {
inspection.accept(
diff --git a/src/test/java/com/android/tools/r8/retrace/StackTraceRegularExpressionParserTests.java b/src/test/java/com/android/tools/r8/retrace/StackTraceRegularExpressionParserTests.java
index 40ec50f..f74fcda 100644
--- a/src/test/java/com/android/tools/r8/retrace/StackTraceRegularExpressionParserTests.java
+++ b/src/test/java/com/android/tools/r8/retrace/StackTraceRegularExpressionParserTests.java
@@ -416,7 +416,7 @@
@Override
public List<String> retracedStackTrace() {
- return ImmutableList.of("com.android.tools.r8.R8.foo()");
+ return ImmutableList.of("com.android.tools.r8.R8.foo(7)");
}
@Override
diff --git a/src/test/java/com/android/tools/r8/retrace/api/RetraceApiTestHelper.java b/src/test/java/com/android/tools/r8/retrace/api/RetraceApiTestHelper.java
index e73ce25..9c84754 100644
--- a/src/test/java/com/android/tools/r8/retrace/api/RetraceApiTestHelper.java
+++ b/src/test/java/com/android/tools/r8/retrace/api/RetraceApiTestHelper.java
@@ -43,7 +43,8 @@
RetraceApiSynthesizedFieldTest.ApiTest.class,
RetraceApiSynthesizedMethodTest.ApiTest.class,
RetraceApiSynthesizedFrameTest.ApiTest.class,
- RetraceApiSynthesizedInnerFrameTest.ApiTest.class);
+ RetraceApiSynthesizedInnerFrameTest.ApiTest.class,
+ RetraceApiUnknownJsonTest.ApiTest.class);
public static List<Class<? extends RetraceApiBinaryTest>> CLASSES_PENDING_BINARY_COMPATIBILITY =
ImmutableList.of();
diff --git a/src/test/java/com/android/tools/r8/retrace/api/RetraceApiUnknownJsonTest.java b/src/test/java/com/android/tools/r8/retrace/api/RetraceApiUnknownJsonTest.java
new file mode 100644
index 0000000..f11a75f
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/retrace/api/RetraceApiUnknownJsonTest.java
@@ -0,0 +1,94 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.retrace.api;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.Diagnostic;
+import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.retrace.ProguardMapProducer;
+import com.android.tools.r8.retrace.RetraceUnknownMappingInformationElement;
+import com.android.tools.r8.retrace.Retracer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class RetraceApiUnknownJsonTest extends RetraceApiTestBase {
+
+ public RetraceApiUnknownJsonTest(TestParameters parameters) {
+ super(parameters);
+ }
+
+ @Override
+ protected Class<? extends RetraceApiBinaryTest> binaryTestClass() {
+ return ApiTest.class;
+ }
+
+ public static class ApiTest implements RetraceApiBinaryTest {
+
+ private final String extraMapping =
+ "{\"id\":\"some.information.with.context\",\"value\":\"Hello World\"}";
+ private final String mapping =
+ "# { 'id': 'com.android.tools.r8.mapping', version: '1.0' }\n"
+ + "# { 'id': 'some.information.without.context' }\n"
+ + "some.Class -> a:\n"
+ + "# "
+ + extraMapping
+ + "\n"
+ + "# {'id': 'sourceFile','fileName':'SomeFileName.kt'}\n"
+ + " 1:3:int strawberry(int):99:101 -> s\n"
+ + " 4:5:int mango(float):121:122 -> s\n";
+
+ @Test
+ public void testRetracingSourceFile() {
+ TestDiagnosticsHandler diagnosticsHandler = new TestDiagnosticsHandler();
+ List<RetraceUnknownMappingInformationElement> mappingInfos =
+ Retracer.createDefault(ProguardMapProducer.fromString(mapping), diagnosticsHandler)
+ .retraceClass(Reference.classFromTypeName("a"))
+ .stream()
+ .flatMap(element -> element.getUnknownJsonMappingInformation().stream())
+ .collect(Collectors.toList());
+ assertEquals(1, mappingInfos.size());
+ RetraceUnknownMappingInformationElement unknownMapping = mappingInfos.get(0);
+ assertEquals("some.information.with.context", unknownMapping.getIdentifier());
+ assertEquals(extraMapping, unknownMapping.getPayLoad());
+
+ assertEquals(2, diagnosticsHandler.infoMessages.size());
+ assertEquals(
+ "Could not find a handler for some.information.without.context",
+ diagnosticsHandler.infoMessages.get(0).getDiagnosticMessage());
+ assertEquals(
+ "Could not find a handler for some.information.with.context",
+ diagnosticsHandler.infoMessages.get(1).getDiagnosticMessage());
+ }
+
+ private static class TestDiagnosticsHandler implements com.android.tools.r8.DiagnosticsHandler {
+
+ private List<Diagnostic> infoMessages = new ArrayList<>();
+
+ @Override
+ public void warning(Diagnostic warning) {
+ throw new RuntimeException("Warning not expected");
+ }
+
+ @Override
+ public void error(Diagnostic error) {
+ throw new RuntimeException("Error not expected");
+ }
+
+ @Override
+ public void info(Diagnostic info) {
+ DiagnosticsHandler.super.info(info);
+ infoMessages.add(info);
+ }
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousMethodVerboseStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousMethodVerboseStackTrace.java
index dcaaa58..3d3a1ee 100644
--- a/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousMethodVerboseStackTrace.java
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousMethodVerboseStackTrace.java
@@ -35,7 +35,7 @@
"\tat com.android.tools.r8.naming.retrace.Main.c(Main.java)",
"\tat com.android.tools.r8.naming.retrace.Main.com.android.Foo main("
+ "java.lang.String[])(Main.java)",
- "\t<OR> at com.android.tools.r8.naming.retrace.Main.void main("
+ "\t<OR #1> at com.android.tools.r8.naming.retrace.Main.void main("
+ "com.android.Bar)(Main.java)",
"\tat com.android.tools.r8.naming.retrace.Main.com.android.Foo main("
+ "java.lang.String[],com.android.Bar)(Main.java)");
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousMissingLineStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousMissingLineStackTrace.java
index b92190e..310390c 100644
--- a/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousMissingLineStackTrace.java
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousMissingLineStackTrace.java
@@ -27,13 +27,13 @@
return Arrays.asList(
"com.android.tools.r8.CompilationException: foo[parens](Source:3)",
" at com.android.tools.r8.R8.bar(R8.java:7)",
- " <OR> at com.android.tools.r8.R8.foo(R8.java:7)",
+ " <OR #1> at com.android.tools.r8.R8.foo(R8.java:7)",
" at com.android.tools.r8.R8.bar(R8.java:8)",
- " <OR> at com.android.tools.r8.R8.foo(R8.java:8)",
+ " <OR #1> at com.android.tools.r8.R8.foo(R8.java:8)",
" at com.android.tools.r8.R8.main(Unknown Source)",
"Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)",
" at com.android.tools.r8.R8.bar(R8.java:9)",
- " <OR> at com.android.tools.r8.R8.foo(R8.java:9)",
+ " <OR #1> at com.android.tools.r8.R8.foo(R8.java:9)",
" ... 42 more");
}
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousStackTrace.java
index 429ee6b..38fbb08 100644
--- a/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousStackTrace.java
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/AmbiguousStackTrace.java
@@ -54,13 +54,13 @@
return Arrays.asList(
"com.android.tools.r8.CompilationException: foo[parens](Source:3)",
" at com.android.tools.r8.R8.bar(R8.java)",
- " <OR> at com.android.tools.r8.R8.foo(R8.java)",
+ " <OR #1> at com.android.tools.r8.R8.foo(R8.java)",
" at com.android.tools.r8.R8.bar(R8.java)",
- " <OR> at com.android.tools.r8.R8.foo(R8.java)",
+ " <OR #1> at com.android.tools.r8.R8.foo(R8.java)",
" at com.android.tools.r8.R8.main(Unknown Source)",
"Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)",
" at com.android.tools.r8.R8.bar(R8.java)",
- " <OR> at com.android.tools.r8.R8.foo(R8.java)",
+ " <OR #1> at com.android.tools.r8.R8.foo(R8.java)",
" ... 42 more");
}
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/MultipleLinesNoLineNumberStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/MultipleLinesNoLineNumberStackTrace.java
new file mode 100644
index 0000000..54ef0bf
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/MultipleLinesNoLineNumberStackTrace.java
@@ -0,0 +1,42 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.retrace.stacktraces;
+
+import com.android.tools.r8.utils.StringUtils;
+import java.util.Arrays;
+import java.util.List;
+
+public class MultipleLinesNoLineNumberStackTrace implements StackTraceForTest {
+
+ @Override
+ public List<String> obfuscatedStackTrace() {
+ return Arrays.asList(
+ "Exception in thread \"main\" java.lang.NullPointerException",
+ "\tat foo.a.a(Unknown Source)");
+ }
+
+ @Override
+ public String mapping() {
+ return StringUtils.lines(
+ "com.android.tools.r8.naming.retrace.Main -> foo.a:",
+ " 0:0:void method1(java.lang.String):42:42 -> a",
+ " 0:0:void main(java.lang.String[]):28 -> a",
+ " 1:1:void main(java.lang.String[]):153 -> a");
+ }
+
+ @Override
+ public List<String> retracedStackTrace() {
+ return Arrays.asList(
+ "Exception in thread \"main\" java.lang.NullPointerException",
+ "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java)",
+ "\t<OR #1> at com.android.tools.r8.naming.retrace.Main.method1(Main.java)",
+ "\t<OR #1> at com.android.tools.r8.naming.retrace.Main.main(Main.java)");
+ }
+
+ @Override
+ public int expectedWarnings() {
+ return 0;
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/NoObfuscatedLineNumberWithOverrideTest.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/NoObfuscatedLineNumberWithOverrideTest.java
index 3f11112..23c5652 100644
--- a/src/test/java/com/android/tools/r8/retrace/stacktraces/NoObfuscatedLineNumberWithOverrideTest.java
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/NoObfuscatedLineNumberWithOverrideTest.java
@@ -36,11 +36,11 @@
public List<String> retracedStackTrace() {
return Arrays.asList(
"Exception in thread \"main\" java.lang.NullPointerException",
- // TODO(b/191513686): Could be retrace to ...Main.main(Main.java:3)
- "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java)",
- "\tat com.android.tools.r8.naming.retrace.Main.overload1(Main.java)",
- "\t<OR> at com.android.tools.r8.naming.retrace.Main.overload2(Main.java)",
- "\tat com.android.tools.r8.naming.retrace.Main.definedOverload(Main.java)",
+ "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java:3)",
+ "\tat com.android.tools.r8.naming.retrace.Main.overload1(Main.java:7)",
+ "\t<OR #1> at com.android.tools.r8.naming.retrace.Main.overload2(Main.java:11)",
+ "\tat com.android.tools.r8.naming.retrace.Main.definedOverload(Main.java:7)",
+ "\t<OR #1> at com.android.tools.r8.naming.retrace.Main.definedOverload(Main.java:11)",
"\tat com.android.tools.r8.naming.retrace.Main.mainPC(Main.java:42)");
}
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/OverloadSameLineTest.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/OverloadSameLineTest.java
index d1659cd..f1fbedb 100644
--- a/src/test/java/com/android/tools/r8/retrace/stacktraces/OverloadSameLineTest.java
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/OverloadSameLineTest.java
@@ -32,8 +32,8 @@
"Exception in thread \"main\" java.lang.NullPointerException",
// TODO(b/199058242): Should be ambiguous and not inline frames
"\tat com.android.tools.r8.naming.retrace.Main.overload(Main.java:7)",
- "\t<OR> at com.android.tools.r8.naming.retrace.Main.overload(Main.java:15)",
- "\t<OR> at com.android.tools.r8.naming.retrace.Main.overload(Main.java:13)");
+ "\t<OR #1> at com.android.tools.r8.naming.retrace.Main.overload(Main.java:15)",
+ "\t<OR #2> at com.android.tools.r8.naming.retrace.Main.overload(Main.java:13)");
}
@Override
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/SingleLineNoLineNumberStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/SingleLineNoLineNumberStackTrace.java
index 4f6ceb8..0b0c7ef 100644
--- a/src/test/java/com/android/tools/r8/retrace/stacktraces/SingleLineNoLineNumberStackTrace.java
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/SingleLineNoLineNumberStackTrace.java
@@ -16,7 +16,8 @@
"Exception in thread \"main\" java.lang.NullPointerException",
"\tat foo.a.a(Unknown Source)",
"\tat foo.a.b(Unknown Source)",
- "\tat foo.a.c(Unknown Source)");
+ "\tat foo.a.c(Unknown Source)",
+ "\tat foo.a.d(Unknown Source)");
}
@Override
@@ -26,20 +27,23 @@
" 0:0:void method1(java.lang.String):42:42 -> a",
" 0:0:void main(java.lang.String[]):28 -> a",
" 0:0:void method2(java.lang.String):42:48 -> b",
- " 0:0:void main2(java.lang.String[]):28 -> b",
- " void main3(java.lang.String[]):153 -> c");
+ " 0:0:void main2(java.lang.String[]):29 -> b",
+ " void method3(java.lang.String):72:72 -> c",
+ " void main3(java.lang.String[]):30 -> c",
+ " void main4(java.lang.String[]):153 -> d");
}
@Override
public List<String> retracedStackTrace() {
- // TODO(b/191513686): Should have line-numbers for main, method1, main2 and main3.
return Arrays.asList(
"Exception in thread \"main\" java.lang.NullPointerException",
- "\tat com.android.tools.r8.naming.retrace.Main.method1(Main.java)",
- "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java)",
- "\tat com.android.tools.r8.naming.retrace.Main.method2(Main.java)",
- "\tat com.android.tools.r8.naming.retrace.Main.main2(Main.java)",
- "\tat com.android.tools.r8.naming.retrace.Main.main3(Main.java)");
+ "\tat com.android.tools.r8.naming.retrace.Main.method1(Main.java:42)",
+ "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java:28)",
+ "\tat com.android.tools.r8.naming.retrace.Main.method2(Main.java:42)",
+ "\tat com.android.tools.r8.naming.retrace.Main.main2(Main.java:29)",
+ "\tat com.android.tools.r8.naming.retrace.Main.main3(Main.java:30)",
+ "\t<OR #1> at com.android.tools.r8.naming.retrace.Main.method3(Main.java:72)",
+ "\tat com.android.tools.r8.naming.retrace.Main.main4(Main.java:153)");
}
@Override
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/UnknownSourceStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/UnknownSourceStackTrace.java
index 76b89e4..13b8bdd 100644
--- a/src/test/java/com/android/tools/r8/retrace/stacktraces/UnknownSourceStackTrace.java
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/UnknownSourceStackTrace.java
@@ -27,13 +27,13 @@
return Arrays.asList(
"com.android.tools.r8.CompilationException: foo[parens](Source:3)",
" at com.android.tools.r8.R8.bar(R8.java)",
- " <OR> at com.android.tools.r8.R8.foo(R8.java)",
+ " <OR #1> at com.android.tools.r8.R8.foo(R8.java)",
" at com.android.tools.r8.R8.bar(R8.java)",
- " <OR> at com.android.tools.r8.R8.foo(R8.java)",
+ " <OR #1> at com.android.tools.r8.R8.foo(R8.java)",
" at com.android.tools.r8.R8.main(Unknown Source)",
"Caused by: com.android.tools.r8.CompilationException: foo[parens](Source:3)",
" at com.android.tools.r8.R8.bar(R8.java)",
- " <OR> at com.android.tools.r8.R8.foo(R8.java)",
+ " <OR #1> at com.android.tools.r8.R8.foo(R8.java)",
" ... 42 more");
}
diff --git a/src/test/java/com/android/tools/r8/smali/OutlineTest.java b/src/test/java/com/android/tools/r8/smali/OutlineTest.java
index 21501d0..c9d30fd 100644
--- a/src/test/java/com/android/tools/r8/smali/OutlineTest.java
+++ b/src/test/java/com/android/tools/r8/smali/OutlineTest.java
@@ -85,6 +85,8 @@
return options -> {
// Disable inlining to make sure that code looks as expected.
options.enableInlining = false;
+ // Disable the devirtulizer to not remove the super calls
+ options.enableDevirtualization = false;
// Disable string concatenation optimization to not bother outlining of StringBuilder usage.
options.enableStringConcatenationOptimization = false;
// Also apply outline options.
diff --git a/third_party/retrace/binary_compatibility.tar.gz.sha1 b/third_party/retrace/binary_compatibility.tar.gz.sha1
index 8bdacb5..0aafcf6 100644
--- a/third_party/retrace/binary_compatibility.tar.gz.sha1
+++ b/third_party/retrace/binary_compatibility.tar.gz.sha1
@@ -1 +1 @@
-2d04d6851b1562286ababb9a4e128bd96a7823ab
\ No newline at end of file
+23a607be2e3644321df25d73e1db663ad06e79cb
\ No newline at end of file