xref: /aosp_15_r20/art/test/626-const-class-linking/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker import java.lang.ref.WeakReference;
18*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Field;
19*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.InvocationTargetException;
20*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Method;
21*795d594fSAndroid Build Coastguard Worker import java.util.ArrayList;
22*795d594fSAndroid Build Coastguard Worker 
23*795d594fSAndroid Build Coastguard Worker public class Main {
main(String[] args)24*795d594fSAndroid Build Coastguard Worker     public static void main(String[] args) throws Exception {
25*795d594fSAndroid Build Coastguard Worker         try {
26*795d594fSAndroid Build Coastguard Worker             // Check if we're running dalvik or RI.
27*795d594fSAndroid Build Coastguard Worker             Class<?> class_loader_class = Class.forName("dalvik.system.PathClassLoader");
28*795d594fSAndroid Build Coastguard Worker             System.loadLibrary(args[0]);
29*795d594fSAndroid Build Coastguard Worker         } catch (ClassNotFoundException e) {
30*795d594fSAndroid Build Coastguard Worker             usingRI = true;
31*795d594fSAndroid Build Coastguard Worker             // Add expected JNI_OnLoad log line to match expected-stdout.txt.
32*795d594fSAndroid Build Coastguard Worker             System.out.println("JNI_OnLoad called");
33*795d594fSAndroid Build Coastguard Worker         }
34*795d594fSAndroid Build Coastguard Worker 
35*795d594fSAndroid Build Coastguard Worker         testClearDexCache();
36*795d594fSAndroid Build Coastguard Worker         testMultiDex();
37*795d594fSAndroid Build Coastguard Worker         testRacyLoader();
38*795d594fSAndroid Build Coastguard Worker         testRacyLoader2();
39*795d594fSAndroid Build Coastguard Worker         testMisbehavingLoader();
40*795d594fSAndroid Build Coastguard Worker         testRacyMisbehavingLoader();
41*795d594fSAndroid Build Coastguard Worker         testRacyMisbehavingLoader2();
42*795d594fSAndroid Build Coastguard Worker     }
43*795d594fSAndroid Build Coastguard Worker 
testClearDexCache()44*795d594fSAndroid Build Coastguard Worker     private static void testClearDexCache() throws Exception {
45*795d594fSAndroid Build Coastguard Worker         DelegatingLoader delegating_loader = createDelegatingLoader();
46*795d594fSAndroid Build Coastguard Worker         Class<?> helper = delegating_loader.loadClass("Helper1");
47*795d594fSAndroid Build Coastguard Worker 
48*795d594fSAndroid Build Coastguard Worker         WeakReference<Class<?>> weak_test1 = wrapHelperGet(helper);
49*795d594fSAndroid Build Coastguard Worker         changeInner(delegating_loader);
50*795d594fSAndroid Build Coastguard Worker         clearResolvedTypes(helper);
51*795d594fSAndroid Build Coastguard Worker         Runtime.getRuntime().gc();
52*795d594fSAndroid Build Coastguard Worker         WeakReference<Class<?>> weak_test2 = wrapHelperGet(helper);
53*795d594fSAndroid Build Coastguard Worker         Runtime.getRuntime().gc();
54*795d594fSAndroid Build Coastguard Worker 
55*795d594fSAndroid Build Coastguard Worker         Class<?> test1 = weak_test1.get();
56*795d594fSAndroid Build Coastguard Worker         if (test1 == null) {
57*795d594fSAndroid Build Coastguard Worker             System.out.println("test1 disappeared");
58*795d594fSAndroid Build Coastguard Worker         }
59*795d594fSAndroid Build Coastguard Worker         Class<?> test2 = weak_test2.get();
60*795d594fSAndroid Build Coastguard Worker         if (test2 == null) {
61*795d594fSAndroid Build Coastguard Worker             System.out.println("test2 disappeared");
62*795d594fSAndroid Build Coastguard Worker         }
63*795d594fSAndroid Build Coastguard Worker         if (test1 != test2) {
64*795d594fSAndroid Build Coastguard Worker             System.out.println("test1 != test2");
65*795d594fSAndroid Build Coastguard Worker         }
66*795d594fSAndroid Build Coastguard Worker 
67*795d594fSAndroid Build Coastguard Worker         System.out.println("testClearDexCache done");
68*795d594fSAndroid Build Coastguard Worker     }
69*795d594fSAndroid Build Coastguard Worker 
testMultiDex()70*795d594fSAndroid Build Coastguard Worker     private static void testMultiDex() throws Exception {
71*795d594fSAndroid Build Coastguard Worker         DelegatingLoader delegating_loader = createDelegatingLoader();
72*795d594fSAndroid Build Coastguard Worker 
73*795d594fSAndroid Build Coastguard Worker         Class<?> helper1 = delegating_loader.loadClass("Helper1");
74*795d594fSAndroid Build Coastguard Worker         WeakReference<Class<?>> weak_test1 = wrapHelperGet(helper1);
75*795d594fSAndroid Build Coastguard Worker 
76*795d594fSAndroid Build Coastguard Worker         changeInner(delegating_loader);
77*795d594fSAndroid Build Coastguard Worker 
78*795d594fSAndroid Build Coastguard Worker         Class<?> helper2 = delegating_loader.loadClass("Helper2");
79*795d594fSAndroid Build Coastguard Worker         WeakReference<Class<?>> weak_test2 = wrapHelperGet(helper2);
80*795d594fSAndroid Build Coastguard Worker 
81*795d594fSAndroid Build Coastguard Worker         Runtime.getRuntime().gc();
82*795d594fSAndroid Build Coastguard Worker 
83*795d594fSAndroid Build Coastguard Worker         Class<?> test1 = weak_test1.get();
84*795d594fSAndroid Build Coastguard Worker         if (test1 == null) {
85*795d594fSAndroid Build Coastguard Worker             System.out.println("test1 disappeared");
86*795d594fSAndroid Build Coastguard Worker         }
87*795d594fSAndroid Build Coastguard Worker         Class<?> test2 = weak_test2.get();
88*795d594fSAndroid Build Coastguard Worker         if (test2 == null) {
89*795d594fSAndroid Build Coastguard Worker             System.out.println("test2 disappeared");
90*795d594fSAndroid Build Coastguard Worker         }
91*795d594fSAndroid Build Coastguard Worker         if (test1 != test2) {
92*795d594fSAndroid Build Coastguard Worker             System.out.println("test1 != test2");
93*795d594fSAndroid Build Coastguard Worker         }
94*795d594fSAndroid Build Coastguard Worker 
95*795d594fSAndroid Build Coastguard Worker         System.out.println("testMultiDex done");
96*795d594fSAndroid Build Coastguard Worker     }
97*795d594fSAndroid Build Coastguard Worker 
testMisbehavingLoader()98*795d594fSAndroid Build Coastguard Worker     private static void testMisbehavingLoader() throws Exception {
99*795d594fSAndroid Build Coastguard Worker         ClassLoader system_loader = ClassLoader.getSystemClassLoader();
100*795d594fSAndroid Build Coastguard Worker         DefiningLoader defining_loader = new DefiningLoader(system_loader);
101*795d594fSAndroid Build Coastguard Worker         MisbehavingLoader misbehaving_loader =
102*795d594fSAndroid Build Coastguard Worker             new MisbehavingLoader(system_loader, defining_loader);
103*795d594fSAndroid Build Coastguard Worker         Class<?> helper = misbehaving_loader.loadClass("Helper1");
104*795d594fSAndroid Build Coastguard Worker 
105*795d594fSAndroid Build Coastguard Worker         try {
106*795d594fSAndroid Build Coastguard Worker             WeakReference<Class<?>> weak_test = wrapHelperGet(helper);
107*795d594fSAndroid Build Coastguard Worker         } catch (InvocationTargetException ite) {
108*795d594fSAndroid Build Coastguard Worker             String message = ite.getCause().getMessage();
109*795d594fSAndroid Build Coastguard Worker             if (usingRI && "Test".equals(message)) {
110*795d594fSAndroid Build Coastguard Worker               // Replace RI message with dalvik message to match expected-stdout.txt.
111*795d594fSAndroid Build Coastguard Worker               message = "Initiating class loader of type " +
112*795d594fSAndroid Build Coastguard Worker                   misbehaving_loader.getClass().getName() +
113*795d594fSAndroid Build Coastguard Worker                   " returned class Helper2 instead of Test.";
114*795d594fSAndroid Build Coastguard Worker             }
115*795d594fSAndroid Build Coastguard Worker             System.out.println(ite.getCause().getClass().getName() + ": " + message);
116*795d594fSAndroid Build Coastguard Worker         }
117*795d594fSAndroid Build Coastguard Worker         System.out.println("testMisbehavingLoader done");
118*795d594fSAndroid Build Coastguard Worker     }
119*795d594fSAndroid Build Coastguard Worker 
testRacyLoader()120*795d594fSAndroid Build Coastguard Worker     private static void testRacyLoader() throws Exception {
121*795d594fSAndroid Build Coastguard Worker         final ClassLoader system_loader = ClassLoader.getSystemClassLoader();
122*795d594fSAndroid Build Coastguard Worker 
123*795d594fSAndroid Build Coastguard Worker         final Thread[] threads = new Thread[4];
124*795d594fSAndroid Build Coastguard Worker         final Object[] results = new Object[threads.length];
125*795d594fSAndroid Build Coastguard Worker 
126*795d594fSAndroid Build Coastguard Worker         final RacyLoader racy_loader = new RacyLoader(system_loader, threads.length);
127*795d594fSAndroid Build Coastguard Worker         final Class<?> helper1 = racy_loader.loadClass("Helper1");
128*795d594fSAndroid Build Coastguard Worker         skipVerification(helper1);  // Avoid class loading during verification.
129*795d594fSAndroid Build Coastguard Worker 
130*795d594fSAndroid Build Coastguard Worker         for (int i = 0; i != threads.length; ++i) {
131*795d594fSAndroid Build Coastguard Worker             final int my_index = i;
132*795d594fSAndroid Build Coastguard Worker             Thread t = new Thread() {
133*795d594fSAndroid Build Coastguard Worker                 public void run() {
134*795d594fSAndroid Build Coastguard Worker                     try {
135*795d594fSAndroid Build Coastguard Worker                         Method get = helper1.getDeclaredMethod("get");
136*795d594fSAndroid Build Coastguard Worker                         results[my_index] = get.invoke(null);
137*795d594fSAndroid Build Coastguard Worker                     } catch (InvocationTargetException ite) {
138*795d594fSAndroid Build Coastguard Worker                         results[my_index] = ite.getCause();
139*795d594fSAndroid Build Coastguard Worker                     } catch (Throwable t) {
140*795d594fSAndroid Build Coastguard Worker                         results[my_index] = t;
141*795d594fSAndroid Build Coastguard Worker                     }
142*795d594fSAndroid Build Coastguard Worker                 }
143*795d594fSAndroid Build Coastguard Worker             };
144*795d594fSAndroid Build Coastguard Worker             t.start();
145*795d594fSAndroid Build Coastguard Worker             threads[i] = t;
146*795d594fSAndroid Build Coastguard Worker         }
147*795d594fSAndroid Build Coastguard Worker         for (Thread t : threads) {
148*795d594fSAndroid Build Coastguard Worker             t.join();
149*795d594fSAndroid Build Coastguard Worker         }
150*795d594fSAndroid Build Coastguard Worker         dumpResultStats(results, 1);
151*795d594fSAndroid Build Coastguard Worker         System.out.println("testRacyLoader done");
152*795d594fSAndroid Build Coastguard Worker     }
153*795d594fSAndroid Build Coastguard Worker 
testRacyLoader2()154*795d594fSAndroid Build Coastguard Worker     private static void testRacyLoader2() throws Exception {
155*795d594fSAndroid Build Coastguard Worker         final ClassLoader system_loader = ClassLoader.getSystemClassLoader();
156*795d594fSAndroid Build Coastguard Worker 
157*795d594fSAndroid Build Coastguard Worker         final Thread[] threads = new Thread[4];
158*795d594fSAndroid Build Coastguard Worker         final Object[] results = new Object[threads.length];
159*795d594fSAndroid Build Coastguard Worker 
160*795d594fSAndroid Build Coastguard Worker         final RacyLoader racy_loader = new RacyLoader(system_loader, threads.length);
161*795d594fSAndroid Build Coastguard Worker         final Class<?> helper1 = racy_loader.loadClass("Helper1");
162*795d594fSAndroid Build Coastguard Worker         skipVerification(helper1);  // Avoid class loading during verification.
163*795d594fSAndroid Build Coastguard Worker         final Class<?> helper3 = racy_loader.loadClass("Helper3");
164*795d594fSAndroid Build Coastguard Worker         skipVerification(helper3);  // Avoid class loading during verification.
165*795d594fSAndroid Build Coastguard Worker 
166*795d594fSAndroid Build Coastguard Worker         for (int i = 0; i != threads.length; ++i) {
167*795d594fSAndroid Build Coastguard Worker             final int my_index = i;
168*795d594fSAndroid Build Coastguard Worker             Thread t = new Thread() {
169*795d594fSAndroid Build Coastguard Worker                 public void run() {
170*795d594fSAndroid Build Coastguard Worker                     try {
171*795d594fSAndroid Build Coastguard Worker                         Class<?> helper = (my_index < threads.length / 2) ? helper1 : helper3;
172*795d594fSAndroid Build Coastguard Worker                         Method get = helper.getDeclaredMethod("get");
173*795d594fSAndroid Build Coastguard Worker                         results[my_index] = get.invoke(null);
174*795d594fSAndroid Build Coastguard Worker                     } catch (InvocationTargetException ite) {
175*795d594fSAndroid Build Coastguard Worker                         results[my_index] = ite.getCause();
176*795d594fSAndroid Build Coastguard Worker                     } catch (Throwable t) {
177*795d594fSAndroid Build Coastguard Worker                         results[my_index] = t;
178*795d594fSAndroid Build Coastguard Worker                     }
179*795d594fSAndroid Build Coastguard Worker                 }
180*795d594fSAndroid Build Coastguard Worker             };
181*795d594fSAndroid Build Coastguard Worker             t.start();
182*795d594fSAndroid Build Coastguard Worker             threads[i] = t;
183*795d594fSAndroid Build Coastguard Worker         }
184*795d594fSAndroid Build Coastguard Worker         for (Thread t : threads) {
185*795d594fSAndroid Build Coastguard Worker             t.join();
186*795d594fSAndroid Build Coastguard Worker         }
187*795d594fSAndroid Build Coastguard Worker         dumpResultStats(results, 2);
188*795d594fSAndroid Build Coastguard Worker         System.out.println("testRacyLoader2 done");
189*795d594fSAndroid Build Coastguard Worker     }
190*795d594fSAndroid Build Coastguard Worker 
testRacyMisbehavingLoader()191*795d594fSAndroid Build Coastguard Worker     private static void testRacyMisbehavingLoader() throws Exception {
192*795d594fSAndroid Build Coastguard Worker         final ClassLoader system_loader = ClassLoader.getSystemClassLoader();
193*795d594fSAndroid Build Coastguard Worker 
194*795d594fSAndroid Build Coastguard Worker         final Thread[] threads = new Thread[4];
195*795d594fSAndroid Build Coastguard Worker         final Object[] results = new Object[threads.length];
196*795d594fSAndroid Build Coastguard Worker 
197*795d594fSAndroid Build Coastguard Worker         final RacyMisbehavingLoader racy_loader =
198*795d594fSAndroid Build Coastguard Worker             new RacyMisbehavingLoader(system_loader, threads.length, false);
199*795d594fSAndroid Build Coastguard Worker         final Class<?> helper1 = racy_loader.loadClass("RacyMisbehavingHelper");
200*795d594fSAndroid Build Coastguard Worker         skipVerification(helper1);  // Avoid class loading during verification.
201*795d594fSAndroid Build Coastguard Worker 
202*795d594fSAndroid Build Coastguard Worker         for (int i = 0; i != threads.length; ++i) {
203*795d594fSAndroid Build Coastguard Worker             final int my_index = i;
204*795d594fSAndroid Build Coastguard Worker             Thread t = new Thread() {
205*795d594fSAndroid Build Coastguard Worker                 public void run() {
206*795d594fSAndroid Build Coastguard Worker                     try {
207*795d594fSAndroid Build Coastguard Worker                         Method get = helper1.getDeclaredMethod("get");
208*795d594fSAndroid Build Coastguard Worker                         results[my_index] = get.invoke(null);
209*795d594fSAndroid Build Coastguard Worker                     } catch (InvocationTargetException ite) {
210*795d594fSAndroid Build Coastguard Worker                         results[my_index] = ite.getCause();
211*795d594fSAndroid Build Coastguard Worker                     } catch (Throwable t) {
212*795d594fSAndroid Build Coastguard Worker                         results[my_index] = t;
213*795d594fSAndroid Build Coastguard Worker                     }
214*795d594fSAndroid Build Coastguard Worker                 }
215*795d594fSAndroid Build Coastguard Worker             };
216*795d594fSAndroid Build Coastguard Worker             t.start();
217*795d594fSAndroid Build Coastguard Worker             threads[i] = t;
218*795d594fSAndroid Build Coastguard Worker         }
219*795d594fSAndroid Build Coastguard Worker         for (Thread t : threads) {
220*795d594fSAndroid Build Coastguard Worker             t.join();
221*795d594fSAndroid Build Coastguard Worker         }
222*795d594fSAndroid Build Coastguard Worker         dumpResultStats(results, 1);
223*795d594fSAndroid Build Coastguard Worker         System.out.println("testRacyMisbehavingLoader done");
224*795d594fSAndroid Build Coastguard Worker     }
225*795d594fSAndroid Build Coastguard Worker 
testRacyMisbehavingLoader2()226*795d594fSAndroid Build Coastguard Worker     private static void testRacyMisbehavingLoader2() throws Exception {
227*795d594fSAndroid Build Coastguard Worker         final ClassLoader system_loader = ClassLoader.getSystemClassLoader();
228*795d594fSAndroid Build Coastguard Worker 
229*795d594fSAndroid Build Coastguard Worker         final Thread[] threads = new Thread[4];
230*795d594fSAndroid Build Coastguard Worker         final Object[] results = new Object[threads.length];
231*795d594fSAndroid Build Coastguard Worker 
232*795d594fSAndroid Build Coastguard Worker         final RacyMisbehavingLoader racy_loader =
233*795d594fSAndroid Build Coastguard Worker             new RacyMisbehavingLoader(system_loader, threads.length, true);
234*795d594fSAndroid Build Coastguard Worker         final Class<?> helper1 = racy_loader.loadClass("RacyMisbehavingHelper");
235*795d594fSAndroid Build Coastguard Worker         skipVerification(helper1);  // Avoid class loading during verification.
236*795d594fSAndroid Build Coastguard Worker 
237*795d594fSAndroid Build Coastguard Worker         for (int i = 0; i != threads.length; ++i) {
238*795d594fSAndroid Build Coastguard Worker             final int my_index = i;
239*795d594fSAndroid Build Coastguard Worker             Thread t = new Thread() {
240*795d594fSAndroid Build Coastguard Worker                 public void run() {
241*795d594fSAndroid Build Coastguard Worker                     try {
242*795d594fSAndroid Build Coastguard Worker                         Method get = helper1.getDeclaredMethod("get");
243*795d594fSAndroid Build Coastguard Worker                         results[my_index] = get.invoke(null);
244*795d594fSAndroid Build Coastguard Worker                     } catch (InvocationTargetException ite) {
245*795d594fSAndroid Build Coastguard Worker                         results[my_index] = ite.getCause();
246*795d594fSAndroid Build Coastguard Worker                     } catch (Throwable t) {
247*795d594fSAndroid Build Coastguard Worker                         results[my_index] = t;
248*795d594fSAndroid Build Coastguard Worker                     }
249*795d594fSAndroid Build Coastguard Worker                 }
250*795d594fSAndroid Build Coastguard Worker             };
251*795d594fSAndroid Build Coastguard Worker             t.start();
252*795d594fSAndroid Build Coastguard Worker             threads[i] = t;
253*795d594fSAndroid Build Coastguard Worker         }
254*795d594fSAndroid Build Coastguard Worker         for (Thread t : threads) {
255*795d594fSAndroid Build Coastguard Worker             t.join();
256*795d594fSAndroid Build Coastguard Worker         }
257*795d594fSAndroid Build Coastguard Worker         dumpResultStats(results, 1);
258*795d594fSAndroid Build Coastguard Worker         System.out.println("testRacyMisbehavingLoader2 done");
259*795d594fSAndroid Build Coastguard Worker     }
260*795d594fSAndroid Build Coastguard Worker 
dumpResultStats(Object[] results, int expected_unique)261*795d594fSAndroid Build Coastguard Worker     private static void dumpResultStats(Object[] results, int expected_unique) throws Exception {
262*795d594fSAndroid Build Coastguard Worker         int throwables = 0;
263*795d594fSAndroid Build Coastguard Worker         int classes = 0;
264*795d594fSAndroid Build Coastguard Worker         int unique_classes = 0;
265*795d594fSAndroid Build Coastguard Worker         for (int i = 0; i != results.length; ++i) {
266*795d594fSAndroid Build Coastguard Worker             Object r = results[i];
267*795d594fSAndroid Build Coastguard Worker             if (r instanceof Throwable) {
268*795d594fSAndroid Build Coastguard Worker                 ++throwables;
269*795d594fSAndroid Build Coastguard Worker                 System.out.println(((Throwable) r).getMessage());
270*795d594fSAndroid Build Coastguard Worker             } else if (isClassPair(r)) {
271*795d594fSAndroid Build Coastguard Worker                 printPair(r);
272*795d594fSAndroid Build Coastguard Worker                 Object ref = getSecond(r);
273*795d594fSAndroid Build Coastguard Worker                 ++classes;
274*795d594fSAndroid Build Coastguard Worker                 ++unique_classes;
275*795d594fSAndroid Build Coastguard Worker                 for (int j = 0; j != i; ++j) {
276*795d594fSAndroid Build Coastguard Worker                     Object rj = results[j];
277*795d594fSAndroid Build Coastguard Worker                     if (isClassPair(results[j]) && getSecond(results[j]) == ref) {
278*795d594fSAndroid Build Coastguard Worker                         --unique_classes;
279*795d594fSAndroid Build Coastguard Worker                         break;
280*795d594fSAndroid Build Coastguard Worker                     }
281*795d594fSAndroid Build Coastguard Worker                 }
282*795d594fSAndroid Build Coastguard Worker             }
283*795d594fSAndroid Build Coastguard Worker         }
284*795d594fSAndroid Build Coastguard Worker         System.out.println("total: " + results.length);
285*795d594fSAndroid Build Coastguard Worker         System.out.println("  throwables: " + throwables);
286*795d594fSAndroid Build Coastguard Worker         System.out.println("  classes: " + classes
287*795d594fSAndroid Build Coastguard Worker             + " (" + unique_classes + " unique)");
288*795d594fSAndroid Build Coastguard Worker         if (expected_unique != unique_classes) {
289*795d594fSAndroid Build Coastguard Worker             System.out.println("MISMATCH with expected_unique: " + expected_unique);
290*795d594fSAndroid Build Coastguard Worker             ArrayList<Class<?>> list = new ArrayList<Class<?>>();
291*795d594fSAndroid Build Coastguard Worker             for (int i = 0; i != results.length; ++i) {
292*795d594fSAndroid Build Coastguard Worker                 Object r = results[i];
293*795d594fSAndroid Build Coastguard Worker                 if (isClassPair(r)) {
294*795d594fSAndroid Build Coastguard Worker                     list.add(getSecond(r));
295*795d594fSAndroid Build Coastguard Worker                 }
296*795d594fSAndroid Build Coastguard Worker             }
297*795d594fSAndroid Build Coastguard Worker             nativeDumpClasses(list.toArray());
298*795d594fSAndroid Build Coastguard Worker         }
299*795d594fSAndroid Build Coastguard Worker     }
300*795d594fSAndroid Build Coastguard Worker 
createDelegatingLoader()301*795d594fSAndroid Build Coastguard Worker     private static DelegatingLoader createDelegatingLoader() {
302*795d594fSAndroid Build Coastguard Worker         ClassLoader system_loader = ClassLoader.getSystemClassLoader();
303*795d594fSAndroid Build Coastguard Worker         DefiningLoader defining_loader = new DefiningLoader(system_loader);
304*795d594fSAndroid Build Coastguard Worker         return new DelegatingLoader(system_loader, defining_loader);
305*795d594fSAndroid Build Coastguard Worker     }
306*795d594fSAndroid Build Coastguard Worker 
changeInner(DelegatingLoader delegating_loader)307*795d594fSAndroid Build Coastguard Worker     private static void changeInner(DelegatingLoader delegating_loader) {
308*795d594fSAndroid Build Coastguard Worker         ClassLoader system_loader = ClassLoader.getSystemClassLoader();
309*795d594fSAndroid Build Coastguard Worker         DefiningLoader defining_loader = new DefiningLoader(system_loader);
310*795d594fSAndroid Build Coastguard Worker         delegating_loader.resetDefiningLoader(defining_loader);
311*795d594fSAndroid Build Coastguard Worker     }
312*795d594fSAndroid Build Coastguard Worker 
wrapHelperGet(Class<?> helper)313*795d594fSAndroid Build Coastguard Worker     private static WeakReference<Class<?>> wrapHelperGet(Class<?> helper) throws Exception {
314*795d594fSAndroid Build Coastguard Worker         Method get = helper.getDeclaredMethod("get");
315*795d594fSAndroid Build Coastguard Worker         Object pair = get.invoke(null);
316*795d594fSAndroid Build Coastguard Worker         printPair(pair);
317*795d594fSAndroid Build Coastguard Worker         return new WeakReference<Class<?>>(getSecond(pair));
318*795d594fSAndroid Build Coastguard Worker     }
319*795d594fSAndroid Build Coastguard Worker 
printPair(Object pair)320*795d594fSAndroid Build Coastguard Worker     private static void printPair(Object pair) throws Exception {
321*795d594fSAndroid Build Coastguard Worker         Method print = pair.getClass().getDeclaredMethod("print");
322*795d594fSAndroid Build Coastguard Worker         print.invoke(pair);
323*795d594fSAndroid Build Coastguard Worker     }
324*795d594fSAndroid Build Coastguard Worker 
getSecond(Object pair)325*795d594fSAndroid Build Coastguard Worker     private static Class<?> getSecond(Object pair) throws Exception {
326*795d594fSAndroid Build Coastguard Worker         Field second = pair.getClass().getDeclaredField("second");
327*795d594fSAndroid Build Coastguard Worker         return (Class<?>) second.get(pair);
328*795d594fSAndroid Build Coastguard Worker     }
329*795d594fSAndroid Build Coastguard Worker 
isClassPair(Object r)330*795d594fSAndroid Build Coastguard Worker     private static boolean isClassPair(Object r) {
331*795d594fSAndroid Build Coastguard Worker         return r != null && r.getClass().getName().equals("ClassPair");
332*795d594fSAndroid Build Coastguard Worker     }
333*795d594fSAndroid Build Coastguard Worker 
clearResolvedTypes(Class<?> c)334*795d594fSAndroid Build Coastguard Worker     public static void clearResolvedTypes(Class<?> c) {
335*795d594fSAndroid Build Coastguard Worker         if (!usingRI) {
336*795d594fSAndroid Build Coastguard Worker             nativeClearResolvedTypes(c);
337*795d594fSAndroid Build Coastguard Worker         }
338*795d594fSAndroid Build Coastguard Worker     }
339*795d594fSAndroid Build Coastguard Worker 
340*795d594fSAndroid Build Coastguard Worker     // Skip verification of a class on ART. Verification can cause classes to be loaded
341*795d594fSAndroid Build Coastguard Worker     // while holding a lock on the class being verified and holding that lock can interfere
342*795d594fSAndroid Build Coastguard Worker     // with the intent of the "racy" tests. In these tests we're waiting in the loadClass()
343*795d594fSAndroid Build Coastguard Worker     // for all the tested threads to synchronize and they cannot reach that point if they
344*795d594fSAndroid Build Coastguard Worker     // are waiting for the class lock on ClassLinker::InitializeClass(Helper1/Helper3).
skipVerification(Class<?> c)345*795d594fSAndroid Build Coastguard Worker     public static void skipVerification(Class<?> c) {
346*795d594fSAndroid Build Coastguard Worker         if (!usingRI) {
347*795d594fSAndroid Build Coastguard Worker             nativeSkipVerification(c);
348*795d594fSAndroid Build Coastguard Worker         }
349*795d594fSAndroid Build Coastguard Worker     }
350*795d594fSAndroid Build Coastguard Worker 
nativeClearResolvedTypes(Class<?> c)351*795d594fSAndroid Build Coastguard Worker     public static native void nativeClearResolvedTypes(Class<?> c);
nativeSkipVerification(Class<?> c)352*795d594fSAndroid Build Coastguard Worker     public static native void nativeSkipVerification(Class<?> c);
nativeDumpClasses(Object[] array)353*795d594fSAndroid Build Coastguard Worker     public static native void nativeDumpClasses(Object[] array);
354*795d594fSAndroid Build Coastguard Worker 
355*795d594fSAndroid Build Coastguard Worker     static boolean usingRI = false;
356*795d594fSAndroid Build Coastguard Worker }
357