blob: af1eaea3086858dd8a7e27998748ad47c789ce23 [file] [log] [blame]
jeffhao5d1ac922011-09-29 17:41:15 -07001/*
2 * Copyright (C) 2010 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
Andreas Gampea727e372015-08-25 09:22:37 -070017import java.lang.reflect.InvocationTargetException;
18import java.lang.reflect.Method;
19import java.lang.reflect.Modifier;
jeffhao5d1ac922011-09-29 17:41:15 -070020
21/*
22 * Entry point and tests that are expected to succeed.
23 */
24public class Main {
25 /**
26 * Drives tests.
27 */
28 public static void main(String[] args) {
29 Main m = new Main();
30
31 m.recursiveSync(0);
32
33 m.nestedMayThrow(false);
34 try {
35 m.nestedMayThrow(true);
36 System.err.println("nestedThrow(true) did not throw");
37 } catch (MyException me) {}
38 System.out.println("nestedMayThrow ok");
39
40 m.constantLock();
41 System.out.println("constantLock ok");
42
43 m.notExcessiveNesting();
jeffhao5d1ac922011-09-29 17:41:15 -070044
45 m.notNested();
46 System.out.println("notNested ok");
47
48 Object obj1 = new Object();
49 Object obj2 = new Object();
50
51 m.twoPath(obj1, obj2, 0);
52 System.out.println("twoPath ok");
53
54 m.triplet(obj1, obj2, 0);
55 System.out.println("triplet ok");
Andreas Gampea727e372015-08-25 09:22:37 -070056
57 System.loadLibrary("arttest");
58 runSmaliTests();
jeffhao5d1ac922011-09-29 17:41:15 -070059 }
60
61 /**
62 * Recursive synchronized method.
63 */
64 synchronized void recursiveSync(int iter) {
65 if (iter < 40) {
66 recursiveSync(iter+1);
67 } else {
68 System.out.println("recursiveSync ok");
69 }
70 }
71
72 /**
73 * Tests simple nesting, with and without a throw.
74 */
75 void nestedMayThrow(boolean doThrow) {
76 synchronized (this) {
77 synchronized (Main.class) {
78 synchronized (new Object()) {
79 synchronized(Class.class) {
80 if (doThrow) {
81 throw new MyException();
82 }
83 }
84 }
85 }
86 }
87 }
88
89 /**
90 * Exercises bug 3215458.
91 */
92 void constantLock() {
93 Class thing = Thread.class;
94 synchronized (Thread.class) {}
95 }
96
97 /**
98 * Confirms that we can have 32 nested monitors on one method.
99 */
100 void notExcessiveNesting() {
101 synchronized (this) { // 1
102 synchronized (this) { // 2
103 synchronized (this) { // 3
104 synchronized (this) { // 4
105 synchronized (this) { // 5
106 synchronized (this) { // 6
107 synchronized (this) { // 7
108 synchronized (this) { // 8
109 synchronized (this) { // 9
110 synchronized (this) { // 10
111 synchronized (this) { // 11
112 synchronized (this) { // 12
113 synchronized (this) { // 13
114 synchronized (this) { // 14
115 synchronized (this) { // 15
116 synchronized (this) { // 16
117 synchronized (this) { // 17
118 synchronized (this) { // 18
119 synchronized (this) { // 19
120 synchronized (this) { // 20
121 synchronized (this) { // 21
122 synchronized (this) { // 22
123 synchronized (this) { // 23
124 synchronized (this) { // 24
125 synchronized (this) { // 25
126 synchronized (this) { // 26
127 synchronized (this) { // 27
128 synchronized (this) { // 28
129 synchronized (this) { // 29
130 synchronized (this) { // 30
131 synchronized (this) { // 31
132 synchronized (this) { // 32
133 }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
134 }
135
136 /**
137 * Confirms that we can have more than 32 non-nested monitors in one
138 * method.
139 */
140 void notNested() {
141 synchronized (this) {} // 1
142 synchronized (this) {} // 2
143 synchronized (this) {} // 3
144 synchronized (this) {} // 4
145 synchronized (this) {} // 5
146 synchronized (this) {} // 6
147 synchronized (this) {} // 7
148 synchronized (this) {} // 8
149 synchronized (this) {} // 9
150 synchronized (this) {} // 10
151 synchronized (this) {} // 11
152 synchronized (this) {} // 12
153 synchronized (this) {} // 13
154 synchronized (this) {} // 14
155 synchronized (this) {} // 15
156 synchronized (this) {} // 16
157 synchronized (this) {} // 17
158 synchronized (this) {} // 18
159 synchronized (this) {} // 19
160 synchronized (this) {} // 20
161 synchronized (this) {} // 21
162 synchronized (this) {} // 22
163 synchronized (this) {} // 23
164 synchronized (this) {} // 24
165 synchronized (this) {} // 25
166 synchronized (this) {} // 26
167 synchronized (this) {} // 27
168 synchronized (this) {} // 28
169 synchronized (this) {} // 29
170 synchronized (this) {} // 30
171 synchronized (this) {} // 31
172 synchronized (this) {} // 32
173 synchronized (this) {} // 33
174 synchronized (this) {} // 34
175 }
176
177 /* does nothing but ensure that the compiler doesn't discard an object */
178 private void doNothing(Object obj) {}
179
180 /**
181 * Conditionally uses one of the synchronized objects.
182 */
183 public void twoPath(Object obj1, Object obj2, int x) {
184 Object localObj;
185
186 synchronized (obj1) {
187 synchronized(obj2) {
188 if (x == 0) {
189 localObj = obj2;
190 } else {
191 localObj = obj1;
192 }
193 }
194 }
195
196 doNothing(localObj);
197 }
198
199 /**
200 * Lock the monitor two or three times, and make use of the locked or
201 * unlocked object.
202 */
203 public void triplet(Object obj1, Object obj2, int x) {
204 Object localObj;
205
206 synchronized (obj1) {
207 synchronized(obj1) {
208 if (x == 0) {
209 synchronized(obj1) {
210 localObj = obj2;
211 }
212 } else {
213 localObj = obj1;
214 }
215 }
216 }
217
218 doNothing(localObj);
219 }
Andreas Gampea727e372015-08-25 09:22:37 -0700220
221 // Smali testing code.
222 private static void runSmaliTests() {
223 runTest("OK", new Object[] { new Object(), new Object() }, null);
224 runTest("TooDeep", new Object[] { new Object() }, null);
225 runTest("NotStructuredOverUnlock", new Object[] { new Object() },
226 IllegalMonitorStateException.class);
227 runTest("NotStructuredUnderUnlock", new Object[] { new Object() }, null);
228 // TODO: new IllegalMonitorStateException());
229 runTest("UnbalancedJoin", new Object[] { new Object(), new Object() }, null);
230 runTest("UnbalancedStraight", new Object[] { new Object(), new Object() }, null);
231 }
232
233 private static void runTest(String className, Object[] parameters, Class<?> excType) {
234 System.out.println(className);
235 try {
236 Class<?> c = Class.forName(className);
237
238 Method[] methods = c.getDeclaredMethods();
239
240 // For simplicity we assume that test methods are not overloaded. So searching by name
241 // will give us the method we need to run.
242 Method method = null;
243 for (Method m : methods) {
244 if (m.getName().equals("run")) {
245 method = m;
246 break;
247 }
248 }
249
250 if (method == null) {
251 System.out.println("Could not find test method for " + className);
252 } else if (!Modifier.isStatic(method.getModifiers())) {
253 System.out.println("Test method for " + className + " is not static.");
254 } else {
255 method.invoke(null, parameters);
256 if (excType != null) {
257 System.out.println("Expected an exception in " + className);
258 }
259 }
260 } catch (Throwable exc) {
261 if (excType == null) {
262 System.out.println("Did not expect exception " + exc + " for " + className);
263 exc.printStackTrace(System.out);
264 } else if (exc instanceof InvocationTargetException && exc.getCause() != null &&
265 exc.getCause().getClass().equals(excType)) {
266 // Expected exception is wrapped in InvocationTargetException.
267 } else if (!excType.equals(exc.getClass())) {
268 System.out.println("Expected " + excType.getName() + ", but got " + exc.getClass());
269 } else {
270 // Expected exception, do nothing.
271 }
272 }
273 }
274
275 // Helpers for the smali code.
276 public static native void assertCallerIsInterpreted();
277 public static native void assertCallerIsManaged();
jeffhao5d1ac922011-09-29 17:41:15 -0700278}