Disallow the use of filled-new-array of objects before kitkat.
R=sgjesse@google.com
Change-Id: I8933a4a6a192006a5fb29e582c2e5a920d5590e1
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 c0f5b40..6450e7f 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
@@ -93,7 +93,7 @@
this.graphLense = graphLense != null ? graphLense : GraphLense.getIdentityLense();
this.options = options;
this.printer = printer;
- this.codeRewriter = new CodeRewriter(appInfo, libraryMethodsReturningReceiver());
+ this.codeRewriter = new CodeRewriter(appInfo, libraryMethodsReturningReceiver(), options);
this.lambdaRewriter = options.enableDesugaring ? new LambdaRewriter(this) : null;
this.interfaceMethodRewriter =
(options.enableDesugaring && enableInterfaceMethodDesugaring())
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index 9ca9ba0..770ac3a 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -108,9 +108,12 @@
private final AppInfo appInfo;
private final DexItemFactory dexItemFactory;
private final Set<DexMethod> libraryMethodsReturningReceiver;
+ private final InternalOptions options;
- public CodeRewriter(AppInfo appInfo, Set<DexMethod> libraryMethodsReturningReceiver) {
+ public CodeRewriter(
+ AppInfo appInfo, Set<DexMethod> libraryMethodsReturningReceiver, InternalOptions options) {
this.appInfo = appInfo;
+ this.options = options;
this.dexItemFactory = appInfo.dexItemFactory;
this.libraryMethodsReturningReceiver = libraryMethodsReturningReceiver;
}
@@ -1259,7 +1262,7 @@
return null;
}
- private boolean isPrimitiveOrStringNewArrayWithPositiveSize(Instruction instruction) {
+ private boolean allowNewFilledArrayConstruction(Instruction instruction) {
if (!(instruction instanceof NewArrayEmpty)) {
return false;
}
@@ -1272,7 +1275,11 @@
if (size < 1) {
return false;
}
- return newArray.type.isPrimitiveArrayType() || newArray.type == dexItemFactory.stringArrayType;
+ if (newArray.type.isPrimitiveArrayType()) {
+ return true;
+ }
+ return newArray.type == dexItemFactory.stringArrayType
+ && options.canUseFilledNewArrayOfObjects();
}
/**
@@ -1289,7 +1296,7 @@
while (it.hasNext()) {
Instruction instruction = it.next();
if (instruction.getLocalInfo() != null
- || !isPrimitiveOrStringNewArrayWithPositiveSize(instruction)) {
+ || !allowNewFilledArrayConstruction(instruction)) {
continue;
}
NewArrayEmpty newArray = instruction.asNewArrayEmpty();
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 7f6fe45..8145bb3 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -388,4 +388,16 @@
public boolean canUseParameterNameAnnotations() {
return minApiLevel >= AndroidApiLevel.O.getLevel();
}
+
+ // Dalvik x86-atom backend had a bug that made it crash on filled-new-array instructions for
+ // arrays of objects. This is unfortunate, since this never hits arm devices, but we have
+ // to disallow filled-new-array of objects for dalvik until kitkat. The buggy code was
+ // removed during the jelly-bean release cycle and is not there from kitkat.
+ //
+ // Buggy code that accidentally call code that only works on primitives arrays.
+ //
+ // https://android.googlesource.com/platform/dalvik/+/ics-mr0/vm/mterp/out/InterpAsm-x86-atom.S#25106
+ public boolean canUseFilledNewArrayOfObjects() {
+ return minApiLevel >= AndroidApiLevel.K.getLevel();
+ }
}