Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 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 | |
| 22 | public static void main(String[] args) throws Exception { |
| 23 | System.loadLibrary(args[0]); |
| 24 | |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 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(); |
Vladimir Marko | 0300822 | 2020-03-06 14:04:21 +0000 | [diff] [blame] | 32 | new CriticalSignatures(); |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 33 | makeVisiblyInitialized(); // Make sure they are visibly initialized. |
| 34 | |
Vladimir Marko | 6bc480b | 2020-06-08 09:00:33 +0100 | [diff] [blame] | 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(); |
Vladimir Marko | 0300822 | 2020-03-06 14:04:21 +0000 | [diff] [blame] | 42 | |
Vladimir Marko | 6bc480b | 2020-06-08 09:00:33 +0100 | [diff] [blame] | 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 | |
Vladimir Marko | c714f40 | 2021-03-04 14:24:38 +0000 | [diff] [blame] | 54 | $noinline$regressionTestB181736463(); |
Vladimir Marko | 654f01c | 2021-05-26 16:40:20 +0100 | [diff] [blame] | 55 | $noinline$regressionTestB189235039(); |
Vladimir Marko | c714f40 | 2021-03-04 14:24:38 +0000 | [diff] [blame] | 56 | |
Vladimir Marko | 6bc480b | 2020-06-08 09:00:33 +0100 | [diff] [blame] | 57 | new CriticalClinitCheck(); |
| 58 | sTestCriticalClinitCheckOtherThread.join(); |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 59 | } |
| 60 | |
Vladimir Marko | 6bc480b | 2020-06-08 09:00:33 +0100 | [diff] [blame] | 61 | static void $noinline$opt$test() { |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 62 | System.out.println("test"); |
Vladimir Marko | fa458ac | 2020-02-12 14:08:07 +0000 | [diff] [blame] | 63 | assertEquals(42, Test.nativeMethodVoid()); |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 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 | |
Vladimir Marko | 6bc480b | 2020-06-08 09:00:33 +0100 | [diff] [blame] | 76 | static void $noinline$opt$testFast() { |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 77 | System.out.println("testFast"); |
Vladimir Marko | fa458ac | 2020-02-12 14:08:07 +0000 | [diff] [blame] | 78 | assertEquals(42, TestFast.nativeMethodVoid()); |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 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 | |
Vladimir Marko | 6bc480b | 2020-06-08 09:00:33 +0100 | [diff] [blame] | 91 | static void $noinline$opt$testCritical() { |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 92 | System.out.println("testCritical"); |
Vladimir Marko | fa458ac | 2020-02-12 14:08:07 +0000 | [diff] [blame] | 93 | assertEquals(42, TestCritical.nativeMethodVoid()); |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 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 | |
Vladimir Marko | 6bc480b | 2020-06-08 09:00:33 +0100 | [diff] [blame] | 106 | static void $noinline$opt$testMissing() { |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 107 | System.out.println("testMissing"); |
| 108 | |
| 109 | try { |
Vladimir Marko | fa458ac | 2020-02-12 14:08:07 +0000 | [diff] [blame] | 110 | TestMissing.nativeMethodVoid(); |
| 111 | throw new Error("UNREACHABLE"); |
| 112 | } catch (LinkageError expected) {} |
| 113 | |
| 114 | try { |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 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 | |
Vladimir Marko | 6bc480b | 2020-06-08 09:00:33 +0100 | [diff] [blame] | 133 | static void $noinline$opt$testMissingFast() { |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 134 | System.out.println("testMissingFast"); |
| 135 | |
| 136 | try { |
Vladimir Marko | fa458ac | 2020-02-12 14:08:07 +0000 | [diff] [blame] | 137 | TestMissingFast.nativeMethodVoid(); |
| 138 | throw new Error("UNREACHABLE"); |
| 139 | } catch (LinkageError expected) {} |
| 140 | |
| 141 | try { |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 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 | |
Vladimir Marko | 6bc480b | 2020-06-08 09:00:33 +0100 | [diff] [blame] | 160 | static void $noinline$opt$testMissingCritical() { |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 161 | System.out.println("testMissingCritical"); |
| 162 | |
| 163 | try { |
Vladimir Marko | fa458ac | 2020-02-12 14:08:07 +0000 | [diff] [blame] | 164 | TestMissingCritical.nativeMethodVoid(); |
| 165 | throw new Error("UNREACHABLE"); |
| 166 | } catch (LinkageError expected) {} |
| 167 | |
| 168 | try { |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 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 | |
Vladimir Marko | 6bc480b | 2020-06-08 09:00:33 +0100 | [diff] [blame] | 187 | static void $noinline$opt$testCriticalSignatures() { |
Vladimir Marko | 0300822 | 2020-03-06 14:04:21 +0000 | [diff] [blame] | 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 | |
Vladimir Marko | c714f40 | 2021-03-04 14:24:38 +0000 | [diff] [blame] | 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 | |
Vladimir Marko | 654f01c | 2021-05-26 16:40:20 +0100 | [diff] [blame] | 384 | static void $noinline$regressionTestB189235039() { |
| 385 | assertEquals(42, new Main().b189235039CallThrough()); |
| 386 | } |
| 387 | |
Vladimir Marko | 6bc480b | 2020-06-08 09:00:33 +0100 | [diff] [blame] | 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 | |
| 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 | |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 426 | static void assertEquals(int expected, int actual) { |
| 427 | if (expected != actual) { |
| 428 | throw new AssertionError("Expected " + expected + " got " + actual); |
| 429 | } |
| 430 | } |
| 431 | |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 432 | public static native void makeVisiblyInitialized(); |
Vladimir Marko | 654f01c | 2021-05-26 16:40:20 +0100 | [diff] [blame] | 433 | |
| 434 | public native synchronized int b189235039CallThrough(); |
| 435 | public static native int b189235039CheckLocks(int placeholder, Main m); |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 436 | } |
| 437 | |
| 438 | class Test { |
Vladimir Marko | fa458ac | 2020-02-12 14:08:07 +0000 | [diff] [blame] | 439 | public static native int nativeMethodVoid(); |
| 440 | |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 441 | public static native int nativeMethod(int i); |
| 442 | |
| 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 |
Vladimir Marko | fa458ac | 2020-02-12 14:08:07 +0000 | [diff] [blame] | 456 | public static native int nativeMethodVoid(); |
| 457 | |
| 458 | @FastNative |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 459 | public static native int nativeMethod(int i); |
| 460 | |
| 461 | @FastNative |
| 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 |
Vladimir Marko | fa458ac | 2020-02-12 14:08:07 +0000 | [diff] [blame] | 475 | public static native int nativeMethodVoid(); |
| 476 | |
| 477 | @CriticalNative |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 478 | public static native int nativeMethod(int i); |
| 479 | |
| 480 | @CriticalNative |
| 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 { |
Vladimir Marko | fa458ac | 2020-02-12 14:08:07 +0000 | [diff] [blame] | 493 | public static native int nativeMethodVoid(); |
| 494 | |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 495 | public static native int nativeMethod(int i); |
| 496 | |
| 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 |
Vladimir Marko | fa458ac | 2020-02-12 14:08:07 +0000 | [diff] [blame] | 510 | public static native int nativeMethodVoid(); |
| 511 | |
| 512 | @FastNative |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 513 | public static native int nativeMethod(int i); |
| 514 | |
| 515 | @FastNative |
| 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 |
Vladimir Marko | fa458ac | 2020-02-12 14:08:07 +0000 | [diff] [blame] | 529 | public static native int nativeMethodVoid(); |
| 530 | |
| 531 | @CriticalNative |
Vladimir Marko | 7dac864 | 2019-11-06 17:09:30 +0000 | [diff] [blame] | 532 | public static native int nativeMethod(int i); |
| 533 | |
| 534 | @CriticalNative |
| 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 | } |
Vladimir Marko | 0300822 | 2020-03-06 14:04:21 +0000 | [diff] [blame] | 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 | } |
Vladimir Marko | 6bc480b | 2020-06-08 09:00:33 +0100 | [diff] [blame] | 822 | |
| 823 | class CriticalClinitCheck { |
| 824 | @CriticalNative |
| 825 | public static native int nativeMethodVoid(); |
| 826 | |
| 827 | @CriticalNative |
| 828 | public static native int nativeMethod(int i); |
| 829 | |
| 830 | @CriticalNative |
| 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 { |
| 842 | Main.initializingCriticalClinitCheck(); |
| 843 | } |
| 844 | } |
Vladimir Marko | c714f40 | 2021-03-04 14:24:38 +0000 | [diff] [blame] | 845 | |
| 846 | class B181736463Error extends Error { |
| 847 | } |
| 848 | |
| 849 | class BadClassB181736463 { |
| 850 | static { |
| 851 | // Deliberately throw from class initializer. |
| 852 | if (true) { |
| 853 | throw new B181736463Error(); |
| 854 | } |
| 855 | } |
| 856 | |
| 857 | public static native int nativeMethodVoid(); |
| 858 | } |