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();
+  }
 }