8329141: Obsolete RTM flags and code

Reviewed-by: chagedorn
This commit is contained in:
Vladimir Kozlov 2024-06-10 17:58:22 +00:00
parent 13642cb4b8
commit 9691153755
99 changed files with 64 additions and 6408 deletions
src
test/hotspot/jtreg
ProblemList.txtTEST.groups
compiler
rtm
testlibrary/rtm

@ -172,310 +172,6 @@ inline Assembler::AvxVectorLen C2_MacroAssembler::vector_length_encoding(int vle
}
}
#if INCLUDE_RTM_OPT
// Update rtm_counters based on abort status
// input: abort_status
// rtm_counters (RTMLockingCounters*)
// flags are killed
void C2_MacroAssembler::rtm_counters_update(Register abort_status, Register rtm_counters) {
atomic_incptr(Address(rtm_counters, RTMLockingCounters::abort_count_offset()));
if (PrintPreciseRTMLockingStatistics) {
for (int i = 0; i < RTMLockingCounters::ABORT_STATUS_LIMIT; i++) {
Label check_abort;
testl(abort_status, (1<<i));
jccb(Assembler::equal, check_abort);
atomic_incptr(Address(rtm_counters, RTMLockingCounters::abortX_count_offset() + (i * sizeof(uintx))));
bind(check_abort);
}
}
}
// Branch if (random & (count-1) != 0), count is 2^n
// tmp, scr and flags are killed
void C2_MacroAssembler::branch_on_random_using_rdtsc(Register tmp, Register scr, int count, Label& brLabel) {
assert(tmp == rax, "");
assert(scr == rdx, "");
rdtsc(); // modifies EDX:EAX
andptr(tmp, count-1);
jccb(Assembler::notZero, brLabel);
}
// Perform abort ratio calculation, set no_rtm bit if high ratio
// input: rtm_counters_Reg (RTMLockingCounters* address)
// tmpReg, rtm_counters_Reg and flags are killed
void C2_MacroAssembler::rtm_abort_ratio_calculation(Register tmpReg,
Register rtm_counters_Reg,
RTMLockingCounters* rtm_counters,
Metadata* method_data) {
Label L_done, L_check_always_rtm1, L_check_always_rtm2;
if (RTMLockingCalculationDelay > 0) {
// Delay calculation
movptr(tmpReg, ExternalAddress((address) RTMLockingCounters::rtm_calculation_flag_addr()));
testptr(tmpReg, tmpReg);
jccb(Assembler::equal, L_done);
}
// Abort ratio calculation only if abort_count > RTMAbortThreshold
// Aborted transactions = abort_count * 100
// All transactions = total_count * RTMTotalCountIncrRate
// Set no_rtm bit if (Aborted transactions >= All transactions * RTMAbortRatio)
movptr(tmpReg, Address(rtm_counters_Reg, RTMLockingCounters::abort_count_offset()));
cmpptr(tmpReg, RTMAbortThreshold);
jccb(Assembler::below, L_check_always_rtm2);
imulptr(tmpReg, tmpReg, 100);
Register scrReg = rtm_counters_Reg;
movptr(scrReg, Address(rtm_counters_Reg, RTMLockingCounters::total_count_offset()));
imulptr(scrReg, scrReg, RTMTotalCountIncrRate);
imulptr(scrReg, scrReg, RTMAbortRatio);
cmpptr(tmpReg, scrReg);
jccb(Assembler::below, L_check_always_rtm1);
if (method_data != nullptr) {
// set rtm_state to "no rtm" in MDO
mov_metadata(tmpReg, method_data);
lock();
orl(Address(tmpReg, MethodData::rtm_state_offset()), NoRTM);
}
jmpb(L_done);
bind(L_check_always_rtm1);
// Reload RTMLockingCounters* address
lea(rtm_counters_Reg, ExternalAddress((address)rtm_counters));
bind(L_check_always_rtm2);
movptr(tmpReg, Address(rtm_counters_Reg, RTMLockingCounters::total_count_offset()));
cmpptr(tmpReg, RTMLockingThreshold / RTMTotalCountIncrRate);
jccb(Assembler::below, L_done);
if (method_data != nullptr) {
// set rtm_state to "always rtm" in MDO
mov_metadata(tmpReg, method_data);
lock();
orl(Address(tmpReg, MethodData::rtm_state_offset()), UseRTM);
}
bind(L_done);
}
// Update counters and perform abort ratio calculation
// input: abort_status_Reg
// rtm_counters_Reg, flags are killed
void C2_MacroAssembler::rtm_profiling(Register abort_status_Reg,
Register rtm_counters_Reg,
RTMLockingCounters* rtm_counters,
Metadata* method_data,
bool profile_rtm) {
assert(rtm_counters != nullptr, "should not be null when profiling RTM");
// update rtm counters based on rax value at abort
// reads abort_status_Reg, updates flags
lea(rtm_counters_Reg, ExternalAddress((address)rtm_counters));
rtm_counters_update(abort_status_Reg, rtm_counters_Reg);
if (profile_rtm) {
// Save abort status because abort_status_Reg is used by following code.
if (RTMRetryCount > 0) {
push(abort_status_Reg);
}
assert(rtm_counters != nullptr, "should not be null when profiling RTM");
rtm_abort_ratio_calculation(abort_status_Reg, rtm_counters_Reg, rtm_counters, method_data);
// restore abort status
if (RTMRetryCount > 0) {
pop(abort_status_Reg);
}
}
}
// Retry on abort if abort's status is 0x6: can retry (0x2) | memory conflict (0x4)
// inputs: retry_count_Reg
// : abort_status_Reg
// output: retry_count_Reg decremented by 1
// flags are killed
void C2_MacroAssembler::rtm_retry_lock_on_abort(Register retry_count_Reg, Register abort_status_Reg, Label& retryLabel) {
Label doneRetry;
assert(abort_status_Reg == rax, "");
// The abort reason bits are in eax (see all states in rtmLocking.hpp)
// 0x6 = conflict on which we can retry (0x2) | memory conflict (0x4)
// if reason is in 0x6 and retry count != 0 then retry
andptr(abort_status_Reg, 0x6);
jccb(Assembler::zero, doneRetry);
testl(retry_count_Reg, retry_count_Reg);
jccb(Assembler::zero, doneRetry);
pause();
decrementl(retry_count_Reg);
jmp(retryLabel);
bind(doneRetry);
}
// Spin and retry if lock is busy,
// inputs: box_Reg (monitor address)
// : retry_count_Reg
// output: retry_count_Reg decremented by 1
// : clear z flag if retry count exceeded
// tmp_Reg, scr_Reg, flags are killed
void C2_MacroAssembler::rtm_retry_lock_on_busy(Register retry_count_Reg, Register box_Reg,
Register tmp_Reg, Register scr_Reg, Label& retryLabel) {
Label SpinLoop, SpinExit, doneRetry;
int owner_offset = OM_OFFSET_NO_MONITOR_VALUE_TAG(owner);
testl(retry_count_Reg, retry_count_Reg);
jccb(Assembler::zero, doneRetry);
decrementl(retry_count_Reg);
movptr(scr_Reg, RTMSpinLoopCount);
bind(SpinLoop);
pause();
decrementl(scr_Reg);
jccb(Assembler::lessEqual, SpinExit);
movptr(tmp_Reg, Address(box_Reg, owner_offset));
testptr(tmp_Reg, tmp_Reg);
jccb(Assembler::notZero, SpinLoop);
bind(SpinExit);
jmp(retryLabel);
bind(doneRetry);
incrementl(retry_count_Reg); // clear z flag
}
// Use RTM for normal stack locks
// Input: objReg (object to lock)
void C2_MacroAssembler::rtm_stack_locking(Register objReg, Register tmpReg, Register scrReg,
Register retry_on_abort_count_Reg,
RTMLockingCounters* stack_rtm_counters,
Metadata* method_data, bool profile_rtm,
Label& DONE_LABEL, Label& IsInflated) {
assert(UseRTMForStackLocks, "why call this otherwise?");
assert(tmpReg == rax, "");
assert(scrReg == rdx, "");
Label L_rtm_retry, L_decrement_retry, L_on_abort;
if (RTMRetryCount > 0) {
movl(retry_on_abort_count_Reg, RTMRetryCount); // Retry on abort
bind(L_rtm_retry);
}
movptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes()));
testptr(tmpReg, markWord::monitor_value); // inflated vs stack-locked|neutral
jcc(Assembler::notZero, IsInflated);
if (PrintPreciseRTMLockingStatistics || profile_rtm) {
Label L_noincrement;
if (RTMTotalCountIncrRate > 1) {
// tmpReg, scrReg and flags are killed
branch_on_random_using_rdtsc(tmpReg, scrReg, RTMTotalCountIncrRate, L_noincrement);
}
assert(stack_rtm_counters != nullptr, "should not be null when profiling RTM");
atomic_incptr(ExternalAddress((address)stack_rtm_counters->total_count_addr()), scrReg);
bind(L_noincrement);
}
xbegin(L_on_abort);
movptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes())); // fetch markword
andptr(tmpReg, markWord::lock_mask_in_place); // look at 2 lock bits
cmpptr(tmpReg, markWord::unlocked_value); // bits = 01 unlocked
jcc(Assembler::equal, DONE_LABEL); // all done if unlocked
Register abort_status_Reg = tmpReg; // status of abort is stored in RAX
if (UseRTMXendForLockBusy) {
xend();
movptr(abort_status_Reg, 0x2); // Set the abort status to 2 (so we can retry)
jmp(L_decrement_retry);
}
else {
xabort(0);
}
bind(L_on_abort);
if (PrintPreciseRTMLockingStatistics || profile_rtm) {
rtm_profiling(abort_status_Reg, scrReg, stack_rtm_counters, method_data, profile_rtm);
}
bind(L_decrement_retry);
if (RTMRetryCount > 0) {
// retry on lock abort if abort status is 'can retry' (0x2) or 'memory conflict' (0x4)
rtm_retry_lock_on_abort(retry_on_abort_count_Reg, abort_status_Reg, L_rtm_retry);
}
}
// Use RTM for inflating locks
// inputs: objReg (object to lock)
// boxReg (on-stack box address (displaced header location) - KILLED)
// tmpReg (ObjectMonitor address + markWord::monitor_value)
void C2_MacroAssembler::rtm_inflated_locking(Register objReg, Register boxReg, Register tmpReg,
Register scrReg, Register retry_on_busy_count_Reg,
Register retry_on_abort_count_Reg,
RTMLockingCounters* rtm_counters,
Metadata* method_data, bool profile_rtm,
Label& DONE_LABEL) {
assert(UseRTMLocking, "why call this otherwise?");
assert(tmpReg == rax, "");
assert(scrReg == rdx, "");
Label L_rtm_retry, L_decrement_retry, L_on_abort;
int owner_offset = OM_OFFSET_NO_MONITOR_VALUE_TAG(owner);
movptr(Address(boxReg, 0), checked_cast<int32_t>(markWord::unused_mark().value()));
movptr(boxReg, tmpReg); // Save ObjectMonitor address
if (RTMRetryCount > 0) {
movl(retry_on_busy_count_Reg, RTMRetryCount); // Retry on lock busy
movl(retry_on_abort_count_Reg, RTMRetryCount); // Retry on abort
bind(L_rtm_retry);
}
if (PrintPreciseRTMLockingStatistics || profile_rtm) {
Label L_noincrement;
if (RTMTotalCountIncrRate > 1) {
// tmpReg, scrReg and flags are killed
branch_on_random_using_rdtsc(tmpReg, scrReg, RTMTotalCountIncrRate, L_noincrement);
}
assert(rtm_counters != nullptr, "should not be null when profiling RTM");
atomic_incptr(ExternalAddress((address)rtm_counters->total_count_addr()), scrReg);
bind(L_noincrement);
}
xbegin(L_on_abort);
movptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes()));
movptr(tmpReg, Address(tmpReg, owner_offset));
testptr(tmpReg, tmpReg);
jcc(Assembler::zero, DONE_LABEL);
if (UseRTMXendForLockBusy) {
xend();
jmp(L_decrement_retry);
}
else {
xabort(0);
}
bind(L_on_abort);
Register abort_status_Reg = tmpReg; // status of abort is stored in RAX
if (PrintPreciseRTMLockingStatistics || profile_rtm) {
rtm_profiling(abort_status_Reg, scrReg, rtm_counters, method_data, profile_rtm);
}
if (RTMRetryCount > 0) {
// retry on lock abort if abort status is 'can retry' (0x2) or 'memory conflict' (0x4)
rtm_retry_lock_on_abort(retry_on_abort_count_Reg, abort_status_Reg, L_rtm_retry);
}
movptr(tmpReg, Address(boxReg, owner_offset)) ;
testptr(tmpReg, tmpReg) ;
jccb(Assembler::notZero, L_decrement_retry) ;
// Appears unlocked - try to swing _owner from null to non-null.
// Invariant: tmpReg == 0. tmpReg is EAX which is the implicit cmpxchg comparand.
#ifdef _LP64
Register threadReg = r15_thread;
#else
get_thread(scrReg);
Register threadReg = scrReg;
#endif
lock();
cmpxchgptr(threadReg, Address(boxReg, owner_offset)); // Updates tmpReg
if (RTMRetryCount > 0) {
// success done else retry
jccb(Assembler::equal, DONE_LABEL) ;
bind(L_decrement_retry);
// Spin and retry if lock is busy.
rtm_retry_lock_on_busy(retry_on_busy_count_Reg, boxReg, tmpReg, scrReg, L_rtm_retry);
}
else {
bind(L_decrement_retry);
}
}
#endif // INCLUDE_RTM_OPT
// fast_lock and fast_unlock used by C2
// Because the transitions from emitted code to the runtime
@ -554,21 +250,13 @@ void C2_MacroAssembler::rtm_inflated_locking(Register objReg, Register boxReg, R
// scr: tmp -- KILLED
void C2_MacroAssembler::fast_lock(Register objReg, Register boxReg, Register tmpReg,
Register scrReg, Register cx1Reg, Register cx2Reg, Register thread,
RTMLockingCounters* rtm_counters,
RTMLockingCounters* stack_rtm_counters,
Metadata* method_data,
bool use_rtm, bool profile_rtm) {
Metadata* method_data) {
assert(LockingMode != LM_LIGHTWEIGHT, "lightweight locking should use fast_lock_lightweight");
// Ensure the register assignments are disjoint
assert(tmpReg == rax, "");
if (use_rtm) {
assert_different_registers(objReg, boxReg, tmpReg, scrReg, cx1Reg, cx2Reg);
} else {
assert(cx1Reg == noreg, "");
assert(cx2Reg == noreg, "");
assert_different_registers(objReg, boxReg, tmpReg, scrReg);
}
assert(cx1Reg == noreg, "");
assert(cx2Reg == noreg, "");
assert_different_registers(objReg, boxReg, tmpReg, scrReg);
// Possible cases that we'll encounter in fast_lock
// ------------------------------------------------
@ -594,15 +282,6 @@ void C2_MacroAssembler::fast_lock(Register objReg, Register boxReg, Register tmp
jcc(Assembler::notZero, DONE_LABEL);
}
#if INCLUDE_RTM_OPT
if (UseRTMForStackLocks && use_rtm) {
assert(LockingMode != LM_MONITOR, "LockingMode == 0 (LM_MONITOR) and +UseRTMForStackLocks are mutually exclusive");
rtm_stack_locking(objReg, tmpReg, scrReg, cx2Reg,
stack_rtm_counters, method_data, profile_rtm,
DONE_LABEL, IsInflated);
}
#endif // INCLUDE_RTM_OPT
movptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes())); // [FETCH]
testptr(tmpReg, markWord::monitor_value); // inflated vs stack-locked|neutral
jcc(Assembler::notZero, IsInflated);
@ -632,14 +311,6 @@ void C2_MacroAssembler::fast_lock(Register objReg, Register boxReg, Register tmp
bind(IsInflated);
// The object is inflated. tmpReg contains pointer to ObjectMonitor* + markWord::monitor_value
#if INCLUDE_RTM_OPT
// Use the same RTM locking code in 32- and 64-bit VM.
if (use_rtm) {
rtm_inflated_locking(objReg, boxReg, tmpReg, scrReg, cx1Reg, cx2Reg,
rtm_counters, method_data, profile_rtm, DONE_LABEL);
} else {
#endif // INCLUDE_RTM_OPT
#ifndef _LP64
// The object is inflated.
@ -700,9 +371,6 @@ void C2_MacroAssembler::fast_lock(Register objReg, Register boxReg, Register tmp
incq(Address(scrReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)));
xorq(rax, rax); // Set ZF = 1 (success) for recursive lock, denoting locking success
#endif // _LP64
#if INCLUDE_RTM_OPT
} // use_rtm()
#endif
bind(DONE_LABEL);
// ZFlag == 1 count in fast path
@ -755,27 +423,13 @@ void C2_MacroAssembler::fast_lock(Register objReg, Register boxReg, Register tmp
// A perfectly viable alternative is to elide the owner check except when
// Xcheck:jni is enabled.
void C2_MacroAssembler::fast_unlock(Register objReg, Register boxReg, Register tmpReg, bool use_rtm) {
void C2_MacroAssembler::fast_unlock(Register objReg, Register boxReg, Register tmpReg) {
assert(LockingMode != LM_LIGHTWEIGHT, "lightweight locking should use fast_unlock_lightweight");
assert(boxReg == rax, "");
assert_different_registers(objReg, boxReg, tmpReg);
Label DONE_LABEL, Stacked, COUNT, NO_COUNT;
#if INCLUDE_RTM_OPT
if (UseRTMForStackLocks && use_rtm) {
assert(LockingMode != LM_MONITOR, "LockingMode == 0 (LM_MONITOR) and +UseRTMForStackLocks are mutually exclusive");
Label L_regular_unlock;
movptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes())); // fetch markword
andptr(tmpReg, markWord::lock_mask_in_place); // look at 2 lock bits
cmpptr(tmpReg, markWord::unlocked_value); // bits = 01 unlocked
jccb(Assembler::notEqual, L_regular_unlock); // if !HLE RegularLock
xend(); // otherwise end...
jmp(DONE_LABEL); // ... and we're done
bind(L_regular_unlock);
}
#endif
if (LockingMode == LM_LEGACY) {
cmpptr(Address(boxReg, 0), NULL_WORD); // Examine the displaced header
jcc (Assembler::zero, COUNT); // 0 indicates recursive stack-lock
@ -788,19 +442,6 @@ void C2_MacroAssembler::fast_unlock(Register objReg, Register boxReg, Register t
// It's inflated.
#if INCLUDE_RTM_OPT
if (use_rtm) {
Label L_regular_inflated_unlock;
int owner_offset = OM_OFFSET_NO_MONITOR_VALUE_TAG(owner);
movptr(boxReg, Address(tmpReg, owner_offset));
testptr(boxReg, boxReg);
jccb(Assembler::notZero, L_regular_inflated_unlock);
xend();
jmp(DONE_LABEL);
bind(L_regular_inflated_unlock);
}
#endif
// Despite our balanced locking property we still check that m->_owner == Self
// as java routines or native JNI code called by this thread might
// have released the lock.

@ -37,39 +37,13 @@ public:
// See full description in macroAssembler_x86.cpp.
void fast_lock(Register obj, Register box, Register tmp,
Register scr, Register cx1, Register cx2, Register thread,
RTMLockingCounters* rtm_counters,
RTMLockingCounters* stack_rtm_counters,
Metadata* method_data,
bool use_rtm, bool profile_rtm);
void fast_unlock(Register obj, Register box, Register tmp, bool use_rtm);
Metadata* method_data);
void fast_unlock(Register obj, Register box, Register tmp);
void fast_lock_lightweight(Register obj, Register box, Register rax_reg,
Register t, Register thread);
void fast_unlock_lightweight(Register obj, Register reg_rax, Register t, Register thread);
#if INCLUDE_RTM_OPT
void rtm_counters_update(Register abort_status, Register rtm_counters);
void branch_on_random_using_rdtsc(Register tmp, Register scr, int count, Label& brLabel);
void rtm_abort_ratio_calculation(Register tmp, Register rtm_counters_reg,
RTMLockingCounters* rtm_counters,
Metadata* method_data);
void rtm_profiling(Register abort_status_Reg, Register rtm_counters_Reg,
RTMLockingCounters* rtm_counters, Metadata* method_data, bool profile_rtm);
void rtm_retry_lock_on_abort(Register retry_count, Register abort_status, Label& retryLabel);
void rtm_retry_lock_on_busy(Register retry_count, Register box, Register tmp, Register scr, Label& retryLabel);
void rtm_stack_locking(Register obj, Register tmp, Register scr,
Register retry_on_abort_count,
RTMLockingCounters* stack_rtm_counters,
Metadata* method_data, bool profile_rtm,
Label& DONE_LABEL, Label& IsInflated);
void rtm_inflated_locking(Register obj, Register box, Register tmp,
Register scr, Register retry_on_busy_count,
Register retry_on_abort_count,
RTMLockingCounters* rtm_counters,
Metadata* method_data, bool profile_rtm,
Label& DONE_LABEL);
#endif
// Generic instructions support for use in .ad files C2 code generation
void vabsnegd(int opcode, XMMRegister dst, XMMRegister src);
void vabsnegd(int opcode, XMMRegister dst, XMMRegister src, int vector_len);

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2024, Oracle and/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
@ -52,11 +52,6 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
#endif
#if defined(COMPILER2)
// Include Restricted Transactional Memory lock eliding optimization
#define INCLUDE_RTM_OPT 1
#endif
#if defined(LINUX) || defined(__APPLE__)
#define SUPPORT_RESERVED_STACK_AREA
#endif

@ -155,51 +155,6 @@ define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong);
product(bool, UseFastStosb, false, \
"Use fast-string operation for zeroing: rep stosb") \
\
/* Use Restricted Transactional Memory for lock eliding */ \
product(bool, UseRTMLocking, false, \
"(Deprecated) Enable RTM lock eliding for inflated locks " \
"in compiled code") \
\
product(bool, UseRTMForStackLocks, false, EXPERIMENTAL, \
"Enable RTM lock eliding for stack locks in compiled code") \
\
product(bool, UseRTMDeopt, false, \
"(Deprecated) Perform deopt and recompilation based on " \
"RTM abort ratio") \
\
product(int, RTMRetryCount, 5, \
"(Deprecated) Number of RTM retries on lock abort or busy") \
range(0, max_jint) \
\
product(int, RTMSpinLoopCount, 100, EXPERIMENTAL, \
"Spin count for lock to become free before RTM retry") \
range(0, max_jint) \
\
product(int, RTMAbortThreshold, 1000, EXPERIMENTAL, \
"Calculate abort ratio after this number of aborts") \
range(0, max_jint) \
\
product(int, RTMLockingThreshold, 10000, EXPERIMENTAL, \
"Lock count at which to do RTM lock eliding without " \
"abort ratio calculation") \
range(0, max_jint) \
\
product(int, RTMAbortRatio, 50, EXPERIMENTAL, \
"Lock abort ratio at which to stop use RTM lock eliding") \
range(0, 100) /* natural range */ \
\
product(int, RTMTotalCountIncrRate, 64, EXPERIMENTAL, \
"Increment total RTM attempted lock count once every n times") \
range(1, max_jint) \
constraint(RTMTotalCountIncrRateConstraintFunc,AfterErgo) \
\
product(intx, RTMLockingCalculationDelay, 0, EXPERIMENTAL, \
"Number of milliseconds to wait before start calculating aborts " \
"for RTM locking") \
\
product(bool, UseRTMXendForLockBusy, true, EXPERIMENTAL, \
"Use RTM Xend instead of Xabort when lock busy") \
\
/* assembler */ \
product(bool, UseCountLeadingZerosInstruction, false, \
"Use count leading zeros instruction") \

@ -30,7 +30,6 @@
#include "code/vmreg.inline.hpp"
#include "compiler/oopMap.hpp"
#include "utilities/macros.hpp"
#include "runtime/rtmLocking.hpp"
#include "runtime/vm_version.hpp"
#include "utilities/checkedCast.hpp"

@ -1476,13 +1476,6 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
// Frame is now completed as far as size and linkage.
int frame_complete = ((intptr_t)__ pc()) - start;
if (UseRTMLocking) {
// Abort RTM transaction before calling JNI
// because critical section will be large and will be
// aborted anyway. Also nmethod could be deoptimized.
__ xabort(0);
}
// Calculate the difference between rsp and rbp,. We need to know it
// after the native call because on windows Java Natives will pop
// the arguments and it is painful to do rsp relative addressing
@ -2422,11 +2415,6 @@ void SharedRuntime::generate_uncommon_trap_blob() {
address start = __ pc();
if (UseRTMLocking) {
// Abort RTM transaction before possible nmethod deoptimization.
__ xabort(0);
}
// Push self-frame.
__ subptr(rsp, return_off*wordSize); // Epilog!
@ -2609,13 +2597,6 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
bool cause_return = (poll_type == POLL_AT_RETURN);
bool save_vectors = (poll_type == POLL_AT_VECTOR_LOOP);
if (UseRTMLocking) {
// Abort RTM transaction before calling runtime
// because critical section will be large and will be
// aborted anyway. Also nmethod could be deoptimized.
__ xabort(0);
}
// If cause_return is true we are at a poll_return and there is
// the return address on the stack to the caller on the nmethod
// that is safepoint. We can leave this return on the stack and

@ -1959,13 +1959,6 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
// Frame is now completed as far as size and linkage.
int frame_complete = ((intptr_t)__ pc()) - start;
if (UseRTMLocking) {
// Abort RTM transaction before calling JNI
// because critical section will be large and will be
// aborted anyway. Also nmethod could be deoptimized.
__ xabort(0);
}
#ifdef ASSERT
__ check_stack_alignment(rsp, "improperly aligned stack");
#endif /* ASSERT */
@ -2921,11 +2914,6 @@ void SharedRuntime::generate_uncommon_trap_blob() {
address start = __ pc();
if (UseRTMLocking) {
// Abort RTM transaction before possible nmethod deoptimization.
__ xabort(0);
}
// Push self-frame. We get here with a return address on the
// stack, so rsp is 8-byte aligned until we allocate our frame.
__ subptr(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Epilog!
@ -3112,13 +3100,6 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
bool cause_return = (poll_type == POLL_AT_RETURN);
bool save_wide_vectors = (poll_type == POLL_AT_VECTOR_LOOP);
if (UseRTMLocking) {
// Abort RTM transaction before calling runtime
// because critical section will be large and will be
// aborted anyway. Also nmethod could be deoptimized.
__ xabort(0);
}
// Make room for return address (or push it again)
if (!cause_return) {
__ push(rbx);

@ -1322,55 +1322,6 @@ void VM_Version::get_processor_features() {
FLAG_SET_DEFAULT(UseSHA, false);
}
if (!supports_rtm() && UseRTMLocking) {
vm_exit_during_initialization("RTM instructions are not available on this CPU");
}
#if INCLUDE_RTM_OPT
if (UseRTMLocking) {
if (!CompilerConfig::is_c2_enabled()) {
// Only C2 does RTM locking optimization.
vm_exit_during_initialization("RTM locking optimization is not supported in this VM");
}
if (is_intel_family_core()) {
if ((_model == CPU_MODEL_HASWELL_E3) ||
(_model == CPU_MODEL_HASWELL_E7 && _stepping < 3) ||
(_model == CPU_MODEL_BROADWELL && _stepping < 4)) {
// currently a collision between SKL and HSW_E3
if (!UnlockExperimentalVMOptions && UseAVX < 3) {
vm_exit_during_initialization("UseRTMLocking is only available as experimental option on this "
"platform. It must be enabled via -XX:+UnlockExperimentalVMOptions flag.");
} else {
warning("UseRTMLocking is only available as experimental option on this platform.");
}
}
}
if (!FLAG_IS_CMDLINE(UseRTMLocking)) {
// RTM locking should be used only for applications with
// high lock contention. For now we do not use it by default.
vm_exit_during_initialization("UseRTMLocking flag should be only set on command line");
}
} else { // !UseRTMLocking
if (UseRTMForStackLocks) {
if (!FLAG_IS_DEFAULT(UseRTMForStackLocks)) {
warning("UseRTMForStackLocks flag should be off when UseRTMLocking flag is off");
}
FLAG_SET_DEFAULT(UseRTMForStackLocks, false);
}
if (UseRTMDeopt) {
FLAG_SET_DEFAULT(UseRTMDeopt, false);
}
if (PrintPreciseRTMLockingStatistics) {
FLAG_SET_DEFAULT(PrintPreciseRTMLockingStatistics, false);
}
}
#else
if (UseRTMLocking) {
// Only C2 does RTM locking optimization.
vm_exit_during_initialization("RTM locking optimization is not supported in this VM");
}
#endif
#ifdef COMPILER2
if (UseFPUForSpilling) {
if (UseSSE < 2) {

@ -13613,25 +13613,8 @@ instruct RethrowException()
// inlined locking and unlocking
instruct cmpFastLockRTM(eFlagsReg cr, eRegP object, eBXRegP box, eAXRegI tmp, eDXRegI scr, rRegI cx1, rRegI cx2, eRegP thread) %{
predicate(Compile::current()->use_rtm());
match(Set cr (FastLock object box));
effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box, TEMP thread);
ins_cost(300);
format %{ "FASTLOCK $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %}
ins_encode %{
__ get_thread($thread$$Register);
__ fast_lock($object$$Register, $box$$Register, $tmp$$Register,
$scr$$Register, $cx1$$Register, $cx2$$Register, $thread$$Register,
_rtm_counters, _stack_rtm_counters,
((Method*)(ra_->C->method()->constant_encoding()))->method_data(),
true, ra_->C->profile_rtm());
%}
ins_pipe(pipe_slow);
%}
instruct cmpFastLock(eFlagsReg cr, eRegP object, eBXRegP box, eAXRegI tmp, eRegP scr, eRegP thread) %{
predicate(LockingMode != LM_LIGHTWEIGHT && !Compile::current()->use_rtm());
predicate(LockingMode != LM_LIGHTWEIGHT);
match(Set cr (FastLock object box));
effect(TEMP tmp, TEMP scr, USE_KILL box, TEMP thread);
ins_cost(300);
@ -13639,7 +13622,7 @@ instruct cmpFastLock(eFlagsReg cr, eRegP object, eBXRegP box, eAXRegI tmp, eRegP
ins_encode %{
__ get_thread($thread$$Register);
__ fast_lock($object$$Register, $box$$Register, $tmp$$Register,
$scr$$Register, noreg, noreg, $thread$$Register, nullptr, nullptr, nullptr, false, false);
$scr$$Register, noreg, noreg, $thread$$Register, nullptr);
%}
ins_pipe(pipe_slow);
%}
@ -13651,7 +13634,7 @@ instruct cmpFastUnlock(eFlagsReg cr, eRegP object, eAXRegP box, eRegP tmp ) %{
ins_cost(300);
format %{ "FASTUNLOCK $object,$box\t! kills $box,$tmp" %}
ins_encode %{
__ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm());
__ fast_unlock($object$$Register, $box$$Register, $tmp$$Register);
%}
ins_pipe(pipe_slow);
%}

@ -12260,31 +12260,15 @@ instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
// ============================================================================
// inlined locking and unlocking
instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{
predicate(Compile::current()->use_rtm());
match(Set cr (FastLock object box));
effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box);
ins_cost(300);
format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %}
ins_encode %{
__ fast_lock($object$$Register, $box$$Register, $tmp$$Register,
$scr$$Register, $cx1$$Register, $cx2$$Register, r15_thread,
_rtm_counters, _stack_rtm_counters,
((Method*)(ra_->C->method()->constant_encoding()))->method_data(),
true, ra_->C->profile_rtm());
%}
ins_pipe(pipe_slow);
%}
instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{
predicate(LockingMode != LM_LIGHTWEIGHT && !Compile::current()->use_rtm());
predicate(LockingMode != LM_LIGHTWEIGHT);
match(Set cr (FastLock object box));
effect(TEMP tmp, TEMP scr, USE_KILL box);
ins_cost(300);
format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %}
ins_encode %{
__ fast_lock($object$$Register, $box$$Register, $tmp$$Register,
$scr$$Register, noreg, noreg, r15_thread, nullptr, nullptr, nullptr, false, false);
$scr$$Register, noreg, noreg, r15_thread, nullptr);
%}
ins_pipe(pipe_slow);
%}
@ -12296,7 +12280,7 @@ instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{
ins_cost(300);
format %{ "fastunlock $object,$box\t! kills $box,$tmp" %}
ins_encode %{
__ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm());
__ fast_unlock($object$$Register, $box$$Register, $tmp$$Register);
%}
ins_pipe(pipe_slow);
%}

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2024, Oracle and/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
@ -1614,11 +1614,6 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
fprintf(fp, " ((MachIfNode*)n%d)->_fcnt = _fcnt;\n", cnt);
}
if (node->is_ideal_fastlock() && new_inst->is_ideal_fastlock()) {
fprintf(fp, " ((MachFastLockNode*)n%d)->_rtm_counters = _rtm_counters;\n", cnt);
fprintf(fp, " ((MachFastLockNode*)n%d)->_stack_rtm_counters = _stack_rtm_counters;\n", cnt);
}
// Fill in the bottom_type where requested
if (node->captures_bottom_type(_globalNames) &&
new_inst->captures_bottom_type(_globalNames)) {
@ -4008,10 +4003,6 @@ void ArchDesc::buildMachNode(FILE *fp_cpp, InstructForm *inst, const char *inden
if (inst->is_ideal_jump()) {
fprintf(fp_cpp, "%s node->_probs = _leaf->as_Jump()->_probs;\n", indent);
}
if( inst->is_ideal_fastlock() ) {
fprintf(fp_cpp, "%s node->_rtm_counters = _leaf->as_FastLock()->rtm_counters();\n", indent);
fprintf(fp_cpp, "%s node->_stack_rtm_counters = _leaf->as_FastLock()->stack_rtm_counters();\n", indent);
}
}

@ -1032,8 +1032,7 @@ void ciEnv::register_method(ciMethod* target,
bool has_unsafe_access,
bool has_wide_vectors,
bool has_monitors,
int immediate_oops_patched,
RTMState rtm_state) {
int immediate_oops_patched) {
VM_ENTRY_MARK;
nmethod* nm = nullptr;
{
@ -1090,14 +1089,6 @@ void ciEnv::register_method(ciMethod* target,
// Check for {class loads, evolution, breakpoints, ...} during compilation
validate_compile_task_dependencies(target);
}
#if INCLUDE_RTM_OPT
if (!failing() && (rtm_state != NoRTM) &&
(method()->method_data() != nullptr) &&
(method()->method_data()->rtm_state() != rtm_state)) {
// Preemptive decompile if rtm state was changed.
record_failure("RTM state change invalidated rtm code");
}
#endif
if (failing()) {
// While not a true deoptimization, it is a preemptive decompile.
@ -1134,9 +1125,6 @@ void ciEnv::register_method(ciMethod* target,
nm->set_has_wide_vectors(has_wide_vectors);
nm->set_has_monitors(has_monitors);
assert(!method->is_synchronized() || nm->has_monitors(), "");
#if INCLUDE_RTM_OPT
nm->set_rtm_state(rtm_state);
#endif
if (entry_bci == InvocationEntryBci) {
if (TieredCompilation) {

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2024, Oracle and/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
@ -383,8 +383,7 @@ public:
bool has_unsafe_access,
bool has_wide_vectors,
bool has_monitors,
int immediate_oops_patched,
RTMState rtm_state = NoRTM);
int immediate_oops_patched);
// Access to certain well known ciObjects.
#define VM_CLASS_FUNC(name, ignore_s) \

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2024, Oracle and/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
@ -479,17 +479,6 @@ public:
int invocation_count() { return _invocation_counter; }
#if INCLUDE_RTM_OPT
// return cached value
int rtm_state() {
if (is_empty()) {
return NoRTM;
} else {
return get_MethodData()->rtm_state();
}
}
#endif
// Transfer information about the method to MethodData*.
// would_profile means we would like to profile this method,
// meaning it's not trivial.

@ -1229,9 +1229,6 @@ void nmethod::init_defaults(CodeBuffer *code_buffer, CodeOffsets* offsets) {
_oops_do_mark_link = nullptr;
_compiled_ic_data = nullptr;
#if INCLUDE_RTM_OPT
_rtm_state = NoRTM;
#endif
_is_unloading_state = 0;
_state = not_installed;

@ -260,12 +260,6 @@ class nmethod : public CodeBlob {
CompLevel _comp_level; // compilation level (s1)
CompilerType _compiler_type; // which compiler made this nmethod (u1)
#if INCLUDE_RTM_OPT
// RTM state at compile time. Used during deoptimization to decide
// whether to restart collecting RTM locking abort statistic again.
RTMState _rtm_state;
#endif
// Local state used to keep track of whether unloading is happening or not
volatile uint8_t _is_unloading_state;
@ -629,12 +623,6 @@ public:
bool is_unloading();
void do_unloading(bool unloading_occurred);
#if INCLUDE_RTM_OPT
// rtm state accessing and manipulating
RTMState rtm_state() const { return _rtm_state; }
void set_rtm_state(RTMState state) { _rtm_state = state; }
#endif
bool make_in_use() {
return try_transition(in_use);
}

@ -98,23 +98,6 @@ inline bool is_compile(int comp_level) {
return is_c1_compile(comp_level) || is_c2_compile(comp_level);
}
// States of Restricted Transactional Memory usage.
enum RTMState: u1 {
NoRTM = 0x2, // Don't use RTM
UseRTM = 0x1, // Use RTM
ProfileRTM = 0x0 // Use RTM with abort ratio calculation
};
#ifndef INCLUDE_RTM_OPT
#define INCLUDE_RTM_OPT 0
#endif
#if INCLUDE_RTM_OPT
#define RTM_OPT_ONLY(code) code
#else
#define RTM_OPT_ONLY(code)
#endif
class CompilerConfig : public AllStatic {
public:
// Scale compile thresholds

@ -77,8 +77,6 @@ class methodHandle;
option(CompileThresholdScaling, "CompileThresholdScaling", Double) \
option(ControlIntrinsic, "ControlIntrinsic", Ccstrlist) \
option(DisableIntrinsic, "DisableIntrinsic", Ccstrlist) \
option(NoRTMLockEliding, "NoRTMLockEliding", Bool) \
option(UseRTMLockEliding, "UseRTMLockEliding", Bool) \
option(BlockLayoutByFrequency, "BlockLayoutByFrequency", Bool) \
option(TraceOptoPipelining, "TraceOptoPipelining", Bool) \
option(TraceOptoOutput, "TraceOptoOutput", Bool) \

@ -1333,21 +1333,6 @@ void MethodData::init() {
_failed_speculations = nullptr;
#endif
#if INCLUDE_RTM_OPT
_rtm_state = NoRTM; // No RTM lock eliding by default
if (UseRTMLocking &&
!CompilerOracle::has_option(mh, CompileCommandEnum::NoRTMLockEliding)) {
if (CompilerOracle::has_option(mh, CompileCommandEnum::UseRTMLockEliding) || !UseRTMDeopt) {
// Generate RTM lock eliding code without abort ratio calculation code.
_rtm_state = UseRTM;
} else if (UseRTMDeopt) {
// Generate RTM lock eliding code and include abort ratio calculation
// code if UseRTMDeopt is on.
_rtm_state = ProfileRTM;
}
}
#endif
// Initialize escape flags.
clear_escape_info();
}

@ -2070,11 +2070,6 @@ private:
int _invoke_mask; // per-method Tier0InvokeNotifyFreqLog
int _backedge_mask; // per-method Tier0BackedgeNotifyFreqLog
#if INCLUDE_RTM_OPT
// State of RTM code generation during compilation of the method
int _rtm_state;
#endif
// Number of loops and blocks is computed when compiling the first
// time with C1. It is used to determine if method is trivial.
short _num_loops;
@ -2270,22 +2265,6 @@ public:
}
#endif
#if INCLUDE_RTM_OPT
int rtm_state() const {
return _rtm_state;
}
void set_rtm_state(RTMState rstate) {
_rtm_state = (int)rstate;
}
void atomic_set_rtm_state(RTMState rstate) {
Atomic::store(&_rtm_state, (int)rstate);
}
static ByteSize rtm_state_offset() {
return byte_offset_of(MethodData, _rtm_state);
}
#endif
void set_would_profile(bool p) { _would_profile = p ? profile : no_profile; }
bool would_profile() const { return _would_profile != no_profile; }

@ -457,9 +457,6 @@
develop(bool, PrintLockStatistics, false, \
"Print precise statistics on the dynamic lock usage") \
\
product(bool, PrintPreciseRTMLockingStatistics, false, DIAGNOSTIC, \
"Print per-lock-site statistics of rtm locking in JVM") \
\
develop(bool, PrintEliminateLocks, false, \
"Print out when locks are eliminated") \
\

@ -269,7 +269,6 @@ macro(Opaque1)
macro(OpaqueLoopInit)
macro(OpaqueLoopStride)
macro(OpaqueZeroTripGuard)
macro(Opaque3)
macro(Opaque4)
macro(OpaqueInitializedAssertionPredicate)
macro(ProfileBoolean)

@ -713,10 +713,9 @@ Compile::Compile( ciEnv* ci_env, ciMethod* target, int osr_bci,
set_print_intrinsics(directive->PrintIntrinsicsOption);
set_has_irreducible_loop(true); // conservative until build_loop_tree() reset it
if (ProfileTraps RTM_OPT_ONLY( || UseRTMLocking )) {
if (ProfileTraps) {
// Make sure the method being compiled gets its own MDO,
// so we can at least track the decompile_count().
// Need MDO to record RTM code generation state.
method()->ensure_method_data();
}
@ -1075,25 +1074,8 @@ void Compile::Init(bool aliasing) {
set_use_cmove(UseCMoveUnconditionally /* || do_vector_loop()*/); //TODO: consider do_vector_loop() mandate use_cmove unconditionally
NOT_PRODUCT(if (use_cmove() && Verbose && has_method()) {tty->print("Compile::Init: use CMove without profitability tests for method %s\n", method()->name()->as_quoted_ascii());})
set_rtm_state(NoRTM); // No RTM lock eliding by default
_max_node_limit = _directive->MaxNodeLimitOption;
#if INCLUDE_RTM_OPT
if (UseRTMLocking && has_method() && (method()->method_data_or_null() != nullptr)) {
int rtm_state = method()->method_data()->rtm_state();
if (method_has_option(CompileCommandEnum::NoRTMLockEliding) || ((rtm_state & NoRTM) != 0)) {
// Don't generate RTM lock eliding code.
set_rtm_state(NoRTM);
} else if (method_has_option(CompileCommandEnum::UseRTMLockEliding) || ((rtm_state & UseRTM) != 0) || !UseRTMDeopt) {
// Generate RTM lock eliding code without abort ratio calculation code.
set_rtm_state(UseRTM);
} else if (UseRTMDeopt) {
// Generate RTM lock eliding code and include abort ratio calculation
// code if UseRTMDeopt is on.
set_rtm_state(ProfileRTM);
}
}
#endif
if (VM_Version::supports_fast_class_init_checks() && has_method() && !is_osr_compilation() && method()->needs_clinit_barrier()) {
set_clinit_barrier_on_entry(true);
}
@ -3222,7 +3204,6 @@ void Compile::final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& f
frc.inc_double_count();
break;
case Op_Opaque1: // Remove Opaque Nodes before matching
case Op_Opaque3:
n->subsume_by(n->in(1), this);
break;
case Op_CallStaticJava:

@ -355,7 +355,6 @@ class Compile : public Phase {
bool _has_method_handle_invokes; // True if this method has MethodHandle invokes.
bool _has_monitors; // Metadata transfered to nmethod to enable Continuations lock-detection fastpath
bool _clinit_barrier_on_entry; // True if clinit barrier is needed on nmethod entry
RTMState _rtm_state; // State of Restricted Transactional Memory usage
int _loop_opts_cnt; // loop opts round
uint _stress_seed; // Seed for stress testing
@ -667,10 +666,6 @@ private:
void set_print_inlining(bool z) { _print_inlining = z; }
bool print_intrinsics() const { return _print_intrinsics; }
void set_print_intrinsics(bool z) { _print_intrinsics = z; }
RTMState rtm_state() const { return _rtm_state; }
void set_rtm_state(RTMState s) { _rtm_state = s; }
bool use_rtm() const { return (_rtm_state & NoRTM) == 0; }
bool profile_rtm() const { return _rtm_state == ProfileRTM; }
uint max_node_limit() const { return (uint)_max_node_limit; }
void set_max_node_limit(uint n) { _max_node_limit = n; }
bool clinit_barrier_on_entry() { return _clinit_barrier_on_entry; }

@ -3491,9 +3491,6 @@ FastLockNode* GraphKit::shared_lock(Node* obj) {
FastLockNode * flock = _gvn.transform(new FastLockNode(0, obj, box) )->as_FastLock();
// Create the rtm counters for this fast lock if needed.
flock->create_rtm_lock_counter(sync_jvms()); // sync_jvms used to get current bci
// Add monitor to debug info for the slow path. If we block inside the
// slow path and de-opt, we need the monitor hanging around
map()->push_monitor( flock );

@ -194,22 +194,6 @@ bool FastUnlockNode::cmp( const Node &n ) const {
return (&n == this); // Always fail except on self
}
void FastLockNode::create_rtm_lock_counter(JVMState* state) {
#if INCLUDE_RTM_OPT
Compile* C = Compile::current();
if (C->profile_rtm() || (PrintPreciseRTMLockingStatistics && C->use_rtm())) {
RTMLockingNamedCounter* rlnc = (RTMLockingNamedCounter*)
OptoRuntime::new_named_counter(state, NamedCounter::RTMLockingCounter);
_rtm_counters = rlnc->counters();
if (UseRTMForStackLocks) {
rlnc = (RTMLockingNamedCounter*)
OptoRuntime::new_named_counter(state, NamedCounter::RTMLockingCounter);
_stack_rtm_counters = rlnc->counters();
}
}
#endif
}
//=============================================================================
//------------------------------do_monitor_enter-------------------------------
void Parse::do_monitor_enter() {

@ -29,8 +29,6 @@
#include "opto/opcodes.hpp"
#include "opto/subnode.hpp"
class RTMLockingCounters;
//------------------------------BoxLockNode------------------------------------
class BoxLockNode : public Node {
private:
@ -130,16 +128,10 @@ public:
//------------------------------FastLockNode-----------------------------------
class FastLockNode: public CmpNode {
private:
RTMLockingCounters* _rtm_counters; // RTM lock counters for inflated locks
RTMLockingCounters* _stack_rtm_counters; // RTM lock counters for stack locks
public:
FastLockNode(Node *ctrl, Node *oop, Node *box) : CmpNode(oop,box) {
init_req(0,ctrl);
init_class_id(Class_FastLock);
_rtm_counters = nullptr;
_stack_rtm_counters = nullptr;
}
Node* obj_node() const { return in(1); }
Node* box_node() const { return in(2); }
@ -153,10 +145,6 @@ public:
virtual int Opcode() const;
virtual const Type* Value(PhaseGVN* phase) const { return TypeInt::CC; }
const Type *sub(const Type *t1, const Type *t2) const { return TypeInt::CC;}
void create_rtm_lock_counter(JVMState* state);
RTMLockingCounters* rtm_counters() const { return _rtm_counters; }
RTMLockingCounters* stack_rtm_counters() const { return _stack_rtm_counters; }
};

@ -901,15 +901,6 @@ bool IdealLoopTree::policy_maximally_unroll(PhaseIdealLoop* phase) const {
case Op_CountPositives: {
return false;
}
#if INCLUDE_RTM_OPT
case Op_FastLock:
case Op_FastUnlock: {
// Don't unroll RTM locking code because it is large.
if (UseRTMLocking) {
return false;
}
}
#endif
} // switch
}
@ -1074,15 +1065,6 @@ bool IdealLoopTree::policy_unroll(PhaseIdealLoop *phase) {
// String intrinsics are large and have loops.
return false;
}
#if INCLUDE_RTM_OPT
case Op_FastLock:
case Op_FastUnlock: {
// Don't unroll RTM locking code because it is large.
if (UseRTMLocking) {
return false;
}
}
#endif
} // switch
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2024, Oracle and/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
@ -54,7 +54,6 @@ class MachSpillCopyNode;
class Matcher;
class PhaseRegAlloc;
class RegMask;
class RTMLockingCounters;
class State;
//---------------------------MachOper------------------------------------------
@ -802,8 +801,6 @@ public:
class MachFastLockNode : public MachNode {
virtual uint size_of() const { return sizeof(*this); } // Size is bigger
public:
RTMLockingCounters* _rtm_counters; // RTM lock counters for inflated locks
RTMLockingCounters* _stack_rtm_counters; // RTM lock counters for stack locks
MachFastLockNode() : MachNode() {}
};

@ -2428,7 +2428,6 @@ void PhaseMacroExpand::eliminate_macro_nodes() {
break;
default:
assert(n->Opcode() == Op_LoopLimit ||
n->Opcode() == Op_Opaque3 ||
n->is_Opaque4() ||
n->is_OpaqueInitializedAssertionPredicate() ||
n->Opcode() == Op_MaxL ||
@ -2481,30 +2480,6 @@ bool PhaseMacroExpand::expand_macro_nodes() {
} else if (n->is_Opaque1()) {
_igvn.replace_node(n, n->in(1));
success = true;
#if INCLUDE_RTM_OPT
} else if ((n->Opcode() == Op_Opaque3) && ((Opaque3Node*)n)->rtm_opt()) {
assert(C->profile_rtm(), "should be used only in rtm deoptimization code");
assert((n->outcnt() == 1) && n->unique_out()->is_Cmp(), "");
Node* cmp = n->unique_out();
#ifdef ASSERT
// Validate graph.
assert((cmp->outcnt() == 1) && cmp->unique_out()->is_Bool(), "");
BoolNode* bol = cmp->unique_out()->as_Bool();
assert((bol->outcnt() == 1) && bol->unique_out()->is_If() &&
(bol->_test._test == BoolTest::ne), "");
IfNode* ifn = bol->unique_out()->as_If();
assert((ifn->outcnt() == 2) &&
ifn->proj_out(1)->is_uncommon_trap_proj(Deoptimization::Reason_rtm_state_change) != nullptr, "");
#endif
Node* repl = n->in(1);
if (!_has_locks) {
// Remove RTM state check if there are no locks in the code.
// Replace input to compare the same value.
repl = (cmp->in(1) == n) ? cmp->in(2) : cmp->in(1);
}
_igvn.replace_node(n, repl);
success = true;
#endif
} else if (n->is_Opaque4()) {
// With Opaque4 nodes, the expectation is that the test of input 1
// is always equal to the constant value of input 2. So we can

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2024, Oracle and/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
@ -45,16 +45,6 @@ Node* Opaque1Node::Identity(PhaseGVN* phase) {
return this;
}
// Do NOT remove the opaque node until no more loop opts can happen.
Node* Opaque3Node::Identity(PhaseGVN* phase) {
if (phase->C->post_loop_opts_phase()) {
return in(1);
} else {
phase->C->record_for_post_loop_opts_igvn(this);
}
return this;
}
#ifdef ASSERT
CountedLoopNode* OpaqueZeroTripGuardNode::guarded_loop() const {
Node* iff = if_node();
@ -92,12 +82,6 @@ IfNode* OpaqueZeroTripGuardNode::if_node() const {
return iff->as_If();
}
// Do not allow value-numbering
uint Opaque3Node::hash() const { return NO_HASH; }
bool Opaque3Node::cmp(const Node &n) const {
return (&n == this); // Always fail except on self
}
const Type* Opaque4Node::Value(PhaseGVN* phase) const {
return phase->type(in(1));
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2024, Oracle and/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
@ -91,26 +91,6 @@ public:
IfNode* if_node() const;
};
//------------------------------Opaque3Node------------------------------------
// A node to prevent unwanted optimizations. Will be optimized only during
// macro nodes expansion.
class Opaque3Node : public Node {
int _opt; // what optimization it was used for
virtual uint hash() const;
virtual bool cmp(const Node &n) const;
public:
enum { RTM_OPT };
Opaque3Node(Compile* C, Node* n, int opt) : Node(0, n), _opt(opt) {
// Put it on the Macro nodes list to removed during macro nodes expansion.
init_flags(Flag_is_macro);
C->add_macro_node(this);
}
virtual int Opcode() const;
virtual const Type* bottom_type() const { return TypeInt::INT; }
virtual Node* Identity(PhaseGVN* phase);
bool rtm_opt() const { return (_opt == RTM_OPT); }
};
// Input 1 is a check that we know implicitly is always true or false
// but the compiler has no way to prove. If during optimizations, that
// check becomes true or false, the Opaque4 node is replaced by that

@ -3388,8 +3388,7 @@ void PhaseOutput::install() {
C->entry_bci(),
CompileBroker::compiler2(),
C->has_unsafe_access(),
SharedRuntime::is_wide_vector(C->max_vector_size()),
C->rtm_state());
SharedRuntime::is_wide_vector(C->max_vector_size()));
}
}
@ -3397,8 +3396,7 @@ void PhaseOutput::install_code(ciMethod* target,
int entry_bci,
AbstractCompiler* compiler,
bool has_unsafe_access,
bool has_wide_vectors,
RTMState rtm_state) {
bool has_wide_vectors) {
// Check if we want to skip execution of all compiled code.
{
#ifndef PRODUCT
@ -3436,8 +3434,7 @@ void PhaseOutput::install_code(ciMethod* target,
has_unsafe_access,
SharedRuntime::is_wide_vector(C->max_vector_size()),
C->has_monitors(),
0,
C->rtm_state());
0);
if (C->log() != nullptr) { // Print code cache state into compiler log
C->log()->code_cache_state();

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2024, Oracle and/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
@ -121,8 +121,7 @@ public:
int entry_bci,
AbstractCompiler* compiler,
bool has_unsafe_access,
bool has_wide_vectors,
RTMState rtm_state);
bool has_wide_vectors);
void install_stub(const char* stub_name);

@ -501,8 +501,6 @@ class Parse : public GraphKit {
void clinit_deopt();
void rtm_deopt();
// Pass current map to exits
void return_current(Node* value);

@ -597,12 +597,9 @@ Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses)
// Add check to deoptimize the nmethod once the holder class is fully initialized
clinit_deopt();
}
// Add check to deoptimize the nmethod if RTM state was changed
rtm_deopt();
}
// Check for bailouts during method entry or RTM state check setup.
// Check for bailouts during method entry.
if (failing()) {
if (log) log->done("parse");
C->set_default_node_notes(caller_nn);
@ -2201,42 +2198,6 @@ void Parse::clinit_deopt() {
guard_klass_being_initialized(holder);
}
// Add check to deoptimize if RTM state is not ProfileRTM
void Parse::rtm_deopt() {
#if INCLUDE_RTM_OPT
if (C->profile_rtm()) {
assert(C->has_method(), "only for normal compilations");
assert(!C->method()->method_data()->is_empty(), "MDO is needed to record RTM state");
assert(depth() == 1, "generate check only for main compiled method");
// Set starting bci for uncommon trap.
set_parse_bci(is_osr_parse() ? osr_bci() : 0);
// Load the rtm_state from the MethodData.
const TypePtr* adr_type = TypeMetadataPtr::make(C->method()->method_data());
Node* mdo = makecon(adr_type);
int offset = in_bytes(MethodData::rtm_state_offset());
Node* adr_node = basic_plus_adr(mdo, mdo, offset);
Node* rtm_state = make_load(control(), adr_node, TypeInt::INT, T_INT, adr_type, MemNode::unordered);
// Separate Load from Cmp by Opaque.
// In expand_macro_nodes() it will be replaced either
// with this load when there are locks in the code
// or with ProfileRTM (cmp->in(2)) otherwise so that
// the check will fold.
Node* profile_state = makecon(TypeInt::make(ProfileRTM));
Node* opq = _gvn.transform( new Opaque3Node(C, rtm_state, Opaque3Node::RTM_OPT) );
Node* chk = _gvn.transform( new CmpINode(opq, profile_state) );
Node* tst = _gvn.transform( new BoolNode(chk, BoolTest::eq) );
// Branch to failure if state was changed
{ BuildCutout unless(this, tst, PROB_ALWAYS);
uncommon_trap(Deoptimization::Reason_rtm_state_change,
Deoptimization::Action_make_not_entrant);
}
}
#endif
}
//------------------------------return_current---------------------------------
// Append current _map to _exit_return
void Parse::return_current(Node* value) {

@ -1856,14 +1856,6 @@ void OptoRuntime::print_named_counters() {
eliminated_lock_count += count;
}
}
#if INCLUDE_RTM_OPT
} else if (c->tag() == NamedCounter::RTMLockingCounter) {
RTMLockingCounters* rlc = ((RTMLockingNamedCounter*)c)->counters();
if (rlc->nonzero()) {
tty->print_cr("%s", c->name());
rlc->print_on(tty);
}
#endif
}
c = c->next();
}
@ -1905,12 +1897,7 @@ NamedCounter* OptoRuntime::new_named_counter(JVMState* youngest_jvms, NamedCount
st.print("@%d", bci);
// To print linenumbers instead of bci use: m->line_number_from_bci(bci)
}
NamedCounter* c;
if (tag == NamedCounter::RTMLockingCounter) {
c = new RTMLockingNamedCounter(st.freeze());
} else {
c = new NamedCounter(st.freeze(), tag);
}
NamedCounter* c = new NamedCounter(st.freeze(), tag);
// atomically add the new counter to the head of the list. We only
// add counters so this is safe.

@ -29,7 +29,6 @@
#include "opto/machnode.hpp"
#include "opto/optoreg.hpp"
#include "opto/type.hpp"
#include "runtime/rtmLocking.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/vframe.hpp"
@ -61,8 +60,7 @@ public:
enum CounterTag {
NoTag,
LockCounter,
EliminatedLockCounter,
RTMLockingCounter
EliminatedLockCounter
};
private:
@ -98,17 +96,6 @@ private:
};
class RTMLockingNamedCounter : public NamedCounter {
private:
RTMLockingCounters _counters;
public:
RTMLockingNamedCounter(const char *n) :
NamedCounter(n, RTMLockingCounter), _counters() {}
RTMLockingCounters* counters() { return &_counters; }
};
typedef const TypeFunc*(*TypeFunc_generator)();
class OptoRuntime : public AllStatic {

@ -507,11 +507,6 @@ static SpecialFlag const special_jvm_flags[] = {
{ "PreserveAllAnnotations", JDK_Version::jdk(23), JDK_Version::jdk(24), JDK_Version::jdk(25) },
{ "UseNotificationThread", JDK_Version::jdk(23), JDK_Version::jdk(24), JDK_Version::jdk(25) },
{ "UseEmptySlotsInSupers", JDK_Version::jdk(23), JDK_Version::jdk(24), JDK_Version::jdk(25) },
#if defined(X86)
{ "UseRTMLocking", JDK_Version::jdk(23), JDK_Version::jdk(24), JDK_Version::jdk(25) },
{ "UseRTMDeopt", JDK_Version::jdk(23), JDK_Version::jdk(24), JDK_Version::jdk(25) },
{ "RTMRetryCount", JDK_Version::jdk(23), JDK_Version::jdk(24), JDK_Version::jdk(25) },
#endif // X86
// --- Deprecated alias flags (see also aliased_jvm_flags) - sorted by obsolete_in then expired_in:
{ "CreateMinidumpOnCrash", JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::undefined() },
@ -545,6 +540,11 @@ static SpecialFlag const special_jvm_flags[] = {
{ "ParallelOldDeadWoodLimiterStdDev", JDK_Version::undefined(), JDK_Version::jdk(23), JDK_Version::jdk(24) },
{ "UseNeon", JDK_Version::undefined(), JDK_Version::jdk(23), JDK_Version::jdk(24) },
{ "ScavengeBeforeFullGC", JDK_Version::undefined(), JDK_Version::jdk(23), JDK_Version::jdk(24) },
#if defined(X86)
{ "UseRTMLocking", JDK_Version::jdk(23), JDK_Version::jdk(24), JDK_Version::jdk(25) },
{ "UseRTMDeopt", JDK_Version::jdk(23), JDK_Version::jdk(24), JDK_Version::jdk(25) },
{ "RTMRetryCount", JDK_Version::jdk(23), JDK_Version::jdk(24), JDK_Version::jdk(25) },
#endif // X86
#ifdef ASSERT
{ "DummyObsoleteTestFlag", JDK_Version::undefined(), JDK_Version::jdk(18), JDK_Version::undefined() },
#endif
@ -1847,14 +1847,6 @@ bool Arguments::check_vm_args_consistency() {
"LockingMode == 0 (LM_MONITOR) is not fully implemented on this architecture\n");
return false;
}
#endif
#if defined(X86) && !defined(ZERO)
if (LockingMode == LM_MONITOR && UseRTMForStackLocks) {
jio_fprintf(defaultStream::error_stream(),
"LockingMode == 0 (LM_MONITOR) and -XX:+UseRTMForStackLocks are mutually exclusive\n");
return false;
}
#endif
if (VerifyHeavyMonitors && LockingMode != LM_MONITOR) {
jio_fprintf(defaultStream::error_stream(),

@ -2076,8 +2076,7 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* current, jint tr
gather_statistics(reason, action, trap_bc);
// Ensure that we can record deopt. history:
// Need MDO to record RTM code generation state.
bool create_if_missing = ProfileTraps RTM_OPT_ONLY( || UseRTMLocking );
bool create_if_missing = ProfileTraps;
methodHandle profiled_method;
#if INCLUDE_JVMCI
@ -2425,16 +2424,6 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* current, jint tr
pdata->set_trap_state(tstate1);
}
#if INCLUDE_RTM_OPT
// Restart collecting RTM locking abort statistic if the method
// is recompiled for a reason other than RTM state change.
// Assume that in new recompiled code the statistic could be different,
// for example, due to different inlining.
if ((reason != Reason_rtm_state_change) && (trap_mdo != nullptr) &&
UseRTMDeopt && (nm->rtm_state() != ProfileRTM)) {
trap_mdo->atomic_set_rtm_state(ProfileRTM);
}
#endif
// For code aging we count traps separately here, using make_not_entrant()
// as a guard against simultaneous deopts in multiple threads.
if (reason == Reason_tenured && trap_mdo != nullptr) {
@ -2724,7 +2713,6 @@ const char* Deoptimization::_trap_reason_name[] = {
"speculate_class_check",
"speculate_null_check",
"speculate_null_assert",
"rtm_state_change",
"unstable_if",
"unstable_fused_if",
"receiver_constraint",

@ -113,7 +113,6 @@ class Deoptimization : AllStatic {
Reason_speculate_class_check, // saw unexpected object class from type speculation
Reason_speculate_null_check, // saw unexpected null from type speculation
Reason_speculate_null_assert, // saw unexpected null from type speculation
Reason_rtm_state_change, // rtm state change detected
Reason_unstable_if, // a branch predicted always false was taken
Reason_unstable_fused_if, // fused two ifs that had each one untaken branch. One is now taken.
Reason_receiver_constraint, // receiver subtype check failed

@ -378,20 +378,6 @@ JVMFlag::Error NodeLimitFudgeFactorConstraintFunc(intx value, bool verbose) {
}
#endif // COMPILER2
JVMFlag::Error RTMTotalCountIncrRateConstraintFunc(int value, bool verbose) {
#if INCLUDE_RTM_OPT
if (UseRTMLocking && !is_power_of_2(RTMTotalCountIncrRate)) {
JVMFlag::printError(verbose,
"RTMTotalCountIncrRate (%d) must be "
"a power of 2, resetting it to 64\n",
RTMTotalCountIncrRate);
FLAG_SET_DEFAULT(RTMTotalCountIncrRate, 64);
}
#endif
return JVMFlag::SUCCESS;
}
#ifdef COMPILER2
JVMFlag::Error LoopStripMiningIterConstraintFunc(uintx value, bool verbose) {
if (UseCountedLoopSafepoints && LoopStripMiningIter == 0) {

@ -49,7 +49,6 @@
f(uint, TypeProfileLevelConstraintFunc) \
f(uint, VerifyIterativeGVNConstraintFunc) \
f(intx, InitArrayShortSizeConstraintFunc) \
f(int , RTMTotalCountIncrRateConstraintFunc) \
f(ccstrlist, DisableIntrinsicConstraintFunc) \
f(ccstrlist, ControlIntrinsicConstraintFunc) \
COMPILER2_PRESENT( \

@ -265,7 +265,7 @@ void print_statistics() {
#endif //COMPILER1
}
if (PrintLockStatistics || PrintPreciseRTMLockingStatistics) {
if (PrintLockStatistics) {
OptoRuntime::print_named_counters();
}
#ifdef ASSERT

@ -1,77 +0,0 @@
/*
* Copyright (c) 2014, 2019, Oracle and/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.
*
*/
#include "precompiled.hpp"
#include "compiler/compilerDefinitions.hpp"
#if INCLUDE_RTM_OPT
#include "memory/allocation.inline.hpp"
#include "runtime/task.hpp"
#include "runtime/rtmLocking.hpp"
// One-shot PeriodicTask subclass for enabling RTM locking
uintx RTMLockingCounters::_calculation_flag = 0;
class RTMLockingCalculationTask : public PeriodicTask {
public:
RTMLockingCalculationTask(size_t interval_time) : PeriodicTask(interval_time){ }
virtual void task() {
RTMLockingCounters::_calculation_flag = 1;
// Reclaim our storage and disenroll ourself
delete this;
}
};
void RTMLockingCounters::init() {
if (UseRTMLocking && RTMLockingCalculationDelay > 0) {
RTMLockingCalculationTask* task = new RTMLockingCalculationTask(RTMLockingCalculationDelay);
task->enroll();
} else {
_calculation_flag = 1;
}
}
const char* RTMLockingCounters::_abortX_desc[ABORT_STATUS_LIMIT] = {
"abort instruction ",
"may succeed on retry",
"thread conflict ",
"buffer overflow ",
"debug or trap hit ",
"maximum nested depth"
};
//------------------------------print_on-------------------------------
void RTMLockingCounters::print_on(outputStream* st) const {
tty->print_cr("# rtm locks total (estimated): " UINTX_FORMAT, _total_count * RTMTotalCountIncrRate);
tty->print_cr("# rtm lock aborts (total): " UINTX_FORMAT, _abort_count);
for (int i = 0; i < ABORT_STATUS_LIMIT; i++) {
tty->print_cr("# rtm lock aborts %d (%s): " UINTX_FORMAT, i, _abortX_desc[i], _abortX_count[i]);
}
}
void RTMLockingCounters::print() const { print_on(tty); }
#endif

@ -1,112 +0,0 @@
/*
* Copyright (c) 2014, 2019, Oracle and/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 SHARE_RUNTIME_RTMLOCKING_HPP
#define SHARE_RUNTIME_RTMLOCKING_HPP
// Generate RTM (Restricted Transactional Memory) locking code for all inflated
// locks when "UseRTMLocking" option is on with normal locking mechanism as fall back
// handler.
//
// On abort/lock busy the lock will be retried a fixed number of times under RTM
// as specified by "RTMRetryCount" option. The locks which abort too often
// can be auto tuned or manually tuned.
//
// Auto-tuning can be done on an option like UseRTMDeopt and it will need abort
// ratio calculation for each lock. The abort ratio will be calculated after
// "RTMAbortThreshold" number of aborts is reached. The formulas are:
//
// Aborted transactions = abort_count * 100
// All transactions = total_count * RTMTotalCountIncrRate
//
// Aborted transactions >= All transactions * RTMAbortRatio
//
// If "UseRTMDeopt" is on and the aborts ratio reaches "RTMAbortRatio"
// the method containing the lock will be deoptimized and recompiled with
// all locks as normal locks. If the abort ratio continues to remain low after
// "RTMLockingThreshold" locks are attempted, then the method will be deoptimized
// and recompiled with all locks as RTM locks without abort ratio calculation code.
// The abort ratio calculation can be delayed by specifying flag
// -XX:RTMLockingCalculationDelay in millisecond.
//
// For manual tuning the abort statistics for each lock needs to be provided
// to the user on some JVM option like "PrintPreciseRTMLockingStatistics".
// Based on the abort statistics users can create a .hotspot_compiler file
// or use -XX:CompileCommand=option,class::method,NoRTMLockEliding
// to specify for which methods to disable RTM locking.
//
// When UseRTMForStackLocks option is enabled along with UseRTMLocking option,
// the RTM locking code is generated for stack locks too.
// The retries, auto-tuning support and rtm locking statistics are all
// supported for stack locks just like inflated locks.
// RTM locking counters
class RTMLockingCounters {
private:
uintx _total_count; // Total RTM locks count
uintx _abort_count; // Total aborts count
public:
enum { ABORT_STATUS_LIMIT = 6 };
// Counters per RTM Abort Status. Incremented with +PrintPreciseRTMLockingStatistics
// RTM uses the EAX register to communicate abort status to software.
// Following an RTM abort the EAX register has the following definition.
//
// EAX register bit position Meaning
// 0 Set if abort caused by XABORT instruction.
// 1 If set, the transaction may succeed on a retry. This bit is always clear if bit 0 is set.
// 2 Set if another logical processor conflicted with a memory address that was part of the transaction that aborted.
// 3 Set if an internal buffer overflowed.
// 4 Set if a debug breakpoint was hit.
// 5 Set if an abort occurred during execution of a nested transaction.
private:
uintx _abortX_count[ABORT_STATUS_LIMIT];
static const char* _abortX_desc[ABORT_STATUS_LIMIT];
public:
static uintx _calculation_flag;
static uintx* rtm_calculation_flag_addr() { return &_calculation_flag; }
static void init();
RTMLockingCounters() : _total_count(0), _abort_count(0) {
for (int i = 0; i < ABORT_STATUS_LIMIT; i++) {
_abortX_count[i] = 0;
}
}
uintx* total_count_addr() { return &_total_count; }
static int total_count_offset() { return (int)offset_of(RTMLockingCounters, _total_count); }
static int abort_count_offset() { return (int)offset_of(RTMLockingCounters, _abort_count); }
static int abortX_count_offset() { return (int)offset_of(RTMLockingCounters, _abortX_count[0]); }
bool nonzero() { return (_abort_count + _total_count) > 0; }
void print_on(outputStream* st) const;
void print() const;
};
#endif // SHARE_RUNTIME_RTMLOCKING_HPP

@ -109,9 +109,6 @@
#ifdef COMPILER2
#include "opto/idealGraphPrinter.hpp"
#endif
#if INCLUDE_RTM_OPT
#include "runtime/rtmLocking.hpp"
#endif
#if INCLUDE_JFR
#include "jfr/jfr.hpp"
#endif
@ -802,10 +799,6 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
StatSampler::engage();
if (CheckJNICalls) JniPeriodicChecker::engage();
#if INCLUDE_RTM_OPT
RTMLockingCounters::init();
#endif
call_postVMInitHook(THREAD);
// The Java side of PostVMInitHook.run must deal with all
// exceptions and provide means of diagnosis.

@ -2259,7 +2259,6 @@
declare_constant(Deoptimization::Reason_speculate_class_check) \
declare_constant(Deoptimization::Reason_speculate_null_check) \
declare_constant(Deoptimization::Reason_speculate_null_assert) \
declare_constant(Deoptimization::Reason_rtm_state_change) \
declare_constant(Deoptimization::Reason_unstable_if) \
declare_constant(Deoptimization::Reason_unstable_fused_if) \
declare_constant(Deoptimization::Reason_receiver_constraint) \

@ -36,7 +36,7 @@
. ftr VB CB
. ftr VBI CBI
.\}
.TH "JAVA" "1" "2024" "JDK 23-ea" "JDK Commands"
.TH "JAVA" "1" "2024" "JDK 24" "JDK Commands"
.hy
.SH NAME
.PP
@ -186,7 +186,7 @@ with new values added and old values removed.
You\[aq]ll get an error message if you use a value of \f[I]N\f[R] that
is no longer supported.
The supported values of \f[I]N\f[R] are the current Java SE release
(\f[V]23\f[R]) and a limited number of previous releases, detailed in
(\f[V]24\f[R]) and a limited number of previous releases, detailed in
the command-line help for \f[V]javac\f[R], under the \f[V]--source\f[R]
and \f[V]--release\f[R] options.
.RE
@ -1195,7 +1195,7 @@ or directories.
\f[V]--source\f[R] \f[I]version\f[R]
Sets the version of the source in source-file mode.
.TP
\f[V]--sun-misc-unsafe-memory-acces=\f[R] \f[I]value\f[R]
\f[V]--sun-misc-unsafe-memory-access=\f[R] \f[I]value\f[R]
Allow or deny usage of unsupported API \f[V]sun.misc.Unsafe\f[R].
\f[I]value\f[R] is one of:
.RS
@ -3484,16 +3484,6 @@ By default, this option is disabled.
Enables printing of information about adaptive-generation sizing.
By default, this option is disabled.
.TP
\f[V]-XX:+ScavengeBeforeFullGC\f[R]
Enables GC of the young generation before each full GC.
This option is enabled by default.
It is recommended that you \f[I]don\[aq]t\f[R] disable it, because
scavenging the young generation before a full GC can reduce the number
of objects reachable from the old generation space into the young
generation space.
To disable GC of the young generation before each full GC, specify the
option \f[V]-XX:-ScavengeBeforeFullGC\f[R].
.TP
\f[V]-XX:SoftRefLRUPolicyMSPerMB=\f[R]\f[I]time\f[R]
Sets the amount of time (in milliseconds) a softly reachable object is
kept active on the heap after the last time it was referenced.
@ -3786,6 +3776,28 @@ The default value is 2.
.PP
Use the option \f[V]-XX:MinRAMPercentage\f[R] instead.
.RE
.SH OBSOLETE JAVA OPTIONS
.PP
These \f[V]java\f[R] options are still accepted but ignored, and a
warning is issued when they\[aq]re used.
.TP
\f[V]--illegal-access=\f[R]\f[I]parameter\f[R]
Controlled \f[I]relaxed strong encapsulation\f[R], as defined in
\f[B]JEP 261\f[R]
[https://openjdk.org/jeps/261#Relaxed-strong-encapsulation].
This option was deprecated in JDK 16 by \f[B]JEP 396\f[R]
[https://openjdk.org/jeps/396] and made obsolete in JDK 17 by \f[B]JEP
403\f[R] [https://openjdk.org/jeps/403].
.TP
\f[V]-XX:+ScavengeBeforeFullGC\f[R]
Enables GC of the young generation before each full GC.
This option is enabled by default.
It is recommended that you \f[I]don\[aq]t\f[R] disable it, because
scavenging the young generation before a full GC can reduce the number
of objects reachable from the old generation space into the young
generation space.
To disable GC of the young generation before each full GC, specify the
option \f[V]-XX:-ScavengeBeforeFullGC\f[R].
.TP
\f[V]-XX:RTMAbortRatio=\f[R]\f[I]abort_ratio\f[R]
Specifies the RTM abort ratio is specified as a percentage (%) of all
@ -3863,21 +3875,9 @@ As a result, the processors repeatedly invalidate the cache lines of
other processors, which forces them to read from main memory instead of
their cache.
.RE
.SH OBSOLETE JAVA OPTIONS
.PP
These \f[V]java\f[R] options are still accepted but ignored, and a
warning is issued when they\[aq]re used.
.TP
\f[V]--illegal-access=\f[R]\f[I]parameter\f[R]
Controlled \f[I]relaxed strong encapsulation\f[R], as defined in
\f[B]JEP 261\f[R]
[https://openjdk.org/jeps/261#Relaxed-strong-encapsulation].
This option was deprecated in JDK 16 by \f[B]JEP 396\f[R]
[https://openjdk.org/jeps/396] and made obsolete in JDK 17 by \f[B]JEP
403\f[R] [https://openjdk.org/jeps/403].
.SH REMOVED JAVA OPTIONS
.PP
These \f[V]java\f[R] options have been removed in JDK 23 and using them
These \f[V]java\f[R] options have been removed in JDK 24 and using them
results in an error of:
.RS
.PP

@ -51,18 +51,6 @@ compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java 8190680 generic-all
compiler/runtime/Test8168712.java 8211769,8211771 generic-ppc64,generic-ppc64le,linux-s390x
compiler/loopopts/TestUnreachableInnerLoop.java 8288981 linux-s390x
compiler/rtm/locking/TestRTMAbortRatio.java 8183263 generic-x64,generic-i586
compiler/rtm/locking/TestRTMAbortThreshold.java 8183263 generic-x64,generic-i586
compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java 8183263 generic-x64,generic-i586
compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java 8183263 generic-x64,generic-i586
compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java 8183263 generic-x64,generic-i586
compiler/rtm/locking/TestRTMLockingCalculationDelay.java 8183263 generic-x64,generic-i586
compiler/rtm/locking/TestRTMLockingThreshold.java 8183263 generic-x64,generic-i586
compiler/rtm/locking/TestRTMSpinLoopCount.java 8183263 generic-x64,generic-i586
compiler/rtm/locking/TestUseRTMDeopt.java 8183263 generic-x64,generic-i586
compiler/rtm/locking/TestUseRTMXendForLockBusy.java 8183263 generic-x64,generic-i586
compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java 8183263 generic-x64,generic-i586
compiler/c2/Test8004741.java 8235801 generic-all
compiler/c2/irTests/TestDuplicateBackedge.java 8318904 generic-all

@ -254,7 +254,6 @@ tier2_compiler = \
compiler/parsing/ \
compiler/rangechecks/ \
compiler/reflection/ \
compiler/rtm/ \
compiler/runtime/Test6826736.java \
compiler/stable/ \
compiler/stringopts/ \

@ -1,214 +0,0 @@
/*
* Copyright (c) 2014, 2021, Oracle and/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.
*/
package compiler.rtm.cli;
import jdk.test.lib.process.ExitCode;
import jdk.test.lib.Platform;
import jdk.test.lib.cli.CommandLineOptionTest;
import java.util.function.BooleanSupplier;
/**
* Base for all RTM-related CLI tests.
*/
public abstract class RTMGenericCommandLineOptionTest {
protected static final String RTM_INSTR_ERROR
= "RTM instructions are not available on this CPU";
protected static final String RTM_UNSUPPORTED_VM_ERROR
= "RTM locking optimization is not supported in this VM";
protected static final String RTM_FOR_STACK_LOCKS_WARNING
= "UseRTMForStackLocks flag should be off when UseRTMLocking "
+ "flag is off";
protected static final String RTM_COUNT_INCR_WARNING
= "must be a power of 2, resetting it to 64";
protected final String optionName;
protected final String errorMessage;
protected final String experimentalOptionError;
protected final boolean isExperimental;
protected final boolean isBoolean;
protected final String defaultValue;
protected final String[] optionValues;
/**
* Constructs new genetic RTM CLI test, for option {@code optionName} which
* has default value {@code defaultValue}. Test cases will use option's
* values passed via {@code optionValues} for verification of correct
* option processing.
*
* Test constructed using this ctor will be started on any cpu regardless
* it's architecture and supported/unsupported features.
*
* @param optionName name of option to be tested
* @param isBoolean {@code true} if option is binary
* @param isExperimental {@code true} if option is experimental
* @param defaultValue default value of tested option
* @param optionValues different option values
*/
public RTMGenericCommandLineOptionTest(
String optionName, boolean isBoolean, boolean isExperimental,
String defaultValue, String... optionValues) {
this.optionName = optionName;
this.isExperimental = isExperimental;
this.isBoolean = isBoolean;
this.defaultValue = defaultValue;
this.optionValues = optionValues;
this.errorMessage = CommandLineOptionTest.
getUnrecognizedOptionErrorMessage(optionName);
this.experimentalOptionError = CommandLineOptionTest.
getExperimentalOptionErrorMessage(optionName);
}
public void runTestCases() throws Throwable {
if (Platform.isX86() || Platform.isX64()) {
if (Platform.isServer()) {
runX86SupportedVMTestCases();
} else {
runX86UnsupportedVMTestCases();
}
} else {
runNonX86TestCases();
}
}
/**
* Runs test cases on X86 CPU if VM supports RTM locking.
* @throws Throwable
*/
protected void runX86SupportedVMTestCases() throws Throwable {
runGenericX86TestCases();
}
/**
* Runs test cases on X86 CPU if VM does not support RTM locking.
* @throws Throwable
*/
protected void runX86UnsupportedVMTestCases() throws Throwable {
runGenericX86TestCases();
}
/**
* Runs test cases on non-X86 CPU.
* @throws Throwable
*/
protected void runNonX86TestCases() throws Throwable {
CommandLineOptionTest.verifySameJVMStartup(
new String[] { errorMessage }, null,
String.format("Option '%s' should be unknown on non-X86CPUs.%n"
+ "JVM startup should fail", optionName), "", ExitCode.FAIL,
prepareOptionValue(defaultValue));
}
/**
* Runs generic X86 test cases.
* @throws Throwable
*/
protected void runGenericX86TestCases() throws Throwable {
verifyJVMStartup();
verifyOptionValues();
}
protected void verifyJVMStartup() throws Throwable {
String optionValue = prepareOptionValue(defaultValue);
String shouldFailMessage = String.format("VM option '%s' is "
+ "experimental.%nVM startup expected to fail without "
+ "-XX:+UnlockExperimentalVMOptions option", optionName);
String shouldPassMessage = String.format("VM option '%s' is "
+ "experimental%nVM startup should pass with "
+ "-XX:+UnlockExperimentalVMOptions option", optionName);
if (isExperimental) {
// verify that option is experimental
CommandLineOptionTest.verifySameJVMStartup(
new String[] { experimentalOptionError },
new String[] { errorMessage }, shouldFailMessage,
shouldFailMessage, ExitCode.FAIL, optionValue);
// verify that it could be passed if experimental options
// are unlocked
CommandLineOptionTest.verifySameJVMStartup(null,
new String[] {
experimentalOptionError,
errorMessage
},
shouldPassMessage,
"JVM should start without any warnings or errors",
ExitCode.OK,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
optionValue);
} else {
// verify that option could be passed
CommandLineOptionTest.verifySameJVMStartup(null,
new String[]{errorMessage},
String.format("VM startup shuld pass with '%s' option",
optionName),
"JVM should start without any warnings or errors",
ExitCode.OK, optionValue);
}
}
protected void verifyOptionValues() throws Throwable {
// verify default value
if (isExperimental) {
CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
defaultValue,
String.format("Option '%s' is expected to have '%s' "
+ "default value", optionName, defaultValue),
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
} else {
CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
defaultValue,
String.format("Option '%s' is expected to have '%s' "
+ "default value", optionName, defaultValue));
}
// verify other specified option values
if (optionValues == null) {
return;
}
for (String value : optionValues) {
if (isExperimental) {
CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
value,
String.format("Option '%s' is set to have '%s' value",
optionName, value),
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
prepareOptionValue(value));
} else {
CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
value,
String.format("Option '%s' is set to have '%s' value",
optionName, value), prepareOptionValue(value));
}
}
}
protected String prepareOptionValue(String value) {
if (isBoolean) {
return CommandLineOptionTest.prepareBooleanFlag(optionName,
Boolean.valueOf(value));
} else {
return String.format("-XX:%s=%s", optionName, value);
}
}
}

@ -1,158 +0,0 @@
/*
* Copyright (c) 2014, 2016, Oracle and/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.
*/
package compiler.rtm.cli;
import jdk.test.lib.process.ExitCode;
import jdk.test.lib.cli.CommandLineOptionTest;
import java.util.LinkedList;
import java.util.List;
/**
* Base for all RTM-related CLI tests on options whose processing depends
* on UseRTMLocking value.
*
* Since UseRTMLocking option could be used when both CPU and VM supports RTM
* locking, this test will be skipped on all unsupported configurations.
*/
public abstract class RTMLockingAwareTest
extends RTMGenericCommandLineOptionTest {
protected final String warningMessage;
protected final String[] correctValues;
protected final String[] incorrectValues;
/**
* Constructs new test for option {@code optionName} that should be executed
* only on CPU with RTM support.
* Test will be executed using set of correct values from
* {@code correctValues} and set of incorrect values from
* {@code incorrectValues}.
*
* @param optionName name of option to be tested
* @param isBoolean {@code true} if tested option is binary
* @param isExperimental {@code true} if tested option is experimental
* @param defaultValue default value of tested option
* @param correctValues array with correct values, that should not emit
* {@code warningMessage} to VM output
* @param incorrectValues array with incorrect values, that should emit
* {@code waningMessage} to VM output
* @param warningMessage warning message associated with tested option
*/
protected RTMLockingAwareTest(String optionName, boolean isBoolean,
boolean isExperimental, String defaultValue,
String[] correctValues, String[] incorrectValues,
String warningMessage) {
super(optionName, isBoolean, isExperimental, defaultValue);
this.correctValues = correctValues;
this.incorrectValues = incorrectValues;
this.warningMessage = warningMessage;
}
@Override
protected void verifyJVMStartup() throws Throwable {
// Run generic sanity checks
super.verifyJVMStartup();
// Verify how option values will be processed depending on
// UseRTMLocking value.
if (correctValues != null) {
for (String correctValue : correctValues) {
// For correct values it is expected to see no warnings
// regardless to UseRTMLocking
verifyStartupWarning(correctValue, true, false);
verifyStartupWarning(correctValue, false, false);
}
}
if (incorrectValues != null) {
for (String incorrectValue : incorrectValues) {
// For incorrect values it is expected to see warning
// only with -XX:+UseRTMLocking
verifyStartupWarning(incorrectValue, true, true);
verifyStartupWarning(incorrectValue, false, false);
}
}
}
@Override
protected void verifyOptionValues() throws Throwable {
super.verifyOptionValues();
// Verify how option values will be setup after processing
// depending on UseRTMLocking value
if (correctValues != null) {
for (String correctValue : correctValues) {
// Correct value could be set up regardless to UseRTMLocking
verifyOptionValues(correctValue, false, correctValue);
verifyOptionValues(correctValue, true, correctValue);
}
}
if (incorrectValues != null) {
for (String incorrectValue : incorrectValues) {
// With -XX:+UseRTMLocking, incorrect value will be changed to
// default value.
verifyOptionValues(incorrectValue, false, incorrectValue);
verifyOptionValues(incorrectValue, true, defaultValue);
}
}
}
private void verifyStartupWarning(String value, boolean useRTMLocking,
boolean isWarningExpected) throws Throwable {
String warnings[] = new String[] { warningMessage };
List<String> options = new LinkedList<>();
options.add(CommandLineOptionTest.prepareBooleanFlag("UseRTMLocking",
useRTMLocking));
if (isExperimental) {
options.add(CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
}
options.add(prepareOptionValue(value));
String errorString = String.format("JVM should start with option '%s'"
+ "'%nWarnings should be shown: %s", optionName,
isWarningExpected);
CommandLineOptionTest.verifySameJVMStartup(
(isWarningExpected ? warnings : null),
(isWarningExpected ? null : warnings),
errorString, errorString, ExitCode.OK,
options.toArray(new String[options.size()]));
}
private void verifyOptionValues(String value, boolean useRTMLocking,
String expectedValue) throws Throwable {
List<String> options = new LinkedList<>();
options.add(CommandLineOptionTest.prepareBooleanFlag("UseRTMLocking",
useRTMLocking));
if (isExperimental) {
options.add(CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
}
options.add(prepareOptionValue(value));
CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
expectedValue, String.format("Option '%s' should have '%s' "
+ "value if '%s' flag set",
optionName, expectedValue, prepareOptionValue(value)),
options.toArray(new String[options.size()]));
}
}

@ -1,102 +0,0 @@
/*
* Copyright (c) 2014, 2016, Oracle and/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.
*/
package compiler.rtm.cli;
import jdk.test.lib.process.ExitCode;
import jdk.test.lib.Platform;
import jdk.test.lib.cli.CommandLineOptionTest;
public abstract class TestPrintPreciseRTMLockingStatisticsBase
extends RTMGenericCommandLineOptionTest {
protected static final String DEFAULT_VALUE = "false";
protected TestPrintPreciseRTMLockingStatisticsBase() {
super("PrintPreciseRTMLockingStatistics", true, false,
TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE);
}
@Override
protected void runNonX86TestCases() throws Throwable {
verifyJVMStartup();
verifyOptionValues();
}
@Override
protected void verifyJVMStartup() throws Throwable {
if (Platform.isServer()) {
if (!Platform.isDebugBuild()) {
String shouldFailMessage = String.format("VM option '%s' is "
+ "diagnostic%nJVM startup should fail without "
+ "-XX:\\+UnlockDiagnosticVMOptions flag", optionName);
String shouldPassMessage = String.format("VM option '%s' is "
+ "diagnostic%nJVM startup should pass with "
+ "-XX:\\+UnlockDiagnosticVMOptions in debug build",
optionName);
String errorMessage = CommandLineOptionTest.
getDiagnosticOptionErrorMessage(optionName);
// verify that option is actually diagnostic
CommandLineOptionTest.verifySameJVMStartup(
new String[] { errorMessage }, null, shouldFailMessage,
shouldFailMessage, ExitCode.FAIL,
prepareOptionValue("true"));
CommandLineOptionTest.verifySameJVMStartup(null,
new String[] { errorMessage }, shouldPassMessage,
shouldPassMessage + "without any warnings", ExitCode.OK,
CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
prepareOptionValue("true"));
} else {
String shouldPassMessage = String.format("JVM startup should "
+ "pass with '%s' option in debug build",
optionName);
CommandLineOptionTest.verifySameJVMStartup(null, null,
shouldPassMessage, shouldPassMessage,
ExitCode.OK, prepareOptionValue("true"));
}
} else {
String errorMessage = CommandLineOptionTest.
getUnrecognizedOptionErrorMessage(optionName);
String shouldFailMessage = String.format("JVM startup should fail"
+ " with '%s' option in not debug build", optionName);
CommandLineOptionTest.verifySameJVMStartup(
new String[]{errorMessage}, null, shouldFailMessage,
shouldFailMessage, ExitCode.FAIL,
CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
prepareOptionValue("true"));
}
}
@Override
protected void verifyOptionValues() throws Throwable {
if (Platform.isServer()) {
// Verify default value
CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE,
String.format("Option '%s' should have '%s' default value",
optionName,
TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE),
CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS);
}
}
}

@ -1,81 +0,0 @@
/*
* Copyright (c) 2014, 2021, Oracle and/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
* @bug 8031320
* @summary Verify PrintPreciseRTMLockingStatistics on CPUs and OSs with
* rtm support and on VM with rtm locking support,
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.flagless
* @requires vm.rtm.cpu & vm.rtm.compiler
* @run driver compiler.rtm.cli.TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig
*/
package compiler.rtm.cli;
import jdk.test.lib.cli.CommandLineOptionTest;
public class TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig
extends TestPrintPreciseRTMLockingStatisticsBase {
@Override
protected void verifyOptionValues() throws Throwable {
super.verifyOptionValues();
// verify default value
CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE,
String.format("Option '%s' should have '%s' default value on"
+ " supported CPU", optionName,
TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE),
CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:+UseRTMLocking");
CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE,
String.format("Option '%s' should have '%s' default value on"
+ " supported CPU when -XX:-UseRTMLocking flag set",
optionName,
TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE),
CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:-UseRTMLocking", prepareOptionValue("true"));
// verify that option could be turned on
CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true",
String.format("Option '%s' should have 'true' value when set "
+ "on supported CPU and -XX:+UseRTMLocking flag set",
optionName),
CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:+UseRTMLocking", prepareOptionValue("true"));
}
public static void main(String args[]) throws Throwable {
new TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig()
.runTestCases();
}
}

@ -1,46 +0,0 @@
/*
* Copyright (c) 2014, 2021, Oracle and/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
* @bug 8031320
* @summary Verify PrintPreciseRTMLockingStatistics on CPUs or OSs without
* rtm support and/or unsupported VM.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.flagless
* @requires !vm.rtm.cpu & vm.rtm.compiler
* @run driver compiler.rtm.cli.TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig
*/
package compiler.rtm.cli;
public class TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig
extends TestPrintPreciseRTMLockingStatisticsBase {
public static void main(String args[]) throws Throwable {
new TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig()
.runTestCases();
}
}

@ -1,51 +0,0 @@
/*
* Copyright (c) 2014, 2021, Oracle and/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
* @bug 8031320
* @summary Verify processing of RTMAbortThreshold option.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.flagless
* @requires vm.rtm.compiler
* @run driver compiler.rtm.cli.TestRTMAbortThresholdOption
*/
package compiler.rtm.cli;
public class TestRTMAbortThresholdOption
extends RTMGenericCommandLineOptionTest {
private static final String DEFAULT_VALUE = "1000";
private TestRTMAbortThresholdOption() {
super("RTMAbortThreshold", false, true,
TestRTMAbortThresholdOption.DEFAULT_VALUE,
"0", "42", "100", "10000");
}
public static void main(String args[]) throws Throwable {
new TestRTMAbortThresholdOption().runTestCases();
}
}

@ -1,50 +0,0 @@
/*
* Copyright (c) 2014, 2021, Oracle and/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
* @bug 8031320
* @summary Verify processing of RTMLockingCalculationDelay option.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.flagless
* @requires vm.rtm.compiler
* @run driver compiler.rtm.cli.TestRTMLockingCalculationDelayOption
*/
package compiler.rtm.cli;
public class TestRTMLockingCalculationDelayOption
extends RTMGenericCommandLineOptionTest {
private static final String DEFAULT_VALUE = "0";
private TestRTMLockingCalculationDelayOption() {
super("RTMLockingCalculationDelay", false,
true, TestRTMLockingCalculationDelayOption.DEFAULT_VALUE);
}
public static void main(String agrs[]) throws Throwable {
new TestRTMLockingCalculationDelayOption().runTestCases();
}
}

@ -1,50 +0,0 @@
/*
* Copyright (c) 2014, 2021, Oracle and/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
* @bug 8031320
* @summary Verify processing of RTMLockingThreshold option.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.flagless
* @requires vm.rtm.compiler
* @run driver compiler.rtm.cli.TestRTMLockingThresholdOption
*/
package compiler.rtm.cli;
public class TestRTMLockingThresholdOption
extends RTMGenericCommandLineOptionTest {
private static final String DEFAULT_VALUE = "10000";
private TestRTMLockingThresholdOption() {
super("RTMLockingThreshold", false, true,
TestRTMLockingThresholdOption.DEFAULT_VALUE);
}
public static void main(String args[]) throws Throwable {
new TestRTMLockingThresholdOption().runTestCases();
}
}

@ -1,50 +0,0 @@
/*
* Copyright (c) 2014, 2021, Oracle and/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
* @bug 8031320
* @summary Verify processing of RTMRetryCount option.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.flagless
* @requires vm.rtm.compiler
* @run driver compiler.rtm.cli.TestRTMRetryCountOption
*/
package compiler.rtm.cli;
public class TestRTMRetryCountOption extends RTMGenericCommandLineOptionTest {
private static final String DEFAULT_VALUE = "5";
private TestRTMRetryCountOption() {
super("RTMRetryCount", false, false,
TestRTMRetryCountOption.DEFAULT_VALUE,
"0", "10", "100", "1000");
}
public static void main(String args[]) throws Throwable {
new TestRTMRetryCountOption().runTestCases();
}
}

@ -1,51 +0,0 @@
/*
* Copyright (c) 2014, 2021, Oracle and/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
* @bug 8031320
* @summary Verify processing of RTMSpinLoopCount option.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.flagless
* @requires vm.rtm.compiler
* @run driver compiler.rtm.cli.TestRTMSpinLoopCountOption
*/
package compiler.rtm.cli;
public class TestRTMSpinLoopCountOption
extends RTMGenericCommandLineOptionTest {
private static final String DEFAULT_VALUE = "100";
private TestRTMSpinLoopCountOption() {
super("RTMSpinLoopCount", false, true,
TestRTMSpinLoopCountOption.DEFAULT_VALUE,
"0", "10", "42", "1000");
}
public static void main(String args[]) throws Throwable {
new TestRTMSpinLoopCountOption().runTestCases();
}
}

@ -1,56 +0,0 @@
/*
* Copyright (c) 2014, 2021, Oracle and/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
* @bug 8031320
* @summary Verify RTMTotalCountIncrRate option processing on CPU and OS with
* rtm support and on VM with rtm locking support.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.flagless
* @requires vm.rtm.cpu & vm.rtm.compiler
* @run driver compiler.rtm.cli.TestRTMTotalCountIncrRateOptionOnSupportedConfig
*/
package compiler.rtm.cli;
public class TestRTMTotalCountIncrRateOptionOnSupportedConfig
extends RTMLockingAwareTest {
private static final String DEFAULT_VALUE = "64";
private TestRTMTotalCountIncrRateOptionOnSupportedConfig() {
super("RTMTotalCountIncrRate", false, true,
TestRTMTotalCountIncrRateOptionOnSupportedConfig.DEFAULT_VALUE,
/* correct values */
new String[] { "1", "2", "128", "1024" },
/* incorrect values */
new String[] { "3", "5", "7", "42" },
RTMGenericCommandLineOptionTest.RTM_COUNT_INCR_WARNING);
}
public static void main(String args[]) throws Throwable {
new TestRTMTotalCountIncrRateOptionOnSupportedConfig().runTestCases();
}
}

@ -1,87 +0,0 @@
/*
* Copyright (c) 2014, 2021, Oracle and/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
* @bug 8031320
* @summary Verify UseRTMDeopt option processing on CPUs with rtm support
* when rtm locking is supported by VM.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.flagless
* @requires vm.rtm.cpu & vm.rtm.compiler
* @run driver compiler.rtm.cli.TestUseRTMDeoptOptionOnSupportedConfig
*/
package compiler.rtm.cli;
import jdk.test.lib.process.ExitCode;
import jdk.test.lib.cli.CommandLineOptionTest;
public class TestUseRTMDeoptOptionOnSupportedConfig {
private static final String DEFAULT_VALUE = "false";
public void runTestCases() throws Throwable {
String shouldPassMessage = " JVM should startup with option '"
+ "-XX:+UseRTMDeopt' without any warnings";
// verify that option could be turned on
CommandLineOptionTest.verifySameJVMStartup(
null, null, shouldPassMessage, shouldPassMessage, ExitCode.OK,
"-XX:+UseRTMDeopt");
shouldPassMessage = " JVM should startup with option '"
+ "-XX:-UseRTMDeopt' without any warnings";
// verify that option could be turned off
CommandLineOptionTest.verifySameJVMStartup(
null, null, shouldPassMessage, shouldPassMessage, ExitCode.OK,
"-XX:-UseRTMDeopt");
String defValMessage = String.format("UseRTMDeopt should have '%s'"
+ "default value",
TestUseRTMDeoptOptionOnSupportedConfig.DEFAULT_VALUE);
// verify default value
CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt",
TestUseRTMDeoptOptionOnSupportedConfig.DEFAULT_VALUE,
defValMessage);
// verify default value
CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt",
TestUseRTMDeoptOptionOnSupportedConfig.DEFAULT_VALUE,
defValMessage,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:+UseRTMLocking");
// verify that option is off when UseRTMLocking is off
CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt",
"false", "UseRTMDeopt should be off when UseRTMLocking is off",
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:-UseRTMLocking", "-XX:+UseRTMDeopt");
// verify that option could be turned on
CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt", "true",
"UseRTMDeopt should be on when UseRTMLocking is on and "
+ "'-XX:+UseRTMDeopt' flag set",
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:+UseRTMLocking", "-XX:+UseRTMDeopt");
}
public static void main(String args[]) throws Throwable {
new TestUseRTMDeoptOptionOnSupportedConfig().runTestCases();
}
}

@ -1,71 +0,0 @@
/*
* Copyright (c) 2014, 2021, Oracle and/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
* @bug 8031320
* @summary Verify UseRTMDeopt option processing on CPUs or OSs without rtm support
* or on VMs without rtm locking support.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.flagless
* @requires !vm.rtm.cpu & vm.rtm.compiler
* @run driver compiler.rtm.cli.TestUseRTMDeoptOptionOnUnsupportedConfig
*/
package compiler.rtm.cli;
import jdk.test.lib.cli.CommandLineOptionTest;
public class TestUseRTMDeoptOptionOnUnsupportedConfig
extends RTMGenericCommandLineOptionTest {
private static final String DEFAULT_VALUE = "false";
private TestUseRTMDeoptOptionOnUnsupportedConfig() {
super("UseRTMDeopt", true, false,
TestUseRTMDeoptOptionOnUnsupportedConfig.DEFAULT_VALUE,
"true");
}
@Override
protected void runX86SupportedVMTestCases() throws Throwable {
super.verifyJVMStartup();
// verify default value
CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
defaultValue, String.format("'%s' should have '%s' "
+ "default value on unsupported configs.",
optionName, DEFAULT_VALUE));
// verify that until RTMLocking is not used, value
// will be set to default false.
CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
defaultValue, String.format("'%s' should be off on unsupported"
+ " configs even if '-XX:+%s' flag set", optionName,
optionName),
"-XX:+UseRTMDeopt");
}
public static void main(String args[]) throws Throwable {
new TestUseRTMDeoptOptionOnUnsupportedConfig().runTestCases();
}
}

@ -1,118 +0,0 @@
/*
* Copyright (c) 2014, 2021, Oracle and/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
* @bug 8031320
* @summary Verify UseRTMForStackLocks option processing on CPU and OS with
* rtm support when VM supports rtm locking.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.flagless
* @requires vm.rtm.cpu & vm.rtm.compiler
* @run driver compiler.rtm.cli.TestUseRTMForStackLocksOptionOnSupportedConfig
*/
package compiler.rtm.cli;
import jdk.test.lib.process.ExitCode;
import jdk.test.lib.cli.CommandLineOptionTest;
public class TestUseRTMForStackLocksOptionOnSupportedConfig {
private static final String DEFAULT_VALUE = "false";
public void runTestCases() throws Throwable {
String errorMessage
= CommandLineOptionTest.getExperimentalOptionErrorMessage(
"UseRTMForStackLocks");
String warningMessage
= RTMGenericCommandLineOptionTest.RTM_FOR_STACK_LOCKS_WARNING;
String shouldFailMessage = " VM option 'UseRTMForStackLocks' is "
+ "experimental%nJVM startup should fail without "
+ "-XX:+UnlockExperimentalVMOptions flag";
CommandLineOptionTest.verifySameJVMStartup(
new String[] { errorMessage }, null, shouldFailMessage,
shouldFailMessage + "%nError message expected", ExitCode.FAIL,
"-XX:+UseRTMForStackLocks");
String shouldPassMessage = " VM option 'UseRTMForStackLocks'"
+ " is experimental%nJVM startup should pass with "
+ "-XX:+UnlockExperimentalVMOptions flag";
// verify that we get a warning when trying to use rtm for stack
// lock, but not using rtm locking.
CommandLineOptionTest.verifySameJVMStartup(
new String[] { warningMessage }, null, shouldPassMessage,
"There should be warning when trying to use rtm for stack "
+ "lock, but not using rtm locking", ExitCode.OK,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:+UseRTMForStackLocks",
"-XX:-UseRTMLocking");
// verify that we don't get a warning when no using rtm for stack
// lock and not using rtm locking.
CommandLineOptionTest.verifySameJVMStartup(null,
new String[] { warningMessage }, shouldPassMessage,
"There should not be any warning when use both "
+ "-XX:-UseRTMForStackLocks and -XX:-UseRTMLocking "
+ "flags",
ExitCode.OK,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:-UseRTMForStackLocks",
"-XX:-UseRTMLocking");
// verify that we don't get a warning when using rtm for stack
// lock and using rtm locking.
CommandLineOptionTest.verifySameJVMStartup(null,
new String[] { warningMessage }, shouldPassMessage,
"There should not be any warning when use both "
+ "-XX:+UseRTMForStackLocks and -XX:+UseRTMLocking"
+ " flags",
ExitCode.OK,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:+UseRTMForStackLocks",
"-XX:+UseRTMLocking");
// verify that default value if false
CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMForStackLocks",
TestUseRTMForStackLocksOptionOnSupportedConfig.DEFAULT_VALUE,
"Default value of option 'UseRTMForStackLocks' should be false",
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
// verify that default value is false even with +UseRTMLocking
CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMForStackLocks",
TestUseRTMForStackLocksOptionOnSupportedConfig.DEFAULT_VALUE,
"Default value of option 'UseRTMForStackLocks' should be false",
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:+UseRTMLocking");
// verify that we can turn the option on
CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMForStackLocks",
"true", "Value of option 'UseRTMForStackLocks' should "
+ "be able to be set as 'true' when both "
+ "-XX:+UseRTMForStackLocks and "
+ "-XX:+UseRTMLocking flags used",
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:+UseRTMLocking", "-XX:+UseRTMForStackLocks");
}
public static void main(String args[]) throws Throwable {
new TestUseRTMForStackLocksOptionOnSupportedConfig().runTestCases();
}
}

@ -1,105 +0,0 @@
/*
* Copyright (c) 2014, 2021, Oracle and/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
* @bug 8031320
* @summary Verify UseRTMForStackLocks option processing on CPUs or OSs without
* rtm support and/or on VMs without rtm locking support.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.flagless
* @requires !vm.rtm.cpu & vm.rtm.compiler
* @run driver compiler.rtm.cli.TestUseRTMForStackLocksOptionOnUnsupportedConfig
*/
package compiler.rtm.cli;
import jdk.test.lib.process.ExitCode;
import jdk.test.lib.cli.CommandLineOptionTest;
public class TestUseRTMForStackLocksOptionOnUnsupportedConfig
extends RTMGenericCommandLineOptionTest {
private static final String DEFAULT_VALUE = "false";
private TestUseRTMForStackLocksOptionOnUnsupportedConfig() {
super("UseRTMForStackLocks", true, true,
TestUseRTMForStackLocksOptionOnUnsupportedConfig.DEFAULT_VALUE,
"true");
}
@Override
protected void runX86SupportedVMTestCases() throws Throwable {
String shouldFailMessage = String.format("VM option '%s' is "
+ "experimental%nJVM startup should fail without "
+ "-XX:+UnlockExperimentalVMOptions flag", optionName);
// verify that option is experimental
CommandLineOptionTest.verifySameJVMStartup(
new String[] { experimentalOptionError }, null,
shouldFailMessage, shouldFailMessage + "%nError message "
+ "should be shown", ExitCode.FAIL,
prepareOptionValue("true"));
CommandLineOptionTest.verifySameJVMStartup(
new String[]{ experimentalOptionError }, null,
shouldFailMessage, shouldFailMessage + "%nError message "
+ "should be shown", ExitCode.FAIL,
prepareOptionValue("false"));
String shouldPassMessage = String.format("VM option '%s' is "
+ " experimental%nJVM startup should pass with "
+ "-XX:+UnlockExperimentalVMOptions flag", optionName);
// verify that if we turn it on, then VM output will contain
// warning saying that this option could be turned on only
// when we use rtm locking
CommandLineOptionTest.verifySameJVMStartup(
new String[]{
RTMGenericCommandLineOptionTest.RTM_FOR_STACK_LOCKS_WARNING
}, null, shouldPassMessage, "There should be warning when try "
+ "to use rtm for stack lock, but not using rtm locking",
ExitCode.OK,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
prepareOptionValue("true")
);
// verify that options is turned off by default
CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
TestUseRTMForStackLocksOptionOnUnsupportedConfig.DEFAULT_VALUE,
String.format("Default value of option '%s' should be '%s'",
optionName, DEFAULT_VALUE),
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
// verify that it could not be turned on without rtm locking
CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
TestUseRTMForStackLocksOptionOnUnsupportedConfig.DEFAULT_VALUE,
String.format("Value of '%s' shouldn't able to be set to "
+ "'true' without setting -XX:+UseRTMLocking flag",
optionName),
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
prepareOptionValue("true"));
}
public static void main(String args[]) throws Throwable {
new TestUseRTMForStackLocksOptionOnUnsupportedConfig().runTestCases();
}
}

@ -1,95 +0,0 @@
/*
* Copyright (c) 2014, 2021, Oracle and/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
* @bug 8031320
* @summary Verify UseRTMLocking option processing on CPU and OS with rtm support and
* on VM with rtm locking support.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.flagless
* @requires vm.rtm.cpu & vm.rtm.compiler
* @run driver compiler.rtm.cli.TestUseRTMLockingOptionOnSupportedConfig
*/
package compiler.rtm.cli;
import jdk.test.lib.process.ExitCode;
import jdk.test.lib.cli.CommandLineOptionTest;
public class TestUseRTMLockingOptionOnSupportedConfig {
private static final String DEFAULT_VALUE = "false";
public void runTestCases() throws Throwable {
String unrecongnizedOption
= CommandLineOptionTest.getUnrecognizedOptionErrorMessage(
"UseRTMLocking");
String shouldPassMessage = "VM option 'UseRTMLocking' is experimental"
+ "%nJVM startup should pass with "
+ "-XX:+UnlockExperimentalVMOptions flag";
// verify that there are no warning or error in VM output
CommandLineOptionTest.verifySameJVMStartup(null,
new String[]{
RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR,
unrecongnizedOption
}, shouldPassMessage, "There should not be any warning when use"
+ "with -XX:+UnlockExperimentalVMOptions", ExitCode.OK,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:+UseRTMLocking"
);
CommandLineOptionTest.verifySameJVMStartup(null,
new String[]{
RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR,
unrecongnizedOption
}, shouldPassMessage, "There should not be any warning when use"
+ "with -XX:+UnlockExperimentalVMOptions", ExitCode.OK,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:-UseRTMLocking"
);
// verify that UseRTMLocking is of by default
CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
TestUseRTMLockingOptionOnSupportedConfig.DEFAULT_VALUE,
String.format("Default value of option 'UseRTMLocking' should "
+ "be '%s'", DEFAULT_VALUE),
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
// verify that we can change UseRTMLocking value
CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
TestUseRTMLockingOptionOnSupportedConfig.DEFAULT_VALUE,
String.format("Default value of option 'UseRTMLocking' should "
+ "be '%s'", DEFAULT_VALUE),
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:-UseRTMLocking");
CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
"true", "Value of 'UseRTMLocking' should be set "
+ "to 'true' if -XX:+UseRTMLocking flag set",
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:+UseRTMLocking");
}
public static void main(String args[]) throws Throwable {
new TestUseRTMLockingOptionOnSupportedConfig().runTestCases();
}
}

@ -1,98 +0,0 @@
/*
* Copyright (c) 2014, 2021, Oracle and/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
* @bug 8031320
* @summary Verify UseRTMLocking option processing on CPUs without
* rtm support.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.flagless
* @requires !vm.rtm.cpu & vm.rtm.compiler
* @run driver compiler.rtm.cli.TestUseRTMLockingOptionOnUnsupportedCPU
*/
package compiler.rtm.cli;
import jdk.test.lib.process.ExitCode;
import jdk.test.lib.Platform;
import jdk.test.lib.cli.CommandLineOptionTest;
public class TestUseRTMLockingOptionOnUnsupportedCPU {
private static final String DEFAULT_VALUE = "false";
public void runTestCases() throws Throwable {
String unrecognizedOption
= CommandLineOptionTest.getUnrecognizedOptionErrorMessage(
"UseRTMLocking");
String errorMessage = RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR;
if (Platform.isX86() || Platform.isX64()) {
String shouldFailMessage = "JVM startup should fail with option " +
"-XX:+UseRTMLocking on unsupported CPU";
// verify that we get an error when use +UseRTMLocking
// on unsupported CPU
CommandLineOptionTest.verifySameJVMStartup(
new String[] { errorMessage },
new String[] { unrecognizedOption }, shouldFailMessage,
shouldFailMessage + ". Error message should be shown.",
ExitCode.FAIL, "-XX:+UseRTMLocking");
String shouldPassMessage = "JVM startup should pass with option "
+ "-XX:-UseRTMLocking even on unsupported CPU";
// verify that we can pass -UseRTMLocking without
// getting any error messages
CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
errorMessage, unrecognizedOption }, shouldPassMessage,
shouldPassMessage + " without any warnings", ExitCode.OK,
"-XX:-UseRTMLocking");
// verify that UseRTMLocking is false by default
CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
TestUseRTMLockingOptionOnUnsupportedCPU.DEFAULT_VALUE,
String.format("Default value of option 'UseRTMLocking' "
+"should be '%s'", DEFAULT_VALUE));
} else {
String shouldFailMessage = "RTMLocking should be unrecognized"
+ " on non-x86 CPUs. JVM startup should fail."
+ "Error message should be shown";
// verify that on non-x86 CPUs RTMLocking could not be used
CommandLineOptionTest.verifySameJVMStartup(
new String[] { unrecognizedOption },
null, shouldFailMessage, shouldFailMessage,
ExitCode.FAIL, "-XX:+UseRTMLocking");
CommandLineOptionTest.verifySameJVMStartup(
new String[] { unrecognizedOption },
null, shouldFailMessage, shouldFailMessage,
ExitCode.FAIL, "-XX:-UseRTMLocking");
}
}
public static void main(String args[]) throws Throwable {
new TestUseRTMLockingOptionOnUnsupportedCPU().runTestCases();
}
}

@ -1,73 +0,0 @@
/*
* Copyright (c) 2014, 2021, Oracle and/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
* @bug 8031320
* @summary Verify UseRTMLocking option processing on CPU with rtm support
* in case when VM should not support this option.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.flagless
* @requires vm.rtm.cpu & !(vm.flavor == "server" & !vm.emulatedClient)
* @run driver compiler.rtm.cli.TestUseRTMLockingOptionOnUnsupportedVM
*/
package compiler.rtm.cli;
import jdk.test.lib.process.ExitCode;
import jdk.test.lib.cli.CommandLineOptionTest;
public class TestUseRTMLockingOptionOnUnsupportedVM {
private static final String DEFAULT_VALUE = "false";
public void runTestCases() throws Throwable {
String errorMessage
= RTMGenericCommandLineOptionTest.RTM_UNSUPPORTED_VM_ERROR;
String shouldFailMessage = "JVM startup should fail with option "
+ "-XX:+UseRTMLocking even on unsupported VM. Error message"
+ " should be shown";
String shouldPassMessage = "JVM startup should pass with option "
+ "-XX:-UseRTMLocking even on unsupported VM";
// verify that we can't use +UseRTMLocking
CommandLineOptionTest.verifySameJVMStartup(
new String[] { errorMessage }, null, shouldFailMessage,
shouldFailMessage, ExitCode.FAIL,
"-XX:+UseRTMLocking");
// verify that we can turn it off
CommandLineOptionTest.verifySameJVMStartup(null,
new String[] { errorMessage }, shouldPassMessage,
shouldPassMessage + " without any warnings", ExitCode.OK,
"-XX:-UseRTMLocking");
// verify that it is off by default
CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
TestUseRTMLockingOptionOnUnsupportedVM.DEFAULT_VALUE,
String.format("Default value of option 'UseRTMLocking' should"
+ " be '%s'", DEFAULT_VALUE));
}
public static void main(String args[]) throws Throwable {
new TestUseRTMLockingOptionOnUnsupportedVM().runTestCases();
}
}

@ -1,50 +0,0 @@
/*
* Copyright (c) 2014, 2021, Oracle and/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
* @bug 8031320
* @summary Verify processing of UseRTMXendForLockBusy option.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.flagless
* @requires vm.rtm.compiler
* @run driver compiler.rtm.cli.TestUseRTMXendForLockBusyOption
*/
package compiler.rtm.cli;
public class TestUseRTMXendForLockBusyOption
extends RTMGenericCommandLineOptionTest {
private static final String DEFAULT_VALUE = "true";
public TestUseRTMXendForLockBusyOption() {
super("UseRTMXendForLockBusy", true, true,
TestUseRTMXendForLockBusyOption.DEFAULT_VALUE, "true");
}
public static void main(String agrs[]) throws Throwable {
new TestUseRTMXendForLockBusyOption().runTestCases();
}
}

@ -1,165 +0,0 @@
/*
* Copyright (c) 2014, 2022, Oracle and/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
* @bug 8031320
* @summary Verify that RTMAbortRatio affects amount of aborts before
* deoptimization.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.rtm.cpu & vm.rtm.compiler
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm/native -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.rtm.locking.TestRTMAbortRatio
*/
package compiler.rtm.locking;
import compiler.testlibrary.rtm.AbortProvoker;
import compiler.testlibrary.rtm.XAbortProvoker;
import compiler.testlibrary.rtm.CompilableTest;
import compiler.testlibrary.rtm.RTMLockingStatistics;
import compiler.testlibrary.rtm.RTMTestBase;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.cli.CommandLineOptionTest;
import java.util.List;
/**
* Test verifies that method will be deoptimized on high abort ratio
* as soon as abort ratio reaches RTMAbortRatio's value.
*/
public class TestRTMAbortRatio {
protected void runTestCases() throws Throwable {
verifyAbortRatio(0, false);
verifyAbortRatio(10, false);
verifyAbortRatio(50, false);
verifyAbortRatio(100, false);
verifyAbortRatio(0, true);
verifyAbortRatio(10, true);
verifyAbortRatio(50, true);
verifyAbortRatio(100, true);
}
private void verifyAbortRatio(int abortRatio, boolean useStackLock)
throws Throwable {
CompilableTest test = new Test();
OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
test,
CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
useStackLock),
"-XX:+UseRTMDeopt",
"-XX:RTMTotalCountIncrRate=1",
"-XX:RTMAbortThreshold=0",
CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold",
10 * Test.TOTAL_ITERATIONS),
CommandLineOptionTest.prepareNumericFlag("RTMAbortRatio",
abortRatio),
"-XX:+PrintPreciseRTMLockingStatistics",
test.getClass().getName(),
Boolean.toString(!useStackLock));
outputAnalyzer.shouldHaveExitValue(0);
List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
test.getMethodWithLockName(), outputAnalyzer.getOutput());
Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+ "exactly one RTM locking statistics entry.");
RTMLockingStatistics lock = statistics.get(0);
int actualRatio;
if (lock.getTotalAborts() == 1L) {
actualRatio = 0;
} else {
actualRatio = (int) (lock.getTotalLocks()
/ (lock.getTotalAborts() - 1L));
}
Asserts.assertLTE(actualRatio, abortRatio, String.format(
"Actual abort ratio (%d) should lower or equal to "
+ "specified (%d).", actualRatio, abortRatio));
}
/**
* Force abort after {@code Test.WARMUP_ITERATIONS} is done.
*/
public static class Test implements CompilableTest {
private static final int TOTAL_ITERATIONS = 10000;
private static final int WARMUP_ITERATIONS = 1000;
private final XAbortProvoker xabort = new XAbortProvoker();
private final Object monitor = new Object();
// Following field have to be static in order to avoid escape analysis.
@SuppressWarnings("UnsuedDeclaration")
private static int field = 0;
@Override
public String getMethodWithLockName() {
return this.getClass().getName() + "::lock";
}
@Override
public String[] getMethodsToCompileNames() {
return new String[] { getMethodWithLockName(), "*.doAbort" };
}
public void lock(boolean abort) {
synchronized(monitor) {
if (abort) {
xabort.doAbort();
}
}
}
/**
* Usage:
* Test &lt;inflate monitor&gt;
*/
public static void main(String args[]) throws Throwable {
Asserts.assertGTE(args.length, 1, "One argument required.");
Test t = new Test();
boolean shouldBeInflated = Boolean.valueOf(args[0]);
if (shouldBeInflated) {
AbortProvoker.inflateMonitor(t.monitor);
}
for (int i = 0; i < Test.TOTAL_ITERATIONS; i++) {
AbortProvoker.verifyMonitorState(t.monitor, shouldBeInflated);
t.lock(i >= Test.WARMUP_ITERATIONS);
}
}
}
public static void main(String args[]) throws Throwable {
new TestRTMAbortRatio().runTestCases();
}
}

@ -1,105 +0,0 @@
/*
* Copyright (c) 2014, 2022, Oracle and/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
* @bug 8031320
* @summary Verify that RTMAbortThreshold option affects
* amount of aborts after which abort ratio is calculated.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.rtm.cpu & vm.rtm.compiler
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm/native -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.rtm.locking.TestRTMAbortThreshold
*/
package compiler.rtm.locking;
import compiler.testlibrary.rtm.AbortProvoker;
import compiler.testlibrary.rtm.AbortType;
import compiler.testlibrary.rtm.RTMLockingStatistics;
import compiler.testlibrary.rtm.RTMTestBase;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.cli.CommandLineOptionTest;
import java.util.List;
/**
* Test verifies that on RTMAbortThreshold option actually affects how soon
* method will be deoptimized on high abort ratio.
*/
public class TestRTMAbortThreshold {
protected void runTestCases() throws Throwable {
verifyAbortThreshold(false, 1);
verifyAbortThreshold(false, 10);
verifyAbortThreshold(false, 1000);
verifyAbortThreshold(true, 1);
verifyAbortThreshold(true, 10);
verifyAbortThreshold(true, 1000);
}
private void verifyAbortThreshold(boolean useStackLock,
long abortThreshold) throws Throwable {
AbortProvoker provoker = AbortType.XABORT.provoker();
OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
provoker,
"-XX:+UseRTMDeopt",
"-XX:RTMAbortRatio=0",
CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold",
abortThreshold),
CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
useStackLock),
"-XX:RTMTotalCountIncrRate=1",
"-XX:+PrintPreciseRTMLockingStatistics",
AbortProvoker.class.getName(),
AbortType.XABORT.toString(),
Boolean.toString(!useStackLock));
outputAnalyzer.shouldHaveExitValue(0);
List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+ "exactly one RTM locking statistics entry for method "
+ provoker.getMethodWithLockName());
Asserts.assertEQ(statistics.get(0).getTotalLocks(), abortThreshold,
String.format("Expected that method with rtm lock elision was"
+ " deoptimized after %d lock attempts",
abortThreshold));
}
public static void main(String args[]) throws Throwable {
new TestRTMAbortThreshold().runTestCases();
}
}

@ -1,212 +0,0 @@
/*
* Copyright (c) 2014, 2022, Oracle and/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
* @bug 8031320
* @summary Verify that if we use RTMDeopt, then deoptimization
* caused by reason other then rtm_state_change will reset
* method's RTM state. And if we don't use RTMDeopt, then
* RTM state remain the same after such deoptimization.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.rtm.cpu & vm.rtm.compiler
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm/native -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.rtm.locking.TestRTMAfterNonRTMDeopt
*/
package compiler.rtm.locking;
import compiler.testlibrary.rtm.AbortProvoker;
import compiler.testlibrary.rtm.XAbortProvoker;
import compiler.testlibrary.rtm.CompilableTest;
import compiler.testlibrary.rtm.RTMLockingStatistics;
import compiler.testlibrary.rtm.RTMTestBase;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.cli.CommandLineOptionTest;
import java.util.List;
/**
* To verify that with +UseRTMDeopt method's RTM state will be
* changed to ProfileRTM on deoptimization unrelated to
* rtm_state_change following sequence of events is used:
* <pre>
*
* rtm state ^
* |
* UseRTM | ******| ******
* | |
* ProfileRTM |******| |*****|
* | | | |
* 0-------|-----|-----|---------------------&gt; time
* | | \ force abort
* | |
* | \ force deoptimization
* |
* \ force xabort
* </pre>
* When xabort is forced by native method call method should
* change it's state to UseRTM, because we use RTMAbortRatio=100
* and low RTMLockingThreshold, so at this point actual abort
* ratio will be below 100% and there should be enough lock
* attempts to recompile method without RTM profiling.
*/
public class TestRTMAfterNonRTMDeopt {
private static final int ABORT_THRESHOLD = 1000;
private static final String RANGE_CHECK = "range_check";
protected void runTestCases() throws Throwable {
verifyRTMAfterDeopt(false, false);
verifyRTMAfterDeopt(true, false);
verifyRTMAfterDeopt(false, true);
verifyRTMAfterDeopt(true, true);
}
private void verifyRTMAfterDeopt(boolean useStackLock,
boolean useRTMDeopt) throws Throwable {
CompilableTest test = new Test();
String logFile = String.format("rtm_%s_stack_lock_%s_deopt.xml",
(useStackLock ? "use" : "no"), (useRTMDeopt ? "use" : "no"));
OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
logFile,
test,
"-XX:CompileThreshold=1",
CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
useStackLock),
CommandLineOptionTest.prepareBooleanFlag("UseRTMDeopt",
useRTMDeopt),
"-XX:RTMAbortRatio=100",
CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold",
TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD),
CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold",
TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD / 2L),
"-XX:RTMTotalCountIncrRate=1",
"-XX:+PrintPreciseRTMLockingStatistics",
Test.class.getName(),
Boolean.toString(!useStackLock)
);
outputAnalyzer.shouldHaveExitValue(0);
int traps = RTMTestBase.firedRTMStateChangeTraps(logFile);
if (useRTMDeopt) {
Asserts.assertEQ(traps, 2, "Two uncommon traps with "
+ "reason rtm_state_change should be fired.");
} else {
Asserts.assertEQ(traps, 0, "No uncommon traps with "
+ "reason rtm_state_change should be fired.");
}
int rangeCheckTraps = RTMTestBase.firedUncommonTraps(logFile,
TestRTMAfterNonRTMDeopt.RANGE_CHECK);
Asserts.assertEQ(rangeCheckTraps, 1,
"One range_check uncommon trap should be fired.");
List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
test.getMethodWithLockName(), outputAnalyzer.getOutput());
int expectedStatEntries = (useRTMDeopt ? 4 : 2);
Asserts.assertEQ(statistics.size(), expectedStatEntries,
String.format("VM output should contain %d RTM locking "
+ "statistics entries.", expectedStatEntries));
}
public static class Test implements CompilableTest {
// Following field have to be static in order to avoid escape analysis.
@SuppressWarnings("UnsuedDeclaration")
private static int field = 0;
private static final int ITERATIONS = 10000;
private static final int RANGE_CHECK_AT = ITERATIONS / 2;
private final XAbortProvoker xabort = new XAbortProvoker();
private final Object monitor = new Object();
@Override
public String getMethodWithLockName() {
return this.getClass().getName() + "::forceAbort";
}
@Override
public String[] getMethodsToCompileNames() {
return new String[] { getMethodWithLockName(),
XAbortProvoker.class.getName() + "::doAbort()" };
}
public void forceAbort(int a[], boolean abort) {
try {
synchronized(monitor) {
a[0]++;
if (abort) {
Test.field = xabort.doAbort();
}
}
} catch (Throwable t) {
// suppress any throwables
}
}
/**
* Usage:
* Test &lt;inflate monitor&gt;
*/
public static void main(String args[]) throws Throwable {
Test t = new Test();
boolean shouldBeInflated = Boolean.valueOf(args[0]);
if (shouldBeInflated) {
AbortProvoker.inflateMonitor(t.monitor);
}
int tmp[] = new int[1];
for (int i = 0; i < Test.ITERATIONS; i++ ) {
AbortProvoker.verifyMonitorState(t.monitor, shouldBeInflated);
if (i == Test.RANGE_CHECK_AT) {
t.forceAbort(new int[0], false);
} else {
boolean isThreshold
= (i == TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD);
boolean isThresholdPlusRange
= (i == TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD
+ Test.RANGE_CHECK_AT);
t.forceAbort(tmp, isThreshold || isThresholdPlusRange);
}
}
}
}
public static void main(String args[]) throws Throwable {
new TestRTMAfterNonRTMDeopt().runTestCases();
}
}

@ -1,116 +0,0 @@
/*
* Copyright (c) 2014, 2022, Oracle and/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
* @bug 8031320
* @summary Verify that on high abort ratio method will be recompiled
* without rtm locking.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.rtm.cpu & vm.rtm.compiler
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm/native -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.rtm.locking.TestRTMDeoptOnHighAbortRatio
*/
package compiler.rtm.locking;
import compiler.testlibrary.rtm.AbortProvoker;
import compiler.testlibrary.rtm.AbortType;
import compiler.testlibrary.rtm.RTMLockingStatistics;
import compiler.testlibrary.rtm.RTMTestBase;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.cli.CommandLineOptionTest;
import java.util.List;
/**
* Test verifies that on high abort ratio method wil be deoptimized with
* <i>rtm_state_change</i> reason and after that RTM-based lock elision will not
* be used for that method.
* This test make asserts on total locks count done by compiled method,
* so in order to avoid issue with retriable locks -XX:RTMRetryCount=0 is used.
* For more details on that issue see {@link TestUseRTMAfterLockInflation}.
*/
public class TestRTMDeoptOnHighAbortRatio {
private static final long ABORT_THRESHOLD
= AbortProvoker.DEFAULT_ITERATIONS / 2L;
protected void runTestCases() throws Throwable {
verifyDeopt(false);
verifyDeopt(true);
}
private void verifyDeopt(boolean useStackLock) throws Throwable {
AbortProvoker provoker = AbortType.XABORT.provoker();
String logFileName = String.format("rtm_deopt_%s_stack_lock.xml",
(useStackLock ? "use" : "no"));
OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
logFileName,
provoker,
"-XX:+UseRTMDeopt",
CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
useStackLock),
"-XX:RTMRetryCount=0",
CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold",
TestRTMDeoptOnHighAbortRatio.ABORT_THRESHOLD),
"-XX:RTMAbortRatio=100",
"-XX:CompileThreshold=1",
"-XX:RTMTotalCountIncrRate=1",
"-XX:+PrintPreciseRTMLockingStatistics",
AbortProvoker.class.getName(),
AbortType.XABORT.toString(),
Boolean.toString(!useStackLock)
);
outputAnalyzer.shouldHaveExitValue(0);
int firedTraps = RTMTestBase.firedRTMStateChangeTraps(logFileName);
Asserts.assertEQ(firedTraps, 1, "Expected to get only one "
+ "deoptimization due to rtm state change");
List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+ "exactly one RTM locking statistics entry for method "
+ provoker.getMethodWithLockName());
Asserts.assertEQ(statistics.get(0).getTotalLocks(),
TestRTMDeoptOnHighAbortRatio.ABORT_THRESHOLD,
"After AbortThreshold was reached, method should be"
+ " recompiled without rtm lock eliding.");
}
public static void main(String args[]) throws Throwable {
new TestRTMDeoptOnHighAbortRatio().runTestCases();
}
}

@ -1,169 +0,0 @@
/*
* Copyright (c) 2014, 2022, Oracle and/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
* @bug 8031320
* @summary Verify that on low abort ratio method will be recompiled.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.rtm.cpu & vm.rtm.compiler
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm/native -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.rtm.locking.TestRTMDeoptOnLowAbortRatio
*/
package compiler.rtm.locking;
import compiler.testlibrary.rtm.AbortProvoker;
import compiler.testlibrary.rtm.XAbortProvoker;
import compiler.testlibrary.rtm.CompilableTest;
import compiler.testlibrary.rtm.RTMLockingStatistics;
import compiler.testlibrary.rtm.RTMTestBase;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.cli.CommandLineOptionTest;
import java.util.List;
/**
* Test verifies that low abort ratio method will be deoptimized with
* <i>rtm_state_change</i> reason and will continue to use RTM-based lock
* elision after that.
* This test make asserts on total locks count done by compiled method,
* so in order to avoid issue with retriable locks -XX:RTMRetryCount=0 is used.
* For more details on that issue see {@link TestUseRTMAfterLockInflation}.
*/
public class TestRTMDeoptOnLowAbortRatio {
private static final long LOCKING_THRESHOLD = 100L;
private static final long ABORT_THRESHOLD = LOCKING_THRESHOLD / 2L;
protected void runTestCases() throws Throwable {
verifyRTMDeopt(false);
verifyRTMDeopt(true);
}
private void verifyRTMDeopt(boolean useStackLock) throws Throwable {
CompilableTest test = new Test();
String logFileName = String.format("rtm_deopt_%s_stack_lock.xml",
useStackLock ? "use" : "no");
OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
logFileName,
test,
"-XX:+UseRTMDeopt",
CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
useStackLock),
CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold",
TestRTMDeoptOnLowAbortRatio.LOCKING_THRESHOLD),
CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold",
TestRTMDeoptOnLowAbortRatio.ABORT_THRESHOLD),
"-XX:RTMAbortRatio=100",
"-XX:CompileThreshold=1",
"-XX:RTMRetryCount=0",
"-XX:RTMTotalCountIncrRate=1",
"-XX:+PrintPreciseRTMLockingStatistics",
Test.class.getName(),
Boolean.toString(!useStackLock)
);
outputAnalyzer.shouldHaveExitValue(0);
int firedTraps = RTMTestBase.firedRTMStateChangeTraps(logFileName);
Asserts.assertEQ(firedTraps, 1,
"Expected to get only one deoptimization due to rtm"
+ " state change");
List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
test.getMethodWithLockName(), outputAnalyzer.getOutput());
Asserts.assertEQ(statistics.size(), 2,
"VM output should contain two RTM locking "
+ "statistics entries for method "
+ test.getMethodWithLockName());
RTMLockingStatistics statisticsBeforeDeopt = null;
for (RTMLockingStatistics s : statistics) {
if (s.getTotalLocks()
== TestRTMDeoptOnLowAbortRatio.LOCKING_THRESHOLD) {
Asserts.assertNull(statisticsBeforeDeopt,
"Only one abort was expected during test run");
statisticsBeforeDeopt = s;
}
}
Asserts.assertNotNull(statisticsBeforeDeopt,
"After LockThreshold was reached, method should be recompiled "
+ "with rtm lock eliding.");
}
public static class Test implements CompilableTest {
private final XAbortProvoker xabort = new XAbortProvoker();
private final Object monitor = new Object();
@Override
public String getMethodWithLockName() {
return this.getClass().getName() + "::forceAbort";
}
@Override
public String[] getMethodsToCompileNames() {
return new String[] { getMethodWithLockName(),
XAbortProvoker.class.getName() + "::doAbort" };
}
public void forceAbort(boolean abort) {
synchronized(monitor) {
if (abort) {
xabort.doAbort();
}
}
}
/**
* Usage:
* Test &lt;inflate monitor&gt;
*/
public static void main(String args[]) throws Throwable {
Asserts.assertGTE(args.length, 1, "One argument required.");
Test t = new Test();
boolean shouldBeInflated = Boolean.valueOf(args[0]);
if (shouldBeInflated) {
AbortProvoker.inflateMonitor(t.monitor);
}
for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) {
AbortProvoker.verifyMonitorState(t.monitor, shouldBeInflated);
t.forceAbort(i >= TestRTMDeoptOnLowAbortRatio.ABORT_THRESHOLD);
}
}
}
public static void main(String args[]) throws Throwable {
new TestRTMDeoptOnLowAbortRatio().runTestCases();
}
}

@ -1,106 +0,0 @@
/*
* Copyright (c) 2014, 2022, Oracle and/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
* @bug 8031320
* @summary Verify that RTMLockingCalculationDelay affect when
* abort ratio calculation is started.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.rtm.cpu & vm.rtm.compiler
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm/native -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.rtm.locking.TestRTMLockingCalculationDelay
*/
package compiler.rtm.locking;
import compiler.testlibrary.rtm.AbortProvoker;
import compiler.testlibrary.rtm.AbortType;
import compiler.testlibrary.rtm.RTMTestBase;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.cli.CommandLineOptionTest;
/**
* Test verifies that abort ratio calculation could be delayed using
* RTMLockingCalculationDelay option.
*/
public class TestRTMLockingCalculationDelay {
private static final boolean INFLATE_MONITOR = true;
protected void runTestCases() throws Throwable {
// verify that calculation will be started immediately
verifyLockingCalculationDelay(0, 0, true);
// verify that calculation will not be started during
// first 10 minutes, while test will be started immediately
verifyLockingCalculationDelay(600000, 0, false);
// verify that calculation will be started after a second
verifyLockingCalculationDelay(1000, 1000, true);
}
private void verifyLockingCalculationDelay(long delay, long testDelay,
boolean deoptExpected) throws Throwable {
AbortProvoker provoker = AbortType.XABORT.provoker();
String logFileName = String.format("rtm_delay_%d_%d.xml", delay,
testDelay);
OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
logFileName,
provoker,
"-XX:+UseRTMDeopt",
CommandLineOptionTest.prepareNumericFlag(
"RTMLockingCalculationDelay", delay),
"-XX:RTMAbortRatio=0",
"-XX:RTMAbortThreshold=0",
AbortProvoker.class.getName(),
AbortType.XABORT.toString(),
Boolean.toString(
TestRTMLockingCalculationDelay.INFLATE_MONITOR),
Long.toString(AbortProvoker.DEFAULT_ITERATIONS),
Long.toString(testDelay)
);
outputAnalyzer.shouldHaveExitValue(0);
int deopts = RTMTestBase.firedRTMStateChangeTraps(logFileName);
if (deoptExpected) {
Asserts.assertGT(deopts, 0, "At least one deoptimization due to "
+ "rtm_state_chage is expected");
} else {
Asserts.assertEQ(deopts, 0, "No deoptimizations due to "
+ "rtm_state_chage are expected");
}
}
public static void main(String args[]) throws Throwable {
new TestRTMLockingCalculationDelay().runTestCases();
}
}

@ -1,180 +0,0 @@
/*
* Copyright (c) 2014, 2022, Oracle and/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
* @bug 8031320
* @summary Verify that RTMLockingThreshold affects rtm state transition
* ProfileRTM => UseRTM.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.rtm.cpu & vm.rtm.compiler
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm/native -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.rtm.locking.TestRTMLockingThreshold
*/
package compiler.rtm.locking;
import compiler.testlibrary.rtm.AbortProvoker;
import compiler.testlibrary.rtm.XAbortProvoker;
import compiler.testlibrary.rtm.CompilableTest;
import compiler.testlibrary.rtm.RTMLockingStatistics;
import compiler.testlibrary.rtm.RTMTestBase;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.cli.CommandLineOptionTest;
import java.util.List;
/**
* Test verifies that RTMLockingThreshold option actually affects how soon
* method will be deoptimized on low abort ratio.
*/
public class TestRTMLockingThreshold {
/**
* We use non-zero abort threshold to avoid abort related to
* interrupts, VMM calls, etc. during first lock attempt.
*
*/
private static final int MIN_ABORT_THRESHOLD = 10;
protected void runTestCases() throws Throwable {
verifyLockingThreshold(0, false);
verifyLockingThreshold(100, false);
verifyLockingThreshold(1000, false);
verifyLockingThreshold(0, true);
verifyLockingThreshold(100, true);
verifyLockingThreshold(1000, true);
}
private void verifyLockingThreshold(int lockingThreshold,
boolean useStackLock) throws Throwable {
CompilableTest test = new Test();
int abortThreshold = Math.max(lockingThreshold / 2,
TestRTMLockingThreshold.MIN_ABORT_THRESHOLD);
OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
test,
"-XX:CompileThreshold=1",
CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
useStackLock),
"-XX:+UseRTMDeopt",
"-XX:RTMTotalCountIncrRate=1",
"-XX:RTMRetryCount=0",
CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold",
abortThreshold),
CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold",
lockingThreshold),
"-XX:RTMAbortRatio=100",
"-XX:+PrintPreciseRTMLockingStatistics",
Test.class.getName(),
Boolean.toString(!useStackLock),
Integer.toString(lockingThreshold)
);
outputAnalyzer.shouldHaveExitValue(0);
List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
test.getMethodWithLockName(), outputAnalyzer.getOutput());
Asserts.assertEQ(statistics.size(), 2, "VM output should contain two "
+ "RTM locking statistics entries.");
/**
* If RTMLockingThreshold==0, then we have to make at least 1 call.
*/
long expectedValue = lockingThreshold;
if (expectedValue == 0) {
expectedValue++;
}
RTMLockingStatistics statBeforeDeopt = null;
for (RTMLockingStatistics s : statistics) {
if (s.getTotalLocks() == expectedValue) {
Asserts.assertNull(statBeforeDeopt,
"Only one statistics entry should contain aborts");
statBeforeDeopt = s;
}
}
Asserts.assertNotNull(statBeforeDeopt, "There should be exactly one "
+ "statistics entry corresponding to ProfileRTM state.");
}
public static class Test implements CompilableTest {
// Following field have to be static in order to avoid escape analysis.
@SuppressWarnings("UnsuedDeclaration")
private static int field = 0;
private static final int TOTAL_ITERATIONS = 10000;
private final XAbortProvoker xabort = new XAbortProvoker();
private final Object monitor = new Object();
@Override
public String getMethodWithLockName() {
return this.getClass().getName() + "::lock";
}
@Override
public String[] getMethodsToCompileNames() {
return new String[] { getMethodWithLockName(),
XAbortProvoker.class.getName() + "::doAbort" };
}
public void lock(boolean abort) {
synchronized(monitor) {
if (abort) {
Test.field += xabort.doAbort();
}
}
}
/**
* Usage:
* Test &lt;inflate monitor&gt;
*/
public static void main(String args[]) throws Throwable {
Asserts.assertGTE(args.length, 2, "Two arguments required.");
Test t = new Test();
boolean shouldBeInflated = Boolean.valueOf(args[0]);
int lockingThreshold = Integer.valueOf(args[1]);
if (shouldBeInflated) {
AbortProvoker.inflateMonitor(t.monitor);
}
for (int i = 0; i < Test.TOTAL_ITERATIONS; i++) {
AbortProvoker.verifyMonitorState(t.monitor, shouldBeInflated);
t.lock(i >= lockingThreshold / 2);
}
}
}
public static void main(String args[]) throws Throwable {
new TestRTMLockingThreshold().runTestCases();
}
}

@ -1,103 +0,0 @@
/*
* Copyright (c) 2014, 2022, Oracle and/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
* @bug 8031320
* @summary Verify that RTMRetryCount affects actual amount of retries.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.rtm.cpu & vm.rtm.compiler
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.rtm.locking.TestRTMRetryCount
*/
package compiler.rtm.locking;
import compiler.testlibrary.rtm.BusyLock;
import compiler.testlibrary.rtm.CompilableTest;
import compiler.testlibrary.rtm.RTMLockingStatistics;
import compiler.testlibrary.rtm.RTMTestBase;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.cli.CommandLineOptionTest;
import java.util.List;
/**
* Test verifies that RTMRetryCount option actually affects amount of
* retries on lock busy.
*/
public class TestRTMRetryCount {
/**
* Time in ms, during which busy lock will be locked.
*/
private static final int LOCKING_TIME = 5000;
private static final boolean INFLATE_MONITOR = true;
protected void runTestCases() throws Throwable {
verifyRTMRetryCount(0);
verifyRTMRetryCount(1);
verifyRTMRetryCount(5);
verifyRTMRetryCount(10);
}
private void verifyRTMRetryCount(int retryCount) throws Throwable {
CompilableTest busyLock = new BusyLock();
long expectedAborts = retryCount + 1L;
OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
busyLock,
"-XX:-UseRTMXendForLockBusy",
"-XX:RTMTotalCountIncrRate=1",
CommandLineOptionTest.prepareNumericFlag("RTMRetryCount",
retryCount),
"-XX:RTMTotalCountIncrRate=1",
"-XX:+PrintPreciseRTMLockingStatistics",
BusyLock.class.getName(),
Boolean.toString(TestRTMRetryCount.INFLATE_MONITOR),
Integer.toString(TestRTMRetryCount.LOCKING_TIME)
);
outputAnalyzer.shouldHaveExitValue(0);
List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
busyLock.getMethodWithLockName(), outputAnalyzer.getStdout());
Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+ "exactly one rtm locking statistics entry for method "
+ busyLock.getMethodWithLockName());
Asserts.assertEQ(statistics.get(0).getTotalAborts(), expectedAborts,
String.format("It is expected to get %d aborts",
expectedAborts));
}
public static void main(String args[]) throws Throwable {
new TestRTMRetryCount().runTestCases();
}
}

@ -1,121 +0,0 @@
/*
* Copyright (c) 2014, 2022, Oracle and/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
* @bug 8031320
* @summary Verify that RTMSpinLoopCount affects time spent
* between locking attempts.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.rtm.cpu & vm.rtm.compiler
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.rtm.locking.TestRTMSpinLoopCount
*/
package compiler.rtm.locking;
import compiler.testlibrary.rtm.BusyLock;
import compiler.testlibrary.rtm.CompilableTest;
import compiler.testlibrary.rtm.RTMLockingStatistics;
import compiler.testlibrary.rtm.RTMTestBase;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.cli.CommandLineOptionTest;
import jdk.test.lib.Platform;
import java.util.List;
/**
* Test verifies that RTMSpinLoopCount increase time spent between retries
* by comparing amount of retries done with different RTMSpinLoopCount's values.
*/
public class TestRTMSpinLoopCount {
private static final int LOCKING_TIME = 1000;
private static final int RTM_RETRY_COUNT = 1000;
private static final boolean INFLATE_MONITOR = true;
private static final long MAX_ABORTS = RTM_RETRY_COUNT + 1L;
private static int[] SPIN_LOOP_COUNTS;
protected void runTestCases() throws Throwable {
SPIN_LOOP_COUNTS = new int[] { 0, 100, 1_000, 10_000, 100_000 };
long[] aborts = new long[TestRTMSpinLoopCount.SPIN_LOOP_COUNTS.length];
for (int i = 0; i < TestRTMSpinLoopCount.SPIN_LOOP_COUNTS.length; i++) {
aborts[i] = getAbortsCountOnLockBusy(
TestRTMSpinLoopCount.SPIN_LOOP_COUNTS[i]);
}
for (int i = 1; i < aborts.length; i++) {
Asserts.assertLTE(aborts[i], aborts[i - 1], "Increased spin loop "
+ "count should not increase retries count.");
}
}
private long getAbortsCountOnLockBusy(int spinLoopCount) throws Throwable {
CompilableTest test = new BusyLock();
OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
test,
CommandLineOptionTest.prepareNumericFlag("RTMRetryCount",
TestRTMSpinLoopCount.RTM_RETRY_COUNT),
CommandLineOptionTest.prepareNumericFlag("RTMSpinLoopCount",
spinLoopCount),
"-XX:-UseRTMXendForLockBusy",
"-XX:RTMTotalCountIncrRate=1",
"-XX:+PrintPreciseRTMLockingStatistics",
BusyLock.class.getName(),
Boolean.toString(TestRTMSpinLoopCount.INFLATE_MONITOR),
Integer.toString(TestRTMSpinLoopCount.LOCKING_TIME)
);
outputAnalyzer.shouldHaveExitValue(0);
List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
test.getMethodWithLockName(), outputAnalyzer.getOutput());
Asserts.assertEQ(statistics.size(), 1,
"VM output should contain exactly one entry for method "
+ test.getMethodWithLockName());
RTMLockingStatistics lock = statistics.get(0);
Asserts.assertLTE(lock.getTotalAborts(),
TestRTMSpinLoopCount.MAX_ABORTS, String.format("Total aborts "
+ "count (%d) should be less or equal to %d",
lock.getTotalAborts(),
TestRTMSpinLoopCount.MAX_ABORTS));
return lock.getTotalAborts();
}
public static void main(String args[]) throws Throwable {
new TestRTMSpinLoopCount().runTestCases();
}
}

@ -1,163 +0,0 @@
/*
* Copyright (c) 2014, 2022, Oracle and/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
* @bug 8031320
* @summary Verify that RTMTotalCountIncrRate option affects
* RTM locking statistics.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.rtm.cpu & vm.rtm.compiler
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm/native -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.rtm.locking.TestRTMTotalCountIncrRate
*/
package compiler.rtm.locking;
import compiler.testlibrary.rtm.AbortProvoker;
import compiler.testlibrary.rtm.XAbortProvoker;
import compiler.testlibrary.rtm.CompilableTest;
import compiler.testlibrary.rtm.RTMLockingStatistics;
import compiler.testlibrary.rtm.RTMTestBase;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.cli.CommandLineOptionTest;
import java.util.List;
/**
* Test verifies that with RTMTotalCountIncrRate=1 RTM locking statistics
* contains precise information abort attempted locks and that with other values
* statistics contains information abort non-zero locking attempts.
* Since assert done for RTMTotalCountIncrRate=1 is pretty strict, test uses
* -XX:RTMRetryCount=0 to avoid issue with retriable aborts. For more details on
* that issue see {@link TestUseRTMAfterLockInflation}.
*/
public class TestRTMTotalCountIncrRate {
protected void runTestCases() throws Throwable {
verifyLocksCount(1, false);
verifyLocksCount(64, false);
verifyLocksCount(128, false);
verifyLocksCount(1, true);
verifyLocksCount(64, true);
verifyLocksCount(128, true);
}
private void verifyLocksCount(int incrRate, boolean useStackLock)
throws Throwable{
CompilableTest test = new Test();
OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
test,
CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
useStackLock),
CommandLineOptionTest.prepareNumericFlag(
"RTMTotalCountIncrRate", incrRate),
"-XX:RTMRetryCount=0",
"-XX:+PrintPreciseRTMLockingStatistics",
Test.class.getName(),
Boolean.toString(!useStackLock)
);
outputAnalyzer.shouldHaveExitValue(0);
List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
test.getMethodWithLockName(), outputAnalyzer.getOutput());
Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+ "exactly one RTM locking statistics entry for method "
+ test.getMethodWithLockName());
RTMLockingStatistics lock = statistics.get(0);
if (incrRate == 1) {
Asserts.assertEQ(lock.getTotalLocks(), Test.TOTAL_ITERATIONS,
"Total locks should be exactly the same as amount of "
+ "iterations.");
}
}
public static class Test implements CompilableTest {
private static final long TOTAL_ITERATIONS = 10000L;
private final XAbortProvoker xabort = new XAbortProvoker();
private final Object monitor = new Object();
// Following field have to be static in order to avoid escape analysis.
@SuppressWarnings("UnsuedDeclaration")
private static int field = 0;
@Override
public String getMethodWithLockName() {
return this.getClass().getName() + "::lock";
}
@Override
public String[] getMethodsToCompileNames() {
return new String[] { getMethodWithLockName(), "*.doAbort" };
}
public void lock(boolean forceAbort) {
synchronized(monitor) {
if (forceAbort) {
// We're calling native method in order to force
// abort. It's done by explicit xabort call emitted
// in SharedRuntime::generate_native_wrapper.
// If an actual JNI call will be replaced by
// intrinsic - we'll be in trouble, since xabort
// will be no longer called and test may fail.
xabort.doAbort();
}
Test.field++;
}
}
/**
* Usage:
* Test &lt;inflate monitor&gt;
*/
public static void main(String args[]) throws Throwable {
Asserts.assertGTE(args.length, 1, "One argument required.");
Test test = new Test();
boolean shouldBeInflated = Boolean.valueOf(args[0]);
if (shouldBeInflated) {
AbortProvoker.inflateMonitor(test.monitor);
}
for (long i = 0L; i < Test.TOTAL_ITERATIONS; i++) {
AbortProvoker.verifyMonitorState(test.monitor,
shouldBeInflated);
// Force abort on first iteration to avoid rare case when
// there were no aborts and locks count was not incremented
// with RTMTotalCountIncrRate > 1 (in such case JVM won't
// print JVM locking statistics).
test.lock(i == 0);
}
}
}
public static void main(String args[]) throws Throwable {
new TestRTMTotalCountIncrRate().runTestCases();
}
}

@ -1,128 +0,0 @@
/*
* Copyright (c) 2014, 2022, Oracle and/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
* @bug 8031320
* @summary Verify that rtm locking is used for stack locks before
* inflation and after it used for inflated locks.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.rtm.cpu & vm.rtm.compiler
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm/native -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.rtm.locking.TestUseRTMAfterLockInflation
*/
package compiler.rtm.locking;
import compiler.testlibrary.rtm.AbortProvoker;
import compiler.testlibrary.rtm.AbortType;
import compiler.testlibrary.rtm.RTMLockingStatistics;
import compiler.testlibrary.rtm.RTMTestBase;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import java.util.List;
/**
* Test verifies that RTM is used after lock inflation by executing compiled
* method with RTM-based lock elision using stack lock first, then that lock
* is inflated and the same compiled method invoked again.
*
* Compiled method invoked {@code AbortProvoker.DEFAULT_ITERATIONS} times before
* lock inflation and the same amount of times after inflation.
* As a result total locks count should be equal to
* {@code 2 * AbortProvoker.DEFAULT_ITERATIONS}.
* It is a pretty strict assertion which could fail if some retriable abort
* happened: it could be {@code AbortType.RETRIABLE} or
* {@code AbortType.MEM_CONFLICT}, but unfortunately abort can has both these
* reasons simultaneously. In order to avoid false negative failures related
* to incorrect aborts counting, -XX:RTMRetryCount=0 is used.
*/
public class TestUseRTMAfterLockInflation {
private static final long EXPECTED_LOCKS
= 2L * AbortProvoker.DEFAULT_ITERATIONS;
protected void runTestCases() throws Throwable {
AbortProvoker provoker = AbortType.XABORT.provoker();
long totalLocksCount = 0;
OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
provoker,
"-XX:+UseRTMForStackLocks",
"-XX:RTMTotalCountIncrRate=1",
"-XX:RTMRetryCount=0",
"-XX:+PrintPreciseRTMLockingStatistics",
Test.class.getName(),
AbortType.XABORT.toString());
outputAnalyzer.shouldHaveExitValue(0);
List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
Asserts.assertEQ(statistics.size(), 2,
"VM output should contain two rtm locking statistics entries "
+ "for method " + provoker.getMethodWithLockName());
for (RTMLockingStatistics s : statistics) {
totalLocksCount += s.getTotalLocks();
}
Asserts.assertEQ(totalLocksCount,
TestUseRTMAfterLockInflation.EXPECTED_LOCKS,
"Total lock count should be greater or equal to "
+ TestUseRTMAfterLockInflation.EXPECTED_LOCKS);
}
public static class Test {
/**
* Usage:
* Test &lt;provoker type&gt;
*/
public static void main(String args[]) throws Throwable {
Asserts.assertGT(args.length, 0,
"AbortType name is expected as first argument.");
AbortProvoker provoker
= AbortType.lookup(Integer.valueOf(args[0])).provoker();
for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) {
AbortProvoker.verifyMonitorState(provoker, false /*deflated*/);
provoker.forceAbort();
}
provoker.inflateMonitor();
for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) {
AbortProvoker.verifyMonitorState(provoker, true /*inflated*/);
provoker.forceAbort();
}
}
}
public static void main(String args[]) throws Throwable {
new TestUseRTMAfterLockInflation().runTestCases();
}
}

@ -1,89 +0,0 @@
/*
* Copyright (c) 2014, 2022, Oracle and/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
* @bug 8031320
* @summary Verify that UseRTMDeopt affects uncommon trap installation in
* compiled methods with synchronized block.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.rtm.cpu & vm.rtm.compiler
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm/native -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.rtm.locking.TestUseRTMDeopt
*/
package compiler.rtm.locking;
import compiler.testlibrary.rtm.AbortProvoker;
import compiler.testlibrary.rtm.AbortType;
import compiler.testlibrary.rtm.RTMTestBase;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.cli.CommandLineOptionTest;
/**
* Test verifies that usage of UseRTMDeopt option affects uncommon traps usage
* for methods that use locking.
*/
public class TestUseRTMDeopt {
protected void runTestCases() throws Throwable {
verifyUseRTMDeopt(false);
verifyUseRTMDeopt(true);
}
private void verifyUseRTMDeopt(boolean useRTMDeopt) throws Throwable {
AbortProvoker provoker = AbortType.XABORT.provoker();
String logFileName = String.format("rtm_%s_deopt.xml",
useRTMDeopt ? "use" : "no");
OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
logFileName,
provoker,
CommandLineOptionTest.prepareBooleanFlag("UseRTMDeopt",
useRTMDeopt),
AbortProvoker.class.getName(),
AbortType.XABORT.toString()
);
outputAnalyzer.shouldHaveExitValue(0);
int expectedUncommonTraps = useRTMDeopt ? 1 : 0;
int installedUncommonTraps
= RTMTestBase.installedRTMStateChangeTraps(logFileName);
Asserts.assertEQ(expectedUncommonTraps, installedUncommonTraps,
String.format("Expected to find %d uncommon traps "
+ "installed with reason rtm_state_change.",
expectedUncommonTraps));
}
public static void main(String args[]) throws Throwable {
new TestUseRTMDeopt().runTestCases();
}
}

@ -1,93 +0,0 @@
/*
* Copyright (c) 2014, 2022, Oracle and/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
* @bug 8031320
* @summary Verify that rtm locking is used for inflated locks.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.rtm.cpu & vm.rtm.compiler
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm/native -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.rtm.locking.TestUseRTMForInflatedLocks
*/
package compiler.rtm.locking;
import compiler.testlibrary.rtm.AbortProvoker;
import compiler.testlibrary.rtm.AbortType;
import compiler.testlibrary.rtm.RTMLockingStatistics;
import compiler.testlibrary.rtm.RTMTestBase;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import java.util.List;
/**
* Test verifies that RTM-based lock elision could be used for inflated locks
* by calling compiled method that use RTM-based lock elision and using
* manually inflated lock.
* Compiled method invoked {@code AbortProvoker.DEFAULT_ITERATIONS} times,
* so total locks count should be the same.
* This test could also be affected by retriable aborts, so -XX:RTMRetryCount=0
* is used. For more information abort that issue see
* {@link TestUseRTMAfterLockInflation}.
*/
public class TestUseRTMForInflatedLocks {
protected void runTestCases() throws Throwable {
AbortProvoker provoker = AbortType.XABORT.provoker();
RTMLockingStatistics lock;
OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
provoker,
"-XX:-UseRTMForStackLocks",
"-XX:RTMTotalCountIncrRate=1",
"-XX:RTMRetryCount=0",
"-XX:+PrintPreciseRTMLockingStatistics",
AbortProvoker.class.getName(),
AbortType.XABORT.toString());
outputAnalyzer.shouldHaveExitValue(0);
List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
Asserts.assertEQ(statistics.size(), 1,
"VM output should contain exactly one rtm locking statistics "
+ "entry for method " + provoker.getMethodWithLockName());
lock = statistics.get(0);
Asserts.assertEQ(lock.getTotalLocks(), AbortProvoker.DEFAULT_ITERATIONS,
"Total lock count should be greater or equal to "
+ AbortProvoker.DEFAULT_ITERATIONS);
}
public static void main(String args[]) throws Throwable {
new TestUseRTMForInflatedLocks().runTestCases();
}
}

@ -1,95 +0,0 @@
/*
* Copyright (c) 2014, 2022, Oracle and/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
* @bug 8031320
* @summary Verify that rtm locking is used for stack locks.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.rtm.cpu & vm.rtm.compiler
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm/native -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.rtm.locking.TestUseRTMForStackLocks
*/
package compiler.rtm.locking;
import compiler.testlibrary.rtm.AbortProvoker;
import compiler.testlibrary.rtm.AbortType;
import compiler.testlibrary.rtm.RTMLockingStatistics;
import compiler.testlibrary.rtm.RTMTestBase;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import java.util.List;
/**
* Test verifies that RTM-based lock elision could be used for stack locks
* by calling compiled method that use RTM-based lock elision and using
* stack lock.
* Compiled method invoked {@code AbortProvoker.DEFAULT_ITERATIONS} times,
* so total locks count should be the same.
* This test could also be affected by retriable aborts, so -XX:RTMRetryCount=0
* is used. For more information abort that issue see
* {@link TestUseRTMAfterLockInflation}.
*/
public class TestUseRTMForStackLocks {
private static final boolean INFLATE_MONITOR = false;
protected void runTestCases() throws Throwable {
AbortProvoker provoker = AbortType.XABORT.provoker();
RTMLockingStatistics lock;
OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
provoker,
"-XX:+UseRTMForStackLocks",
"-XX:RTMTotalCountIncrRate=1",
"-XX:RTMRetryCount=0",
"-XX:+PrintPreciseRTMLockingStatistics",
AbortProvoker.class.getName(),
AbortType.XABORT.toString(),
Boolean.toString(TestUseRTMForStackLocks.INFLATE_MONITOR));
outputAnalyzer.shouldHaveExitValue(0);
List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
Asserts.assertEQ(statistics.size(), 1,
"VM output should contain exactly one rtm locking statistics "
+ "entry for method " + provoker.getMethodWithLockName());
lock = statistics.get(0);
Asserts.assertEQ(lock.getTotalLocks(), AbortProvoker.DEFAULT_ITERATIONS,
"Total locks count should be greater or equal to "
+ AbortProvoker.DEFAULT_ITERATIONS);
}
public static void main(String args[]) throws Throwable {
new TestUseRTMForStackLocks().runTestCases();
}
}

@ -1,113 +0,0 @@
/*
* Copyright (c) 2014, 2022, Oracle and/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
* @bug 8031320
* @summary Verify that UseRTMXendForLockBusy option affects
* method behaviour if lock is busy.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.rtm.cpu & vm.rtm.compiler
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.rtm.locking.TestUseRTMXendForLockBusy
*/
package compiler.rtm.locking;
import compiler.testlibrary.rtm.AbortType;
import compiler.testlibrary.rtm.BusyLock;
import compiler.testlibrary.rtm.CompilableTest;
import compiler.testlibrary.rtm.RTMLockingStatistics;
import compiler.testlibrary.rtm.RTMTestBase;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.cli.CommandLineOptionTest;
import java.util.List;
/**
* Test verifies that with +UseRTMXendForLockBusy there will be no aborts
* forced by the test.
*/
public class TestUseRTMXendForLockBusy {
private final static int LOCKING_TIME = 5000;
protected void runTestCases() throws Throwable {
// inflated lock, xabort on lock busy
verifyXendForLockBusy(true, false);
// inflated lock, xend on lock busy
verifyXendForLockBusy(true, true);
// stack lock, xabort on lock busy
verifyXendForLockBusy(false, false);
// stack lock, xend on lock busy
verifyXendForLockBusy(false, true);
}
private void verifyXendForLockBusy(boolean inflateMonitor,
boolean useXend) throws Throwable {
CompilableTest test = new BusyLock();
OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
test,
CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
!inflateMonitor),
CommandLineOptionTest.prepareBooleanFlag(
"UseRTMXendForLockBusy",
useXend),
"-XX:RTMRetryCount=0",
"-XX:RTMTotalCountIncrRate=1",
"-XX:+PrintPreciseRTMLockingStatistics",
BusyLock.class.getName(),
Boolean.toString(inflateMonitor),
Integer.toString(TestUseRTMXendForLockBusy.LOCKING_TIME)
);
outputAnalyzer.shouldHaveExitValue(0);
List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
test.getMethodWithLockName(), outputAnalyzer.getOutput());
Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+ "exactly one rtm locking statistics entry for method "
+ test.getMethodWithLockName());
long aborts = statistics.get(0).getAborts(AbortType.XABORT);
if (useXend) {
Asserts.assertEQ(aborts, 0L,
"Expected to get no aborts on busy lock");
} else {
Asserts.assertGT(aborts, 0L,
"Expected to get at least one abort on busy lock");
}
}
public static void main(String args[]) throws Throwable {
new TestUseRTMXendForLockBusy().runTestCases();
}
}

@ -1,105 +0,0 @@
/*
* Copyright (c) 2014, 2022, Oracle and/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
* @bug 8031320
* @summary Verify that NoRTMLockEliding option could be applied to
* specified method and that such method will not use rtm.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.rtm.cpu & vm.rtm.compiler
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm/native -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.rtm.method_options.TestNoRTMLockElidingOption
*/
package compiler.rtm.method_options;
import compiler.testlibrary.rtm.AbortProvoker;
import compiler.testlibrary.rtm.AbortType;
import compiler.testlibrary.rtm.RTMLockingStatistics;
import compiler.testlibrary.rtm.RTMTestBase;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.cli.CommandLineOptionTest;
import java.util.List;
/**
* Test verifies that method tagged with option <i>NoRTMLockElidingOption</i>
* will not use RTM-based lock elision.
* Test invokes compiled method and checks that no deoptimization with
* <i>rtm_state_change</i> reason had happened and that that VM output
* does not contain RTM locking statistics for compiled method.
*/
public class TestNoRTMLockElidingOption {
public void runTestCases() throws Throwable {
verifyOption(false);
verifyOption(true);
}
public void verifyOption(boolean useStackLock) throws Throwable {
AbortProvoker provoker = AbortType.XABORT.provoker();
String logFileName = String.format("rtm_deopt_%s_stack_lock.xml",
(useStackLock ? "use" : "no"));
String methodOption = String.format("-XX:CompileCommand=option," +
"%s,NoRTMLockEliding", provoker.getMethodWithLockName());
OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
logFileName,
provoker,
CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
useStackLock),
methodOption,
"-XX:RTMTotalCountIncrRate=1",
"-XX:+UseRTMDeopt",
"-XX:+PrintPreciseRTMLockingStatistics",
AbortProvoker.class.getName(),
AbortType.XABORT.toString(),
Boolean.toString(!useStackLock)
);
outputAnalyzer.shouldHaveExitValue(0);
int firedTraps = RTMTestBase.firedRTMStateChangeTraps(logFileName);
Asserts.assertEQ(firedTraps, 0,
"No deoptimizations with rtm_state_change reason are expected");
List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
Asserts.assertEQ(statistics.size(), 0,
"VM output should not contain RTM locking statistics entries "
+ "for method " + provoker.getMethodWithLockName());
}
public static void main(String args[]) throws Throwable {
new TestNoRTMLockElidingOption().runTestCases();
}
}

@ -1,119 +0,0 @@
/*
* Copyright (c) 2014, 2022, Oracle and/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
* @bug 8031320
* @summary Verify that UseRTMLockEliding option could be applied to
* specified method and that such method will not be deoptimized
* on high abort ratio.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.rtm.cpu & vm.rtm.compiler
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm/native -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.rtm.method_options.TestUseRTMLockElidingOption
*/
package compiler.rtm.method_options;
import compiler.testlibrary.rtm.AbortProvoker;
import compiler.testlibrary.rtm.AbortType;
import compiler.testlibrary.rtm.RTMLockingStatistics;
import compiler.testlibrary.rtm.RTMTestBase;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.cli.CommandLineOptionTest;
import java.util.List;
/**
* Test verifies that method tagged with option <i>UseRTMLockElidingOption</i>
* will use RTM-based lock elision, but will be never deoptimized with
* <i>rtm_state_change reason</i>.
* Test invokes compiled method and checks that no deoptimization with
* <i>rtm_state_change</i> reason had happened and that that VM output
* contains RTM locking statistics for compiled method and that total locks
* count equals to method's invocations.
* Since last assert is pretty strict, test uses -XX:RTMRetryCount=0 in order
* to avoid issue with retriable aborts described in
* {@link TestUseRTMAfterLockInflation}.
*/
public class TestUseRTMLockElidingOption {
public void runTestCases() throws Throwable {
verifyOption(false);
verifyOption(true);
}
public void verifyOption(boolean useStackLock) throws Throwable {
AbortProvoker provoker = AbortType.XABORT.provoker();
String logFileName = String.format("rtm_deopt_%s_stack_lock.xml",
(useStackLock ? "use" : "no"));
String methodOption = String.format("-XX:CompileCommand=option," +
"%s,UseRTMLockEliding", provoker.getMethodWithLockName());
OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
logFileName,
provoker,
CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
useStackLock),
methodOption,
"-XX:RTMTotalCountIncrRate=1",
"-XX:RTMRetryCount=0",
"-XX:+UseRTMDeopt",
"-XX:+PrintPreciseRTMLockingStatistics",
provoker.getClass().getName(),
AbortType.XABORT.toString(),
Boolean.toString(!useStackLock)
);
outputAnalyzer.shouldHaveExitValue(0);
int firedTraps = RTMTestBase.firedRTMStateChangeTraps(logFileName);
Asserts.assertEQ(firedTraps, 0,
"Method deoptimization with rtm_state_change is unexpected");
List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
Asserts.assertEQ(statistics.size(), 1,
"VM output should contain exactly one RTM locking "
+ "statistics entry for method "
+ provoker.getMethodWithLockName());
RTMLockingStatistics lock = statistics.get(0);
Asserts.assertEQ(lock.getTotalLocks(), AbortProvoker.DEFAULT_ITERATIONS,
"Expected to get total locks count equal to total amount of "
+ "lock attempts.");
}
public static void main(String args[]) throws Throwable {
new TestUseRTMLockElidingOption().runTestCases();
}
}

@ -1,142 +0,0 @@
/*
* Copyright (c) 2014, 2022, Oracle and/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
* @bug 8031320
* @summary Verify that rtm locking statistics contain proper information
* on overall aborts and locks count and count of aborts of
* different types. Test also verify that VM output does not
* contain rtm locking statistics when it should not.
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.rtm.cpu & vm.rtm.compiler
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm/native -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.rtm.print.TestPrintPreciseRTMLockingStatistics
*/
package compiler.rtm.print;
import compiler.testlibrary.rtm.AbortProvoker;
import compiler.testlibrary.rtm.AbortType;
import compiler.testlibrary.rtm.RTMLockingStatistics;
import compiler.testlibrary.rtm.RTMTestBase;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/**
* Test verifies that VM output does not contain RTM locking statistics when it
* should not (when PrintPreciseRTMLockingStatistics is off) and that with
* -XX:+PrintPreciseRTMLockingStatistics locking statistics contains sane
* total locks and aborts count as well as for specific abort types.
*/
public class TestPrintPreciseRTMLockingStatistics {
public void runTestCases() throws Throwable {
verifyNoStatistics();
verifyStatistics();
}
// verify that VM output does not contain
// rtm locking statistics
private void verifyNoStatistics() throws Throwable {
verifyNoStatistics(AbortType.XABORT);
verifyNoStatistics(AbortType.XABORT,
"-XX:-PrintPreciseRTMLockingStatistics");
verifyNoStatistics(AbortType.XABORT, "-XX:-UseRTMLocking",
"-XX:+PrintPreciseRTMLockingStatistics");
}
// verify that rtm locking statistics contain information
// about each type of aborts
private void verifyStatistics() throws Throwable {
verifyAbortsCount(AbortType.XABORT);
verifyAbortsCount(AbortType.MEM_CONFLICT);
verifyAbortsCount(AbortType.BUF_OVERFLOW);
verifyAbortsCount(AbortType.NESTED_ABORT);
}
private void verifyNoStatistics(AbortType abortProvokerType,
String... vmOpts) throws Throwable {
AbortProvoker provoker = abortProvokerType.provoker();
List<String> finalVMOpts = new LinkedList<>();
Collections.addAll(finalVMOpts, vmOpts);
Collections.addAll(finalVMOpts, AbortProvoker.class.getName(),
abortProvokerType.toString());
OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(provoker,
finalVMOpts.toArray(new String[finalVMOpts.size()]));
outputAnalyzer.shouldHaveExitValue(0);
List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
outputAnalyzer.getOutput());
Asserts.assertEQ(statistics.size(), 0, "VM output should not contain "
+ "any RTM locking statistics");
}
private void verifyAbortsCount(AbortType abortType) throws Throwable {
AbortProvoker provoker = abortType.provoker();
OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
provoker,
"-XX:+PrintPreciseRTMLockingStatistics",
AbortProvoker.class.getName(),
abortType.toString());
outputAnalyzer.shouldHaveExitValue(0);
List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
provoker.getMethodWithLockName(),outputAnalyzer.getOutput());
Asserts.assertGT(statistics.size(), 0, "VM output should contain one "
+ "rtm locking statistics entry for method "
+ provoker.getMethodWithLockName());
RTMLockingStatistics lock = statistics.get(0);
Asserts.assertGT(lock.getTotalAborts(), 0L,
"RTM locking statistics should contain non zero total aborts "
+ "count");
Asserts.assertGT(lock.getAborts(abortType), 0L, String.format(
"RTM locking statistics should contain non zero aborts count "
+ "for abort reason %s", abortType));
}
public static void main(String args[]) throws Throwable {
new TestPrintPreciseRTMLockingStatistics().runTestCases();
}
}

@ -1,216 +0,0 @@
/*
* Copyright (c) 2014, 2022, Oracle and/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.
*/
package compiler.testlibrary.rtm;
import jdk.test.lib.Asserts;
import jdk.test.whitebox.WhiteBox;
import java.util.Objects;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* Base class for different transactional execution abortion
* provokers aimed to force abort due to specified reason.
*/
public abstract class AbortProvoker implements CompilableTest {
public static final long DEFAULT_ITERATIONS = 10000L;
private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
@SuppressWarnings("unused")
private static int sharedState = 0;
/**
* Inflates monitor associated with object {@code monitor}.
* Inflation is forced by entering the same monitor from
* two different threads.
*
* @param monitor monitor to be inflated.
* @return inflated monitor.
* @throws Exception if something went wrong.
*/
public static Object inflateMonitor(Object monitor) throws Exception {
CyclicBarrier barrier = new CyclicBarrier(2);
Runnable inflatingRunnable = () -> {
synchronized (monitor) {
try {
barrier.await();
} catch (BrokenBarrierException | InterruptedException e) {
throw new RuntimeException(
"Synchronization issue occurred.", e);
}
try {
monitor.wait();
} catch (InterruptedException e) {
throw new AssertionError("The thread waiting on an"
+ " inflated monitor was interrupted, thus test"
+ " results may be incorrect.", e);
}
}
};
Thread t = new Thread(inflatingRunnable);
t.setDaemon(true);
t.start();
// Wait until thread t enters the monitor.
barrier.await();
synchronized (monitor) {
// At this point thread t is already waiting on the monitor.
// Modifying static field just to avoid lock's elimination.
sharedState++;
}
verifyMonitorState(monitor, true /* inflated */);
return monitor;
}
/**
* Verifies that {@code monitor} is a stack-lock or inflated lock depending
* on {@code shouldBeInflated} value. If {@code monitor} is inflated while
* it is expected that it should be a stack-lock, then this method attempts
* to deflate it by forcing a safepoint and then verifies the state once
* again.
*
* @param monitor monitor to be verified.
* @param shouldBeInflated flag indicating whether or not monitor is
* expected to be inflated.
* @throws RuntimeException if the {@code monitor} in a wrong state.
*/
public static void verifyMonitorState(Object monitor,
boolean shouldBeInflated) {
if (!shouldBeInflated && WHITE_BOX.isMonitorInflated(monitor)) {
boolean did_deflation = WHITE_BOX.deflateIdleMonitors();
Asserts.assertEQ(did_deflation, true,
"deflateIdleMonitors() should have worked.");
}
Asserts.assertEQ(WHITE_BOX.isMonitorInflated(monitor), shouldBeInflated,
"Monitor in a wrong state.");
}
/**
* Verifies that monitor used by the {@code provoker} is a stack-lock or
* inflated lock depending on {@code shouldBeInflated} value. If such
* monitor is inflated while it is expected that it should be a stack-lock,
* then this method attempts to deflate it by forcing a safepoint and then
* verifies the state once again.
*
* @param provoker AbortProvoker whose monitor's state should be verified.
* @param shouldBeInflated flag indicating whether or not monitor is
* expected to be inflated.
* @throws RuntimeException if the {@code monitor} in a wrong state.
*/
public static void verifyMonitorState(AbortProvoker provoker,
boolean shouldBeInflated) {
verifyMonitorState(provoker.monitor, shouldBeInflated);
}
/**
* Get instance of specified AbortProvoker, inflate associated monitor
* if needed and then invoke forceAbort method in a loop.
*
* Usage:
* AbortProvoker &lt;AbortType name&gt; [&lt;inflate monitor&gt
* [&lt;iterations&gt; [ &lt;delay&gt;]]]
*
* Default parameters are:
* <ul>
* <li>inflate monitor = <b>true</b></li>
* <li>iterations = {@code AbortProvoker.DEFAULT_ITERATIONS}</li>
* <li>delay = <b>0</b></li>
* </ul>
*/
public static void main(String args[]) throws Throwable {
Asserts.assertGT(args.length, 0, "At least one argument is required.");
AbortType abortType = AbortType.lookup(Integer.valueOf(args[0]));
boolean monitorShouldBeInflated = true;
long iterations = AbortProvoker.DEFAULT_ITERATIONS;
if (args.length > 1) {
monitorShouldBeInflated = Boolean.valueOf(args[1]);
if (args.length > 2) {
iterations = Long.valueOf(args[2]);
if (args.length > 3) {
Thread.sleep(Integer.valueOf(args[3]));
}
}
}
AbortProvoker provoker = abortType.provoker();
if (monitorShouldBeInflated) {
provoker.inflateMonitor();
}
for (long i = 0; i < iterations; i++) {
AbortProvoker.verifyMonitorState(provoker, monitorShouldBeInflated);
provoker.forceAbort();
}
}
protected final Object monitor;
protected AbortProvoker() {
this(new Object());
}
protected AbortProvoker(Object monitor) {
this.monitor = Objects.requireNonNull(monitor);
}
/**
* Inflates monitor used by this AbortProvoker instance.
* @throws Exception
*/
public void inflateMonitor() throws Exception {
AbortProvoker.inflateMonitor(monitor);
}
/**
* Forces transactional execution abortion.
*/
public abstract void forceAbort();
/**
* Returns names of all methods that have to be compiled
* in order to successfully force transactional execution
* abortion.
*
* @return array with methods' names that have to be compiled.
*/
@Override
public String[] getMethodsToCompileNames() {
return new String[] { getMethodWithLockName() };
}
/**
* Returns name of the method that will contain monitor whose locking
* will be elided using transactional execution.
*
* @return name of the method that will contain elided lock.
*/
@Override
public String getMethodWithLockName() {
return this.getClass().getName() + "::forceAbort";
}
}

@ -1,102 +0,0 @@
/*
* Copyright (c) 2014, 2015, Oracle and/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.
*/
package compiler.testlibrary.rtm;
import jdk.test.lib.Asserts;
import java.util.HashMap;
import java.util.Map;
/**
* Type of transactional execution abort.
* For more details on different abort types please see
* shared/vm/runtime/rtmLocking.hpp
*/
public enum AbortType {
XABORT(0),
RETRIABLE(1),
MEM_CONFLICT(2),
BUF_OVERFLOW(3),
DEBUG_BREAKPOINT(4),
NESTED_ABORT(5);
private final int type;
private static final Map<Integer, AbortType> LOOKUP_MAP = new HashMap<>();
static {
for (AbortType abortType : AbortType.values()) {
Asserts.assertFalse(LOOKUP_MAP.containsKey(abortType.type),
"Abort type values should be unique.");
LOOKUP_MAP.put(abortType.type, abortType);
}
}
private AbortType(int type) {
this.type = type;
}
/**
* Returns AbortProvoker for aborts represented by this abort type.
*
* @return an AbortProvoker instance
*/
public AbortProvoker provoker() {
return AbortType.createNewProvoker(this);
}
public static AbortType lookup(int type) {
Asserts.assertLT(type, AbortType.values().length,
"Unknown abort type.");
return LOOKUP_MAP.get(type);
}
/**
* Returns transaction execution abort provoker for specified abortion type.
*
* @param type a type of abort which will be forced by returned
* AbortProvoker instance.
* @return AbortProvoker instance that will force abort of specified type
* @throws RuntimeException if there is no provoker for specified type
*/
private static AbortProvoker createNewProvoker(AbortType type) {
switch (type) {
case XABORT:
return new XAbortProvoker();
case MEM_CONFLICT:
return new MemoryConflictProvoker();
case BUF_OVERFLOW:
return new BufferOverflowProvoker();
case NESTED_ABORT:
return new NestedAbortProvoker();
default:
throw new RuntimeException("No provoker exists for type "
+ type.name());
}
}
@Override
public String toString() {
return Integer.toString(type);
}
}

@ -1,47 +0,0 @@
/*
* Copyright (c) 2014, Oracle and/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.
*/
package compiler.testlibrary.rtm;
/**
* In order to provoke transactional execution abort due to
* internal's buffer overflow BufferOverflowProvoker modifies
* 1MB of BYTES during single transaction.
*/
class BufferOverflowProvoker extends AbortProvoker {
/**
* To force buffer overflow abort we modify memory region with
* size more then L1d cache size.
*/
private static final int MORE_THAN_L1D_SIZE = 1024 * 1024;
private static final byte[] DATA = new byte[MORE_THAN_L1D_SIZE];
@Override
public void forceAbort() {
synchronized(monitor) {
for (int i = 0; i < BufferOverflowProvoker.DATA.length; i++) {
BufferOverflowProvoker.DATA[i]++;
}
}
}
}

@ -1,125 +0,0 @@
/*
* Copyright (c) 2014, 2015, Oracle and/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.
*/
package compiler.testlibrary.rtm;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* Test case for busy lock scenario.
* One thread enters the monitor and sleep for a while.
* Another thread is blocked on the same monitor.
*/
public class BusyLock implements CompilableTest, Runnable {
private static final int DEFAULT_TIMEOUT = 1000;
private final CyclicBarrier barrier;
// Following field have to be static in order to avoid escape analysis.
@SuppressWarnings("UnsuedDeclaration")
private static int field = 0;
protected final Object monitor;
protected final int timeout;
public BusyLock() {
this(BusyLock.DEFAULT_TIMEOUT);
}
public BusyLock(int timeout) {
this.timeout = timeout;
this.monitor = new Object();
this.barrier = new CyclicBarrier(2);
}
@Override
public void run() {
try {
synchronized (monitor) {
barrier.await();
Thread.sleep(timeout);
}
} catch (InterruptedException | BrokenBarrierException e) {
throw new RuntimeException("Synchronization error happened.", e);
}
}
public void syncAndTest() {
try {
// wait until monitor is locked by a ::run method
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
throw new RuntimeException("Synchronization error happened.", e);
}
test();
}
public void test() {
synchronized(monitor) {
BusyLock.field++;
}
}
@Override
public String getMethodWithLockName() {
return this.getClass().getName() + "::test";
}
@Override
public String[] getMethodsToCompileNames() {
return new String[] { getMethodWithLockName() };
}
/**
* Usage:
* BusyLock [ &lt;inflate monitor&gt; [ &lt;timeout&gt; ] ]
*
* Default values are:
* <ul>
* <li>inflate monitor = {@code true}</li>
* <li>timeout = {@code BusyLock.DEFAULT_TIMEOUT}</li>
* </ul>
*/
public static void main(String args[]) throws Exception {
int timeoutValue = BusyLock.DEFAULT_TIMEOUT;
boolean inflateMonitor = true;
if (args.length > 0 ) {
inflateMonitor = Boolean.valueOf(args[0]);
if (args.length > 1) {
timeoutValue = Integer.valueOf(args[1]);
}
}
BusyLock busyLock = new BusyLock(timeoutValue);
if (inflateMonitor) {
AbortProvoker.inflateMonitor(busyLock.monitor);
}
Thread t = new Thread(busyLock);
t.start();
busyLock.syncAndTest();
t.join();
}
}

@ -1,40 +0,0 @@
/*
* Copyright (c) 2014, Oracle and/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.
*/
package compiler.testlibrary.rtm;
/**
* Interface for test scenarios that contain methods
* that should be compiled.
*/
public interface CompilableTest {
/**
* @return array with methods' names that should be compiled.
*/
String[] getMethodsToCompileNames();
/**
* @return name of method with RTM-elided lock.
*/
String getMethodWithLockName();
}

@ -1,99 +0,0 @@
/*
* Copyright (c) 2014, Oracle and/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.
*/
package compiler.testlibrary.rtm;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* To force transactional execution abort due to memory conflict
* one thread should access memory region from transactional region
* while another thread should modify the same memory region.
* Since this scenario is based on the race condition between threads
* you should not expect some particular amount of aborts.
*/
class MemoryConflictProvoker extends AbortProvoker {
// Following field have to be static in order to avoid escape analysis.
@SuppressWarnings("UnsuedDeclaration")
private static int field = 0;
private static final int INNER_ITERATIONS = 10000;
private final CyclicBarrier barrier;
/**
* This thread will access and modify memory region
* from outside of the transaction.
*/
private final Runnable conflictingThread;
public MemoryConflictProvoker() {
this(new Object());
}
public MemoryConflictProvoker(Object monitor) {
super(monitor);
barrier = new CyclicBarrier(2);
conflictingThread = () -> {
try {
barrier.await();
} catch (Exception e) {
throw new RuntimeException(e);
}
for (int i = 0; i < MemoryConflictProvoker.INNER_ITERATIONS; i++) {
MemoryConflictProvoker.field++;
}
};
}
/**
* Accesses and modifies memory region from within the transaction.
*/
public void transactionalRegion() {
for (int i = 0; i < MemoryConflictProvoker.INNER_ITERATIONS; i++) {
synchronized(monitor) {
MemoryConflictProvoker.field--;
}
}
}
@Override
public void forceAbort() {
try {
Thread t = new Thread(conflictingThread);
t.start();
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
throw new RuntimeException(e);
}
transactionalRegion();
t.join();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public String getMethodWithLockName() {
return this.getClass().getName() + "::transactionalRegion";
}
}

@ -1,60 +0,0 @@
/*
* Copyright (c) 2014, Oracle and/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.
*/
package compiler.testlibrary.rtm;
import java.util.Arrays;
/**
* In order to force nested transaction abort NestedAbortProvoker
* invoke BufferOverflowProvoker from transactional region.
*/
class NestedAbortProvoker extends AbortProvoker {
// Following field have to be static in order to avoid escape analysis.
@SuppressWarnings("UnsuedDeclaration")
private static int field = 0;
private final AbortProvoker nestedAbortProvoker;
public NestedAbortProvoker() {
this.nestedAbortProvoker = new XAbortProvoker(monitor);
}
@Override
public void forceAbort() {
synchronized(monitor) {
NestedAbortProvoker.field++;
nestedAbortProvoker.forceAbort();
NestedAbortProvoker.field--;
}
}
@Override
public String[] getMethodsToCompileNames() {
String nestedProvokerMethods[]
= nestedAbortProvoker.getMethodsToCompileNames();
String methods[] = Arrays.copyOf(nestedProvokerMethods,
nestedProvokerMethods.length + 1);
methods[methods.length - 1] = getMethodWithLockName();
return methods;
}
}

@ -1,226 +0,0 @@
/*
* Copyright (c) 2014, 2019, Oracle and/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.
*/
package compiler.testlibrary.rtm;
import java.util.EnumMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Wrapper for +UsePreciseRTMLockingStatistics output.
*
* Example of locking statistics:
*
* java/lang/ClassLoader.loadClass@7
* # rtm locks total (estimated): 6656
* # rtm lock aborts (total): 10000
* # rtm lock aborts 0 (abort instruction ): 9999
* # rtm lock aborts 1 (may succeed on retry): 9999
* # rtm lock aborts 2 (thread conflict ): 0
* # rtm lock aborts 3 (buffer overflow ): 1
* # rtm lock aborts 4 (debug or trap hit ): 0
* # rtm lock aborts 5 (maximum nested depth): 0
*/
public class RTMLockingStatistics {
/**
* Pattern for aborts per abort type entries.
*/
private static final Pattern ABORT_PATTERN;
/**
* Pattern for whole statistics.
*/
private static final Pattern RTM_LOCKING_STATISTICS_PATTERN;
static {
String abortRe
= "# rtm lock aborts\\s+(?<type>[0-9]+)\\s+\\([a-z\\s]+\\):\\s(?<count>[0-9]+)";
ABORT_PATTERN = Pattern.compile(abortRe);
RTM_LOCKING_STATISTICS_PATTERN = Pattern.compile(
"(?<className>[^.\n]+)\\." +
"(?<methodName>[^@\n]+)@(?<bci>[0-9]+)\n" +
"# rtm locks total \\(estimated\\):\\s*" +
"(?<totalLocks>[0-9]+)\n" +
"# rtm lock aborts\\s+\\(total\\):\\s*(?<totalAborts>[0-9]+)\n" +
"(?<abortStats>(" + abortRe + "\n)+)");
}
private final long totalLocks;
private final long totalAborts;
private final String className;
private final String methodName;
private final int bci;
private final Map<AbortType, Long> aborts = new EnumMap<>(AbortType.class);
/**
* Constructs RTMLockingStatistics from matcher captured statistics entry.
* @param matcher Matcher captured statistics entry.
*/
private RTMLockingStatistics(Matcher matcher) {
className = matcher.group("className");
methodName = matcher.group("methodName");
bci = Integer.valueOf(matcher.group("bci"));
totalLocks = Long.valueOf(matcher.group("totalLocks"));
totalAborts = Long.valueOf(matcher.group("totalAborts"));
Matcher abortMatcher = ABORT_PATTERN.matcher(matcher.
group("abortStats"));
while (abortMatcher.find()) {
int type = Integer.valueOf(abortMatcher.group("type"));
long count = Long.valueOf(abortMatcher.group("count"));
setAborts(AbortType.lookup(type), count);
}
}
/**
* Parses string and return all founded RTM locking statistics entries.
*
* @param str the string to be parsed.
* @return list with all founded RTM locking statistics entries or
* empty list if nothing was found.
*/
public static List<RTMLockingStatistics> fromString(String str) {
List<RTMLockingStatistics> statistics = new LinkedList<>();
Matcher matcher = RTM_LOCKING_STATISTICS_PATTERN.matcher(str);
while (matcher.find()) {
RTMLockingStatistics lock = new RTMLockingStatistics(matcher);
statistics.add(lock);
}
return statistics;
}
/**
* Parses string and return all founded RTM locking statistics entries
* for locks in method {@code methodName}.
*
* @param methodName a name of the method for locks from which statistics
* should be gathered.
* @param str the string to be parsed.
* @return list with all founded RTM locking statistics entries or
* empty list if nothing was found.
*/
public static List<RTMLockingStatistics> fromString(String methodName,
String str) {
String formattedMethodName = formatMethodName(methodName);
List<RTMLockingStatistics> statisticsForMethod = new LinkedList<>();
for (RTMLockingStatistics statistics : fromString(str)) {
if (statistics.getLockName().startsWith(formattedMethodName)) {
statisticsForMethod.add(statistics);
}
}
return statisticsForMethod;
}
/**
* Formats method's name so it will have the same format as
* in rtm locking statistics.
*
* <pre>
* Example:
* com/example/Klass::method =&gt; com/example/Klass.method
* com/example/Klass.method =&gt; com/example/Klass.method
* com.example.Klass::method =&gt; com/example/Klass.method
* com.example.Klass.method =&gt; com/example/Klass.method
* </pre>
*
* @param methodName method's name that should be formatted.
* @return formatted method's name.
*/
private static String formatMethodName(String methodName) {
String m[];
if (methodName.contains("::")) {
m = methodName.split("::");
} else {
int splitAt = methodName.lastIndexOf('.');
m = new String[2];
m[0] = methodName.substring(0, splitAt);
m[1] = methodName.substring(splitAt + 1);
}
return String.format("%s.%s", m[0].replaceAll("\\.", "/"), m[1]);
}
/**
* Returns name of lock for which this statistics was collected.
* Lock name has following format:
* &lt;class name&gt;.&lt;method name&gt;@&lt;bci&gt;
*
* @return name of lock.
*/
public String getLockName() {
return String.format("%s.%s@%d", className, methodName, bci);
}
/**
* Returns aborts count for specified abort type.
*
* @param type an abort type.
* @return count of aborts.
*/
public long getAborts(AbortType type) {
return aborts.getOrDefault(type, 0L);
}
/**
* Sets aborts count for specified abort type.
*
* @param type an abort type.
* @param count count of aborts.
*/
public void setAborts(AbortType type, long count) {
aborts.put(type, count);
}
public long getTotalLocks() {
return totalLocks;
}
public long getTotalAborts() {
return totalAborts;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(getLockName()).append('\n');
builder.append(String.format("# rtm locks total (estimated): %d\n",
getTotalLocks()));
builder.append(String.format("# rtm lock aborts: %d\n",
getTotalLocks()));
for (AbortType type : AbortType.values()) {
builder.append(String.format("# rtm lock aborts %s %d\n",
type.toString(), getAborts(type)));
}
return builder.toString();
}
}

@ -1,280 +0,0 @@
/*
* Copyright (c) 2014, 2023, Oracle and/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.
*/
package compiler.testlibrary.rtm;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.Utils;
import jdk.test.lib.cli.CommandLineOptionTest;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Auxiliary methods used for RTM testing.
*/
public class RTMTestBase {
private static final String RTM_STATE_CHANGE_REASON = "rtm_state_change";
/**
* We don't parse compilation log as XML-document and use regular
* expressions instead, because in some cases it could be
* malformed.
*/
private static final String FIRED_UNCOMMON_TRAP_PATTERN_TEMPLATE
= "<uncommon_trap thread='[0-9]+' reason='%s'";
private static final String INSTALLED_UNCOMMON_TRAP_PATTERN_TEMPLATE
= "<uncommon_trap bci='[0-9]+' reason='%s'";
/**
* Executes RTM test in a new JVM started with {@code options} cli options.
*
* @param test test case to execute.
* @param options additional options for VM
* @throws Exception when something went wrong.
*/
public static OutputAnalyzer executeRTMTest(CompilableTest test,
String... options) throws Exception {
ProcessBuilder processBuilder
= ProcessTools.createLimitedTestJavaProcessBuilder(
RTMTestBase.prepareTestOptions(test, options));
OutputAnalyzer outputAnalyzer
= new OutputAnalyzer(processBuilder.start());
System.out.println(outputAnalyzer.getOutput());
return outputAnalyzer;
}
/**
* Executes test case and save compilation log to {@code logFileName}.
*
* @param logFileName a name of compilation log file
* @param test a test case to execute case to execute
* @param options additional options to VM
* @return OutputAnalyzer for started test case
* @throws Exception when something went wrong
*/
public static OutputAnalyzer executeRTMTest(String logFileName,
CompilableTest test, String... options) throws Exception {
ProcessBuilder processBuilder
= ProcessTools.createLimitedTestJavaProcessBuilder(
RTMTestBase.prepareTestOptions(logFileName, test, options));
OutputAnalyzer outputAnalyzer
= new OutputAnalyzer(processBuilder.start());
System.out.println(outputAnalyzer.getOutput());
return outputAnalyzer;
}
/**
* Finds count of uncommon traps with reason {@code reason} installed
* during compilation.
*
* @param compilationLogFile a path to file with LogCompilation output.
* @param reason reason of installed uncommon traps.
* @return count of installed uncommon traps with reason {@code reason}.
* @throws IOException
*/
public static int installedUncommonTraps(String compilationLogFile,
String reason)throws IOException {
String pattern = String.format(
RTMTestBase.INSTALLED_UNCOMMON_TRAP_PATTERN_TEMPLATE,
reason);
return RTMTestBase.findTraps(compilationLogFile, pattern);
}
/**
* Finds count of uncommon traps with reason <i>rtm_state_change</i>
* installed during compilation.
*
* @param compilationLogFile a path to file with LogCompilation output.
* @return count of installed uncommon traps with reason
* <i>rtm_state_change</i>.
* @throws IOException
*/
public static int installedRTMStateChangeTraps(String compilationLogFile)
throws IOException {
return RTMTestBase.installedUncommonTraps(compilationLogFile,
RTMTestBase.RTM_STATE_CHANGE_REASON);
}
/**
* Finds count of fired uncommon traps with reason {@code reason}.
*
* @param compilationLogFile a path to file with LogCompilation output.
* @param reason a reason of fired uncommon traps.
* @return count of fired uncommon traps with reason {@code reason}.
* @throws IOException
*/
public static int firedUncommonTraps(String compilationLogFile,
String reason) throws IOException {
String pattern = String.format(
RTMTestBase.FIRED_UNCOMMON_TRAP_PATTERN_TEMPLATE,
reason);
return RTMTestBase.findTraps(compilationLogFile, pattern);
}
/**
* Finds count of fired uncommon traps with reason <i>rtm_state_change</i>.
*
* @param compilationLogFile a path to file with LogCompilation output.
* @return count of fired uncommon traps with reason
* <i>rtm_state_change</i>.
* @throws IOException
*/
public static int firedRTMStateChangeTraps(String compilationLogFile)
throws IOException {
return RTMTestBase.firedUncommonTraps(compilationLogFile,
RTMTestBase.RTM_STATE_CHANGE_REASON);
}
/**
* Finds count of uncommon traps that matches regular
* expression in {@code re}.
*
* @param compilationLogFile a path to file with LogCompilation output.
* @param re regular expression to match uncommon traps.
* @throws IOException
*/
private static int findTraps(String compilationLogFile, String re)
throws IOException {
String compilationLog = RTMTestBase.fileAsString(compilationLogFile);
Pattern pattern = Pattern.compile(re);
Matcher matcher = pattern.matcher(compilationLog);
int traps = 0;
while (matcher.find()) {
traps++;
}
return traps;
}
/**
* Returns file's content as a string.
*
* @param path a path to file to operate on.
* @return string with content of file.
* @throws IOException
*/
private static String fileAsString(String path) throws IOException {
byte[] fileAsBytes = Files.readAllBytes(Paths.get(path));
return new String(fileAsBytes);
}
/**
* Prepares VM options for test execution.
* This method get test java options, filter out all RTM-related options,
* adds CompileCommand=compileonly,method_name options for each method
* from {@code methodToCompile} and finally appends all {@code vmOpts}.
*
* @param test test case whose methods that should be compiled.
* If {@code null} then no additional <i>compileonly</i>
* commands will be added to VM options.
* @param vmOpts additional options to pass to VM.
* @return Array with VM options.
*/
private static String[] prepareTestOptions(CompilableTest test,
String... vmOpts) {
return RTMTestBase.prepareFilteredTestOptions(test, null, vmOpts);
}
/**
* Prepares VM options for test execution.
* This method get test java options, filter out all RTM-related options
* and all options that matches regexps in {@code additionalFilters},
* adds CompileCommand=compileonly,method_name options for each method
* from {@code methodToCompile} and finally appends all {@code vmOpts}.
*
* @param test test case whose methods that should be compiled.
* If {@code null} then no additional <i>compileonly</i>
* commands will be added to VM options.
* @param additionalFilters array with regular expression that will be
* used to filter out test java options.
* If {@code null} then no additional filters
* will be used.
* @param vmOpts additional options to pass to VM.
* @return array with VM options.
*/
private static String[] prepareFilteredTestOptions(CompilableTest test,
String[] additionalFilters, String... vmOpts) {
List<String> finalVMOpts = new LinkedList<>();
String[] filters;
if (additionalFilters != null) {
filters = Arrays.copyOf(additionalFilters,
additionalFilters.length + 1);
} else {
filters = new String[1];
}
filters[filters.length - 1] = "RTM";
String[] filteredVMOpts = Utils.getFilteredTestJavaOpts(filters);
Collections.addAll(finalVMOpts, filteredVMOpts);
Collections.addAll(finalVMOpts, "-Xcomp", "-server",
"-XX:-TieredCompilation", "-XX:+UseRTMLocking",
CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-Xbootclasspath/a:.", "-XX:+WhiteBoxAPI",
"--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED");
if (test != null) {
for (String method : test.getMethodsToCompileNames()) {
finalVMOpts.add("-XX:CompileCommand=compileonly," + method);
}
}
Collections.addAll(finalVMOpts, vmOpts);
return finalVMOpts.toArray(new String[finalVMOpts.size()]);
}
/**
* Adds additional options for VM required for successful execution of test.
*
* @param logFileName a name of compilation log file
* @param test a test case to execute
* @param options additional options to VM
* @return an array with VM options
*/
private static String[] prepareTestOptions(String logFileName,
CompilableTest test, String... options) {
String[] preparedOptions = RTMTestBase.prepareFilteredTestOptions(
test,
new String[] {
"LogCompilation",
"LogFile"
});
List<String> updatedOptions = new LinkedList<>();
Collections.addAll(updatedOptions, preparedOptions);
Collections.addAll(updatedOptions,
"-XX:+LogCompilation",
"-XX:LogFile=" + logFileName);
Collections.addAll(updatedOptions, options);
return updatedOptions.toArray(new String[updatedOptions.size()]);
}
}

@ -1,68 +0,0 @@
/*
* Copyright (c) 2014, 2019, Oracle and/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.
*/
package compiler.testlibrary.rtm;
/**
* Current RTM locking implementation force transaction abort
* before native method call by explicit xabort(0) call.
*/
public class XAbortProvoker extends AbortProvoker {
static {
try {
System.loadLibrary("XAbortProvoker");
} catch (UnsatisfiedLinkError e) {
System.out.println("Could not load native library: " + e);
}
}
public native int doAbort();
// Following field have to be static in order to avoid escape analysis.
@SuppressWarnings("UnsuedDeclaration")
private static int field = 0;
public XAbortProvoker() {
this(new Object());
}
public XAbortProvoker(Object monitor) {
super(monitor);
}
@Override
public void forceAbort() {
synchronized(monitor) {
XAbortProvoker.field = doAbort();
}
}
@Override
public String[] getMethodsToCompileNames() {
return new String[] {
getMethodWithLockName(),
XAbortProvoker.class.getName() + "::doAbort"
};
}
}

@ -1,34 +0,0 @@
/*
* Copyright (c) 2019, Oracle and/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.
*/
#include "jni.h"
/**
* Simply calling a JNI method from the JVM will abort any active transaction,
* so doAbort() does nothing special and only returns after being called.
* The transaction abortion happens right before the JNI method is called.
*/
JNIEXPORT int JNICALL
Java_compiler_testlibrary_rtm_XAbortProvoker_doAbort(JNIEnv *env, jobject o) {
return 0;
}