OSDN Git Service

Call HuntForOriginalReference to get to the null.
authorNicolas Geoffray <ngeoffray@google.com>
Fri, 18 Mar 2016 16:25:38 +0000 (16:25 +0000)
committerNicolas Geoffray <ngeoffray@google.com>
Mon, 21 Mar 2016 10:30:56 +0000 (10:30 +0000)
The null constant might be hiding under a HBoundType
(which we could clean up in instruction simplifier, but
that is orthogonal).

bug:27683874
Change-Id: Ide8ec5bcd439ec0fca5e54175ebeedc5a9f679a3

compiler/optimizing/load_store_elimination.cc
test/586-checker-null-array-get/src/Main.java

index 561dcfb..9601b06 100644 (file)
@@ -738,10 +738,12 @@ class LSEVisitor : public HGraphVisitor {
           DCHECK(instruction->IsArrayGet()) << instruction->DebugName();
           HInstruction* array = instruction->AsArrayGet()->GetArray();
           DCHECK(array->IsNullCheck()) << array->DebugName();
-          DCHECK(array->InputAt(0)->IsNullConstant()) << array->InputAt(0)->DebugName();
+          HInstruction* input = HuntForOriginalReference(array->InputAt(0));
+          DCHECK(input->IsNullConstant()) << input->DebugName();
           array = heap_value->AsArrayGet()->GetArray();
           DCHECK(array->IsNullCheck()) << array->DebugName();
-          DCHECK(array->InputAt(0)->IsNullConstant()) << array->InputAt(0)->DebugName();
+          input = HuntForOriginalReference(array->InputAt(0));
+          DCHECK(input->IsNullConstant()) << input->DebugName();
         }
         return;
       }
index 4b03ff2..332cfb0 100644 (file)
@@ -17,6 +17,7 @@
 public class Main {
   public static Object[] getObjectArray() { return null; }
   public static long[] getLongArray() { return null; }
+  public static Object getNull() { return null; }
 
   public static void main(String[] args) {
     try {
@@ -37,6 +38,36 @@ public class Main {
     objectField = getObjectArray()[0];
   }
 
+  /// CHECK-START: void Main.bar() load_store_elimination (after)
+  /// CHECK-DAG: <<Null:l\d+>>       NullConstant
+  /// CHECK-DAG: <<BoundType:l\d+>>  BoundType [<<Null>>]
+  /// CHECK-DAG: <<CheckL:l\d+>>     NullCheck [<<BoundType>>]
+  /// CHECK-DAG: <<GetL0:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
+  /// CHECK-DAG: <<GetL1:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
+  /// CHECK-DAG: <<GetL2:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
+  /// CHECK-DAG: <<GetL3:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
+  /// CHECK-DAG: <<CheckJ:l\d+>>     NullCheck [<<Null>>]
+  /// CHECK-DAG: <<GetJ0:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
+  /// CHECK-DAG: <<GetJ1:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
+  /// CHECK-DAG: <<GetJ2:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
+  /// CHECK-DAG: <<GetJ3:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
+  public static void bar() {
+    // We create multiple accesses that will lead the bounds check
+    // elimination pass to add a HDeoptimize. Not having the bounds check helped
+    // the load store elimination think it could merge two ArrayGet with different
+    // types.
+    String[] array = ((String[])getNull());
+    objectField = array[0];
+    objectField = array[1];
+    objectField = array[2];
+    objectField = array[3];
+    long[] longArray = getLongArray();
+    longField = longArray[0];
+    longField = longArray[1];
+    longField = longArray[2];
+    longField = longArray[3];
+  }
+
   public static long longField;
   public static Object objectField;
 }