Skip to content

Commit

Permalink
8186670: Implement _onSpinWait() intrinsic for AArch64
Browse files Browse the repository at this point in the history
Backport-of: 6954b98f8faf29b6c2d13687a7a94e83302bdd85
  • Loading branch information
eastig authored and Paul Hohensee committed Jan 18, 2022
1 parent 761e298 commit c7329f3
Show file tree
Hide file tree
Showing 13 changed files with 766 additions and 2 deletions.
14 changes: 14 additions & 0 deletions src/hotspot/cpu/aarch64/aarch64.ad
Original file line number Diff line number Diff line change
Expand Up @@ -2373,6 +2373,8 @@ const bool Matcher::match_rule_supported(int opcode) {

bool ret_value = true;
switch (opcode) {
case Op_OnSpinWait:
return VM_Version::supports_on_spin_wait();
case Op_CacheWB:
case Op_CacheWBPreSync:
case Op_CacheWBPostSync:
Expand Down Expand Up @@ -14321,6 +14323,18 @@ instruct signumF_reg(vRegF dst, vRegF src, vRegF zero, vRegF one) %{
ins_pipe(fp_uop_d);
%}

instruct onspinwait() %{
match(OnSpinWait);
ins_cost(INSN_COST);

format %{ "onspinwait" %}

ins_encode %{
__ spin_wait();
%}
ins_pipe(pipe_class_empty);
%}

// ============================================================================
// Logical Instructions

Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2988,7 +2988,7 @@ void LIR_Assembler::membar_loadstore() { __ membar(MacroAssembler::LoadStore); }
void LIR_Assembler::membar_storeload() { __ membar(MacroAssembler::StoreLoad); }

void LIR_Assembler::on_spin_wait() {
Unimplemented();
__ spin_wait();
}

void LIR_Assembler::get_thread(LIR_Opr result_reg) {
Expand Down
10 changes: 9 additions & 1 deletion src/hotspot/cpu/aarch64/globals_aarch64.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,15 @@ define_pd_global(intx, InlineSmallCode, 1000);
product(int, SoftwarePrefetchHintDistance, -1, \
"Use prfm hint with specified distance in compiled code." \
"Value -1 means off.") \
range(-1, 4096)
range(-1, 4096) \
product(ccstr, OnSpinWaitInst, "none", DIAGNOSTIC, \
"The instruction to use to implement " \
"java.lang.Thread.onSpinWait()." \
"Options: none, nop, isb, yield.") \
product(uint, OnSpinWaitInstCount, 1, DIAGNOSTIC, \
"The number of OnSpinWaitInst instructions to generate." \
"It cannot be used with OnSpinWaitInst=none.") \
range(1, 99)

// end of ARCH_FLAGS

Expand Down
18 changes: 18 additions & 0 deletions src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5352,3 +5352,21 @@ void MacroAssembler::verify_cross_modify_fence_not_required() {
}
}
#endif

void MacroAssembler::spin_wait() {
for (int i = 0; i < VM_Version::spin_wait_desc().inst_count(); ++i) {
switch (VM_Version::spin_wait_desc().inst()) {
case SpinWait::NOP:
nop();
break;
case SpinWait::ISB:
isb();
break;
case SpinWait::YIELD:
yield();
break;
default:
ShouldNotReachHere();
}
}
}
3 changes: 3 additions & 0 deletions src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1410,6 +1410,9 @@ class MacroAssembler: public Assembler {
void cache_wb(Address line);
void cache_wbsync(bool is_pre);

// Code for java.lang.Thread::onSpinWait() intrinsic.
void spin_wait();

private:
// Check the current thread doesn't need a cross modify fence.
void verify_cross_modify_fence_not_required() PRODUCT_RETURN;
Expand Down
48 changes: 48 additions & 0 deletions src/hotspot/cpu/aarch64/spin_wait_aarch64.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2021, 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.
*
*/

#ifndef CPU_AARCH64_SPIN_WAIT_AARCH64_HPP
#define CPU_AARCH64_SPIN_WAIT_AARCH64_HPP

class SpinWait {
public:
enum Inst {
NONE = -1,
NOP,
ISB,
YIELD
};

private:
Inst _inst;
int _count;

public:
SpinWait(Inst inst = NONE, int count = 0) : _inst(inst), _count(count) {}

Inst inst() const { return _inst; }
int inst_count() const { return _count; }
};

#endif // CPU_AARCH64_SPIN_WAIT_AARCH64_HPP
22 changes: 22 additions & 0 deletions src/hotspot/cpu/aarch64/vm_version_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,26 @@ int VM_Version::_dcache_line_size;
int VM_Version::_icache_line_size;
int VM_Version::_initial_sve_vector_length;

SpinWait VM_Version::_spin_wait;

static SpinWait get_spin_wait_desc() {
if (strcmp(OnSpinWaitInst, "nop") == 0) {
return SpinWait(SpinWait::NOP, OnSpinWaitInstCount);
} else if (strcmp(OnSpinWaitInst, "isb") == 0) {
return SpinWait(SpinWait::ISB, OnSpinWaitInstCount);
} else if (strcmp(OnSpinWaitInst, "yield") == 0) {
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);
}

if (!FLAG_IS_DEFAULT(OnSpinWaitInstCount) && OnSpinWaitInstCount > 0) {
vm_exit_during_initialization("OnSpinWaitInstCount cannot be used for OnSpinWaitInst 'none'");
}

return SpinWait{};
}

void VM_Version::initialize() {
_supports_cx8 = true;
_supports_atomic_getset4 = true;
Expand Down Expand Up @@ -450,5 +470,7 @@ void VM_Version::initialize() {
}
#endif

_spin_wait = get_spin_wait_desc();

UNSUPPORTED_OPTION(CriticalJNINatives);
}
7 changes: 7 additions & 0 deletions src/hotspot/cpu/aarch64/vm_version_aarch64.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#ifndef CPU_AARCH64_VM_VERSION_AARCH64_HPP
#define CPU_AARCH64_VM_VERSION_AARCH64_HPP

#include "spin_wait_aarch64.hpp"
#include "runtime/abstract_vm_version.hpp"
#include "utilities/sizes.hpp"

Expand All @@ -45,6 +46,8 @@ class VM_Version : public Abstract_VM_Version {
static int _icache_line_size;
static int _initial_sve_vector_length;

static SpinWait _spin_wait;

// Read additional info using OS-specific interfaces
static void get_os_cpu_info();

Expand Down Expand Up @@ -142,6 +145,10 @@ class VM_Version : public Abstract_VM_Version {

static void get_compatible_board(char *buf, int buflen);

static const SpinWait& spin_wait_desc() { return _spin_wait; }

static bool supports_on_spin_wait() { return _spin_wait.inst() != SpinWait::NONE; }

#ifdef __APPLE__
// Is the CPU running emulated (for example macOS Rosetta running x86_64 code on M1 ARM (aarch64)
static bool is_cpu_emulated();
Expand Down
Loading

1 comment on commit c7329f3

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.