Version 0.1.18.

Merge: Disallow the use of filled-new-array of objects before kitkat.
CL: https://r8-review.googlesource.com/c/r8/+/8582

The Dalvik bug that this is a workaround for only exists in the
x86-atom backend before KitKat.

R=sgjesse@google.com

Change-Id: Ie1608794b49e1878165a05bb920905c6ff22379a
Bug:
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index 5a97375..a3985a9 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -55,7 +55,7 @@
  */
 public final class D8 {
 
-  private static final String VERSION = "v0.1.17";
+  private static final String VERSION = "v0.1.18";
   private static final int STATUS_ERROR = 1;
 
   private D8() {}
diff --git a/src/main/java/com/android/tools/r8/GenerateMainDexList.java b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
index 44d523e..a90ee59 100644
--- a/src/main/java/com/android/tools/r8/GenerateMainDexList.java
+++ b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
@@ -28,7 +28,7 @@
 import java.util.stream.Collectors;
 
 public class GenerateMainDexList {
-  private static final String VERSION = "v0.2.0";
+  private static final String VERSION = "v0.1.18";
   private final Timing timing = new Timing("maindex");
   private final InternalOptions options;
 
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 1c248b9..dd47e37 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -71,7 +71,7 @@
 
 public class R8 {
 
-  private static final String VERSION = "v0.1.17";
+  private static final String VERSION = "v0.1.18";
   private final Timing timing = new Timing("R8");
   private final InternalOptions options;
 
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 357c2ce..d6f10c8 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
@@ -89,7 +89,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 = enableDesugaring ? new LambdaRewriter(this) : null;
     this.interfaceMethodRewriter =
         (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 5ca8fd1..a80aa9e 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
@@ -102,9 +102,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;
   }
@@ -1060,7 +1063,7 @@
     return null;
   }
 
-  private boolean isPrimitiveOrStringNewArrayWithPositiveSize(Instruction instruction) {
+  private boolean allowNewFilledArrayConstruction(Instruction instruction) {
     if (!(instruction instanceof NewArrayEmpty)) {
       return false;
     }
@@ -1073,7 +1076,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();
   }
 
   /**
@@ -1089,7 +1096,7 @@
       InstructionListIterator it = block.listIterator();
       while (it.hasNext()) {
         Instruction instruction = it.next();
-        if (!isPrimitiveOrStringNewArrayWithPositiveSize(instruction)) {
+        if (!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 b03721f..80ab396 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -353,4 +353,16 @@
   public boolean canUseParameterNameAnnotations() {
     return minApiLevel >= Constants.ANDROID_O_API;
   }
+
+  // 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();
+  }
 }