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