Fix NumberUnboxer and virtual methods
Bug: b/307872552
Change-Id: I907a02ddf422c15269f2873598b637295a4e8472
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/numberunboxer/NumberUnboxerImpl.java b/src/main/java/com/android/tools/r8/ir/optimize/numberunboxer/NumberUnboxerImpl.java
index 1e623e1..b171360 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/numberunboxer/NumberUnboxerImpl.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/numberunboxer/NumberUnboxerImpl.java
@@ -26,6 +26,7 @@
import com.android.tools.r8.ir.optimize.numberunboxer.TransitiveDependency.MethodRet;
import com.android.tools.r8.optimize.argumentpropagation.utils.ProgramClassesBidirectedGraph;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.MapUtils;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
@@ -142,6 +143,7 @@
DexMethod contextReference = code.context().getReference();
ValueBoxingStatus[] args = null;
ValueBoxingStatus returnStatus = null;
+ int shift = BooleanUtils.intValue(!code.context().getDefinition().isStatic());
for (Instruction next : code.instructions()) {
if (next.isArgument()) {
ValueBoxingStatus unboxingStatus = analyzeOutput(next.outValue());
@@ -149,7 +151,7 @@
if (args == null) {
args = new ValueBoxingStatus[contextReference.getArity()];
}
- args[next.asArgument().getIndex()] = unboxingStatus;
+ args[next.asArgument().getIndex() - shift] = unboxingStatus;
}
} else if (next.isReturn()) {
Return ret = next.asReturn();
@@ -223,8 +225,9 @@
if (!inValue.isPhi()) {
Instruction definition = inValue.getAliasedValue().getDefinition();
if (definition.isArgument()) {
+ int shift = BooleanUtils.intValue(!context.getDefinition().isStatic());
return ValueBoxingStatus.with(
- new MethodArg(definition.asArgument().getIndex(), context.getReference()));
+ new MethodArg(definition.asArgument().getIndex() - shift, context.getReference()));
}
if (definition.isInvokeMethod()) {
if (boxPrimitiveMethod.isIdenticalTo(definition.asInvokeMethod().getInvokedMethod())) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/numberunboxer/TransitiveDependency.java b/src/main/java/com/android/tools/r8/ir/optimize/numberunboxer/TransitiveDependency.java
index f368e52..ff49fe2 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/numberunboxer/TransitiveDependency.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/numberunboxer/TransitiveDependency.java
@@ -113,6 +113,7 @@
public MethodArg(int parameterIndex, DexMethod method) {
super(method);
assert parameterIndex >= 0;
+ assert parameterIndex < method.getArity();
this.parameterIndex = parameterIndex;
}
diff --git a/src/test/java/com/android/tools/r8/numberunboxing/SimpleNumberUnboxingTest.java b/src/test/java/com/android/tools/r8/numberunboxing/StaticMethodsNumberUnboxingTest.java
similarity index 73%
rename from src/test/java/com/android/tools/r8/numberunboxing/SimpleNumberUnboxingTest.java
rename to src/test/java/com/android/tools/r8/numberunboxing/StaticMethodsNumberUnboxingTest.java
index ceaf904..61a658a 100644
--- a/src/test/java/com/android/tools/r8/numberunboxing/SimpleNumberUnboxingTest.java
+++ b/src/test/java/com/android/tools/r8/numberunboxing/StaticMethodsNumberUnboxingTest.java
@@ -16,14 +16,13 @@
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import java.util.Objects;
-import org.hamcrest.CoreMatchers;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
-public class SimpleNumberUnboxingTest extends TestBase {
+public class StaticMethodsNumberUnboxingTest extends TestBase {
private final TestParameters parameters;
@@ -32,7 +31,7 @@
return getTestParameters().withAllRuntimesAndApiLevels().build();
}
- public SimpleNumberUnboxingTest(TestParameters parameters) {
+ public StaticMethodsNumberUnboxingTest(TestParameters parameters) {
this.parameters = parameters;
}
@@ -45,33 +44,8 @@
.addOptionsModification(opt -> opt.testing.enableNumberUnboxer = true)
.addOptionsModification(opt -> opt.testing.printNumberUnboxed = true)
.setMinApi(parameters)
- .allowDiagnosticWarningMessages()
.compile()
.inspect(this::assertUnboxing)
- .assertWarningMessageThatMatches(
- CoreMatchers.containsString(
- "Unboxing of arg 0 of void"
- + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.print(java.lang.Integer)"))
- .assertWarningMessageThatMatches(
- CoreMatchers.containsString(
- "Unboxing of arg 0 of void"
- + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.forwardToPrint2(java.lang.Integer)"))
- .assertWarningMessageThatMatches(
- CoreMatchers.containsString(
- "Unboxing of arg 0 of void"
- + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.directPrintUnbox(java.lang.Integer)"))
- .assertWarningMessageThatMatches(
- CoreMatchers.containsString(
- "Unboxing of arg 0 of void"
- + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.forwardToPrint(java.lang.Integer)"))
- .assertWarningMessageThatMatches(
- CoreMatchers.containsString(
- "Unboxing of return value of java.lang.Integer"
- + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.get()"))
- .assertWarningMessageThatMatches(
- CoreMatchers.containsString(
- "Unboxing of return value of java.lang.Integer"
- + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.forwardGet()"))
.run(parameters.getRuntime(), Main.class)
.assertSuccessWithOutputLines("32", "33", "42", "43", "51", "52", "2");
}
diff --git a/src/test/java/com/android/tools/r8/numberunboxing/SimpleNumberUnboxingTest.java b/src/test/java/com/android/tools/r8/numberunboxing/VirtualMethodsNumberUnboxingTest.java
similarity index 63%
copy from src/test/java/com/android/tools/r8/numberunboxing/SimpleNumberUnboxingTest.java
copy to src/test/java/com/android/tools/r8/numberunboxing/VirtualMethodsNumberUnboxingTest.java
index ceaf904..d902229 100644
--- a/src/test/java/com/android/tools/r8/numberunboxing/SimpleNumberUnboxingTest.java
+++ b/src/test/java/com/android/tools/r8/numberunboxing/VirtualMethodsNumberUnboxingTest.java
@@ -16,14 +16,13 @@
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import java.util.Objects;
-import org.hamcrest.CoreMatchers;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
-public class SimpleNumberUnboxingTest extends TestBase {
+public class VirtualMethodsNumberUnboxingTest extends TestBase {
private final TestParameters parameters;
@@ -32,7 +31,7 @@
return getTestParameters().withAllRuntimesAndApiLevels().build();
}
- public SimpleNumberUnboxingTest(TestParameters parameters) {
+ public VirtualMethodsNumberUnboxingTest(TestParameters parameters) {
this.parameters = parameters;
}
@@ -43,35 +42,9 @@
.addKeepMainRule(Main.class)
.enableInliningAnnotations()
.addOptionsModification(opt -> opt.testing.enableNumberUnboxer = true)
- .addOptionsModification(opt -> opt.testing.printNumberUnboxed = true)
.setMinApi(parameters)
- .allowDiagnosticWarningMessages()
.compile()
.inspect(this::assertUnboxing)
- .assertWarningMessageThatMatches(
- CoreMatchers.containsString(
- "Unboxing of arg 0 of void"
- + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.print(java.lang.Integer)"))
- .assertWarningMessageThatMatches(
- CoreMatchers.containsString(
- "Unboxing of arg 0 of void"
- + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.forwardToPrint2(java.lang.Integer)"))
- .assertWarningMessageThatMatches(
- CoreMatchers.containsString(
- "Unboxing of arg 0 of void"
- + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.directPrintUnbox(java.lang.Integer)"))
- .assertWarningMessageThatMatches(
- CoreMatchers.containsString(
- "Unboxing of arg 0 of void"
- + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.forwardToPrint(java.lang.Integer)"))
- .assertWarningMessageThatMatches(
- CoreMatchers.containsString(
- "Unboxing of return value of java.lang.Integer"
- + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.get()"))
- .assertWarningMessageThatMatches(
- CoreMatchers.containsString(
- "Unboxing of return value of java.lang.Integer"
- + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.forwardGet()"))
.run(parameters.getRuntime(), Main.class)
.assertSuccessWithOutputLines("32", "33", "42", "43", "51", "52", "2");
}
@@ -105,59 +78,62 @@
static class Main {
+ private static final Main MAIN = new Main();
+
public static void main(String[] args) {
+
// The number unboxer should immediately find this method is worth unboxing.
- directPrintUnbox(31);
- directPrintUnbox(32);
+ MAIN.directPrintUnbox(31);
+ MAIN.directPrintUnbox(32);
// The number unboxer should find the chain of calls is worth unboxing.
- forwardToPrint(41);
- forwardToPrint(42);
+ MAIN.forwardToPrint(41);
+ MAIN.forwardToPrint(42);
// The number unboxer should find this method is *not* worth unboxing.
Integer decode1 = Integer.decode("51");
Objects.requireNonNull(decode1);
- directPrintNotUnbox(decode1);
+ MAIN.directPrintNotUnbox(decode1);
Integer decode2 = Integer.decode("52");
Objects.requireNonNull(decode2);
- directPrintNotUnbox(decode2);
+ MAIN.directPrintNotUnbox(decode2);
// The number unboxer should unbox the return values.
- System.out.println(forwardGet() + 1);
+ System.out.println(MAIN.forwardGet() + 1);
}
@NeverInline
- private static Integer get() {
+ public Integer get() {
return System.currentTimeMillis() > 0 ? 1 : -1;
}
@NeverInline
- private static Integer forwardGet() {
+ public Integer forwardGet() {
return get();
}
@NeverInline
- private static void forwardToPrint(Integer boxed) {
+ public void forwardToPrint(Integer boxed) {
forwardToPrint2(boxed);
}
@NeverInline
- private static void forwardToPrint2(Integer boxed) {
+ public void forwardToPrint2(Integer boxed) {
print(boxed);
}
@NeverInline
- private static void print(Integer boxed) {
+ public void print(Integer boxed) {
System.out.println(boxed + 1);
}
@NeverInline
- private static void directPrintUnbox(Integer boxed) {
+ public void directPrintUnbox(Integer boxed) {
System.out.println(boxed + 1);
}
@NeverInline
- private static void directPrintNotUnbox(Integer boxed) {
+ public void directPrintNotUnbox(Integer boxed) {
System.out.println(boxed);
}
}