blob: ba75f5a1590db4d8b725cd5dde52af7cd99f2e2b [file] [log] [blame]
Mingyao Yangf711f2c2016-05-23 12:29:39 -07001/*
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
17import java.lang.reflect.Method;
18import java.util.Arrays;
19import java.util.Comparator;
20import java.util.HashMap;
21
Orion Hodson2731eb42020-07-24 12:10:12 +010022class TestObject {
Mingyao Yangf711f2c2016-05-23 12:29:39 -070023 public static boolean sHashCodeInvoked = false;
24 private int i;
25
Orion Hodson2731eb42020-07-24 12:10:12 +010026 public TestObject(int i) {
Mingyao Yangf711f2c2016-05-23 12:29:39 -070027 this.i = i;
28 }
29
30 public boolean equals(Object obj) {
Orion Hodson2731eb42020-07-24 12:10:12 +010031 return (obj instanceof TestObject) && (i == ((TestObject)obj).i);
Mingyao Yangf711f2c2016-05-23 12:29:39 -070032 }
33
34 public int hashCode() {
35 sHashCodeInvoked = true;
Mingyao Yangf711f2c2016-05-23 12:29:39 -070036 Main.deoptimizeAll();
Mingyao Yangf711f2c2016-05-23 12:29:39 -070037 return i % 64;
38 }
39}
40
41public class Main {
42 static boolean sFlag = false;
43
44 public static native void deoptimizeAll();
45 public static native void undeoptimizeAll();
Mingyao Yangf711f2c2016-05-23 12:29:39 -070046
47 public static void execute(Runnable runnable) throws Exception {
48 Thread t = new Thread(runnable);
49 t.start();
50 t.join();
51 }
52
53 public static void main(String[] args) throws Exception {
54 System.loadLibrary(args[0]);
Orion Hodson2731eb42020-07-24 12:10:12 +010055 final HashMap<TestObject, Long> map = new HashMap<TestObject, Long>();
Mingyao Yangf711f2c2016-05-23 12:29:39 -070056
57 // Single-frame deoptimization that covers partial fragment.
58 execute(new Runnable() {
59 public void run() {
60 int[] arr = new int[3];
Mingyao Yangf711f2c2016-05-23 12:29:39 -070061 int res = $noinline$run1(arr);
Mingyao Yangf711f2c2016-05-23 12:29:39 -070062 if (res != 79) {
63 System.out.println("Failure 1!");
Nicolas Geoffrayadfd25c2018-09-14 20:07:30 +000064 System.exit(0);
Mingyao Yangf711f2c2016-05-23 12:29:39 -070065 }
66 }
67 });
68
69 // Single-frame deoptimization that covers a full fragment.
70 execute(new Runnable() {
71 public void run() {
72 try {
73 int[] arr = new int[3];
Mingyao Yangf711f2c2016-05-23 12:29:39 -070074 // Use reflection to call $noinline$run2 so that it does
75 // full-fragment deoptimization since that is an upcall.
76 Class<?> cls = Class.forName("Main");
77 Method method = cls.getDeclaredMethod("$noinline$run2", int[].class);
78 double res = (double)method.invoke(Main.class, arr);
Mingyao Yangf711f2c2016-05-23 12:29:39 -070079 if (res != 79.3d) {
80 System.out.println("Failure 2!");
Nicolas Geoffrayadfd25c2018-09-14 20:07:30 +000081 System.exit(0);
Mingyao Yangf711f2c2016-05-23 12:29:39 -070082 }
83 } catch (Exception e) {
Kevin Brodskyf6c66c32015-12-17 14:13:00 +000084 e.printStackTrace(System.out);
Mingyao Yangf711f2c2016-05-23 12:29:39 -070085 }
86 }
87 });
88
89 // Full-fragment deoptimization.
90 execute(new Runnable() {
91 public void run() {
Mingyao Yangf711f2c2016-05-23 12:29:39 -070092 float res = $noinline$run3B();
Mingyao Yangf711f2c2016-05-23 12:29:39 -070093 if (res != 0.034f) {
94 System.out.println("Failure 3!");
Nicolas Geoffrayadfd25c2018-09-14 20:07:30 +000095 System.exit(0);
Mingyao Yangf711f2c2016-05-23 12:29:39 -070096 }
97 }
98 });
99
100 undeoptimizeAll(); // Make compiled code useable again.
101
102 // Partial-fragment deoptimization.
103 execute(new Runnable() {
104 public void run() {
105 try {
Orion Hodson2731eb42020-07-24 12:10:12 +0100106 map.put(new TestObject(10), Long.valueOf(100));
107 if (map.get(new TestObject(10)) == null) {
108 System.out.println("Expected map to contain TestObject(10)");
Nicolas Geoffray41627362018-09-18 14:48:36 +0100109 }
Mingyao Yangf711f2c2016-05-23 12:29:39 -0700110 } catch (Exception e) {
Kevin Brodskyf6c66c32015-12-17 14:13:00 +0000111 e.printStackTrace(System.out);
Mingyao Yangf711f2c2016-05-23 12:29:39 -0700112 }
113 }
114 });
115
116 undeoptimizeAll(); // Make compiled code useable again.
117
Orion Hodson2731eb42020-07-24 12:10:12 +0100118 if (!TestObject.sHashCodeInvoked) {
Mingyao Yangf711f2c2016-05-23 12:29:39 -0700119 System.out.println("hashCode() method not invoked!");
120 }
Orion Hodson2731eb42020-07-24 12:10:12 +0100121 if (map.get(new TestObject(10)) != 100) {
Mingyao Yangf711f2c2016-05-23 12:29:39 -0700122 System.out.println("Wrong hashmap value!");
123 }
124 System.out.println("Finishing");
125 }
126
127 public static int $noinline$run1(int[] arr) {
Mingyao Yangf711f2c2016-05-23 12:29:39 -0700128 // Prevent inlining.
129 if (sFlag) {
130 throw new Error();
131 }
132 boolean caught = false;
133 // BCE will use deoptimization for the code below.
134 try {
135 arr[0] = 1;
136 arr[1] = 1;
137 arr[2] = 1;
138 // This causes AIOOBE and triggers deoptimization from compiled code.
139 arr[3] = 1;
140 } catch (ArrayIndexOutOfBoundsException e) {
Mingyao Yangf711f2c2016-05-23 12:29:39 -0700141 caught = true;
142 }
143 if (!caught) {
144 System.out.println("Expected exception");
145 }
Mingyao Yangf711f2c2016-05-23 12:29:39 -0700146 return 79;
147 }
148
149 public static double $noinline$run2(int[] arr) {
Mingyao Yangf711f2c2016-05-23 12:29:39 -0700150 // Prevent inlining.
151 if (sFlag) {
152 throw new Error();
153 }
154 boolean caught = false;
155 // BCE will use deoptimization for the code below.
156 try {
157 arr[0] = 1;
158 arr[1] = 1;
159 arr[2] = 1;
160 // This causes AIOOBE and triggers deoptimization from compiled code.
161 arr[3] = 1;
162 } catch (ArrayIndexOutOfBoundsException e) {
Mingyao Yangf711f2c2016-05-23 12:29:39 -0700163 caught = true;
164 }
165 if (!caught) {
166 System.out.println("Expected exception");
Mingyao Yangf711f2c2016-05-23 12:29:39 -0700167 }
Mingyao Yangf711f2c2016-05-23 12:29:39 -0700168 return 79.3d;
169 }
170
171 public static float $noinline$run3A() {
Mingyao Yangf711f2c2016-05-23 12:29:39 -0700172 // Prevent inlining.
173 if (sFlag) {
174 throw new Error();
175 }
176 // Deoptimize callers.
177 deoptimizeAll();
Mingyao Yangf711f2c2016-05-23 12:29:39 -0700178 return 0.034f;
179 }
180
181 public static float $noinline$run3B() {
Mingyao Yangf711f2c2016-05-23 12:29:39 -0700182 // Prevent inlining.
183 if (sFlag) {
184 throw new Error();
185 }
186 float res = $noinline$run3A();
Mingyao Yangf711f2c2016-05-23 12:29:39 -0700187 return res;
188 }
189}