From 901b590888e9847e9804e02896072693fcb48600 Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Fri, 10 Dec 2021 15:56:44 +0000 Subject: [PATCH 1/5] 8278241: Implement JVM SpinPause on linux-aarch64 --- src/hotspot/cpu/aarch64/spin_wait_aarch64.hpp | 39 ++++++++- .../cpu/aarch64/vm_version_aarch64.cpp | 8 +- .../cpu/aarch64/vm_version_aarch64.hpp | 4 + .../os_cpu/linux_aarch64/os_linux_aarch64.cpp | 8 +- .../jtreg/runtime/Thread/TestSpinPause.java | 87 +++++++++++++++++++ 5 files changed, 138 insertions(+), 8 deletions(-) create mode 100644 test/hotspot/jtreg/runtime/Thread/TestSpinPause.java diff --git a/src/hotspot/cpu/aarch64/spin_wait_aarch64.hpp b/src/hotspot/cpu/aarch64/spin_wait_aarch64.hpp index 4edce2642e9ff..c6c4f5cd930cd 100644 --- a/src/hotspot/cpu/aarch64/spin_wait_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/spin_wait_aarch64.hpp @@ -25,7 +25,14 @@ #ifndef CPU_AARCH64_SPIN_WAIT_AARCH64_HPP #define CPU_AARCH64_SPIN_WAIT_AARCH64_HPP -class SpinWait { +// SpinWait provides a description for implementations of spin wait/pause. +// The description includes: +// - what an instruction should be used by an implementation. +// - how many of the instructions. +// - a runner which can execute the requested number of instructions. +// +// Creation of SpinWait is controlled by VM_Version. +class SpinWait final { public: enum Inst { NONE = -1, @@ -33,16 +40,42 @@ class SpinWait { ISB, YIELD }; + using InstRunner = void (*)(int count); private: Inst _inst; int _count; + InstRunner _inst_runner; -public: - SpinWait(Inst inst = NONE, int count = 0) : _inst(inst), _count(count) {} + static void run_nop(int count) { + while (count-- > 0) { + __asm volatile("nop"); + } + } + + static void run_isb(int count) { + while (count-- > 0) { + __asm volatile("isb"); + } + } + + static void run_yield(int count) { + while (count-- > 0) { + __asm volatile("yield"); + } + } + + static void run_none(int) {} + SpinWait(Inst inst = NONE, int count = 0, InstRunner inst_runner = run_none) : + _inst(inst), _count(count), _inst_runner(inst_runner) {} + +public: Inst inst() const { return _inst; } int inst_count() const { return _count; } + InstRunner inst_runner() const { return _inst_runner; } + + friend class VM_Version; }; #endif // CPU_AARCH64_SPIN_WAIT_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp index e08d0b6f134b7..6b457074501ba 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp @@ -48,13 +48,13 @@ int VM_Version::_initial_sve_vector_length; SpinWait VM_Version::_spin_wait; -static SpinWait get_spin_wait_desc() { +SpinWait VM_Version::get_spin_wait_desc() { if (strcmp(OnSpinWaitInst, "nop") == 0) { - return SpinWait(SpinWait::NOP, OnSpinWaitInstCount); + return SpinWait(SpinWait::NOP, OnSpinWaitInstCount, SpinWait::run_nop); } else if (strcmp(OnSpinWaitInst, "isb") == 0) { - return SpinWait(SpinWait::ISB, OnSpinWaitInstCount); + return SpinWait(SpinWait::ISB, OnSpinWaitInstCount, SpinWait::run_isb); } else if (strcmp(OnSpinWaitInst, "yield") == 0) { - return SpinWait(SpinWait::YIELD, OnSpinWaitInstCount); + return SpinWait(SpinWait::YIELD, OnSpinWaitInstCount, SpinWait::run_yield); } else if (strcmp(OnSpinWaitInst, "none") != 0) { vm_exit_during_initialization("The options for OnSpinWaitInst are nop, isb, yield, and none", OnSpinWaitInst); } diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp index 61f422bd2d38b..6a9d3e2f45546 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp @@ -57,6 +57,10 @@ class VM_Version : public Abstract_VM_Version { static int set_and_get_current_sve_vector_length(int len); static int get_current_sve_vector_length(); + // Get SpinWait based on values of OnSpinWaitInst/OnSpinWaitInstCount options + // describing it. + static SpinWait get_spin_wait_desc(); + public: // Initialization static void initialize(); diff --git a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp index b3c60b6e62482..cf19bcd2da9f8 100644 --- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp +++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp @@ -382,7 +382,13 @@ int os::extra_bang_size_in_bytes() { extern "C" { int SpinPause() { - return 0; + const SpinWait& spin_wait = VM_Version::spin_wait_desc(); + if (spin_wait.inst() == SpinWait::NONE) { + return 0; + } + SpinWait::InstRunner run_inst = spin_wait.inst_runner(); + (*run_inst)(spin_wait.inst_count()); + return 1; } void _Copy_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) { diff --git a/test/hotspot/jtreg/runtime/Thread/TestSpinPause.java b/test/hotspot/jtreg/runtime/Thread/TestSpinPause.java new file mode 100644 index 0000000000000..91c9e53c82afb --- /dev/null +++ b/test/hotspot/jtreg/runtime/Thread/TestSpinPause.java @@ -0,0 +1,87 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test TestSpinPause + * @summary JVM runtime can use SpinPause function for synchronized statements. + * Check different implementations of JVM SpinPause don't crash JVM. + * @bug 8278241 + * @library /test/lib + * + * @requires os.arch=="aarch64" + * + * @run main/othervm TestSpinPause + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=none TestSpinPause + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=nop TestSpinPause + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=isb TestSpinPause + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=yield TestSpinPause + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=nop -XX:OnSpinWaitInstCount=10 TestSpinPause + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=isb -XX:OnSpinWaitInstCount=3 TestSpinPause + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=yield -XX:OnSpinWaitInstCount=3 TestSpinPause + * @run main/othervm -Xint TestSpinPause + * @run main/othervm -Xint -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=none TestSpinPause + * @run main/othervm -Xint -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=nop TestSpinPause + * @run main/othervm -Xint -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=isb TestSpinPause + * @run main/othervm -Xint -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=yield TestSpinPause + * @run main/othervm -Xint -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=nop -XX:OnSpinWaitInstCount=10 TestSpinPause + * @run main/othervm -Xint -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=isb -XX:OnSpinWaitInstCount=3 TestSpinPause + * @run main/othervm -Xint -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=yield -XX:OnSpinWaitInstCount=3 TestSpinPause + * @run main/othervm -Xcomp TestSpinPause + * @run main/othervm -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=none TestSpinPause + * @run main/othervm -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=nop TestSpinPause + * @run main/othervm -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=isb TestSpinPause + * @run main/othervm -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=yield TestSpinPause + * @run main/othervm -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=nop -XX:OnSpinWaitInstCount=10 TestSpinPause + * @run main/othervm -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=isb -XX:OnSpinWaitInstCount=3 TestSpinPause + * @run main/othervm -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=yield -XX:OnSpinWaitInstCount=3 TestSpinPause + */ + +public class TestSpinPause { + private Integer[] valueHolder; + + private TestSpinPause () { + valueHolder = new Integer[] {Integer.valueOf(101)}; + } + + private void getSet() { + final int iterCount = 1000; + for (int i = 0; i < iterCount; ++i) { + synchronized (valueHolder) { + Integer v = valueHolder[0]; + valueHolder[0] = Integer.reverse(v); + } + } + } + + public static void main(String[] args) throws Exception { + TestSpinPause test = new TestSpinPause(); + Thread t1 = new Thread(test::getSet); + Thread t2 = new Thread(test::getSet); + t1.start(); + t2.start(); + t1.join(); + t2.join(); + System.out.println("Done: " + test.valueHolder[0]); + } +} + From 7c9877e50ab886eb911b7384e18aaaf8c0f46a22 Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Mon, 13 Dec 2021 15:51:29 +0000 Subject: [PATCH 2/5] Reimplement JVM SpinPause with using stub code --- src/hotspot/cpu/aarch64/spin_wait_aarch64.hpp | 39 ++----------------- .../cpu/aarch64/stubGenerator_aarch64.cpp | 16 ++++++++ .../cpu/aarch64/stubRoutines_aarch64.cpp | 1 + .../cpu/aarch64/stubRoutines_aarch64.hpp | 6 +++ .../cpu/aarch64/vm_version_aarch64.cpp | 8 ++-- .../cpu/aarch64/vm_version_aarch64.hpp | 4 -- .../os_cpu/linux_aarch64/os_linux_aarch64.cpp | 9 +++-- .../jtreg/runtime/Thread/TestSpinPause.java | 2 +- 8 files changed, 36 insertions(+), 49 deletions(-) diff --git a/src/hotspot/cpu/aarch64/spin_wait_aarch64.hpp b/src/hotspot/cpu/aarch64/spin_wait_aarch64.hpp index c6c4f5cd930cd..4edce2642e9ff 100644 --- a/src/hotspot/cpu/aarch64/spin_wait_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/spin_wait_aarch64.hpp @@ -25,14 +25,7 @@ #ifndef CPU_AARCH64_SPIN_WAIT_AARCH64_HPP #define CPU_AARCH64_SPIN_WAIT_AARCH64_HPP -// SpinWait provides a description for implementations of spin wait/pause. -// The description includes: -// - what an instruction should be used by an implementation. -// - how many of the instructions. -// - a runner which can execute the requested number of instructions. -// -// Creation of SpinWait is controlled by VM_Version. -class SpinWait final { +class SpinWait { public: enum Inst { NONE = -1, @@ -40,42 +33,16 @@ class SpinWait final { ISB, YIELD }; - using InstRunner = void (*)(int count); private: Inst _inst; int _count; - InstRunner _inst_runner; - - static void run_nop(int count) { - while (count-- > 0) { - __asm volatile("nop"); - } - } - - static void run_isb(int count) { - while (count-- > 0) { - __asm volatile("isb"); - } - } - - static void run_yield(int count) { - while (count-- > 0) { - __asm volatile("yield"); - } - } - - static void run_none(int) {} - - SpinWait(Inst inst = NONE, int count = 0, InstRunner inst_runner = run_none) : - _inst(inst), _count(count), _inst_runner(inst_runner) {} public: + SpinWait(Inst inst = NONE, int count = 0) : _inst(inst), _count(count) {} + Inst inst() const { return _inst; } int inst_count() const { return _count; } - InstRunner inst_runner() const { return _inst_runner; } - - friend class VM_Version; }; #endif // CPU_AARCH64_SPIN_WAIT_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp index fdf874b2e0d8e..dbc3c66807e39 100644 --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp @@ -6397,6 +6397,18 @@ class StubGenerator: public StubCodeGenerator { return start; } + // Support for spin waits. + address generate_spin_wait() { + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", "spin_wait"); + address start = __ pc(); + + __ spin_wait(); + __ ret(lr); + + return start; + } + #ifdef LINUX // ARMv8.1 LSE versions of the atomic stubs used by Atomic::PlatformXX. @@ -7715,6 +7727,10 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_updateBytesAdler32 = generate_updateBytesAdler32(); } + if (VM_Version::spin_wait_desc().inst() != SpinWait::NONE) { + StubRoutines::aarch64::_spin_wait = generate_spin_wait(); + } + #ifdef LINUX generate_atomic_entry_points(); diff --git a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp index 1cbc3ed21d16f..bb1a3325cea27 100644 --- a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp @@ -57,6 +57,7 @@ address StubRoutines::aarch64::_string_indexof_linear_uu = NULL; address StubRoutines::aarch64::_string_indexof_linear_ul = NULL; address StubRoutines::aarch64::_large_byte_array_inflate = NULL; address StubRoutines::aarch64::_method_entry_barrier = NULL; +address StubRoutines::aarch64::_spin_wait = NULL; bool StubRoutines::aarch64::_completed = false; /** diff --git a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp index 67536dc1d2b12..295264b7aaf22 100644 --- a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp @@ -72,6 +72,8 @@ class aarch64 { static address _method_entry_barrier; + static address _spin_wait; + static bool _completed; public: @@ -177,6 +179,10 @@ class aarch64 { return _method_entry_barrier; } + static address spin_wait() { + return _spin_wait; + } + static bool complete() { return _completed; } diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp index 6b457074501ba..e08d0b6f134b7 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp @@ -48,13 +48,13 @@ int VM_Version::_initial_sve_vector_length; SpinWait VM_Version::_spin_wait; -SpinWait VM_Version::get_spin_wait_desc() { +static SpinWait get_spin_wait_desc() { if (strcmp(OnSpinWaitInst, "nop") == 0) { - return SpinWait(SpinWait::NOP, OnSpinWaitInstCount, SpinWait::run_nop); + return SpinWait(SpinWait::NOP, OnSpinWaitInstCount); } else if (strcmp(OnSpinWaitInst, "isb") == 0) { - return SpinWait(SpinWait::ISB, OnSpinWaitInstCount, SpinWait::run_isb); + return SpinWait(SpinWait::ISB, OnSpinWaitInstCount); } else if (strcmp(OnSpinWaitInst, "yield") == 0) { - return SpinWait(SpinWait::YIELD, OnSpinWaitInstCount, SpinWait::run_yield); + return SpinWait(SpinWait::YIELD, OnSpinWaitInstCount); } else if (strcmp(OnSpinWaitInst, "none") != 0) { vm_exit_during_initialization("The options for OnSpinWaitInst are nop, isb, yield, and none", OnSpinWaitInst); } diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp index 6a9d3e2f45546..61f422bd2d38b 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp @@ -57,10 +57,6 @@ class VM_Version : public Abstract_VM_Version { static int set_and_get_current_sve_vector_length(int len); static int get_current_sve_vector_length(); - // Get SpinWait based on values of OnSpinWaitInst/OnSpinWaitInstCount options - // describing it. - static SpinWait get_spin_wait_desc(); - public: // Initialization static void initialize(); diff --git a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp index cf19bcd2da9f8..56671ea6bd3f1 100644 --- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp +++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp @@ -382,12 +382,13 @@ int os::extra_bang_size_in_bytes() { extern "C" { int SpinPause() { - const SpinWait& spin_wait = VM_Version::spin_wait_desc(); - if (spin_wait.inst() == SpinWait::NONE) { + if (VM_Version::spin_wait_desc().inst() == SpinWait::NONE) { return 0; } - SpinWait::InstRunner run_inst = spin_wait.inst_runner(); - (*run_inst)(spin_wait.inst_count()); + + using spin_wait_func_ptr_t = void (*)(); + spin_wait_func_ptr_t func = CAST_TO_FN_PTR(spin_wait_func_ptr_t, StubRoutines::aarch64::spin_wait()); + (*func)(); return 1; } diff --git a/test/hotspot/jtreg/runtime/Thread/TestSpinPause.java b/test/hotspot/jtreg/runtime/Thread/TestSpinPause.java index 91c9e53c82afb..7935d8a1a4614 100644 --- a/test/hotspot/jtreg/runtime/Thread/TestSpinPause.java +++ b/test/hotspot/jtreg/runtime/Thread/TestSpinPause.java @@ -64,7 +64,7 @@ private TestSpinPause () { } private void getSet() { - final int iterCount = 1000; + final int iterCount = 100; for (int i = 0; i < iterCount; ++i) { synchronized (valueHolder) { Integer v = valueHolder[0]; From 419508b9558f0643120cbb94a6a1a85728dbbded Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Mon, 13 Dec 2021 17:55:07 +0000 Subject: [PATCH 3/5] Check if StubRoutines::aarch64::spin_wait() is not null --- src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp index 56671ea6bd3f1..3a01ac40f13be 100644 --- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp +++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp @@ -382,12 +382,11 @@ int os::extra_bang_size_in_bytes() { extern "C" { int SpinPause() { - if (VM_Version::spin_wait_desc().inst() == SpinWait::NONE) { - return 0; - } - using spin_wait_func_ptr_t = void (*)(); spin_wait_func_ptr_t func = CAST_TO_FN_PTR(spin_wait_func_ptr_t, StubRoutines::aarch64::spin_wait()); + if (func == nullptr) { + return 0; + } (*func)(); return 1; } From 53d165801a06eb517206880448b21924fd49c16b Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Tue, 14 Dec 2021 13:12:55 +0000 Subject: [PATCH 4/5] RET only StubRoutines::aarch64::spin_wait() for SpinWait::NONE --- src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp | 8 ++++---- .../os_cpu/linux_aarch64/os_linux_aarch64.cpp | 13 ++++++++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp index dbc3c66807e39..a8b2820bb62aa 100644 --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp @@ -6403,7 +6403,9 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, "StubRoutines", "spin_wait"); address start = __ pc(); - __ spin_wait(); + if (VM_Version::spin_wait_desc().inst() != SpinWait::NONE) { + __ spin_wait(); + } __ ret(lr); return start; @@ -7727,9 +7729,7 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_updateBytesAdler32 = generate_updateBytesAdler32(); } - if (VM_Version::spin_wait_desc().inst() != SpinWait::NONE) { - StubRoutines::aarch64::_spin_wait = generate_spin_wait(); - } + StubRoutines::aarch64::_spin_wait = generate_spin_wait(); #ifdef LINUX diff --git a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp index 3a01ac40f13be..6b09069e09dd7 100644 --- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp +++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp @@ -384,10 +384,17 @@ extern "C" { int SpinPause() { using spin_wait_func_ptr_t = void (*)(); spin_wait_func_ptr_t func = CAST_TO_FN_PTR(spin_wait_func_ptr_t, StubRoutines::aarch64::spin_wait()); - if (func == nullptr) { - return 0; - } + assert(func != nullptr, "StubRoutines::aarch64::spin_wait must not be null."); (*func)(); + // If StubRoutines::aarch64::spin_wait consists of only a RET, + // SpinPause can be considered as implemented. There will be a sequence + // of instructions for: + // - call of SpinPause + // - load of StubRoutines::aarch64::spin_wait stub pointer + // - indirect call of the stub + // - return from the stub + // - return from SpinPause + // So '1' always is returned. return 1; } From 08e8ce4d6c876bc71e4bb2def90a2175e4c28bbd Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Tue, 14 Dec 2021 15:55:38 +0000 Subject: [PATCH 5/5] Remove redundant check and guarantee non-null spin_wait --- src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp | 4 +--- src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp | 5 ++++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp index a8b2820bb62aa..e946f3be9703d 100644 --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp @@ -6403,9 +6403,7 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, "StubRoutines", "spin_wait"); address start = __ pc(); - if (VM_Version::spin_wait_desc().inst() != SpinWait::NONE) { - __ spin_wait(); - } + __ spin_wait(); __ ret(lr); return start; diff --git a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp index bb1a3325cea27..9e16a1f9f8812 100644 --- a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp @@ -57,7 +57,10 @@ address StubRoutines::aarch64::_string_indexof_linear_uu = NULL; address StubRoutines::aarch64::_string_indexof_linear_ul = NULL; address StubRoutines::aarch64::_large_byte_array_inflate = NULL; address StubRoutines::aarch64::_method_entry_barrier = NULL; -address StubRoutines::aarch64::_spin_wait = NULL; + +static void empty_spin_wait() { } +address StubRoutines::aarch64::_spin_wait = CAST_FROM_FN_PTR(address, empty_spin_wait); + bool StubRoutines::aarch64::_completed = false; /**