|
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