Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 class Test1 {
     18   int[] iarr;
     19 }
     20 
     21 class Test2 {
     22   float[] farr;
     23 }
     24 
     25 public class Main {
     26   public static Object[] getObjectArray() { return null; }
     27   public static long[] getLongArray() { return null; }
     28   public static Object getNull() { return null; }
     29   public static Test1 getNullTest1() { return null; }
     30   public static Test2 getNullTest2() { return null; }
     31 
     32   public static void main(String[] args) {
     33     try {
     34       foo();
     35       throw new Error("Expected NullPointerException");
     36     } catch (NullPointerException e) {
     37       // Expected.
     38     }
     39     try {
     40       bar();
     41       throw new Error("Expected NullPointerException");
     42     } catch (NullPointerException e) {
     43       // Expected.
     44     }
     45     try {
     46       test1();
     47       throw new Error("Expected NullPointerException");
     48     } catch (NullPointerException e) {
     49       // Expected.
     50     }
     51   }
     52 
     53   /// CHECK-START: void Main.foo() load_store_elimination (after)
     54   /// CHECK-DAG: <<Null:l\d+>>   NullConstant
     55   /// CHECK-DAG: <<Check:l\d+>>  NullCheck [<<Null>>]
     56   /// CHECK-DAG: <<Get1:j\d+>>   ArrayGet [<<Check>>,{{i\d+}}]
     57   /// CHECK-DAG: <<Get2:l\d+>>   ArrayGet [<<Check>>,{{i\d+}}]
     58   public static void foo() {
     59     longField = getLongArray()[0];
     60     objectField = getObjectArray()[0];
     61   }
     62 
     63   /// CHECK-START: void Main.bar() load_store_elimination (after)
     64   /// CHECK-DAG: <<Null:l\d+>>       NullConstant
     65   /// CHECK-DAG: <<BoundType:l\d+>>  BoundType [<<Null>>]
     66   /// CHECK-DAG: <<CheckL:l\d+>>     NullCheck [<<BoundType>>]
     67   /// CHECK-DAG: <<GetL0:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
     68   /// CHECK-DAG: <<GetL1:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
     69   /// CHECK-DAG: <<GetL2:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
     70   /// CHECK-DAG: <<GetL3:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
     71   /// CHECK-DAG: <<CheckJ:l\d+>>     NullCheck [<<Null>>]
     72   /// CHECK-DAG: <<GetJ0:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
     73   /// CHECK-DAG: <<GetJ1:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
     74   /// CHECK-DAG: <<GetJ2:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
     75   /// CHECK-DAG: <<GetJ3:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
     76   public static void bar() {
     77     // We create multiple accesses that will lead the bounds check
     78     // elimination pass to add a HDeoptimize. Not having the bounds check helped
     79     // the load store elimination think it could merge two ArrayGet with different
     80     // types.
     81     String[] array = (String[])getNull();
     82     objectField = array[0];
     83     objectField = array[1];
     84     objectField = array[2];
     85     objectField = array[3];
     86     long[] longArray = getLongArray();
     87     longField = longArray[0];
     88     longField = longArray[1];
     89     longField = longArray[2];
     90     longField = longArray[3];
     91   }
     92 
     93   /// CHECK-START: float Main.test1() load_store_elimination (after)
     94   /// CHECK-DAG: <<Null:l\d+>>       NullConstant
     95   /// CHECK-DAG: <<Check1:l\d+>>     NullCheck [<<Null>>]
     96   /// CHECK-DAG: <<FieldGet1:l\d+>>  InstanceFieldGet [<<Check1>>] field_name:Test1.iarr
     97   /// CHECK-DAG: <<Check2:l\d+>>     NullCheck [<<FieldGet1>>]
     98   /// CHECK-DAG: <<ArrayGet1:i\d+>>  ArrayGet [<<Check2>>,{{i\d+}}]
     99   /// CHECK-DAG: <<ArrayGet2:f\d+>>  ArrayGet [<<Check2>>,{{i\d+}}]
    100   /// CHECK-DAG:                     Return [<<ArrayGet2>>]
    101   public static float test1() {
    102     Test1 test1 = getNullTest1();
    103     Test2 test2 = getNullTest2();;
    104     int[] iarr = test1.iarr;
    105     float[] farr = test2.farr;
    106     iarr[0] = iarr[1];
    107     return farr[0];
    108   }
    109 
    110   public static long longField;
    111   public static Object objectField;
    112 }
    113