xref: /aosp_15_r20/art/test/004-JniTest/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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