Skip to content
Permalink
Browse files
8186670: Implement _onSpinWait() intrinsic for AArch64
Reviewed-by: phh
Backport-of: 6954b98f8faf29b6c2d13687a7a94e83302bdd85
  • Loading branch information
eastig authored and Paul Hohensee committed Mar 10, 2022
1 parent b98036f commit e972e77af38d4cd4c1e6e3e408b3a5c2909aaa46
Showing 13 changed files with 765 additions and 2 deletions.
@@ -2060,6 +2060,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:
@@ -13227,6 +13229,18 @@ instruct roundD_reg(vRegD dst, vRegD src, immI rmode) %{
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

@@ -2974,7 +2974,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) {
@@ -108,6 +108,14 @@ 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) \
diagnostic(ccstr, OnSpinWaitInst, "none", \
"The instruction to use to implement " \
"java.lang.Thread.onSpinWait()." \
"Options: none, nop, isb, yield.") \
diagnostic(uint, OnSpinWaitInstCount, 1, \
"The number of OnSpinWaitInst instructions to generate." \
"It cannot be used with OnSpinWaitInst=none.") \
range(1, 99)

#endif // CPU_AARCH64_GLOBALS_AARCH64_HPP
@@ -5265,3 +5265,21 @@ void MacroAssembler::cache_wbsync(bool is_pre) {
membar(Assembler::AnyAny);
}
}

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();
}
}
}
@@ -1368,6 +1368,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();
};

#ifdef ASSERT
@@ -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
@@ -74,6 +74,26 @@ VM_Version::PsrInfo VM_Version::_psr_info = { 0, };
static BufferBlob* stub_blob;
static const int stub_size = 550;

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();
}

extern "C" {
typedef void (*getPsrInfo_stub_t)(void*);
}
@@ -478,5 +498,7 @@ void VM_Version::initialize() {

get_processor_features();

_spin_wait = get_spin_wait_desc();

UNSUPPORTED_OPTION(CriticalJNINatives);
}
@@ -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 "runtime/globals_extension.hpp"
#include "utilities/sizes.hpp"
@@ -46,6 +47,9 @@ class VM_Version : public Abstract_VM_Version {
uint32_t ctr_el0;
};
static PsrInfo _psr_info;

static SpinWait _spin_wait;

static void get_processor_features();

public:
@@ -125,6 +129,10 @@ class VM_Version : public Abstract_VM_Version {
return (1 << ((_psr_info.ctr_el0 >> 16) & 0x0f)) * 4;
}
static bool supports_fast_class_init_checks() { return true; }

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

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

#endif // CPU_AARCH64_VM_VERSION_AARCH64_HPP

1 comment on commit e972e77

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on e972e77 Mar 10, 2022

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.