blob: de9429fd8b40d9c500a9e0bf82d866260300b445 [file] [log] [blame]
Nicolas Geoffray03971632016-03-17 10:44:24 +00001/*
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
Igor Murashkin11ffec22017-06-27 15:36:23 -070017import java.lang.reflect.Method;
18import java.lang.reflect.InvocationTargetException;
19
Nicolas Geoffraybb2c93b2016-05-04 14:00:12 +010020class Test1 {
21 int[] iarr;
22}
23
24class Test2 {
25 float[] farr;
26}
27
Nicolas Geoffray03971632016-03-17 10:44:24 +000028public class Main {
29 public static Object[] getObjectArray() { return null; }
30 public static long[] getLongArray() { return null; }
Nicolas Geoffrayb1d91572016-03-18 16:25:38 +000031 public static Object getNull() { return null; }
Nicolas Geoffraybb2c93b2016-05-04 14:00:12 +010032 public static Test1 getNullTest1() { return null; }
33 public static Test2 getNullTest2() { return null; }
Nicolas Geoffray03971632016-03-17 10:44:24 +000034
Igor Murashkin11ffec22017-06-27 15:36:23 -070035 public static void $noinline$runSmaliTest(String name) throws Throwable {
36 try {
37 Class<?> c = Class.forName("SmaliTests");
38 Method m = c.getMethod(name);
39 m.invoke(null);
40 } catch (InvocationTargetException ex) {
41 throw ex.getCause(); // re-raise expected exception.
42 } catch (Exception ex) {
43 throw new Error(ex);
44 }
45 }
46
Nicolas Geoffray03971632016-03-17 10:44:24 +000047 public static void main(String[] args) {
48 try {
49 foo();
50 throw new Error("Expected NullPointerException");
51 } catch (NullPointerException e) {
52 // Expected.
53 }
Nicolas Geoffraybb2c93b2016-05-04 14:00:12 +010054 try {
55 bar();
56 throw new Error("Expected NullPointerException");
57 } catch (NullPointerException e) {
58 // Expected.
59 }
60 try {
Igor Murashkin11ffec22017-06-27 15:36:23 -070061 $noinline$runSmaliTest("bar");
62 throw new Error("Expected NullPointerException");
63 } catch (NullPointerException e) {
64 // Expected.
65 } catch (Throwable t) {
66 throw new Error("Unexpected Throwable", t);
67 }
Alan Leung213f8572017-09-08 14:44:24 -070068 try {
69 $noinline$runSmaliTest("bar2");
70 throw new Error("Expected NullPointerException");
71 } catch (NullPointerException e) {
72 // Expected.
73 } catch (Throwable t) {
74 throw new Error("Unexpected Throwable", t);
75 }
Igor Murashkin11ffec22017-06-27 15:36:23 -070076
77 try {
Nicolas Geoffraybb2c93b2016-05-04 14:00:12 +010078 test1();
79 throw new Error("Expected NullPointerException");
80 } catch (NullPointerException e) {
81 // Expected.
82 }
Nicolas Geoffray03971632016-03-17 10:44:24 +000083 }
84
85 /// CHECK-START: void Main.foo() load_store_elimination (after)
Nicolas Geoffraybb2c93b2016-05-04 14:00:12 +010086 /// CHECK-DAG: <<Null:l\d+>> NullConstant
87 /// CHECK-DAG: <<Check:l\d+>> NullCheck [<<Null>>]
88 /// CHECK-DAG: <<Get1:j\d+>> ArrayGet [<<Check>>,{{i\d+}}]
89 /// CHECK-DAG: <<Get2:l\d+>> ArrayGet [<<Check>>,{{i\d+}}]
Nicolas Geoffray03971632016-03-17 10:44:24 +000090 public static void foo() {
91 longField = getLongArray()[0];
92 objectField = getObjectArray()[0];
93 }
94
Nicolas Geoffrayb1d91572016-03-18 16:25:38 +000095 /// CHECK-START: void Main.bar() load_store_elimination (after)
96 /// CHECK-DAG: <<Null:l\d+>> NullConstant
Alan Leung213f8572017-09-08 14:44:24 -070097 /// CHECK-DAG: BoundType [<<Null>>]
98 /// CHECK-DAG: <<CheckL:l\d+>> NullCheck
Nicolas Geoffrayb1d91572016-03-18 16:25:38 +000099 /// CHECK-DAG: <<GetL0:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}]
100 /// CHECK-DAG: <<GetL1:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}]
101 /// CHECK-DAG: <<GetL2:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}]
102 /// CHECK-DAG: <<GetL3:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}]
103 /// CHECK-DAG: <<CheckJ:l\d+>> NullCheck [<<Null>>]
104 /// CHECK-DAG: <<GetJ0:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}]
105 /// CHECK-DAG: <<GetJ1:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}]
106 /// CHECK-DAG: <<GetJ2:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}]
107 /// CHECK-DAG: <<GetJ3:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}]
108 public static void bar() {
109 // We create multiple accesses that will lead the bounds check
110 // elimination pass to add a HDeoptimize. Not having the bounds check helped
111 // the load store elimination think it could merge two ArrayGet with different
112 // types.
Nicolas Geoffraybb2c93b2016-05-04 14:00:12 +0100113 String[] array = (String[])getNull();
Nicolas Geoffrayb1d91572016-03-18 16:25:38 +0000114 objectField = array[0];
115 objectField = array[1];
116 objectField = array[2];
117 objectField = array[3];
118 long[] longArray = getLongArray();
119 longField = longArray[0];
120 longField = longArray[1];
121 longField = longArray[2];
122 longField = longArray[3];
123 }
124
Nicolas Geoffraybb2c93b2016-05-04 14:00:12 +0100125 /// CHECK-START: float Main.test1() load_store_elimination (after)
126 /// CHECK-DAG: <<Null:l\d+>> NullConstant
127 /// CHECK-DAG: <<Check1:l\d+>> NullCheck [<<Null>>]
128 /// CHECK-DAG: <<FieldGet1:l\d+>> InstanceFieldGet [<<Check1>>] field_name:Test1.iarr
129 /// CHECK-DAG: <<Check2:l\d+>> NullCheck [<<FieldGet1>>]
130 /// CHECK-DAG: <<ArrayGet1:i\d+>> ArrayGet [<<Check2>>,{{i\d+}}]
131 /// CHECK-DAG: <<ArrayGet2:f\d+>> ArrayGet [<<Check2>>,{{i\d+}}]
132 /// CHECK-DAG: Return [<<ArrayGet2>>]
133 public static float test1() {
134 Test1 test1 = getNullTest1();
Mathieu Chartier6beced42016-11-15 15:51:31 -0800135 Test2 test2 = getNullTest2();
Nicolas Geoffraybb2c93b2016-05-04 14:00:12 +0100136 int[] iarr = test1.iarr;
137 float[] farr = test2.farr;
138 iarr[0] = iarr[1];
139 return farr[0];
140 }
141
Nicolas Geoffray03971632016-03-17 10:44:24 +0000142 public static long longField;
143 public static Object objectField;
144}