8329141: Obsolete RTM flags and code
Reviewed-by: chagedorn
This commit is contained in:
parent
13642cb4b8
commit
9691153755
src
hotspot
cpu/x86
c2_MacroAssembler_x86.cppc2_MacroAssembler_x86.hppglobalDefinitions_x86.hppglobals_x86.hppmacroAssembler_x86.hppsharedRuntime_x86_32.cppsharedRuntime_x86_64.cppvm_version_x86.cppx86_32.adx86_64.ad
share
java.base/share/man
test/hotspot/jtreg
ProblemList.txtTEST.groups
compiler
rtm
cli
RTMGenericCommandLineOptionTest.javaRTMLockingAwareTest.javaTestPrintPreciseRTMLockingStatisticsBase.javaTestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.javaTestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig.javaTestRTMAbortThresholdOption.javaTestRTMLockingCalculationDelayOption.javaTestRTMLockingThresholdOption.javaTestRTMRetryCountOption.javaTestRTMSpinLoopCountOption.javaTestRTMTotalCountIncrRateOptionOnSupportedConfig.javaTestUseRTMDeoptOptionOnSupportedConfig.javaTestUseRTMDeoptOptionOnUnsupportedConfig.javaTestUseRTMForStackLocksOptionOnSupportedConfig.javaTestUseRTMForStackLocksOptionOnUnsupportedConfig.javaTestUseRTMLockingOptionOnSupportedConfig.javaTestUseRTMLockingOptionOnUnsupportedCPU.javaTestUseRTMLockingOptionOnUnsupportedVM.javaTestUseRTMXendForLockBusyOption.java
locking
TestRTMAbortRatio.javaTestRTMAbortThreshold.javaTestRTMAfterNonRTMDeopt.javaTestRTMDeoptOnHighAbortRatio.javaTestRTMDeoptOnLowAbortRatio.javaTestRTMLockingCalculationDelay.javaTestRTMLockingThreshold.javaTestRTMRetryCount.javaTestRTMSpinLoopCount.javaTestRTMTotalCountIncrRate.javaTestUseRTMAfterLockInflation.javaTestUseRTMDeopt.javaTestUseRTMForInflatedLocks.javaTestUseRTMForStackLocks.javaTestUseRTMXendForLockBusy.java
method_options
print
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);
|
||||
}
|
||||
}
|
||||
}
|
81
test/hotspot/jtreg/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java
81
test/hotspot/jtreg/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java
@ -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 <inflate monitor>
|
||||
*/
|
||||
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-------|-----|-----|---------------------> 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 <inflate monitor>
|
||||
*/
|
||||
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 <inflate monitor>
|
||||
*/
|
||||
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 <inflate monitor>
|
||||
*/
|
||||
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 <inflate monitor>
|
||||
*/
|
||||
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 <provoker type>
|
||||
*/
|
||||
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 <AbortType name> [<inflate monitor>
|
||||
* [<iterations> [ <delay>]]]
|
||||
*
|
||||
* 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 [ <inflate monitor> [ <timeout> ] ]
|
||||
*
|
||||
* 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 => com/example/Klass.method
|
||||
* com/example/Klass.method => com/example/Klass.method
|
||||
* com.example.Klass::method => com/example/Klass.method
|
||||
* com.example.Klass.method => 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:
|
||||
* <class name>.<method name>@<bci>
|
||||
*
|
||||
* @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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user