1 /*
2  * Copyright 2019 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 dalvik.annotation.optimization.FastNative;
18 import dalvik.annotation.optimization.CriticalNative;
19 
20 public class Main {
21 
main(String[] args)22   public static void main(String[] args) throws Exception {
23     System.loadLibrary(args[0]);
24 
25     // To avoid going through resolution trampoline, make test classes visibly initialized.
26     new Test();
27     new TestFast();
28     new TestCritical();
29     new TestMissing();
30     new TestMissingFast();
31     new TestMissingCritical();
32     new CriticalSignatures();
33     makeVisiblyInitialized();  // Make sure they are visibly initialized.
34 
35     $noinline$opt$test();
36     $noinline$opt$testFast();
37     $noinline$opt$testCritical();
38     $noinline$opt$testMissing();
39     $noinline$opt$testMissingFast();
40     $noinline$opt$testMissingCritical();
41     $noinline$opt$testCriticalSignatures();
42 
43     // For calls from AOT-compiled code, the first call shall use the resolution method
44     // retrieved from the .bss and the second call should find the .bss entry populated
45     // with the target method. Re-run these tests to exercise the second path.
46     $noinline$opt$test();
47     $noinline$opt$testFast();
48     $noinline$opt$testCritical();
49     $noinline$opt$testMissing();
50     $noinline$opt$testMissingFast();
51     $noinline$opt$testMissingCritical();
52     $noinline$opt$testCriticalSignatures();
53 
54     new CriticalClinitCheck();
55     sTestCriticalClinitCheckOtherThread.join();
56   }
57 
$noinline$opt$test()58   static void $noinline$opt$test() {
59     System.out.println("test");
60     assertEquals(42, Test.nativeMethodVoid());
61     assertEquals(42, Test.nativeMethod(42));
62     assertEquals(42, Test.nativeMethodWithManyParameters(
63         11, 12L, 13.0f, 14.0d,
64         21, 22L, 23.0f, 24.0d,
65         31, 32L, 33.0f, 34.0d,
66         41, 42L, 43.0f, 44.0d,
67         51, 52L, 53.0f, 54.0d,
68         61, 62L, 63.0f, 64.0d,
69         71, 72L, 73.0f, 74.0d,
70         81, 82L, 83.0f, 84.0d));
71   }
72 
$noinline$opt$testFast()73   static void $noinline$opt$testFast() {
74     System.out.println("testFast");
75     assertEquals(42, TestFast.nativeMethodVoid());
76     assertEquals(42, TestFast.nativeMethod(42));
77     assertEquals(42, TestFast.nativeMethodWithManyParameters(
78         11, 12L, 13.0f, 14.0d,
79         21, 22L, 23.0f, 24.0d,
80         31, 32L, 33.0f, 34.0d,
81         41, 42L, 43.0f, 44.0d,
82         51, 52L, 53.0f, 54.0d,
83         61, 62L, 63.0f, 64.0d,
84         71, 72L, 73.0f, 74.0d,
85         81, 82L, 83.0f, 84.0d));
86   }
87 
$noinline$opt$testCritical()88   static void $noinline$opt$testCritical() {
89     System.out.println("testCritical");
90     assertEquals(42, TestCritical.nativeMethodVoid());
91     assertEquals(42, TestCritical.nativeMethod(42));
92     assertEquals(42, TestCritical.nativeMethodWithManyParameters(
93         11, 12L, 13.0f, 14.0d,
94         21, 22L, 23.0f, 24.0d,
95         31, 32L, 33.0f, 34.0d,
96         41, 42L, 43.0f, 44.0d,
97         51, 52L, 53.0f, 54.0d,
98         61, 62L, 63.0f, 64.0d,
99         71, 72L, 73.0f, 74.0d,
100         81, 82L, 83.0f, 84.0d));
101   }
102 
$noinline$opt$testMissing()103   static void $noinline$opt$testMissing() {
104     System.out.println("testMissing");
105 
106     try {
107       TestMissing.nativeMethodVoid();
108       throw new Error("UNREACHABLE");
109     } catch (LinkageError expected) {}
110 
111     try {
112       TestMissing.nativeMethod(42);
113       throw new Error("UNREACHABLE");
114     } catch (LinkageError expected) {}
115 
116     try {
117       TestMissing.nativeMethodWithManyParameters(
118           11, 12L, 13.0f, 14.0d,
119           21, 22L, 23.0f, 24.0d,
120           31, 32L, 33.0f, 34.0d,
121           41, 42L, 43.0f, 44.0d,
122           51, 52L, 53.0f, 54.0d,
123           61, 62L, 63.0f, 64.0d,
124           71, 72L, 73.0f, 74.0d,
125           81, 82L, 83.0f, 84.0d);
126       throw new Error("UNREACHABLE");
127     } catch (LinkageError expected) {}
128   }
129 
$noinline$opt$testMissingFast()130   static void $noinline$opt$testMissingFast() {
131     System.out.println("testMissingFast");
132 
133     try {
134       TestMissingFast.nativeMethodVoid();
135       throw new Error("UNREACHABLE");
136     } catch (LinkageError expected) {}
137 
138     try {
139       TestMissingFast.nativeMethod(42);
140       throw new Error("UNREACHABLE");
141     } catch (LinkageError expected) {}
142 
143     try {
144       TestMissingFast.nativeMethodWithManyParameters(
145           11, 12L, 13.0f, 14.0d,
146           21, 22L, 23.0f, 24.0d,
147           31, 32L, 33.0f, 34.0d,
148           41, 42L, 43.0f, 44.0d,
149           51, 52L, 53.0f, 54.0d,
150           61, 62L, 63.0f, 64.0d,
151           71, 72L, 73.0f, 74.0d,
152           81, 82L, 83.0f, 84.0d);
153       throw new Error("UNREACHABLE");
154     } catch (LinkageError expected) {}
155   }
156 
$noinline$opt$testMissingCritical()157   static void $noinline$opt$testMissingCritical() {
158     System.out.println("testMissingCritical");
159 
160     try {
161       TestMissingCritical.nativeMethodVoid();
162       throw new Error("UNREACHABLE");
163     } catch (LinkageError expected) {}
164 
165     try {
166       TestMissingCritical.nativeMethod(42);
167       throw new Error("UNREACHABLE");
168     } catch (LinkageError expected) {}
169 
170     try {
171       TestMissingCritical.nativeMethodWithManyParameters(
172           11, 12L, 13.0f, 14.0d,
173           21, 22L, 23.0f, 24.0d,
174           31, 32L, 33.0f, 34.0d,
175           41, 42L, 43.0f, 44.0d,
176           51, 52L, 53.0f, 54.0d,
177           61, 62L, 63.0f, 64.0d,
178           71, 72L, 73.0f, 74.0d,
179           81, 82L, 83.0f, 84.0d);
180       throw new Error("UNREACHABLE");
181     } catch (LinkageError expected) {}
182   }
183 
$noinline$opt$testCriticalSignatures()184   static void $noinline$opt$testCriticalSignatures() {
185     System.out.println("testCriticalSignatures");
186     long l = 0xf00000000L;
187     assertEquals(42, CriticalSignatures.nativeILFFFFD(1, l + 2L, 3.0f, 4.0f, 5.0f, 6.0f, 7.0));
188     assertEquals(42, CriticalSignatures.nativeLIFFFFD(l + 7L, 6, 5.0f, 4.0f, 3.0f, 2.0f, 1.0));
189     assertEquals(42, CriticalSignatures.nativeFLIFFFD(1.0f, l + 2L, 3, 4.0f, 5.0f, 6.0f, 7.0));
190     assertEquals(42, CriticalSignatures.nativeDDIIIIII(8.0, 7.0, 6, 5, 4, 3, 2, 1));
191     assertEquals(42, CriticalSignatures.nativeDFFILIII(1.0, 2.0f, 3.0f, 4, l + 5L, 6, 7, 8));
192     assertEquals(42, CriticalSignatures.nativeDDFILIII(8.0, 7.0, 6.0f, 5, l + 4L, 3, 2, 1));
193     assertEquals(42, CriticalSignatures.nativeDDIFII(1.0, 2.0, 3, 4.0f, 5, 6));
194     assertEquals(42, CriticalSignatures.nativeFullArgs(
195         // Generated by script (then modified to close argument list):
196         //   for i in {0..84}; \
197         //     do echo "        0xf00000000L + $((i*3))L,"; \
198         //     echo "        $((i*3+2)),"; \
199         //  done
200         0xf00000000L + 0L,
201         2,
202         0xf00000000L + 3L,
203         5,
204         0xf00000000L + 6L,
205         8,
206         0xf00000000L + 9L,
207         11,
208         0xf00000000L + 12L,
209         14,
210         0xf00000000L + 15L,
211         17,
212         0xf00000000L + 18L,
213         20,
214         0xf00000000L + 21L,
215         23,
216         0xf00000000L + 24L,
217         26,
218         0xf00000000L + 27L,
219         29,
220         0xf00000000L + 30L,
221         32,
222         0xf00000000L + 33L,
223         35,
224         0xf00000000L + 36L,
225         38,
226         0xf00000000L + 39L,
227         41,
228         0xf00000000L + 42L,
229         44,
230         0xf00000000L + 45L,
231         47,
232         0xf00000000L + 48L,
233         50,
234         0xf00000000L + 51L,
235         53,
236         0xf00000000L + 54L,
237         56,
238         0xf00000000L + 57L,
239         59,
240         0xf00000000L + 60L,
241         62,
242         0xf00000000L + 63L,
243         65,
244         0xf00000000L + 66L,
245         68,
246         0xf00000000L + 69L,
247         71,
248         0xf00000000L + 72L,
249         74,
250         0xf00000000L + 75L,
251         77,
252         0xf00000000L + 78L,
253         80,
254         0xf00000000L + 81L,
255         83,
256         0xf00000000L + 84L,
257         86,
258         0xf00000000L + 87L,
259         89,
260         0xf00000000L + 90L,
261         92,
262         0xf00000000L + 93L,
263         95,
264         0xf00000000L + 96L,
265         98,
266         0xf00000000L + 99L,
267         101,
268         0xf00000000L + 102L,
269         104,
270         0xf00000000L + 105L,
271         107,
272         0xf00000000L + 108L,
273         110,
274         0xf00000000L + 111L,
275         113,
276         0xf00000000L + 114L,
277         116,
278         0xf00000000L + 117L,
279         119,
280         0xf00000000L + 120L,
281         122,
282         0xf00000000L + 123L,
283         125,
284         0xf00000000L + 126L,
285         128,
286         0xf00000000L + 129L,
287         131,
288         0xf00000000L + 132L,
289         134,
290         0xf00000000L + 135L,
291         137,
292         0xf00000000L + 138L,
293         140,
294         0xf00000000L + 141L,
295         143,
296         0xf00000000L + 144L,
297         146,
298         0xf00000000L + 147L,
299         149,
300         0xf00000000L + 150L,
301         152,
302         0xf00000000L + 153L,
303         155,
304         0xf00000000L + 156L,
305         158,
306         0xf00000000L + 159L,
307         161,
308         0xf00000000L + 162L,
309         164,
310         0xf00000000L + 165L,
311         167,
312         0xf00000000L + 168L,
313         170,
314         0xf00000000L + 171L,
315         173,
316         0xf00000000L + 174L,
317         176,
318         0xf00000000L + 177L,
319         179,
320         0xf00000000L + 180L,
321         182,
322         0xf00000000L + 183L,
323         185,
324         0xf00000000L + 186L,
325         188,
326         0xf00000000L + 189L,
327         191,
328         0xf00000000L + 192L,
329         194,
330         0xf00000000L + 195L,
331         197,
332         0xf00000000L + 198L,
333         200,
334         0xf00000000L + 201L,
335         203,
336         0xf00000000L + 204L,
337         206,
338         0xf00000000L + 207L,
339         209,
340         0xf00000000L + 210L,
341         212,
342         0xf00000000L + 213L,
343         215,
344         0xf00000000L + 216L,
345         218,
346         0xf00000000L + 219L,
347         221,
348         0xf00000000L + 222L,
349         224,
350         0xf00000000L + 225L,
351         227,
352         0xf00000000L + 228L,
353         230,
354         0xf00000000L + 231L,
355         233,
356         0xf00000000L + 234L,
357         236,
358         0xf00000000L + 237L,
359         239,
360         0xf00000000L + 240L,
361         242,
362         0xf00000000L + 243L,
363         245,
364         0xf00000000L + 246L,
365         248,
366         0xf00000000L + 249L,
367         251,
368         0xf00000000L + 252L,
369         254));
370   }
371 
initializingCriticalClinitCheck()372   static void initializingCriticalClinitCheck() {
373     // Called from CriticalClinitCheck.<clinit>().
374     // Test @CriticalNative calls on the initializing thread.
375     $noinline$opt$testCriticalClinitCheck();
376     sTestCriticalClinitCheckOtherThread = new Thread() {
377       public void run() {
378         $noinline$opt$testCriticalClinitCheck();
379       }
380     };
381     sTestCriticalClinitCheckOtherThread.start();
382     // Sleep for a second to give the other thread an opportunity to run.
383     // We're testing that it performs a clinit check and blocks until we
384     // exit the class initializer after writing the output below.
385     try {
386       Thread.sleep(1000);
387     } catch (InterruptedException ie) {
388       throw new Error(ie);
389     }
390     System.out.println("initializingCriticalClinitCheck finished");
391   }
392 
$noinline$opt$testCriticalClinitCheck()393   static void $noinline$opt$testCriticalClinitCheck() {
394     assertEquals(42, CriticalClinitCheck.nativeMethodVoid());
395     assertEquals(42, CriticalClinitCheck.nativeMethod(42));
396     assertEquals(42, CriticalClinitCheck.nativeMethodWithManyParameters(
397         11, 12L, 13.0f, 14.0d,
398         21, 22L, 23.0f, 24.0d,
399         31, 32L, 33.0f, 34.0d,
400         41, 42L, 43.0f, 44.0d,
401         51, 52L, 53.0f, 54.0d,
402         61, 62L, 63.0f, 64.0d,
403         71, 72L, 73.0f, 74.0d,
404         81, 82L, 83.0f, 84.0d));
405     System.out.println("testCriticalClinitCheck passed");
406   }
407 
408   static Thread sTestCriticalClinitCheckOtherThread = null;
409 
assertEquals(int expected, int actual)410   static void assertEquals(int expected, int actual) {
411     if (expected != actual) {
412       throw new AssertionError("Expected " + expected + " got " + actual);
413     }
414   }
415 
makeVisiblyInitialized()416   public static native void makeVisiblyInitialized();
417 }
418 
419 class Test {
nativeMethodVoid()420   public static native int nativeMethodVoid();
421 
nativeMethod(int i)422   public static native int nativeMethod(int i);
423 
nativeMethodWithManyParameters( int i1, long l1, float f1, double d1, int i2, long l2, float f2, double d2, int i3, long l3, float f3, double d3, int i4, long l4, float f4, double d4, int i5, long l5, float f5, double d5, int i6, long l6, float f6, double d6, int i7, long l7, float f7, double d7, int i8, long l8, float f8, double d8)424   public static native int nativeMethodWithManyParameters(
425       int i1, long l1, float f1, double d1,
426       int i2, long l2, float f2, double d2,
427       int i3, long l3, float f3, double d3,
428       int i4, long l4, float f4, double d4,
429       int i5, long l5, float f5, double d5,
430       int i6, long l6, float f6, double d6,
431       int i7, long l7, float f7, double d7,
432       int i8, long l8, float f8, double d8);
433 }
434 
435 class TestFast {
436   @FastNative
nativeMethodVoid()437   public static native int nativeMethodVoid();
438 
439   @FastNative
nativeMethod(int i)440   public static native int nativeMethod(int i);
441 
442   @FastNative
nativeMethodWithManyParameters( int i1, long l1, float f1, double d1, int i2, long l2, float f2, double d2, int i3, long l3, float f3, double d3, int i4, long l4, float f4, double d4, int i5, long l5, float f5, double d5, int i6, long l6, float f6, double d6, int i7, long l7, float f7, double d7, int i8, long l8, float f8, double d8)443   public static native int nativeMethodWithManyParameters(
444       int i1, long l1, float f1, double d1,
445       int i2, long l2, float f2, double d2,
446       int i3, long l3, float f3, double d3,
447       int i4, long l4, float f4, double d4,
448       int i5, long l5, float f5, double d5,
449       int i6, long l6, float f6, double d6,
450       int i7, long l7, float f7, double d7,
451       int i8, long l8, float f8, double d8);
452 }
453 
454 class TestCritical {
455   @CriticalNative
nativeMethodVoid()456   public static native int nativeMethodVoid();
457 
458   @CriticalNative
nativeMethod(int i)459   public static native int nativeMethod(int i);
460 
461   @CriticalNative
nativeMethodWithManyParameters( int i1, long l1, float f1, double d1, int i2, long l2, float f2, double d2, int i3, long l3, float f3, double d3, int i4, long l4, float f4, double d4, int i5, long l5, float f5, double d5, int i6, long l6, float f6, double d6, int i7, long l7, float f7, double d7, int i8, long l8, float f8, double d8)462   public static native int nativeMethodWithManyParameters(
463       int i1, long l1, float f1, double d1,
464       int i2, long l2, float f2, double d2,
465       int i3, long l3, float f3, double d3,
466       int i4, long l4, float f4, double d4,
467       int i5, long l5, float f5, double d5,
468       int i6, long l6, float f6, double d6,
469       int i7, long l7, float f7, double d7,
470       int i8, long l8, float f8, double d8);
471 }
472 
473 class TestMissing {
nativeMethodVoid()474   public static native int nativeMethodVoid();
475 
nativeMethod(int i)476   public static native int nativeMethod(int i);
477 
nativeMethodWithManyParameters( int i1, long l1, float f1, double d1, int i2, long l2, float f2, double d2, int i3, long l3, float f3, double d3, int i4, long l4, float f4, double d4, int i5, long l5, float f5, double d5, int i6, long l6, float f6, double d6, int i7, long l7, float f7, double d7, int i8, long l8, float f8, double d8)478   public static native int nativeMethodWithManyParameters(
479       int i1, long l1, float f1, double d1,
480       int i2, long l2, float f2, double d2,
481       int i3, long l3, float f3, double d3,
482       int i4, long l4, float f4, double d4,
483       int i5, long l5, float f5, double d5,
484       int i6, long l6, float f6, double d6,
485       int i7, long l7, float f7, double d7,
486       int i8, long l8, float f8, double d8);
487 }
488 
489 class TestMissingFast {
490   @FastNative
nativeMethodVoid()491   public static native int nativeMethodVoid();
492 
493   @FastNative
nativeMethod(int i)494   public static native int nativeMethod(int i);
495 
496   @FastNative
nativeMethodWithManyParameters( int i1, long l1, float f1, double d1, int i2, long l2, float f2, double d2, int i3, long l3, float f3, double d3, int i4, long l4, float f4, double d4, int i5, long l5, float f5, double d5, int i6, long l6, float f6, double d6, int i7, long l7, float f7, double d7, int i8, long l8, float f8, double d8)497   public static native int nativeMethodWithManyParameters(
498       int i1, long l1, float f1, double d1,
499       int i2, long l2, float f2, double d2,
500       int i3, long l3, float f3, double d3,
501       int i4, long l4, float f4, double d4,
502       int i5, long l5, float f5, double d5,
503       int i6, long l6, float f6, double d6,
504       int i7, long l7, float f7, double d7,
505       int i8, long l8, float f8, double d8);
506 }
507 
508 class TestMissingCritical {
509   @CriticalNative
nativeMethodVoid()510   public static native int nativeMethodVoid();
511 
512   @CriticalNative
nativeMethod(int i)513   public static native int nativeMethod(int i);
514 
515   @CriticalNative
nativeMethodWithManyParameters( int i1, long l1, float f1, double d1, int i2, long l2, float f2, double d2, int i3, long l3, float f3, double d3, int i4, long l4, float f4, double d4, int i5, long l5, float f5, double d5, int i6, long l6, float f6, double d6, int i7, long l7, float f7, double d7, int i8, long l8, float f8, double d8)516   public static native int nativeMethodWithManyParameters(
517       int i1, long l1, float f1, double d1,
518       int i2, long l2, float f2, double d2,
519       int i3, long l3, float f3, double d3,
520       int i4, long l4, float f4, double d4,
521       int i5, long l5, float f5, double d5,
522       int i6, long l6, float f6, double d6,
523       int i7, long l7, float f7, double d7,
524       int i8, long l8, float f8, double d8);
525 }
526 
527 class CriticalSignatures {
528   // The following signatures exercise ARM argument moving and serve
529   // as an example of the optimizations performed by the assembler.
530   // Moving arguments is a lot simpler for other architectures.
531 
532   // JNI compiler does not emit the CFG, so we cannot CHECK the "dissassembly (after)".
533 
534   // vstm sp, {d0-d2}         # f1, f2, f3, f4, d -- store floats as D regs together with double
535   // mov r4, r0               # hidden arg
536   // mov r0, r1               # i
537   //                          # l stays in r2-r3
538   @CriticalNative
nativeILFFFFD( int i, long l, float f1, float f2, float f3, float f4, double d)539   public static native int nativeILFFFFD(
540       int i, long l, float f1, float f2, float f3, float f4, double d);
541 
542   // vstm sp, {s1-s3}         # f2, f3, f4 -- store floats up to alignment gap
543   // vstr d2, [sp, #16]       # d
544   // mov r4, r0               # hidden arg
545   // mov r0, r2               # low(l)
546   // mov r1, r3               # high(l)
547   // ldr r2, [sp, #...]       # i
548   // vmov r3, s0              # f1
549   @CriticalNative
nativeLIFFFFD( long l, int i, float f1, float f2, float f3, float f4, double d)550   public static native int nativeLIFFFFD(
551       long l, int i, float f1, float f2, float f3, float f4, double d);
552 
553   // ldr  ip, [sp, #...]      # i
554   // str  ip, [sp]            # i
555   // add  ip, sp, #4          # Spilling multiple floats at an offset from SP
556   // vstm ip, {s1-s5}         # f2, f3, f4, d
557   // mov r4, r0               # hidden arg
558   // vmov r0, s0              # f1
559   //                          # l stays in r2-r3
560   @CriticalNative
nativeFLIFFFD( float f1, long l, int i, float f2, float f3, float f4, double d)561   public static native int nativeFLIFFFD(
562       float f1, long l, int i, float f2, float f3, float f4, double d);
563 
564   // stm sp, {r1,r2,r3}       # i1, i2, i3 -- store ints together
565   // ldrd r1, ip, [sp, #...]  # i4, i5
566   // strd r1, ip, [sp, #12]   # i4, i5
567   // ldr ip, [sp, #72]        # i6
568   // str ip, [sp, #20]        # i6
569   // mov r4, r0               # hidden arg
570   // vmov r0, r1, d0          # d1
571   // vmov r2, r3, d1          # d2
572   @CriticalNative
nativeDDIIIIII( double d1, double d2, int i1, int i2, int i3, int i4, int i5, int i6)573   public static native int nativeDDIIIIII(
574       double d1, double d2, int i1, int i2, int i3, int i4, int i5, int i6);
575 
576   // str r1, [sp]             # i1 -- cannot store with l due to alignment gap
577   // strd r2, r3, [sp, #8]    # l
578   // ldrd r1, ip, [sp, #...]  # i2, i3
579   // strd r1, ip, [sp, #16]   # i2, i3
580   // ldr ip, [sp, #...]       # i4
581   // str ip, [sp, #24]        # i4
582   // mov r4, r0               # hidden arg
583   // vmov r0, r1, d0          # d
584   // vmov r2, r3, d1          # f1, f2 -- move both floats together as double
585   @CriticalNative
nativeDFFILIII( double d, float f1, float f2, int i1, long l, int i2, int i3, int i4)586   public static native int nativeDFFILIII(
587       double d, float f1, float f2, int i1, long l, int i2, int i3, int i4);
588 
589   // vstr s4, [sp]            # f
590   // add ip, sp, #4           # Spilling multiple core registers at an offset from SP
591   // stm ip, {r1,r2,r3}       # i1, l -- store int together with long
592   // ldrd r1, ip, [sp, #...]  # i2, i3
593   // strd r1, ip, [sp, #16]   # i2, i3
594   // ldr ip, [sp, #...]       # i4
595   // str ip, [sp, #24]        # i4
596   // mov r4, r0               # hidden arg
597   // vmov r0, r1, d0          # d1
598   // vmov r2, r3, d1          # d2
599   @CriticalNative
nativeDDFILIII( double d1, double d2, float f, int i1, long l, int i2, int i3, int i4)600   public static native int nativeDDFILIII(
601       double d1, double d2, float f, int i1, long l, int i2, int i3, int i4);
602 
603   // str r1, [sp]             # i1
604   // vstr s4, [sp, #4]        # f
605   // strd r2, r3, [sp, #8]    # i2, i3 -- store ints together with STRD
606   // mov r4, r0               # hidden arg
607   // vmov r0, r1, d0          # d1
608   // vmov r2, r3, d1          # d2
609   @CriticalNative
nativeDDIFII( double d1, double d2, int i1, float f, int i2, int i3)610   public static native int nativeDDIFII(
611       double d1, double d2, int i1, float f, int i2, int i3);
612 
613   // ...
614   // ldr ip, [sp, #2112]      # int
615   // str ip, [sp, #1000]      # int
616   // add r1, sp, #2048        # Prepare to use LDRD for loading long from a large offset
617   // ldrd r1, ip, [r1, #68]   # long
618   // strd r1, ip, [sp, #1008] # long
619   // ldr ip, [sp, #2124]      # int
620   // str ip, [sp, #1016]      # int
621   // ldr ip, [sp, #2128]      # low(long) -- copy the next long as two words because the offset
622   // str ip, [sp, #1024]      # low(long) -- is too large for STRD and we only use 2 temps (r1, ip)
623   // ldr ip, [sp, #2132]      # high(long)
624   // str ip, [sp, #1028]      # high(long)
625   // ...
626   @CriticalNative
nativeFullArgs( long l0, int i2, long l3, int i5, long l6, int i8, long l9, int i11, long l12, int i14, long l15, int i17, long l18, int i20, long l21, int i23, long l24, int i26, long l27, int i29, long l30, int i32, long l33, int i35, long l36, int i38, long l39, int i41, long l42, int i44, long l45, int i47, long l48, int i50, long l51, int i53, long l54, int i56, long l57, int i59, long l60, int i62, long l63, int i65, long l66, int i68, long l69, int i71, long l72, int i74, long l75, int i77, long l78, int i80, long l81, int i83, long l84, int i86, long l87, int i89, long l90, int i92, long l93, int i95, long l96, int i98, long l99, int i101, long l102, int i104, long l105, int i107, long l108, int i110, long l111, int i113, long l114, int i116, long l117, int i119, long l120, int i122, long l123, int i125, long l126, int i128, long l129, int i131, long l132, int i134, long l135, int i137, long l138, int i140, long l141, int i143, long l144, int i146, long l147, int i149, long l150, int i152, long l153, int i155, long l156, int i158, long l159, int i161, long l162, int i164, long l165, int i167, long l168, int i170, long l171, int i173, long l174, int i176, long l177, int i179, long l180, int i182, long l183, int i185, long l186, int i188, long l189, int i191, long l192, int i194, long l195, int i197, long l198, int i200, long l201, int i203, long l204, int i206, long l207, int i209, long l210, int i212, long l213, int i215, long l216, int i218, long l219, int i221, long l222, int i224, long l225, int i227, long l228, int i230, long l231, int i233, long l234, int i236, long l237, int i239, long l240, int i242, long l243, int i245, long l246, int i248, long l249, int i251, long l252, int i254)627   public static native int nativeFullArgs(
628       // Note: Numbered by dalvik registers, 0-254 (max 255 regs for invoke-*-range)
629       //
630       // Generated by script (then modified to close the argument list):
631       //   for i in {0..84}; do echo "      long l$((i*3)),"; echo "      int i$(($i*3+2)),"; done
632       long l0,
633       int i2,
634       long l3,
635       int i5,
636       long l6,
637       int i8,
638       long l9,
639       int i11,
640       long l12,
641       int i14,
642       long l15,
643       int i17,
644       long l18,
645       int i20,
646       long l21,
647       int i23,
648       long l24,
649       int i26,
650       long l27,
651       int i29,
652       long l30,
653       int i32,
654       long l33,
655       int i35,
656       long l36,
657       int i38,
658       long l39,
659       int i41,
660       long l42,
661       int i44,
662       long l45,
663       int i47,
664       long l48,
665       int i50,
666       long l51,
667       int i53,
668       long l54,
669       int i56,
670       long l57,
671       int i59,
672       long l60,
673       int i62,
674       long l63,
675       int i65,
676       long l66,
677       int i68,
678       long l69,
679       int i71,
680       long l72,
681       int i74,
682       long l75,
683       int i77,
684       long l78,
685       int i80,
686       long l81,
687       int i83,
688       long l84,
689       int i86,
690       long l87,
691       int i89,
692       long l90,
693       int i92,
694       long l93,
695       int i95,
696       long l96,
697       int i98,
698       long l99,
699       int i101,
700       long l102,
701       int i104,
702       long l105,
703       int i107,
704       long l108,
705       int i110,
706       long l111,
707       int i113,
708       long l114,
709       int i116,
710       long l117,
711       int i119,
712       long l120,
713       int i122,
714       long l123,
715       int i125,
716       long l126,
717       int i128,
718       long l129,
719       int i131,
720       long l132,
721       int i134,
722       long l135,
723       int i137,
724       long l138,
725       int i140,
726       long l141,
727       int i143,
728       long l144,
729       int i146,
730       long l147,
731       int i149,
732       long l150,
733       int i152,
734       long l153,
735       int i155,
736       long l156,
737       int i158,
738       long l159,
739       int i161,
740       long l162,
741       int i164,
742       long l165,
743       int i167,
744       long l168,
745       int i170,
746       long l171,
747       int i173,
748       long l174,
749       int i176,
750       long l177,
751       int i179,
752       long l180,
753       int i182,
754       long l183,
755       int i185,
756       long l186,
757       int i188,
758       long l189,
759       int i191,
760       long l192,
761       int i194,
762       long l195,
763       int i197,
764       long l198,
765       int i200,
766       long l201,
767       int i203,
768       long l204,
769       int i206,
770       long l207,
771       int i209,
772       long l210,
773       int i212,
774       long l213,
775       int i215,
776       long l216,
777       int i218,
778       long l219,
779       int i221,
780       long l222,
781       int i224,
782       long l225,
783       int i227,
784       long l228,
785       int i230,
786       long l231,
787       int i233,
788       long l234,
789       int i236,
790       long l237,
791       int i239,
792       long l240,
793       int i242,
794       long l243,
795       int i245,
796       long l246,
797       int i248,
798       long l249,
799       int i251,
800       long l252,
801       int i254);
802 }
803 
804 class CriticalClinitCheck {
805   @CriticalNative
nativeMethodVoid()806   public static native int nativeMethodVoid();
807 
808   @CriticalNative
nativeMethod(int i)809   public static native int nativeMethod(int i);
810 
811   @CriticalNative
nativeMethodWithManyParameters( int i1, long l1, float f1, double d1, int i2, long l2, float f2, double d2, int i3, long l3, float f3, double d3, int i4, long l4, float f4, double d4, int i5, long l5, float f5, double d5, int i6, long l6, float f6, double d6, int i7, long l7, float f7, double d7, int i8, long l8, float f8, double d8)812   public static native int nativeMethodWithManyParameters(
813       int i1, long l1, float f1, double d1,
814       int i2, long l2, float f2, double d2,
815       int i3, long l3, float f3, double d3,
816       int i4, long l4, float f4, double d4,
817       int i5, long l5, float f5, double d5,
818       int i6, long l6, float f6, double d6,
819       int i7, long l7, float f7, double d7,
820       int i8, long l8, float f8, double d8);
821 
822   static {
Main.initializingCriticalClinitCheck()823     Main.initializingCriticalClinitCheck();
824   }
825 }
826