• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 import java.lang.reflect.InvocationHandler;
18 import java.lang.reflect.Method;
19 import java.lang.reflect.Proxy;
20 
21 import dalvik.annotation.optimization.CriticalNative;
22 import dalvik.annotation.optimization.FastNative;
23 
24 public class Main {
main(String[] args)25     public static void main(String[] args) {
26         System.loadLibrary(args[0]);
27         testFindClassOnAttachedNativeThread();
28         testFindFieldOnAttachedNativeThread();
29         testReflectFieldGetFromAttachedNativeThreadNative();
30         testCallStaticVoidMethodOnSubClass();
31         testGetMirandaMethod();
32         testZeroLengthByteBuffers();
33         testByteMethod();
34         testShortMethod();
35         testBooleanMethod();
36         testCharMethod();
37         testIsAssignableFromOnPrimitiveTypes();
38         testShallowGetCallingClassLoader();
39         testShallowGetStackClass2();
40         testCallNonvirtual();
41         testNewStringObject();
42         testRemoveLocalObject();
43         testProxyGetMethodID();
44         testJniCriticalSectionAndGc();
45         testCallDefaultMethods();
46         String lambda = "λ";
47         testInvokeLambdaMethod(() -> { System.out.println("hi-lambda: " + lambda); });
48         String def = "δ";
49         testInvokeLambdaDefaultMethod(() -> { System.out.println("hi-default " + def + lambda); });
50 
51         registerNativesJniTest();
52         testFastNativeMethods();
53         testCriticalNativeMethods();
54     }
55 
registerNativesJniTest()56     private static native boolean registerNativesJniTest();
57 
testCallDefaultMethods()58     private static native void testCallDefaultMethods();
59 
testFindClassOnAttachedNativeThread()60     private static native void testFindClassOnAttachedNativeThread();
61 
62     private static boolean testFindFieldOnAttachedNativeThreadField;
63 
testReflectFieldGetFromAttachedNativeThreadNative()64     private static native void testReflectFieldGetFromAttachedNativeThreadNative();
65 
66     public static boolean testReflectFieldGetFromAttachedNativeThreadField;
67 
testFindFieldOnAttachedNativeThread()68     private static void testFindFieldOnAttachedNativeThread() {
69       testFindFieldOnAttachedNativeThreadNative();
70       if (!testFindFieldOnAttachedNativeThreadField) {
71             throw new AssertionError();
72         }
73     }
74 
testFindFieldOnAttachedNativeThreadNative()75     private static native void testFindFieldOnAttachedNativeThreadNative();
76 
testCallStaticVoidMethodOnSubClass()77     private static void testCallStaticVoidMethodOnSubClass() {
78         testCallStaticVoidMethodOnSubClassNative();
79         if (!testCallStaticVoidMethodOnSubClass_SuperClass.executed) {
80             throw new AssertionError();
81         }
82     }
83 
testCallStaticVoidMethodOnSubClassNative()84     private static native void testCallStaticVoidMethodOnSubClassNative();
85 
86     private static class testCallStaticVoidMethodOnSubClass_SuperClass {
87         private static boolean executed = false;
execute()88         private static void execute() {
89             executed = true;
90         }
91     }
92 
93     private static class testCallStaticVoidMethodOnSubClass_SubClass
94         extends testCallStaticVoidMethodOnSubClass_SuperClass {
95     }
96 
testGetMirandaMethodNative()97     private static native Method testGetMirandaMethodNative();
98 
testGetMirandaMethod()99     private static void testGetMirandaMethod() {
100         Method m = testGetMirandaMethodNative();
101         if (m.getDeclaringClass() != testGetMirandaMethod_MirandaInterface.class) {
102             throw new AssertionError();
103         }
104     }
105 
testZeroLengthByteBuffers()106     private static native void testZeroLengthByteBuffers();
107 
108     private static abstract class testGetMirandaMethod_MirandaAbstract implements testGetMirandaMethod_MirandaInterface {
inAbstract()109         public boolean inAbstract() {
110             return true;
111         }
112     }
113 
114     private static interface testGetMirandaMethod_MirandaInterface {
inInterface()115         public boolean inInterface();
116     }
117 
118     // Test sign-extension for values < 32b
119 
byteMethod(byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8, byte b9, byte b10)120     static native byte byteMethod(byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7,
121         byte b8, byte b9, byte b10);
122 
testByteMethod()123     private static void testByteMethod() {
124       byte returns[] = { 0, 1, 2, 127, -1, -2, -128 };
125       for (int i = 0; i < returns.length; i++) {
126         byte result = byteMethod((byte)i, (byte)2, (byte)(-3), (byte)4, (byte)(-5), (byte)6,
127             (byte)(-7), (byte)8, (byte)(-9), (byte)10);
128         if (returns[i] != result) {
129           System.out.println("Run " + i + " with " + returns[i] + " vs " + result);
130           throw new AssertionError();
131         }
132       }
133     }
134 
removeLocalObject(Object o)135     private static native void removeLocalObject(Object o);
136 
testRemoveLocalObject()137     private static void testRemoveLocalObject() {
138         removeLocalObject(new Object());
139     }
140 
shortMethod(short s1, short s2, short s3, short s4, short s5, short s6, short s7, short s8, short s9, short s10)141     private static native short shortMethod(short s1, short s2, short s3, short s4, short s5, short s6, short s7,
142         short s8, short s9, short s10);
143 
testShortMethod()144     private static void testShortMethod() {
145       short returns[] = { 0, 1, 2, 127, 32767, -1, -2, -128, -32768 };
146       for (int i = 0; i < returns.length; i++) {
147         short result = shortMethod((short)i, (short)2, (short)(-3), (short)4, (short)(-5), (short)6,
148             (short)(-7), (short)8, (short)(-9), (short)10);
149         if (returns[i] != result) {
150           System.out.println("Run " + i + " with " + returns[i] + " vs " + result);
151           throw new AssertionError();
152         }
153       }
154     }
155 
156     // Test zero-extension for values < 32b
157 
booleanMethod(boolean b1, boolean b2, boolean b3, boolean b4, boolean b5, boolean b6, boolean b7, boolean b8, boolean b9, boolean b10)158     private static native boolean booleanMethod(boolean b1, boolean b2, boolean b3, boolean b4, boolean b5, boolean b6, boolean b7,
159         boolean b8, boolean b9, boolean b10);
160 
testBooleanMethod()161     private static void testBooleanMethod() {
162       if (booleanMethod(false, true, false, true, false, true, false, true, false, true)) {
163         throw new AssertionError();
164       }
165 
166       if (!booleanMethod(true, true, false, true, false, true, false, true, false, true)) {
167         throw new AssertionError();
168       }
169     }
170 
charMethod(char c1, char c2, char c3, char c4, char c5, char c6, char c7, char c8, char c9, char c10)171     private static native char charMethod(char c1, char c2, char c3, char c4, char c5, char c6, char c7,
172         char c8, char c9, char c10);
173 
testCharMethod()174     private static void testCharMethod() {
175       char returns[] = { (char)0, (char)1, (char)2, (char)127, (char)255, (char)256, (char)15000,
176           (char)34000 };
177       for (int i = 0; i < returns.length; i++) {
178         char result = charMethod((char)i, 'a', 'b', 'c', '0', '1', '2', (char)1234, (char)2345,
179             (char)3456);
180         if (returns[i] != result) {
181           System.out.println("Run " + i + " with " + (int)returns[i] + " vs " + (int)result);
182           throw new AssertionError();
183         }
184       }
185     }
186 
187     // http://b/16531674
testIsAssignableFromOnPrimitiveTypes()188     private static void testIsAssignableFromOnPrimitiveTypes() {
189       if (!nativeIsAssignableFrom(int.class, Integer.TYPE)) {
190         System.out.println("IsAssignableFrom(int.class, Integer.TYPE) returned false, expected true");
191         throw new AssertionError();
192       }
193 
194       if (!nativeIsAssignableFrom(Integer.TYPE, int.class)) {
195         System.out.println("IsAssignableFrom(Integer.TYPE, int.class) returned false, expected true");
196         throw new AssertionError();
197       }
198     }
199 
nativeIsAssignableFrom(Class<?> from, Class<?> to)200     private static native boolean nativeIsAssignableFrom(Class<?> from, Class<?> to);
201 
testShallowGetCallingClassLoader()202     private static void testShallowGetCallingClassLoader() {
203         nativeTestShallowGetCallingClassLoader();
204     }
205 
nativeTestShallowGetCallingClassLoader()206     private native static void nativeTestShallowGetCallingClassLoader();
207 
testShallowGetStackClass2()208     private static void testShallowGetStackClass2() {
209         nativeTestShallowGetStackClass2();
210     }
211 
nativeTestShallowGetStackClass2()212     private static native void nativeTestShallowGetStackClass2();
213 
testCallNonvirtual()214     private static native void testCallNonvirtual();
215 
testNewStringObject()216     private static native void testNewStringObject();
217 
218     private interface SimpleInterface {
a()219         void a();
220     }
221 
222     private static class DummyInvocationHandler implements InvocationHandler {
invoke(Object proxy, Method method, Object[] args)223         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
224             return null;
225         }
226     }
227 
testProxyGetMethodID()228     private static void testProxyGetMethodID() {
229         InvocationHandler handler = new DummyInvocationHandler();
230         SimpleInterface proxy =
231                 (SimpleInterface) Proxy.newProxyInstance(SimpleInterface.class.getClassLoader(),
232                         new Class<?>[] {SimpleInterface.class}, handler);
233         if (testGetMethodID(SimpleInterface.class) == 0) {
234             throw new AssertionError();
235         }
236         if (testGetMethodID(proxy.getClass()) == 0) {
237             throw new AssertionError();
238         }
239     }
240 
testGetMethodID(Class<?> c)241     private static native long testGetMethodID(Class<?> c);
242 
243     // Exercise GC and JNI critical sections in parallel.
testJniCriticalSectionAndGc()244     private static void testJniCriticalSectionAndGc() {
245         Thread runGcThread = new Thread(new Runnable() {
246             @Override
247             public void run() {
248                 for (int i = 0; i < 10; ++i) {
249                     Runtime.getRuntime().gc();
250                 }
251             }
252         });
253         Thread jniCriticalThread = new Thread(new Runnable() {
254             @Override
255             public void run() {
256                 final int arraySize = 32;
257                 byte[] array0 = new byte[arraySize];
258                 byte[] array1 = new byte[arraySize];
259                 enterJniCriticalSection(arraySize, array0, array1);
260             }
261         });
262         jniCriticalThread.start();
263         runGcThread.start();
264         try {
265             jniCriticalThread.join();
266             runGcThread.join();
267         } catch (InterruptedException ignored) {}
268     }
269 
enterJniCriticalSection(int arraySize, byte[] array0, byte[] array)270     private static native void enterJniCriticalSection(int arraySize, byte[] array0, byte[] array);
271 
testInvokeLambdaMethod(LambdaInterface iface)272     private static native void testInvokeLambdaMethod(LambdaInterface iface);
273 
testInvokeLambdaDefaultMethod(LambdaInterface iface)274     private static native void testInvokeLambdaDefaultMethod(LambdaInterface iface);
275 
276     // Test invoking @FastNative methods works correctly.
277 
278     // Return sum of a+b+c.
279     @FastNative
intFastNativeMethod(int a, int b, int c)280     static native int intFastNativeMethod(int a, int b, int c);
281 
testFastNativeMethods()282     private static void testFastNativeMethods() {
283       int returns[] = { 0, 3, 6, 9, 12 };
284       for (int i = 0; i < returns.length; i++) {
285         int result = intFastNativeMethod(i, i, i);
286         if (returns[i] != result) {
287           System.out.println("FastNative Int Run " + i + " with " + returns[i] + " vs " + result);
288           throw new AssertionError();
289         }
290       }
291     }
292 
293     // Smoke test for @CriticalNative
294     // TODO: Way more thorough tests since it involved quite a bit of changes.
295 
296     // Return sum of a+b+c.
297     @CriticalNative
intCriticalNativeMethod(int a, int b, int c)298     static native int intCriticalNativeMethod(int a, int b, int c);
299 
testCriticalNativeMethods()300     private static void testCriticalNativeMethods() {
301       int returns[] = { 3, 6, 9, 12, 15 };
302       for (int i = 0; i < returns.length; i++) {
303         int result = intCriticalNativeMethod(i, i+1, i+2);
304         if (returns[i] != result) {
305           System.out.println("CriticalNative Int Run " + i + " with " + returns[i] + " vs " + result);
306           throw new AssertionError();
307         }
308       }
309     }
310 }
311 
312 @FunctionalInterface
313 interface LambdaInterface {
sayHi()314   public void sayHi();
sayHiTwice()315   public default void sayHiTwice() {
316     sayHi();
317     sayHi();
318   }
319 }
320 
321 class JniCallNonvirtualTest {
322     public boolean nonstaticMethodSuperCalled = false;
323     public boolean nonstaticMethodSubCalled = false;
324 
testCallNonvirtual()325     private static native void testCallNonvirtual();
326 
JniCallNonvirtualTest()327     public JniCallNonvirtualTest() {
328         System.out.println("Super.<init>");
329     }
330 
staticMethod()331     public static void staticMethod() {
332         System.out.println("Super.staticMethod");
333     }
334 
nonstaticMethod()335     public void nonstaticMethod() {
336         System.out.println("Super.nonstaticMethod");
337         nonstaticMethodSuperCalled = true;
338     }
339 }
340 
341 class JniCallNonvirtualTestSubclass extends JniCallNonvirtualTest {
342 
JniCallNonvirtualTestSubclass()343     public JniCallNonvirtualTestSubclass() {
344         System.out.println("Subclass.<init>");
345     }
346 
staticMethod()347     public static void staticMethod() {
348         System.out.println("Subclass.staticMethod");
349     }
350 
nonstaticMethod()351     public void nonstaticMethod() {
352         System.out.println("Subclass.nonstaticMethod");
353         nonstaticMethodSubCalled = true;
354     }
355 }
356