8278241: Implement JVM SpinPause on linux-aarch64
Reviewed-by: aph, phh
This commit is contained in:
parent
fcebe65ce9
commit
bcb79fd012
src/hotspot
cpu/aarch64
os_cpu/linux_aarch64
test/hotspot/jtreg/runtime/Thread
@ -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,8 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubRoutines::_updateBytesAdler32 = generate_updateBytesAdler32();
|
||||
}
|
||||
|
||||
StubRoutines::aarch64::_spin_wait = generate_spin_wait();
|
||||
|
||||
#ifdef LINUX
|
||||
|
||||
generate_atomic_entry_points();
|
||||
|
@ -57,6 +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;
|
||||
|
||||
static void empty_spin_wait() { }
|
||||
address StubRoutines::aarch64::_spin_wait = CAST_FROM_FN_PTR(address, empty_spin_wait);
|
||||
|
||||
bool StubRoutines::aarch64::_completed = false;
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -382,7 +382,20 @@ int os::extra_bang_size_in_bytes() {
|
||||
|
||||
extern "C" {
|
||||
int SpinPause() {
|
||||
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());
|
||||
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;
|
||||
}
|
||||
|
||||
void _Copy_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
|
||||
|
87
test/hotspot/jtreg/runtime/Thread/TestSpinPause.java
Normal file
87
test/hotspot/jtreg/runtime/Thread/TestSpinPause.java
Normal file
@ -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 = 100;
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user