|
49 | 49 | #include "runtime/sharedRuntime.hpp"
|
50 | 50 | #include "runtime/stubRoutines.hpp"
|
51 | 51 | #include "runtime/timer.hpp"
|
| 52 | +#include "runtime/vm_version.hpp" |
52 | 53 | #include "signals_posix.hpp"
|
53 | 54 | #include "utilities/align.hpp"
|
| 55 | +#include "utilities/debug.hpp" |
54 | 56 | #include "utilities/events.hpp"
|
55 | 57 | #include "utilities/vmError.hpp"
|
56 | 58 |
|
@@ -524,40 +526,32 @@ static inline void atomic_copy64(const volatile void *src, volatile void *dst) {
|
524 | 526 | }
|
525 | 527 |
|
526 | 528 | extern "C" {
|
527 |
| - // needs local assembler label '1:' to avoid trouble when using linktime optimization |
528 | 529 | int SpinPause() {
|
529 | 530 | // We don't use StubRoutines::aarch64::spin_wait stub in order to
|
530 | 531 | // avoid a costly call to os::current_thread_enable_wx() on MacOS.
|
531 | 532 | // We should return 1 if SpinPause is implemented, and since there
|
532 |
| - // will be a sequence of 11 instructions for NONE and YIELD and 12 |
533 |
| - // instructions for NOP and ISB, SpinPause will always return 1. |
534 |
| - uint64_t br_dst; |
535 |
| - const int instructions_per_case = 2; |
536 |
| - int64_t off = VM_Version::spin_wait_desc().inst() * instructions_per_case * Assembler::instruction_size; |
537 |
| - |
538 |
| - assert(VM_Version::spin_wait_desc().inst() >= SpinWait::NONE && |
539 |
| - VM_Version::spin_wait_desc().inst() <= SpinWait::YIELD, "must be"); |
540 |
| - assert(-1 == SpinWait::NONE, "must be"); |
541 |
| - assert( 0 == SpinWait::NOP, "must be"); |
542 |
| - assert( 1 == SpinWait::ISB, "must be"); |
543 |
| - assert( 2 == SpinWait::YIELD, "must be"); |
544 |
| - |
545 |
| - asm volatile( |
546 |
| - " adr %[d], 20 \n" // 20 == PC here + 5 instructions => address |
547 |
| - // to entry for case SpinWait::NOP |
548 |
| - " add %[d], %[d], %[o] \n" |
549 |
| - " br %[d] \n" |
550 |
| - " b 1f \n" // case SpinWait::NONE (-1) |
551 |
| - " nop \n" // padding |
552 |
| - " nop \n" // case SpinWait::NOP ( 0) |
553 |
| - " b 1f \n" |
554 |
| - " isb \n" // case SpinWait::ISB ( 1) |
555 |
| - " b 1f \n" |
556 |
| - " yield \n" // case SpinWait::YIELD ( 2) |
557 |
| - "1: \n" |
558 |
| - : [d]"=&r"(br_dst) |
559 |
| - : [o]"r"(off) |
560 |
| - : "memory"); |
| 533 | + // will be always a sequence of instructions, SpinPause will always return 1. |
| 534 | + switch (VM_Version::spin_wait_desc().inst()) { |
| 535 | + case SpinWait::NONE: |
| 536 | + break; |
| 537 | + case SpinWait::NOP: |
| 538 | + asm volatile("nop" : : : "memory"); |
| 539 | + break; |
| 540 | + case SpinWait::ISB: |
| 541 | + asm volatile("isb" : : : "memory"); |
| 542 | + break; |
| 543 | + case SpinWait::YIELD: |
| 544 | + asm volatile("yield" : : : "memory"); |
| 545 | + break; |
| 546 | + case SpinWait::SB: |
| 547 | + assert(VM_Version::supports_sb(), "current CPU does not support SB instruction"); |
| 548 | + asm volatile(".inst 0xd50330ff" : : : "memory"); |
| 549 | + break; |
| 550 | +#ifdef ASSERT |
| 551 | + default: |
| 552 | + ShouldNotReachHere(); |
| 553 | +#endif |
| 554 | + } |
561 | 555 | return 1;
|
562 | 556 | }
|
563 | 557 |
|
|
0 commit comments