-
Notifications
You must be signed in to change notification settings - Fork 6.1k
8362193: Re-work MacOS/AArch64 SpinPause to handle SB #26387
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
…in-wait insns range checks
👋 Welcome back eastigeevich! A progress list of the required criteria for merging this PR into |
❗ This change is not yet ready to be integrated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, I think it is not very reasonable to pull things into shared parts, when that deviates significantly from the common Hotspot way of handling things. I don't think it even saves us any duplication to move implementations to spin_wait_aarch64.(inline.)pp
? So I suggest we don't.
* @requires vm.flagless | ||
* @requires os.arch=="aarch64" | ||
* @requires vm.cpu.features ~= ".*sb.*" | ||
* @run main/native GTestWrapper --gtest_filter=SpinPause* -XX:+UnlockDiagnosticVMOptions -XX:OnSpinWaitInst=sb |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This configuration is for @requires vm.cpu.features ~= ".*sb.*"
, correct?
If so, you can put this entire @test
block in the TestSpinPauseAArch64.java
, then jtreg would just execute them as subtests. Here is an inspiration: https://github.com/openjdk/jdk/blob/master/test/hotspot/jtreg/gc/shenandoah/TestAllocObjects.java
* questions. | ||
*/ | ||
|
||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/** | |
/* |
@@ -114,10 +115,11 @@ define_pd_global(intx, InlineSmallCode, 1000); | |||
"Use prfm hint with specified distance in compiled code." \ | |||
"Value -1 means off.") \ | |||
range(-1, 4096) \ | |||
product(ccstr, OnSpinWaitInst, "yield", DIAGNOSTIC, \ | |||
product(ccstr, OnSpinWaitInst, DEFAULT_SPIN_WAIT_INST, DIAGNOSTIC, \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is somewhat weird to introduce references to macros here. At some point, this might lead to interesting include circularities, as I think globals.*
are supposed to be at the leaves of include trees. Other options do not do this, see for example UseBranchProtection
below. So, keep this part intact?
Do I understand you correctly we should not have |
Yes. I don't see a benefit for them? Collecting everything related to spin wait implementation is not worth it, IMO. We have duplication by asm-stubs, macroassembler, c1_assembler, c2.ad rules for the arch-specific code already. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More reviews.
I think the PR drifted from my initial "oh, just assert range problem" to "Re-work MacOS/AArch64 spin-waits to handle SB". Rewrite the JBS/PR title accordingly?
*/ | ||
|
||
/* | ||
* @test TestSpinPauseAArch64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A common way to tag the tests:
@test id=default
I assume all these are supported in ARMv8.0 (default? baseline?) profile. That's why I put default
. Put something else if that is incorrect.
Same for the second @test
block.
return SpinWait(SpinWait::SB, OnSpinWaitInstCount); | ||
} else if (strcmp(OnSpinWaitInst, "none") != 0) { | ||
vm_exit_during_initialization("The options for OnSpinWaitInst are nop, isb, yield, sb, and none", OnSpinWaitInst); | ||
if (!SpinWait::supports(OnSpinWaitInst)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this is not about the actual spin-wait hints support, correct? This only checks the option string is in expected domain? A common way to deal with this is to use constraint functions, see for example:
product(ccstr, AOTCache, nullptr, \
"Cache for improving start up and warm up") \
constraint(AOTCacheConstraintFunc, AtParse) \
\
assert(inst_id == 0 || is_power_of_2(inst_id), "Values of SpinWait::Inst must be 0 or power of 2"); | ||
assert(inst_id != SpinWait::SB || VM_Version::supports_sb(), "current CPU does not support SB instruction"); | ||
if (inst_id > SpinWait::NOP) { | ||
warining("Unsupported type of SpinWait::Inst: %d", inst_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning
Also, I think we want to minimize the amount of code we actually execute in SpinPause
, since it likely sits in the hot loop. So checking this here is probably counter-productive.
Background
With JDK-8359435 "AArch64: add support for SB instruction to MacroAssembler::spin_wait" we have an option to use the speculation barrier (SB) instruction for
j.l.Thread::onSpinWait
andSpinPause
. On Linux AArch64SpinPause
uses a stub which is generated withMacroAssembler::spin_wait
.j.l.Thread::onSpinWait
uses it as well. As a result tests forj.l.Thread::onSpinWait
, e.g.compiler/onSpinWait/TestOnSpinWaitAArch64.java
, cover bothj.l.Thread::onSpinWait
andSpinPause
. Also we don't need to updateSpinPause
when we add support for a new instruction toMacroAssembler::spin_wait
.On Mac AArch64
SpinPause
does not use the generated stub to avoid a costly call toos::current_thread_enable_wx()
. It uses inline assembly instead. As a result we haveSpinWait
implementation details leaking intoSpinPause
. Besides asserts there are no tests covering Mac implementation ofSpinPause
. Testing on Apple M3 Pro showed thatcompiler/onSpinWait/TestOnSpinWaitAArch64.java
could not reliably trigger those asserts.ArchiveWorkers::run_task_multi
did not invokespin.wait()
. The inline assembly in Mac AArch64SpinPause
has another issue. It uses a jump table. An offset in the table is calculated based on the value ofenum SpinWait::Inst
. When a new valueSB
was added the offset became out of bounds. The jump goes out of the assembly code.Summary of changes
SpinPause
not to use a jump table.SpinWait::supports()
andSpinWait::from_name()
methods to validate and convert instruction names into corresponding enum values.SpinWait::Inst
enum to use bit flags for simplified assembly testing and added a constructor to initializeSpinWait
using instruction names.src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
: Added an assertion to ensure thesb
instruction is supported by the CPU before generation.OnSpinWaitInst
flag description to clarify valid values and added runtime constraints.SpinPause
.SpinPause
with various instructions, including a separate test for thesb
instruction if supported by the CPU.Testing results: fastdebug, release
test/hotspot/jtreg/gtest/TestSpinPauseAArch64.java
: Passedtest/hotspot/jtreg/compiler/onSpinWait
: Passedtest/hotspot/jtreg/gtest/TestSpinPauseAArch64.java
: TBDtest/hotspot/jtreg/compiler/onSpinWait
: TBDtest/hotspot/jtreg/gtest/TestSpinPauseAArch64.java
: TBDtest/hotspot/jtreg/compiler/onSpinWait
: TBDProgress
Issue
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/26387/head:pull/26387
$ git checkout pull/26387
Update a local copy of the PR:
$ git checkout pull/26387
$ git pull https://git.openjdk.org/jdk.git pull/26387/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 26387
View PR using the GUI difftool:
$ git pr show -t 26387
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/26387.diff