1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2013 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.reflect.Constructor; 18*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.InvocationHandler; 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.lang.reflect.Field; 22*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Proxy; 23*795d594fSAndroid Build Coastguard Worker import java.util.regex.Pattern; 24*795d594fSAndroid Build Coastguard Worker 25*795d594fSAndroid Build Coastguard Worker import dalvik.annotation.optimization.CriticalNative; 26*795d594fSAndroid Build Coastguard Worker import dalvik.annotation.optimization.FastNative; 27*795d594fSAndroid Build Coastguard Worker 28*795d594fSAndroid Build Coastguard Worker public class Main { main(String[] args)29*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) { 30*795d594fSAndroid Build Coastguard Worker System.loadLibrary(args[0]); 31*795d594fSAndroid Build Coastguard Worker 32*795d594fSAndroid Build Coastguard Worker if (!isSlowDebug()) { 33*795d594fSAndroid Build Coastguard Worker throw new RuntimeException("Slow-debug flags unexpectedly off."); 34*795d594fSAndroid Build Coastguard Worker } 35*795d594fSAndroid Build Coastguard Worker 36*795d594fSAndroid Build Coastguard Worker testFieldSubclass(); 37*795d594fSAndroid Build Coastguard Worker testFindClassOnAttachedNativeThread(); 38*795d594fSAndroid Build Coastguard Worker testFindFieldOnAttachedNativeThread(); 39*795d594fSAndroid Build Coastguard Worker testReflectFieldGetFromAttachedNativeThreadNative(); 40*795d594fSAndroid Build Coastguard Worker testCallStaticVoidMethodOnSubClass(); 41*795d594fSAndroid Build Coastguard Worker testGetMirandaMethod(); 42*795d594fSAndroid Build Coastguard Worker testZeroLengthByteBuffers(); 43*795d594fSAndroid Build Coastguard Worker testByteMethod(); 44*795d594fSAndroid Build Coastguard Worker testShortMethod(); 45*795d594fSAndroid Build Coastguard Worker testBooleanMethod(); 46*795d594fSAndroid Build Coastguard Worker testCharMethod(); 47*795d594fSAndroid Build Coastguard Worker testIsAssignableFromOnPrimitiveTypes(); 48*795d594fSAndroid Build Coastguard Worker testShallowGetCallingClassLoader(); 49*795d594fSAndroid Build Coastguard Worker testShallowGetStackClass2(); 50*795d594fSAndroid Build Coastguard Worker testCallNonvirtual(); 51*795d594fSAndroid Build Coastguard Worker testNewStringObject(); 52*795d594fSAndroid Build Coastguard Worker testRemoveLocalObject(); 53*795d594fSAndroid Build Coastguard Worker testProxyGetMethodID(); 54*795d594fSAndroid Build Coastguard Worker testJniCriticalSectionAndGc(); 55*795d594fSAndroid Build Coastguard Worker testCallDefaultMethods(); 56*795d594fSAndroid Build Coastguard Worker String lambda = "λ"; 57*795d594fSAndroid Build Coastguard Worker testInvokeLambdaMethod(() -> { System.out.println("hi-lambda: " + lambda); }); 58*795d594fSAndroid Build Coastguard Worker String def = "δ"; 59*795d594fSAndroid Build Coastguard Worker testInvokeLambdaDefaultMethod(() -> { System.out.println("hi-default " + def + lambda); }); 60*795d594fSAndroid Build Coastguard Worker 61*795d594fSAndroid Build Coastguard Worker registerNativesJniTest(); 62*795d594fSAndroid Build Coastguard Worker testFastNativeMethods(); 63*795d594fSAndroid Build Coastguard Worker testCriticalNativeMethods(); 64*795d594fSAndroid Build Coastguard Worker 65*795d594fSAndroid Build Coastguard Worker testClinitMethodLookup(); 66*795d594fSAndroid Build Coastguard Worker 67*795d594fSAndroid Build Coastguard Worker testDoubleLoad(args[0]); 68*795d594fSAndroid Build Coastguard Worker testUTFRegion("\0\0\0"); 69*795d594fSAndroid Build Coastguard Worker 70*795d594fSAndroid Build Coastguard Worker testBadFastCriticalNatives(); 71*795d594fSAndroid Build Coastguard Worker } 72*795d594fSAndroid Build Coastguard Worker 73*795d594fSAndroid Build Coastguard Worker static class ABC { public static int XYZ = 12; } 74*795d594fSAndroid Build Coastguard Worker static class DEF extends ABC {} testFieldSubclass()75*795d594fSAndroid Build Coastguard Worker public static void testFieldSubclass() { 76*795d594fSAndroid Build Coastguard Worker try { 77*795d594fSAndroid Build Coastguard Worker System.out.println("ABC.XYZ = " + ABC.XYZ + ", GetStaticIntField(DEF.class, 'XYZ') = " + 78*795d594fSAndroid Build Coastguard Worker getFieldSubclass(ABC.class.getDeclaredField("XYZ"), DEF.class)); 79*795d594fSAndroid Build Coastguard Worker } catch (Exception e) { 80*795d594fSAndroid Build Coastguard Worker throw new RuntimeException("Failed to test get static field on a subclass", e); 81*795d594fSAndroid Build Coastguard Worker } 82*795d594fSAndroid Build Coastguard Worker } 83*795d594fSAndroid Build Coastguard Worker testUTFRegion(String null_str)84*795d594fSAndroid Build Coastguard Worker public static native void testUTFRegion(String null_str); 85*795d594fSAndroid Build Coastguard Worker getFieldSubclass(Field f, Class sub)86*795d594fSAndroid Build Coastguard Worker public static native int getFieldSubclass(Field f, Class sub); 87*795d594fSAndroid Build Coastguard Worker registerNativesJniTest()88*795d594fSAndroid Build Coastguard Worker private static native boolean registerNativesJniTest(); 89*795d594fSAndroid Build Coastguard Worker testCallDefaultMethods()90*795d594fSAndroid Build Coastguard Worker private static native void testCallDefaultMethods(); 91*795d594fSAndroid Build Coastguard Worker testFindClassOnAttachedNativeThread()92*795d594fSAndroid Build Coastguard Worker private static native void testFindClassOnAttachedNativeThread(); 93*795d594fSAndroid Build Coastguard Worker 94*795d594fSAndroid Build Coastguard Worker private static boolean testFindFieldOnAttachedNativeThreadField; 95*795d594fSAndroid Build Coastguard Worker testReflectFieldGetFromAttachedNativeThreadNative()96*795d594fSAndroid Build Coastguard Worker private static native void testReflectFieldGetFromAttachedNativeThreadNative(); 97*795d594fSAndroid Build Coastguard Worker 98*795d594fSAndroid Build Coastguard Worker public static boolean testReflectFieldGetFromAttachedNativeThreadField; 99*795d594fSAndroid Build Coastguard Worker testFindFieldOnAttachedNativeThread()100*795d594fSAndroid Build Coastguard Worker private static void testFindFieldOnAttachedNativeThread() { 101*795d594fSAndroid Build Coastguard Worker testFindFieldOnAttachedNativeThreadNative(); 102*795d594fSAndroid Build Coastguard Worker if (!testFindFieldOnAttachedNativeThreadField) { 103*795d594fSAndroid Build Coastguard Worker throw new AssertionError(); 104*795d594fSAndroid Build Coastguard Worker } 105*795d594fSAndroid Build Coastguard Worker } 106*795d594fSAndroid Build Coastguard Worker testFindFieldOnAttachedNativeThreadNative()107*795d594fSAndroid Build Coastguard Worker private static native void testFindFieldOnAttachedNativeThreadNative(); 108*795d594fSAndroid Build Coastguard Worker testCallStaticVoidMethodOnSubClass()109*795d594fSAndroid Build Coastguard Worker private static void testCallStaticVoidMethodOnSubClass() { 110*795d594fSAndroid Build Coastguard Worker testCallStaticVoidMethodOnSubClassNative(); 111*795d594fSAndroid Build Coastguard Worker if (!testCallStaticVoidMethodOnSubClass_SuperClass.executed) { 112*795d594fSAndroid Build Coastguard Worker throw new AssertionError(); 113*795d594fSAndroid Build Coastguard Worker } 114*795d594fSAndroid Build Coastguard Worker } 115*795d594fSAndroid Build Coastguard Worker testCallStaticVoidMethodOnSubClassNative()116*795d594fSAndroid Build Coastguard Worker private static native void testCallStaticVoidMethodOnSubClassNative(); 117*795d594fSAndroid Build Coastguard Worker 118*795d594fSAndroid Build Coastguard Worker private static class testCallStaticVoidMethodOnSubClass_SuperClass { 119*795d594fSAndroid Build Coastguard Worker private static boolean executed = false; execute()120*795d594fSAndroid Build Coastguard Worker private static void execute() { 121*795d594fSAndroid Build Coastguard Worker executed = true; 122*795d594fSAndroid Build Coastguard Worker } 123*795d594fSAndroid Build Coastguard Worker } 124*795d594fSAndroid Build Coastguard Worker 125*795d594fSAndroid Build Coastguard Worker private static class testCallStaticVoidMethodOnSubClass_SubClass 126*795d594fSAndroid Build Coastguard Worker extends testCallStaticVoidMethodOnSubClass_SuperClass { 127*795d594fSAndroid Build Coastguard Worker } 128*795d594fSAndroid Build Coastguard Worker testGetMirandaMethodNative()129*795d594fSAndroid Build Coastguard Worker private static native Method testGetMirandaMethodNative(); 130*795d594fSAndroid Build Coastguard Worker testGetMirandaMethod()131*795d594fSAndroid Build Coastguard Worker private static void testGetMirandaMethod() { 132*795d594fSAndroid Build Coastguard Worker Method m = testGetMirandaMethodNative(); 133*795d594fSAndroid Build Coastguard Worker if (m.getDeclaringClass() != testGetMirandaMethod_MirandaInterface.class) { 134*795d594fSAndroid Build Coastguard Worker throw new AssertionError(); 135*795d594fSAndroid Build Coastguard Worker } 136*795d594fSAndroid Build Coastguard Worker } 137*795d594fSAndroid Build Coastguard Worker testZeroLengthByteBuffers()138*795d594fSAndroid Build Coastguard Worker private static native void testZeroLengthByteBuffers(); 139*795d594fSAndroid Build Coastguard Worker 140*795d594fSAndroid Build Coastguard Worker private static abstract class testGetMirandaMethod_MirandaAbstract implements testGetMirandaMethod_MirandaInterface { inAbstract()141*795d594fSAndroid Build Coastguard Worker public boolean inAbstract() { 142*795d594fSAndroid Build Coastguard Worker return true; 143*795d594fSAndroid Build Coastguard Worker } 144*795d594fSAndroid Build Coastguard Worker } 145*795d594fSAndroid Build Coastguard Worker 146*795d594fSAndroid Build Coastguard Worker private static interface testGetMirandaMethod_MirandaInterface { inInterface()147*795d594fSAndroid Build Coastguard Worker public boolean inInterface(); 148*795d594fSAndroid Build Coastguard Worker } 149*795d594fSAndroid Build Coastguard Worker 150*795d594fSAndroid Build Coastguard Worker // Test sign-extension for values < 32b 151*795d594fSAndroid Build Coastguard Worker byteMethod(byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8, byte b9, byte b10)152*795d594fSAndroid Build Coastguard Worker static native byte byteMethod(byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, 153*795d594fSAndroid Build Coastguard Worker byte b8, byte b9, byte b10); 154*795d594fSAndroid Build Coastguard Worker testByteMethod()155*795d594fSAndroid Build Coastguard Worker private static void testByteMethod() { 156*795d594fSAndroid Build Coastguard Worker byte returns[] = { 0, 1, 2, 127, -1, -2, -128 }; 157*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < returns.length; i++) { 158*795d594fSAndroid Build Coastguard Worker byte result = byteMethod((byte)i, (byte)2, (byte)(-3), (byte)4, (byte)(-5), (byte)6, 159*795d594fSAndroid Build Coastguard Worker (byte)(-7), (byte)8, (byte)(-9), (byte)10); 160*795d594fSAndroid Build Coastguard Worker if (returns[i] != result) { 161*795d594fSAndroid Build Coastguard Worker System.out.println("Run " + i + " with " + returns[i] + " vs " + result); 162*795d594fSAndroid Build Coastguard Worker throw new AssertionError(); 163*795d594fSAndroid Build Coastguard Worker } 164*795d594fSAndroid Build Coastguard Worker } 165*795d594fSAndroid Build Coastguard Worker } 166*795d594fSAndroid Build Coastguard Worker removeLocalObject(Object o)167*795d594fSAndroid Build Coastguard Worker private static native void removeLocalObject(Object o); 168*795d594fSAndroid Build Coastguard Worker testRemoveLocalObject()169*795d594fSAndroid Build Coastguard Worker private static void testRemoveLocalObject() { 170*795d594fSAndroid Build Coastguard Worker removeLocalObject(new Object()); 171*795d594fSAndroid Build Coastguard Worker } 172*795d594fSAndroid Build Coastguard Worker shortMethod(short s1, short s2, short s3, short s4, short s5, short s6, short s7, short s8, short s9, short s10)173*795d594fSAndroid Build Coastguard Worker private static native short shortMethod(short s1, short s2, short s3, short s4, short s5, short s6, short s7, 174*795d594fSAndroid Build Coastguard Worker short s8, short s9, short s10); 175*795d594fSAndroid Build Coastguard Worker testShortMethod()176*795d594fSAndroid Build Coastguard Worker private static void testShortMethod() { 177*795d594fSAndroid Build Coastguard Worker short returns[] = { 0, 1, 2, 127, 32767, -1, -2, -128, -32768 }; 178*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < returns.length; i++) { 179*795d594fSAndroid Build Coastguard Worker short result = shortMethod((short)i, (short)2, (short)(-3), (short)4, (short)(-5), (short)6, 180*795d594fSAndroid Build Coastguard Worker (short)(-7), (short)8, (short)(-9), (short)10); 181*795d594fSAndroid Build Coastguard Worker if (returns[i] != result) { 182*795d594fSAndroid Build Coastguard Worker System.out.println("Run " + i + " with " + returns[i] + " vs " + result); 183*795d594fSAndroid Build Coastguard Worker throw new AssertionError(); 184*795d594fSAndroid Build Coastguard Worker } 185*795d594fSAndroid Build Coastguard Worker } 186*795d594fSAndroid Build Coastguard Worker } 187*795d594fSAndroid Build Coastguard Worker 188*795d594fSAndroid Build Coastguard Worker // Test zero-extension for values < 32b 189*795d594fSAndroid Build Coastguard Worker booleanMethod(boolean b1, boolean b2, boolean b3, boolean b4, boolean b5, boolean b6, boolean b7, boolean b8, boolean b9, boolean b10)190*795d594fSAndroid Build Coastguard Worker private static native boolean booleanMethod(boolean b1, boolean b2, boolean b3, boolean b4, boolean b5, boolean b6, boolean b7, 191*795d594fSAndroid Build Coastguard Worker boolean b8, boolean b9, boolean b10); 192*795d594fSAndroid Build Coastguard Worker testBooleanMethod()193*795d594fSAndroid Build Coastguard Worker private static void testBooleanMethod() { 194*795d594fSAndroid Build Coastguard Worker if (booleanMethod(false, true, false, true, false, true, false, true, false, true)) { 195*795d594fSAndroid Build Coastguard Worker throw new AssertionError(); 196*795d594fSAndroid Build Coastguard Worker } 197*795d594fSAndroid Build Coastguard Worker 198*795d594fSAndroid Build Coastguard Worker if (!booleanMethod(true, true, false, true, false, true, false, true, false, true)) { 199*795d594fSAndroid Build Coastguard Worker throw new AssertionError(); 200*795d594fSAndroid Build Coastguard Worker } 201*795d594fSAndroid Build Coastguard Worker } 202*795d594fSAndroid Build Coastguard Worker charMethod(char c1, char c2, char c3, char c4, char c5, char c6, char c7, char c8, char c9, char c10)203*795d594fSAndroid Build Coastguard Worker private static native char charMethod(char c1, char c2, char c3, char c4, char c5, char c6, char c7, 204*795d594fSAndroid Build Coastguard Worker char c8, char c9, char c10); 205*795d594fSAndroid Build Coastguard Worker testCharMethod()206*795d594fSAndroid Build Coastguard Worker private static void testCharMethod() { 207*795d594fSAndroid Build Coastguard Worker char returns[] = { (char)0, (char)1, (char)2, (char)127, (char)255, (char)256, (char)15000, 208*795d594fSAndroid Build Coastguard Worker (char)34000 }; 209*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < returns.length; i++) { 210*795d594fSAndroid Build Coastguard Worker char result = charMethod((char)i, 'a', 'b', 'c', '0', '1', '2', (char)1234, (char)2345, 211*795d594fSAndroid Build Coastguard Worker (char)3456); 212*795d594fSAndroid Build Coastguard Worker if (returns[i] != result) { 213*795d594fSAndroid Build Coastguard Worker System.out.println("Run " + i + " with " + (int)returns[i] + " vs " + (int)result); 214*795d594fSAndroid Build Coastguard Worker throw new AssertionError(); 215*795d594fSAndroid Build Coastguard Worker } 216*795d594fSAndroid Build Coastguard Worker } 217*795d594fSAndroid Build Coastguard Worker } 218*795d594fSAndroid Build Coastguard Worker 219*795d594fSAndroid Build Coastguard Worker // http://b/16531674 testIsAssignableFromOnPrimitiveTypes()220*795d594fSAndroid Build Coastguard Worker private static void testIsAssignableFromOnPrimitiveTypes() { 221*795d594fSAndroid Build Coastguard Worker if (!nativeIsAssignableFrom(int.class, Integer.TYPE)) { 222*795d594fSAndroid Build Coastguard Worker System.out.println("IsAssignableFrom(int.class, Integer.TYPE) returned false, expected true"); 223*795d594fSAndroid Build Coastguard Worker throw new AssertionError(); 224*795d594fSAndroid Build Coastguard Worker } 225*795d594fSAndroid Build Coastguard Worker 226*795d594fSAndroid Build Coastguard Worker if (!nativeIsAssignableFrom(Integer.TYPE, int.class)) { 227*795d594fSAndroid Build Coastguard Worker System.out.println("IsAssignableFrom(Integer.TYPE, int.class) returned false, expected true"); 228*795d594fSAndroid Build Coastguard Worker throw new AssertionError(); 229*795d594fSAndroid Build Coastguard Worker } 230*795d594fSAndroid Build Coastguard Worker } 231*795d594fSAndroid Build Coastguard Worker nativeIsAssignableFrom(Class<?> from, Class<?> to)232*795d594fSAndroid Build Coastguard Worker private static native boolean nativeIsAssignableFrom(Class<?> from, Class<?> to); 233*795d594fSAndroid Build Coastguard Worker testShallowGetCallingClassLoader()234*795d594fSAndroid Build Coastguard Worker private static void testShallowGetCallingClassLoader() { 235*795d594fSAndroid Build Coastguard Worker nativeTestShallowGetCallingClassLoader(); 236*795d594fSAndroid Build Coastguard Worker } 237*795d594fSAndroid Build Coastguard Worker nativeTestShallowGetCallingClassLoader()238*795d594fSAndroid Build Coastguard Worker private native static void nativeTestShallowGetCallingClassLoader(); 239*795d594fSAndroid Build Coastguard Worker testShallowGetStackClass2()240*795d594fSAndroid Build Coastguard Worker private static void testShallowGetStackClass2() { 241*795d594fSAndroid Build Coastguard Worker nativeTestShallowGetStackClass2(); 242*795d594fSAndroid Build Coastguard Worker } 243*795d594fSAndroid Build Coastguard Worker nativeTestShallowGetStackClass2()244*795d594fSAndroid Build Coastguard Worker private static native void nativeTestShallowGetStackClass2(); 245*795d594fSAndroid Build Coastguard Worker testCallNonvirtual()246*795d594fSAndroid Build Coastguard Worker private static native void testCallNonvirtual(); 247*795d594fSAndroid Build Coastguard Worker testNewStringObject()248*795d594fSAndroid Build Coastguard Worker private static native void testNewStringObject(); 249*795d594fSAndroid Build Coastguard Worker 250*795d594fSAndroid Build Coastguard Worker private interface SimpleInterface { a()251*795d594fSAndroid Build Coastguard Worker void a(); 252*795d594fSAndroid Build Coastguard Worker } 253*795d594fSAndroid Build Coastguard Worker 254*795d594fSAndroid Build Coastguard Worker private static class MinimalInvocationHandler implements InvocationHandler { invoke(Object proxy, Method method, Object[] args)255*795d594fSAndroid Build Coastguard Worker public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 256*795d594fSAndroid Build Coastguard Worker return null; 257*795d594fSAndroid Build Coastguard Worker } 258*795d594fSAndroid Build Coastguard Worker } 259*795d594fSAndroid Build Coastguard Worker testProxyGetMethodID()260*795d594fSAndroid Build Coastguard Worker private static void testProxyGetMethodID() { 261*795d594fSAndroid Build Coastguard Worker InvocationHandler handler = new MinimalInvocationHandler(); 262*795d594fSAndroid Build Coastguard Worker SimpleInterface proxy = 263*795d594fSAndroid Build Coastguard Worker (SimpleInterface) Proxy.newProxyInstance(SimpleInterface.class.getClassLoader(), 264*795d594fSAndroid Build Coastguard Worker new Class<?>[] {SimpleInterface.class}, handler); 265*795d594fSAndroid Build Coastguard Worker if (testGetMethodID(SimpleInterface.class) == 0) { 266*795d594fSAndroid Build Coastguard Worker throw new AssertionError(); 267*795d594fSAndroid Build Coastguard Worker } 268*795d594fSAndroid Build Coastguard Worker if (testGetMethodID(proxy.getClass()) == 0) { 269*795d594fSAndroid Build Coastguard Worker throw new AssertionError(); 270*795d594fSAndroid Build Coastguard Worker } 271*795d594fSAndroid Build Coastguard Worker } 272*795d594fSAndroid Build Coastguard Worker testGetMethodID(Class<?> c)273*795d594fSAndroid Build Coastguard Worker private static native long testGetMethodID(Class<?> c); 274*795d594fSAndroid Build Coastguard Worker 275*795d594fSAndroid Build Coastguard Worker // Exercise GC and JNI critical sections in parallel. testJniCriticalSectionAndGc()276*795d594fSAndroid Build Coastguard Worker private static void testJniCriticalSectionAndGc() { 277*795d594fSAndroid Build Coastguard Worker Thread runGcThread = new Thread(new Runnable() { 278*795d594fSAndroid Build Coastguard Worker @Override 279*795d594fSAndroid Build Coastguard Worker public void run() { 280*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; ++i) { 281*795d594fSAndroid Build Coastguard Worker Runtime.getRuntime().gc(); 282*795d594fSAndroid Build Coastguard Worker } 283*795d594fSAndroid Build Coastguard Worker } 284*795d594fSAndroid Build Coastguard Worker }); 285*795d594fSAndroid Build Coastguard Worker Thread jniCriticalThread = new Thread(new Runnable() { 286*795d594fSAndroid Build Coastguard Worker @Override 287*795d594fSAndroid Build Coastguard Worker public void run() { 288*795d594fSAndroid Build Coastguard Worker final int arraySize = 32; 289*795d594fSAndroid Build Coastguard Worker byte[] array0 = new byte[arraySize]; 290*795d594fSAndroid Build Coastguard Worker byte[] array1 = new byte[arraySize]; 291*795d594fSAndroid Build Coastguard Worker enterJniCriticalSection(arraySize, array0, array1); 292*795d594fSAndroid Build Coastguard Worker } 293*795d594fSAndroid Build Coastguard Worker }); 294*795d594fSAndroid Build Coastguard Worker jniCriticalThread.start(); 295*795d594fSAndroid Build Coastguard Worker runGcThread.start(); 296*795d594fSAndroid Build Coastguard Worker try { 297*795d594fSAndroid Build Coastguard Worker jniCriticalThread.join(); 298*795d594fSAndroid Build Coastguard Worker runGcThread.join(); 299*795d594fSAndroid Build Coastguard Worker } catch (InterruptedException ignored) {} 300*795d594fSAndroid Build Coastguard Worker } 301*795d594fSAndroid Build Coastguard Worker enterJniCriticalSection(int arraySize, byte[] array0, byte[] array)302*795d594fSAndroid Build Coastguard Worker private static native void enterJniCriticalSection(int arraySize, byte[] array0, byte[] array); 303*795d594fSAndroid Build Coastguard Worker testInvokeLambdaMethod(LambdaInterface iface)304*795d594fSAndroid Build Coastguard Worker private static native void testInvokeLambdaMethod(LambdaInterface iface); 305*795d594fSAndroid Build Coastguard Worker testInvokeLambdaDefaultMethod(LambdaInterface iface)306*795d594fSAndroid Build Coastguard Worker private static native void testInvokeLambdaDefaultMethod(LambdaInterface iface); 307*795d594fSAndroid Build Coastguard Worker 308*795d594fSAndroid Build Coastguard Worker // Test invoking @FastNative methods works correctly. 309*795d594fSAndroid Build Coastguard Worker 310*795d594fSAndroid Build Coastguard Worker // Return sum of a+b+c. 311*795d594fSAndroid Build Coastguard Worker @FastNative intFastNativeMethod(int a, int b, int c)312*795d594fSAndroid Build Coastguard Worker static native int intFastNativeMethod(int a, int b, int c); 313*795d594fSAndroid Build Coastguard Worker testFastNativeMethods()314*795d594fSAndroid Build Coastguard Worker private static void testFastNativeMethods() { 315*795d594fSAndroid Build Coastguard Worker int returns[] = { 0, 3, 6, 9, 12 }; 316*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < returns.length; i++) { 317*795d594fSAndroid Build Coastguard Worker int result = intFastNativeMethod(i, i, i); 318*795d594fSAndroid Build Coastguard Worker if (returns[i] != result) { 319*795d594fSAndroid Build Coastguard Worker System.out.println("FastNative Int Run " + i + " with " + returns[i] + " vs " + result); 320*795d594fSAndroid Build Coastguard Worker throw new AssertionError(); 321*795d594fSAndroid Build Coastguard Worker } 322*795d594fSAndroid Build Coastguard Worker } 323*795d594fSAndroid Build Coastguard Worker } 324*795d594fSAndroid Build Coastguard Worker 325*795d594fSAndroid Build Coastguard Worker // Smoke test for @CriticalNative 326*795d594fSAndroid Build Coastguard Worker // TODO: Way more thorough tests since it involved quite a bit of changes. 327*795d594fSAndroid Build Coastguard Worker 328*795d594fSAndroid Build Coastguard Worker // Return sum of a+b+c. 329*795d594fSAndroid Build Coastguard Worker @CriticalNative intCriticalNativeMethod(int a, int b, int c)330*795d594fSAndroid Build Coastguard Worker static native int intCriticalNativeMethod(int a, int b, int c); 331*795d594fSAndroid Build Coastguard Worker testCriticalNativeMethods()332*795d594fSAndroid Build Coastguard Worker private static void testCriticalNativeMethods() { 333*795d594fSAndroid Build Coastguard Worker int returns[] = { 3, 6, 9, 12, 15 }; 334*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < returns.length; i++) { 335*795d594fSAndroid Build Coastguard Worker int result = intCriticalNativeMethod(i, i+1, i+2); 336*795d594fSAndroid Build Coastguard Worker if (returns[i] != result) { 337*795d594fSAndroid Build Coastguard Worker System.out.println("CriticalNative Int Run " + i + " with " + returns[i] + " vs " + result); 338*795d594fSAndroid Build Coastguard Worker throw new AssertionError(); 339*795d594fSAndroid Build Coastguard Worker } 340*795d594fSAndroid Build Coastguard Worker } 341*795d594fSAndroid Build Coastguard Worker } 342*795d594fSAndroid Build Coastguard Worker isSlowDebug()343*795d594fSAndroid Build Coastguard Worker private static native boolean isSlowDebug(); 344*795d594fSAndroid Build Coastguard Worker testClinitMethodLookup()345*795d594fSAndroid Build Coastguard Worker private static void testClinitMethodLookup() { 346*795d594fSAndroid Build Coastguard Worker // Expect this to print <NSME Exception> 347*795d594fSAndroid Build Coastguard Worker try { 348*795d594fSAndroid Build Coastguard Worker System.out.println("Clinit Lookup: ClassWithoutClinit: " + methodString(lookupClinit(ClassWithoutClinit.class))); 349*795d594fSAndroid Build Coastguard Worker } catch (NoSuchMethodError e) { 350*795d594fSAndroid Build Coastguard Worker System.out.println("Clinit Lookup: ClassWithoutClinit: <NSME Exception>"); 351*795d594fSAndroid Build Coastguard Worker } 352*795d594fSAndroid Build Coastguard Worker // Expect this to print <clinit> 353*795d594fSAndroid Build Coastguard Worker try { 354*795d594fSAndroid Build Coastguard Worker System.out.println("Clinit Lookup: ClassWithClinit: " + methodString(lookupClinit(ClassWithClinit.class))); 355*795d594fSAndroid Build Coastguard Worker } catch (NoSuchMethodError e) { 356*795d594fSAndroid Build Coastguard Worker System.out.println("Clinit Lookup: ClassWithClinit: <NSME Exception>"); 357*795d594fSAndroid Build Coastguard Worker } 358*795d594fSAndroid Build Coastguard Worker } 359*795d594fSAndroid Build Coastguard Worker methodString(java.lang.reflect.Executable method)360*795d594fSAndroid Build Coastguard Worker private static String methodString(java.lang.reflect.Executable method) { 361*795d594fSAndroid Build Coastguard Worker if (method == null) { 362*795d594fSAndroid Build Coastguard Worker return "<<null>>"; 363*795d594fSAndroid Build Coastguard Worker } else { 364*795d594fSAndroid Build Coastguard Worker return method.toString() + "(Class: " + method.getClass().toString() + ")"; 365*795d594fSAndroid Build Coastguard Worker } 366*795d594fSAndroid Build Coastguard Worker } lookupClinit(Class kls)367*795d594fSAndroid Build Coastguard Worker private static native java.lang.reflect.Executable lookupClinit(Class kls); 368*795d594fSAndroid Build Coastguard Worker 369*795d594fSAndroid Build Coastguard Worker private static class ClassWithoutClinit { 370*795d594fSAndroid Build Coastguard Worker } 371*795d594fSAndroid Build Coastguard Worker private static class ClassWithClinit { 372*795d594fSAndroid Build Coastguard Worker static {} 373*795d594fSAndroid Build Coastguard Worker } 374*795d594fSAndroid Build Coastguard Worker testDoubleLoad(String library)375*795d594fSAndroid Build Coastguard Worker private static void testDoubleLoad(String library) { 376*795d594fSAndroid Build Coastguard Worker // Test that nothing observably happens on loading "library" again. 377*795d594fSAndroid Build Coastguard Worker System.loadLibrary(library); 378*795d594fSAndroid Build Coastguard Worker 379*795d594fSAndroid Build Coastguard Worker // Now load code in a separate classloader and try to let it load. 380*795d594fSAndroid Build Coastguard Worker ClassLoader loader = createClassLoader(); 381*795d594fSAndroid Build Coastguard Worker try { 382*795d594fSAndroid Build Coastguard Worker Class<?> aClass = loader.loadClass("A"); 383*795d594fSAndroid Build Coastguard Worker Method runMethod = aClass.getDeclaredMethod("run", String.class); 384*795d594fSAndroid Build Coastguard Worker runMethod.invoke(null, library); 385*795d594fSAndroid Build Coastguard Worker } catch (InvocationTargetException ite) { 386*795d594fSAndroid Build Coastguard Worker if (ite.getCause() instanceof UnsatisfiedLinkError) { 387*795d594fSAndroid Build Coastguard Worker if (!(loader instanceof java.net.URLClassLoader)) { 388*795d594fSAndroid Build Coastguard Worker String msg = ite.getCause().getMessage(); 389*795d594fSAndroid Build Coastguard Worker String pattern = "^Shared library .*libarttest.* already opened by ClassLoader.*" + 390*795d594fSAndroid Build Coastguard Worker "004-JniTest.jar.*; can't open in ClassLoader.*004-JniTest-ex.jar.*"; 391*795d594fSAndroid Build Coastguard Worker if (!Pattern.matches(pattern, msg)) { 392*795d594fSAndroid Build Coastguard Worker throw new RuntimeException("Could not find pattern in message", ite.getCause()); 393*795d594fSAndroid Build Coastguard Worker } 394*795d594fSAndroid Build Coastguard Worker } 395*795d594fSAndroid Build Coastguard Worker System.out.println("Got UnsatisfiedLinkError for duplicate loadLibrary"); 396*795d594fSAndroid Build Coastguard Worker } else { 397*795d594fSAndroid Build Coastguard Worker throw new RuntimeException(ite); 398*795d594fSAndroid Build Coastguard Worker } 399*795d594fSAndroid Build Coastguard Worker } catch (Throwable t) { 400*795d594fSAndroid Build Coastguard Worker // Anything else just let die. 401*795d594fSAndroid Build Coastguard Worker throw new RuntimeException(t); 402*795d594fSAndroid Build Coastguard Worker } 403*795d594fSAndroid Build Coastguard Worker } 404*795d594fSAndroid Build Coastguard Worker createClassLoader()405*795d594fSAndroid Build Coastguard Worker private static ClassLoader createClassLoader() { 406*795d594fSAndroid Build Coastguard Worker String location = System.getenv("DEX_LOCATION"); 407*795d594fSAndroid Build Coastguard Worker try { 408*795d594fSAndroid Build Coastguard Worker Class<?> class_loader_class = Class.forName("dalvik.system.PathClassLoader"); 409*795d594fSAndroid Build Coastguard Worker Constructor<?> ctor = class_loader_class.getConstructor(String.class, ClassLoader.class); 410*795d594fSAndroid Build Coastguard Worker 411*795d594fSAndroid Build Coastguard Worker return (ClassLoader)ctor.newInstance(location + "/004-JniTest-ex.jar", 412*795d594fSAndroid Build Coastguard Worker Main.class.getClassLoader()); 413*795d594fSAndroid Build Coastguard Worker } catch (ClassNotFoundException e) { 414*795d594fSAndroid Build Coastguard Worker // Running on RI. Use URLClassLoader. 415*795d594fSAndroid Build Coastguard Worker try { 416*795d594fSAndroid Build Coastguard Worker return new java.net.URLClassLoader( 417*795d594fSAndroid Build Coastguard Worker new java.net.URL[] { new java.net.URL("file://" + location + "/classes-ex/") }); 418*795d594fSAndroid Build Coastguard Worker } catch (Throwable t) { 419*795d594fSAndroid Build Coastguard Worker throw new RuntimeException(t); 420*795d594fSAndroid Build Coastguard Worker } 421*795d594fSAndroid Build Coastguard Worker } catch (Throwable t) { 422*795d594fSAndroid Build Coastguard Worker throw new RuntimeException(t); 423*795d594fSAndroid Build Coastguard Worker } 424*795d594fSAndroid Build Coastguard Worker } 425*795d594fSAndroid Build Coastguard Worker testBadFastCriticalNatives()426*795d594fSAndroid Build Coastguard Worker private static void testBadFastCriticalNatives() { 427*795d594fSAndroid Build Coastguard Worker testBadFastCriticalNative("BadFastNative"); 428*795d594fSAndroid Build Coastguard Worker testBadFastCriticalNative("BadCriticalNative"); 429*795d594fSAndroid Build Coastguard Worker testBadFastCriticalNative("BadCriticalNative2"); 430*795d594fSAndroid Build Coastguard Worker testBadFastCriticalNative("BadCriticalNative3"); 431*795d594fSAndroid Build Coastguard Worker } 432*795d594fSAndroid Build Coastguard Worker testBadFastCriticalNative(String className)433*795d594fSAndroid Build Coastguard Worker private static void testBadFastCriticalNative(String className) { 434*795d594fSAndroid Build Coastguard Worker try { 435*795d594fSAndroid Build Coastguard Worker Class.forName(className); 436*795d594fSAndroid Build Coastguard Worker throw new Error("Expected verification error"); 437*795d594fSAndroid Build Coastguard Worker } catch (VerifyError e) { 438*795d594fSAndroid Build Coastguard Worker // Expected. 439*795d594fSAndroid Build Coastguard Worker } catch (Throwable e) { 440*795d594fSAndroid Build Coastguard Worker throw new Error("Expected verification error"); 441*795d594fSAndroid Build Coastguard Worker } 442*795d594fSAndroid Build Coastguard Worker } 443*795d594fSAndroid Build Coastguard Worker } 444*795d594fSAndroid Build Coastguard Worker 445*795d594fSAndroid Build Coastguard Worker @FunctionalInterface 446*795d594fSAndroid Build Coastguard Worker interface LambdaInterface { sayHi()447*795d594fSAndroid Build Coastguard Worker public void sayHi(); sayHiTwice()448*795d594fSAndroid Build Coastguard Worker public default void sayHiTwice() { 449*795d594fSAndroid Build Coastguard Worker sayHi(); 450*795d594fSAndroid Build Coastguard Worker sayHi(); 451*795d594fSAndroid Build Coastguard Worker } 452*795d594fSAndroid Build Coastguard Worker } 453*795d594fSAndroid Build Coastguard Worker 454*795d594fSAndroid Build Coastguard Worker class JniCallNonvirtualTest { 455*795d594fSAndroid Build Coastguard Worker public boolean nonstaticMethodSuperCalled = false; 456*795d594fSAndroid Build Coastguard Worker public boolean nonstaticMethodSubCalled = false; 457*795d594fSAndroid Build Coastguard Worker testCallNonvirtual()458*795d594fSAndroid Build Coastguard Worker private static native void testCallNonvirtual(); 459*795d594fSAndroid Build Coastguard Worker JniCallNonvirtualTest()460*795d594fSAndroid Build Coastguard Worker public JniCallNonvirtualTest() { 461*795d594fSAndroid Build Coastguard Worker System.out.println("Super.<init>"); 462*795d594fSAndroid Build Coastguard Worker } 463*795d594fSAndroid Build Coastguard Worker staticMethod()464*795d594fSAndroid Build Coastguard Worker public static void staticMethod() { 465*795d594fSAndroid Build Coastguard Worker System.out.println("Super.staticMethod"); 466*795d594fSAndroid Build Coastguard Worker } 467*795d594fSAndroid Build Coastguard Worker nonstaticMethod()468*795d594fSAndroid Build Coastguard Worker public void nonstaticMethod() { 469*795d594fSAndroid Build Coastguard Worker System.out.println("Super.nonstaticMethod"); 470*795d594fSAndroid Build Coastguard Worker nonstaticMethodSuperCalled = true; 471*795d594fSAndroid Build Coastguard Worker } 472*795d594fSAndroid Build Coastguard Worker } 473*795d594fSAndroid Build Coastguard Worker 474*795d594fSAndroid Build Coastguard Worker class JniCallNonvirtualTestSubclass extends JniCallNonvirtualTest { 475*795d594fSAndroid Build Coastguard Worker JniCallNonvirtualTestSubclass()476*795d594fSAndroid Build Coastguard Worker public JniCallNonvirtualTestSubclass() { 477*795d594fSAndroid Build Coastguard Worker System.out.println("Subclass.<init>"); 478*795d594fSAndroid Build Coastguard Worker } 479*795d594fSAndroid Build Coastguard Worker staticMethod()480*795d594fSAndroid Build Coastguard Worker public static void staticMethod() { 481*795d594fSAndroid Build Coastguard Worker System.out.println("Subclass.staticMethod"); 482*795d594fSAndroid Build Coastguard Worker } 483*795d594fSAndroid Build Coastguard Worker nonstaticMethod()484*795d594fSAndroid Build Coastguard Worker public void nonstaticMethod() { 485*795d594fSAndroid Build Coastguard Worker System.out.println("Subclass.nonstaticMethod"); 486*795d594fSAndroid Build Coastguard Worker nonstaticMethodSubCalled = true; 487*795d594fSAndroid Build Coastguard Worker } 488*795d594fSAndroid Build Coastguard Worker } 489*795d594fSAndroid Build Coastguard Worker 490*795d594fSAndroid Build Coastguard Worker class BadFastNative { 491*795d594fSAndroid Build Coastguard Worker @FastNative test()492*795d594fSAndroid Build Coastguard Worker public static native synchronized void test(); 493*795d594fSAndroid Build Coastguard Worker } 494*795d594fSAndroid Build Coastguard Worker 495*795d594fSAndroid Build Coastguard Worker class BadCriticalNative { 496*795d594fSAndroid Build Coastguard Worker @CriticalNative test()497*795d594fSAndroid Build Coastguard Worker public static native synchronized void test(); 498*795d594fSAndroid Build Coastguard Worker } 499*795d594fSAndroid Build Coastguard Worker 500*795d594fSAndroid Build Coastguard Worker class BadCriticalNative2 { 501*795d594fSAndroid Build Coastguard Worker @CriticalNative test()502*795d594fSAndroid Build Coastguard Worker public native void test(); 503*795d594fSAndroid Build Coastguard Worker } 504*795d594fSAndroid Build Coastguard Worker 505*795d594fSAndroid Build Coastguard Worker class BadCriticalNative3 { 506*795d594fSAndroid Build Coastguard Worker @CriticalNative test(Object o)507*795d594fSAndroid Build Coastguard Worker public static native void test(Object o); 508*795d594fSAndroid Build Coastguard Worker } 509