Merge commit 'fb5b6dad1e23261f8b70b94e6ea21de4045b335c' into dev-release
Change-Id: I257f80f1f9a1e34809c14f377deebb7aadce2f56
diff --git a/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollectionImpl.java b/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollectionImpl.java
index 2ffe096..669e86b 100644
--- a/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollectionImpl.java
+++ b/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollectionImpl.java
@@ -122,6 +122,16 @@
return clazz.isInterface() && interfacesWithUnknownSubtypeHierarchy.contains(clazz);
}
+ /**
+ * Returns true if the type is an annotation interface which (by design) has an unknown subtype
+ * hierarchy.
+ */
+ public boolean isAnnotationInterfaceWithUnknownSubtypeHierarchy(DexProgramClass iface) {
+ return iface.isInterface()
+ && iface.isAnnotation()
+ && annotationsWithUnknownSubtypeHierarchy.contains(iface);
+ }
+
/** Returns true if the type is an immediate interface of an instantiated lambda. */
@Override
public boolean isImmediateInterfaceOfInstantiatedLambda(DexProgramClass iface) {
@@ -522,6 +532,18 @@
assert !interfacesWithUnknownSubtypeHierarchy.contains(rewrittenClass);
interfacesWithUnknownSubtypeHierarchy.add(rewrittenClass);
}
+ for (DexProgramClass abstractType :
+ objectAllocationInfos.annotationsWithUnknownSubtypeHierarchy) {
+ DexType type = lens.lookupType(abstractType.type, appliedLens);
+ if (type.isPrimitiveType()) {
+ assert false;
+ continue;
+ }
+ DexProgramClass rewrittenClass = asProgramClassOrNull(definitions.definitionFor(type));
+ assert rewrittenClass != null;
+ assert !annotationsWithUnknownSubtypeHierarchy.contains(rewrittenClass);
+ annotationsWithUnknownSubtypeHierarchy.add(rewrittenClass);
+ }
LensCodeRewriterUtils rewriter = new LensCodeRewriterUtils(definitions, lens, appliedLens);
objectAllocationInfos.instantiatedLambdas.forEach(
(iface, lambdas) -> {
diff --git a/src/main/java/com/android/tools/r8/ir/code/Invoke.java b/src/main/java/com/android/tools/r8/ir/code/Invoke.java
index d16fdc6..6aa12e5 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Invoke.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Invoke.java
@@ -258,8 +258,13 @@
// Used to decide if this invoke should be emitted as invoke/range.
protected boolean needsRangedInvoke(DexBuilder builder) {
if (arguments().size() == 1) {
- // Prefer invoke-range since this does not impose any constraints on the operand register.
- return true;
+ // Prefer non-range invoke since ART's LSE does not always consider invoke/range
+ // (b/378823200).
+ int registerEnd =
+ builder.getRegisterAllocator().getRegisterForValue(getFirstArgument(), getNumber())
+ + getFirstArgument().requiredRegisters()
+ - 1;
+ return registerEnd > Constants.U4BIT_MAX;
}
if (requiredArgumentRegisters() > 5) {
// No way around using an invoke-range instruction.
diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/RegisterMoveCycleDetector.java b/src/main/java/com/android/tools/r8/ir/regalloc/RegisterMoveCycleDetector.java
index cdb321d..a6b2ad6 100644
--- a/src/main/java/com/android/tools/r8/ir/regalloc/RegisterMoveCycleDetector.java
+++ b/src/main/java/com/android/tools/r8/ir/regalloc/RegisterMoveCycleDetector.java
@@ -19,10 +19,7 @@
@SuppressWarnings("MixedMutabilityReturnType")
static List<RegisterMoveCycle> getMoveCycles(TreeSet<RegisterMove> moveSet) {
- // Although there can be a cycle when there are two moves, we return no cycles, since the
- // default move scheduling has the same behavior as the cycle-based move scheduling in this
- // case.
- if (moveSet.size() <= 2) {
+ if (moveSet.size() <= 1) {
return Collections.emptyList();
}
List<RegisterMoveCycle> moveCycles = new ArrayList<>();
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 022be10..cbba232 100644
--- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
+++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
@@ -1156,8 +1156,10 @@
// TODO(b/148769279): Disable lookup single target on lambda's for now.
if (resolvedHolder.isInterface()
&& resolvedHolder.isProgramClass()
- && objectAllocationInfoCollection.isImmediateInterfaceOfInstantiatedLambda(
- resolvedHolder.asProgramClass())) {
+ && (objectAllocationInfoCollection.isImmediateInterfaceOfInstantiatedLambda(
+ resolvedHolder.asProgramClass())
+ || objectAllocationInfoCollection.isAnnotationInterfaceWithUnknownSubtypeHierarchy(
+ resolvedHolder.asProgramClass()))) {
singleTargetLookupCache.addNoSingleTargetToCache(refinedReceiverType, method);
return null;
}
diff --git a/src/test/java/com/android/tools/r8/accessrelaxation/InvokeTypeConversionTest.java b/src/test/java/com/android/tools/r8/accessrelaxation/InvokeTypeConversionTest.java
index e1c7e00..f29440c 100644
--- a/src/test/java/com/android/tools/r8/accessrelaxation/InvokeTypeConversionTest.java
+++ b/src/test/java/com/android/tools/r8/accessrelaxation/InvokeTypeConversionTest.java
@@ -13,8 +13,8 @@
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.dex.code.DexInvokeDirectRange;
-import com.android.tools.r8.dex.code.DexInvokeVirtualRange;
+import com.android.tools.r8.dex.code.DexInvokeDirect;
+import com.android.tools.r8.dex.code.DexInvokeVirtual;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.smali.SmaliBuilder;
@@ -121,7 +121,7 @@
assertNotNull(method);
DexCode code = method.getCode().asDexCode();
// The given invoke line is remained as-is.
- assertTrue(code.instructions[2] instanceof DexInvokeDirectRange);
+ assertTrue(code.instructions[2] instanceof DexInvokeDirect);
});
}
@@ -152,7 +152,7 @@
assertNotNull(method);
DexCode code = method.getCode().asDexCode();
// The given invoke line is changed to invoke-virtual
- assertTrue(code.instructions[2] instanceof DexInvokeVirtualRange);
+ assertTrue(code.instructions[2] instanceof DexInvokeVirtual);
});
}
diff --git a/src/test/java/com/android/tools/r8/compatproguard/ForNameTest.java b/src/test/java/com/android/tools/r8/compatproguard/ForNameTest.java
index d64aa20..9c7cf17 100644
--- a/src/test/java/com/android/tools/r8/compatproguard/ForNameTest.java
+++ b/src/test/java/com/android/tools/r8/compatproguard/ForNameTest.java
@@ -8,7 +8,7 @@
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.dex.code.DexConstString;
-import com.android.tools.r8.dex.code.DexInvokeStaticRange;
+import com.android.tools.r8.dex.code.DexInvokeStatic;
import com.android.tools.r8.dex.code.DexReturnVoid;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.smali.SmaliBuilder;
@@ -55,7 +55,7 @@
assertTrue(code.instructions[0] instanceof DexConstString);
DexConstString constString = (DexConstString) code.instructions[0];
assertNotEquals(BOO, constString.getString().toString());
- assertTrue(code.instructions[1] instanceof DexInvokeStaticRange);
+ assertTrue(code.instructions[1] instanceof DexInvokeStatic);
assertTrue(code.instructions[2] instanceof DexReturnVoid);
}
@@ -91,7 +91,7 @@
assertTrue(code.instructions[0] instanceof DexConstString);
DexConstString constString = (DexConstString) code.instructions[0];
assertEquals(BOO, constString.getString().toString());
- assertTrue(code.instructions[1] instanceof DexInvokeStaticRange);
+ assertTrue(code.instructions[1] instanceof DexInvokeStatic);
assertTrue(code.instructions[2] instanceof DexReturnVoid);
}
diff --git a/src/test/java/com/android/tools/r8/compatproguard/GetMembersTest.java b/src/test/java/com/android/tools/r8/compatproguard/GetMembersTest.java
index eb24283..3449aa1 100644
--- a/src/test/java/com/android/tools/r8/compatproguard/GetMembersTest.java
+++ b/src/test/java/com/android/tools/r8/compatproguard/GetMembersTest.java
@@ -15,7 +15,7 @@
import com.android.tools.r8.dex.code.DexConst4;
import com.android.tools.r8.dex.code.DexConstClass;
import com.android.tools.r8.dex.code.DexConstString;
-import com.android.tools.r8.dex.code.DexFilledNewArrayRange;
+import com.android.tools.r8.dex.code.DexFilledNewArray;
import com.android.tools.r8.dex.code.DexInvokeVirtual;
import com.android.tools.r8.dex.code.DexMoveResultObject;
import com.android.tools.r8.dex.code.DexNewArray;
@@ -75,9 +75,9 @@
private void inspectGetMethodTest(MethodSubject method) {
// Accept either array construction style (differs based on minSdkVersion).
DexCode code = method.getMethod().getCode().asDexCode();
- if (code.instructions[1] instanceof DexFilledNewArrayRange) {
+ if (code.instructions[1] instanceof DexFilledNewArray) {
assertTrue(code.instructions[0] instanceof DexConstClass);
- assertTrue(code.instructions[1] instanceof DexFilledNewArrayRange);
+ assertTrue(code.instructions[1] instanceof DexFilledNewArray);
assertTrue(code.instructions[2] instanceof DexMoveResultObject);
assertTrue(code.instructions[3] instanceof DexConstClass);
assertTrue(code.instructions[4] instanceof DexConstString);
diff --git a/src/test/java/com/android/tools/r8/ir/regalloc/RegisterMoveSchedulerTest.java b/src/test/java/com/android/tools/r8/ir/regalloc/RegisterMoveSchedulerTest.java
index 804b482..7e42fa9 100644
--- a/src/test/java/com/android/tools/r8/ir/regalloc/RegisterMoveSchedulerTest.java
+++ b/src/test/java/com/android/tools/r8/ir/regalloc/RegisterMoveSchedulerTest.java
@@ -544,6 +544,21 @@
assertEquals(2, scheduler.getUsedTempRegisters());
}
+ @Test
+ public void regressionTestBug378850589() {
+ CollectMovesIterator moves = new CollectMovesIterator();
+ int temp = 42;
+ RegisterMoveScheduler scheduler = new RegisterMoveScheduler(moves, temp);
+ scheduler.addMove(new RegisterMove(9, 12, TypeElement.getLong()));
+ scheduler.addMove(new RegisterMove(11, 8, TypeElement.getLong()));
+ scheduler.schedule();
+ assertEquals(3, moves.size());
+ assertEquals("42 <- 12", toString(moves.get(0)));
+ assertEquals("11 <- 8", toString(moves.get(1)));
+ assertEquals("9 <- 42", toString(moves.get(3)));
+ assertEquals(2, scheduler.getUsedTempRegisters());
+ }
+
// Debugging aid.
private void printMoves(List<Instruction> moves) {
System.out.println("Generated moves:");
diff --git a/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java b/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
index 42a037e..cc150aa 100644
--- a/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
+++ b/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
@@ -18,10 +18,9 @@
import com.android.tools.r8.dex.code.DexConst4;
import com.android.tools.r8.dex.code.DexConstClass;
import com.android.tools.r8.dex.code.DexConstString;
-import com.android.tools.r8.dex.code.DexFilledNewArrayRange;
-import com.android.tools.r8.dex.code.DexInvokeDirectRange;
+import com.android.tools.r8.dex.code.DexFilledNewArray;
+import com.android.tools.r8.dex.code.DexInvokeDirect;
import com.android.tools.r8.dex.code.DexInvokeStatic;
-import com.android.tools.r8.dex.code.DexInvokeStaticRange;
import com.android.tools.r8.dex.code.DexInvokeVirtual;
import com.android.tools.r8.dex.code.DexIputObject;
import com.android.tools.r8.dex.code.DexMoveResultObject;
@@ -86,10 +85,7 @@
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
- DexConstString.class,
- DexIputObject.class,
- DexReturnVoid.class));
+ DexInvokeDirect.class, DexConstString.class, DexIputObject.class, DexReturnVoid.class));
DexConstString constString = (DexConstString) code.instructions[1];
assertEquals(BOO, constString.getString().toString());
}
@@ -123,7 +119,7 @@
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexSgetObject.class,
DexConstString.class,
DexInvokeVirtual.class,
@@ -164,7 +160,7 @@
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexSgetObject.class,
DexConstString.class,
DexInvokeVirtual.class,
@@ -415,7 +411,7 @@
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexConstString.class,
DexConstString.class,
DexInvokeStatic.class,
@@ -459,11 +455,11 @@
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexSgetObject.class,
DexConstString.class,
DexInvokeVirtual.class,
- DexInvokeStaticRange.class,
+ DexInvokeStatic.class,
DexReturnVoid.class));
DexConstString constString = (DexConstString) code.instructions[2];
assertEquals(BOO, constString.getString().toString());
@@ -504,12 +500,12 @@
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexSgetObject.class,
DexConstString.class,
DexInvokeVirtual.class,
DexConstString.class,
- DexInvokeStaticRange.class,
+ DexInvokeStatic.class,
DexReturnVoid.class));
DexConstString constString = (DexConstString) code.instructions[2];
assertEquals(BOO, constString.getString().toString());
@@ -559,7 +555,7 @@
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexConstClass.class,
DexConstString.class,
DexInvokeStatic.class,
@@ -610,7 +606,7 @@
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexConstClass.class,
DexConstString.class,
DexInvokeStatic.class,
@@ -666,13 +662,13 @@
DexCode code = method.getCode().asDexCode();
// Accept either array construction style (differs based on minSdkVersion).
- if (code.instructions[2].getClass() == DexFilledNewArrayRange.class) {
+ if (code.instructions[2].getClass() == DexFilledNewArray.class) {
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexConstClass.class,
- DexFilledNewArrayRange.class,
+ DexFilledNewArray.class,
DexMoveResultObject.class,
DexConstString.class,
DexInvokeStatic.class,
@@ -681,7 +677,7 @@
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexConstClass.class,
DexConst4.class,
DexNewArray.class,
@@ -742,13 +738,13 @@
DexCode code = method.getCode().asDexCode();
// Accept either array construction style (differs based on minSdkVersion).
- if (code.instructions[2].getClass() == DexFilledNewArrayRange.class) {
+ if (code.instructions[2].getClass() == DexFilledNewArray.class) {
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexConstClass.class,
- DexFilledNewArrayRange.class,
+ DexFilledNewArray.class,
DexMoveResultObject.class,
DexConstString.class,
DexInvokeStatic.class,
@@ -757,7 +753,7 @@
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexConstClass.class,
DexConst4.class,
DexNewArray.class,
diff --git a/src/test/java/com/android/tools/r8/optimize/ReproduceKT72888Test.java b/src/test/java/com/android/tools/r8/optimize/AnnotationImplementedAndInstantiatedInProgramTest.java
similarity index 93%
rename from src/test/java/com/android/tools/r8/optimize/ReproduceKT72888Test.java
rename to src/test/java/com/android/tools/r8/optimize/AnnotationImplementedAndInstantiatedInProgramTest.java
index a61ef15..83e0029 100644
--- a/src/test/java/com/android/tools/r8/optimize/ReproduceKT72888Test.java
+++ b/src/test/java/com/android/tools/r8/optimize/AnnotationImplementedAndInstantiatedInProgramTest.java
@@ -15,8 +15,9 @@
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
+// This is a reproduction of b/378473616 (extracted from KT-72888)
@RunWith(Parameterized.class)
-public class ReproduceKT72888Test extends TestBase {
+public class AnnotationImplementedAndInstantiatedInProgramTest extends TestBase {
@Parameter(0)
public TestParameters parameters;
@@ -57,7 +58,7 @@
.addKeepRuntimeVisibleAnnotations()
.setMinApi(parameters)
.run(parameters.getRuntime(), TestClass.class)
- .assertFailureWithErrorThatThrows(ClassCastException.class);
+ .assertSuccessWithOutput(EXPECTED_OUTPUT);
}
@Retention(RetentionPolicy.RUNTIME)
diff --git a/src/test/java/com/android/tools/r8/smali/IfSimplificationTest.java b/src/test/java/com/android/tools/r8/smali/IfSimplificationTest.java
index c7adad6..9642e4e 100644
--- a/src/test/java/com/android/tools/r8/smali/IfSimplificationTest.java
+++ b/src/test/java/com/android/tools/r8/smali/IfSimplificationTest.java
@@ -14,7 +14,7 @@
import com.android.tools.r8.dex.code.DexIfLez;
import com.android.tools.r8.dex.code.DexIfLtz;
import com.android.tools.r8.dex.code.DexIfNez;
-import com.android.tools.r8.dex.code.DexInvokeVirtualRange;
+import com.android.tools.r8.dex.code.DexInvokeVirtual;
import com.android.tools.r8.dex.code.DexReturn;
import com.android.tools.r8.dex.code.DexReturnObject;
import com.android.tools.r8.graph.DexCode;
@@ -399,7 +399,7 @@
" goto :label_7");
DexCode code = method.getCode().asDexCode();
assertEquals(3, code.instructions.length);
- assertTrue(code.instructions[0] instanceof DexInvokeVirtualRange);
+ assertTrue(code.instructions[0] instanceof DexInvokeVirtual);
assertTrue(code.instructions[1] instanceof DexConst4);
assertEquals(0, ((DexConst4) code.instructions[1]).B);
assertTrue(code.instructions[2] instanceof DexReturnObject);
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 b3a09bf..25e8d89 100644
--- a/src/test/java/com/android/tools/r8/smali/OutlineTest.java
+++ b/src/test/java/com/android/tools/r8/smali/OutlineTest.java
@@ -575,7 +575,7 @@
DexInvokeStatic invoke = (DexInvokeStatic) mainCode.instructions[4];
assertTrue(isOutlineMethodName(invoke.getMethod()));
} else if (i == 3) {
- DexInvokeStaticRange invoke = (DexInvokeStaticRange) mainCode.instructions[1];
+ DexInvokeStatic invoke = (DexInvokeStatic) mainCode.instructions[1];
assertTrue(isOutlineMethodName(invoke.getMethod()));
} else {
assert i == 4 || i == 5;