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