8274004: Change 'nonleaf' rank name

8273956: Add checking for rank values

Reviewed-by: dholmes, pchilanomate
This commit is contained in:
Coleen Phillimore 2021-10-08 12:23:19 +00:00
parent b60837a7d5
commit 6364719cd1
41 changed files with 335 additions and 347 deletions

View file

@ -46,8 +46,7 @@ void OSThread::pd_initialize() {
sigemptyset(&_caller_sigmask); sigemptyset(&_caller_sigmask);
_startThread_lock = new Monitor(Mutex::event, "startThread_lock", _startThread_lock = new Monitor(Mutex::event, "startThread_lock");
Monitor::_safepoint_check_never);
assert(_startThread_lock != NULL, "check"); assert(_startThread_lock != NULL, "check");
} }

View file

@ -45,8 +45,7 @@ void OSThread::pd_initialize() {
sigemptyset(&_caller_sigmask); sigemptyset(&_caller_sigmask);
_startThread_lock = new Monitor(Mutex::event, "startThread_lock", _startThread_lock = new Monitor(Mutex::event, "startThread_lock");
Monitor::_safepoint_check_never);
assert(_startThread_lock !=NULL, "check"); assert(_startThread_lock !=NULL, "check");
} }

View file

@ -40,8 +40,7 @@ void OSThread::pd_initialize() {
sigemptyset(&_caller_sigmask); sigemptyset(&_caller_sigmask);
_startThread_lock = new Monitor(Mutex::event, "startThread_lock", _startThread_lock = new Monitor(Mutex::event, "startThread_lock");
Monitor::_safepoint_check_never);
assert(_startThread_lock !=NULL, "check"); assert(_startThread_lock !=NULL, "check");
} }

View file

@ -133,8 +133,7 @@ void ClassLoaderData::initialize_name(Handle class_loader) {
ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool has_class_mirror_holder) : ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool has_class_mirror_holder) :
_metaspace(NULL), _metaspace(NULL),
_metaspace_lock(new Mutex(Mutex::nosafepoint-2, "MetaspaceAllocation_lock", _metaspace_lock(new Mutex(Mutex::nosafepoint-2, "MetaspaceAllocation_lock")),
Mutex::_safepoint_check_never)),
_unloading(false), _has_class_mirror_holder(has_class_mirror_holder), _unloading(false), _has_class_mirror_holder(has_class_mirror_holder),
_modified_oops(true), _modified_oops(true),
// A non-strong hidden class loader data doesn't have anything to keep // A non-strong hidden class loader data doesn't have anything to keep

View file

@ -104,7 +104,7 @@ class CompileTask : public CHeapObj<mtCompiler> {
public: public:
CompileTask() : _failure_reason(NULL), _failure_reason_on_C_heap(false) { CompileTask() : _failure_reason(NULL), _failure_reason_on_C_heap(false) {
_lock = new Monitor(Mutex::nonleaf, "CompileTask_lock", Mutex::_safepoint_check_always); _lock = new Monitor(Mutex::safepoint, "CompileTask_lock");
} }
void initialize(int compile_id, const methodHandle& method, int osr_bci, int comp_level, void initialize(int compile_id, const methodHandle& method, int osr_bci, int comp_level,

View file

@ -167,7 +167,7 @@ class G1RegionsSmallerThanCommitSizeMapper : public G1RegionToSpaceMapper {
MEMFLAGS type) : MEMFLAGS type) :
G1RegionToSpaceMapper(rs, actual_size, page_size, alloc_granularity, commit_factor, type), G1RegionToSpaceMapper(rs, actual_size, page_size, alloc_granularity, commit_factor, type),
_regions_per_page((page_size * commit_factor) / alloc_granularity), _regions_per_page((page_size * commit_factor) / alloc_granularity),
_lock(Mutex::service-3, "G1Mapper_lock", Mutex::_safepoint_check_never) { _lock(Mutex::service-3, "G1Mapper_lock") {
guarantee((page_size * commit_factor) >= alloc_granularity, "allocation granularity smaller than commit granularity"); guarantee((page_size * commit_factor) >= alloc_granularity, "allocation granularity smaller than commit granularity");
} }

View file

@ -40,9 +40,7 @@ void G1SentinelTask::execute() {
G1ServiceThread::G1ServiceThread() : G1ServiceThread::G1ServiceThread() :
ConcurrentGCThread(), ConcurrentGCThread(),
_monitor(Mutex::nosafepoint, _monitor(Mutex::nosafepoint, "G1ServiceThread_lock"),
"G1ServiceThread_lock",
Monitor::_safepoint_check_never),
_task_queue() { _task_queue() {
set_name("G1 Service"); set_name("G1 Service");
create_and_start(); create_and_start();

View file

@ -233,7 +233,7 @@ HeapRegion::HeapRegion(uint hrm_index,
_top(NULL), _top(NULL),
_compaction_top(NULL), _compaction_top(NULL),
_bot_part(bot, this), _bot_part(bot, this),
_par_alloc_lock(Mutex::service-2, "HeapRegionParAlloc_lock", Mutex::_safepoint_check_never), _par_alloc_lock(Mutex::service-2, "HeapRegionParAlloc_lock"),
_pre_dummy_top(NULL), _pre_dummy_top(NULL),
_rem_set(NULL), _rem_set(NULL),
_hrm_index(hrm_index), _hrm_index(hrm_index),

View file

@ -47,7 +47,7 @@ const char* HeapRegionRemSet::_short_state_strings[] = {"UNTRA", "UPDAT", "CMPL
HeapRegionRemSet::HeapRegionRemSet(HeapRegion* hr, HeapRegionRemSet::HeapRegionRemSet(HeapRegion* hr,
G1CardSetConfiguration* config) : G1CardSetConfiguration* config) :
_m(Mutex::service - 1, FormatBuffer<128>("HeapRegionRemSet#%u_lock", hr->hrm_index()), Monitor::_safepoint_check_never), _m(Mutex::service - 1, FormatBuffer<128>("HeapRegionRemSet#%u_lock", hr->hrm_index())),
_code_roots(), _code_roots(),
_card_set_mm(config, G1CardSetFreePool::free_list_pool()), _card_set_mm(config, G1CardSetFreePool::free_list_pool()),
_card_set(config, &_card_set_mm), _card_set(config, &_card_set_mm),

View file

@ -92,8 +92,7 @@ void ParCompactionManager::initialize(ParMarkBitMap* mbm) {
_shadow_region_array = new (ResourceObj::C_HEAP, mtGC) GrowableArray<size_t >(10, mtGC); _shadow_region_array = new (ResourceObj::C_HEAP, mtGC) GrowableArray<size_t >(10, mtGC);
_shadow_region_monitor = new Monitor(Mutex::nosafepoint, "CompactionManager_lock", _shadow_region_monitor = new Monitor(Mutex::nosafepoint, "CompactionManager_lock");
Monitor::_safepoint_check_never);
} }
void ParCompactionManager::reset_all_bitmap_query_caches() { void ParCompactionManager::reset_all_bitmap_query_caches() {

View file

@ -34,8 +34,7 @@ void GCLogPrecious::initialize() {
_lines = new (ResourceObj::C_HEAP, mtGC) stringStream(); _lines = new (ResourceObj::C_HEAP, mtGC) stringStream();
_temp = new (ResourceObj::C_HEAP, mtGC) stringStream(); _temp = new (ResourceObj::C_HEAP, mtGC) stringStream();
_lock = new Mutex(Mutex::event, /* The lowest lock rank I could find */ _lock = new Mutex(Mutex::event, /* The lowest lock rank I could find */
"GCLogPrecious Lock", "GCLogPrecious Lock");
Mutex::_safepoint_check_never);
} }
void GCLogPrecious::vwrite_inner(LogTargetHandle log, const char* format, va_list args) { void GCLogPrecious::vwrite_inner(LogTargetHandle log, const char* format, va_list args) {

View file

@ -811,10 +811,10 @@ const size_t initial_active_array_size = 8;
static Mutex* make_oopstorage_mutex(const char* storage_name, static Mutex* make_oopstorage_mutex(const char* storage_name,
const char* kind, const char* kind,
int rank) { Mutex::Rank rank) {
char name[256]; char name[256];
os::snprintf(name, sizeof(name), "%s %s lock", storage_name, kind); os::snprintf(name, sizeof(name), "%s %s lock", storage_name, kind);
return new PaddedMutex(rank, name, Mutex::_safepoint_check_never); return new PaddedMutex(rank, name);
} }
void* OopStorage::operator new(size_t size, MEMFLAGS memflags) { void* OopStorage::operator new(size_t size, MEMFLAGS memflags) {
@ -844,10 +844,6 @@ OopStorage::OopStorage(const char* name, MEMFLAGS memflags) :
"%s: active_mutex must have lower rank than allocation_mutex", _name); "%s: active_mutex must have lower rank than allocation_mutex", _name);
assert(Service_lock->rank() < _active_mutex->rank(), assert(Service_lock->rank() < _active_mutex->rank(),
"%s: active_mutex must have higher rank than Service_lock", _name); "%s: active_mutex must have higher rank than Service_lock", _name);
assert(_active_mutex->_safepoint_check_required == Mutex::_safepoint_check_never,
"%s: active mutex requires never safepoint check", _name);
assert(_allocation_mutex->_safepoint_check_required == Mutex::_safepoint_check_never,
"%s: allocation mutex requires never safepoint check", _name);
} }
void OopStorage::delete_empty_block(const Block& block) { void OopStorage::delete_empty_block(const Block& block) {

View file

@ -773,8 +773,7 @@ void OffsetTableContigSpace::alloc_block(HeapWord* start, HeapWord* end) {
OffsetTableContigSpace::OffsetTableContigSpace(BlockOffsetSharedArray* sharedOffsetArray, OffsetTableContigSpace::OffsetTableContigSpace(BlockOffsetSharedArray* sharedOffsetArray,
MemRegion mr) : MemRegion mr) :
_offsets(sharedOffsetArray, mr), _offsets(sharedOffsetArray, mr),
_par_alloc_lock(Mutex::nonleaf, "OffsetTableContigSpaceParAlloc_lock", _par_alloc_lock(Mutex::safepoint, "OffsetTableContigSpaceParAlloc_lock", true)
Mutex::_safepoint_check_always, true)
{ {
_offsets.set_contig_space(this); _offsets.set_contig_space(this);
initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle); initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle);

View file

@ -72,7 +72,7 @@ TaskTerminator::TaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set) :
_n_threads(n_threads), _n_threads(n_threads),
_queue_set(queue_set), _queue_set(queue_set),
_offered_termination(0), _offered_termination(0),
_blocker(Mutex::nosafepoint, "TaskTerminator_lock", Monitor::_safepoint_check_never), _blocker(Mutex::nosafepoint, "TaskTerminator_lock"),
_spin_master(NULL) { } _spin_master(NULL) { }
TaskTerminator::~TaskTerminator() { TaskTerminator::~TaskTerminator() {

View file

@ -245,8 +245,7 @@ void GangWorker::loop() {
// *** WorkGangBarrierSync // *** WorkGangBarrierSync
WorkGangBarrierSync::WorkGangBarrierSync() WorkGangBarrierSync::WorkGangBarrierSync()
: _monitor(Mutex::nosafepoint, "WorkGangBarrierSync_lock", : _monitor(Mutex::nosafepoint, "WorkGangBarrierSync_lock"),
Monitor::_safepoint_check_never),
_n_workers(0), _n_completed(0), _should_reset(false), _aborted(false) { _n_workers(0), _n_completed(0), _should_reset(false), _aborted(false) {
} }

View file

@ -47,8 +47,8 @@
ShenandoahControlThread::ShenandoahControlThread() : ShenandoahControlThread::ShenandoahControlThread() :
ConcurrentGCThread(), ConcurrentGCThread(),
_alloc_failure_waiters_lock(Mutex::nonleaf, "ShenandoahAllocFailureGC_lock", Monitor::_safepoint_check_always, true), _alloc_failure_waiters_lock(Mutex::safepoint, "ShenandoahAllocFailureGC_lock", true),
_gc_waiters_lock(Mutex::nonleaf, "ShenandoahRequestedGC_lock", Monitor::_safepoint_check_always, true), _gc_waiters_lock(Mutex::safepoint, "ShenandoahRequestedGC_lock", true),
_periodic_task(this), _periodic_task(this),
_requested_gc_cause(GCCause::_no_cause_specified), _requested_gc_cause(GCCause::_no_cause_specified),
_degen_point(ShenandoahGC::_degenerated_outside_cycle), _degen_point(ShenandoahGC::_degenerated_outside_cycle),

View file

@ -67,7 +67,7 @@ public:
_heap(heap), _heap(heap),
_last_time(os::elapsedTime()), _last_time(os::elapsedTime()),
_progress_history(new TruncatedSeq(5)), _progress_history(new TruncatedSeq(5)),
_wait_monitor(new Monitor(Mutex::nonleaf-1, "ShenandoahWaitMonitor_lock", Monitor::_safepoint_check_always, true)), _wait_monitor(new Monitor(Mutex::safepoint-1, "ShenandoahWaitMonitor_lock", true)),
_epoch(0), _epoch(0),
_tax_rate(1), _tax_rate(1),
_budget(0), _budget(0),

View file

@ -66,9 +66,7 @@ public:
template <typename T> template <typename T>
inline ZMessagePort<T>::ZMessagePort() : inline ZMessagePort<T>::ZMessagePort() :
_monitor(Monitor::nosafepoint, _monitor(Monitor::nosafepoint, "ZMessagePort_lock"),
"ZMessagePort_lock",
Monitor::_safepoint_check_never),
_has_message(false), _has_message(false),
_seqnum(0), _seqnum(0),
_queue() {} _queue() {}

View file

@ -28,7 +28,7 @@
#include "utilities/ticks.hpp" #include "utilities/ticks.hpp"
ZMetronome::ZMetronome(uint64_t hz) : ZMetronome::ZMetronome(uint64_t hz) :
_monitor(Monitor::nosafepoint, "ZMetronome_lock", Monitor::_safepoint_check_never), _monitor(Monitor::nosafepoint, "ZMetronome_lock"),
_interval_ms(MILLIUNITS / hz), _interval_ms(MILLIUNITS / hz),
_start_ms(0), _start_ms(0),
_nticks(0), _nticks(0),

View file

@ -245,7 +245,7 @@ class ParHeapInspectTask : public AbstractGangTask {
_filter(filter), _filter(filter),
_missed_count(0), _missed_count(0),
_success(true), _success(true),
_mutex(Mutex::nosafepoint, "ParHeapInspectTask_lock", Mutex::_safepoint_check_never) {} _mutex(Mutex::nosafepoint, "ParHeapInspectTask_lock") {}
uintx missed_count() const { uintx missed_count() const {
return _missed_count; return _missed_count;

View file

@ -92,7 +92,7 @@ MetaspaceTestContext::~MetaspaceTestContext() {
// Create an arena, feeding off this area. // Create an arena, feeding off this area.
MetaspaceTestArena* MetaspaceTestContext::create_arena(Metaspace::MetaspaceType type) { MetaspaceTestArena* MetaspaceTestContext::create_arena(Metaspace::MetaspaceType type) {
const ArenaGrowthPolicy* growth_policy = ArenaGrowthPolicy::policy_for_space_type(type, false); const ArenaGrowthPolicy* growth_policy = ArenaGrowthPolicy::policy_for_space_type(type, false);
Mutex* lock = new Mutex(Monitor::nosafepoint, "MetaspaceTestArea_lock", Monitor::_safepoint_check_never); Mutex* lock = new Mutex(Monitor::nosafepoint, "MetaspaceTestArea_lock");
MetaspaceArena* arena = NULL; MetaspaceArena* arena = NULL;
{ {
MutexLocker ml(lock, Mutex::_no_safepoint_check_flag); MutexLocker ml(lock, Mutex::_no_safepoint_check_flag);

View file

@ -1207,7 +1207,7 @@ void MethodData::post_initialize(BytecodeStream* stream) {
MethodData::MethodData(const methodHandle& method) MethodData::MethodData(const methodHandle& method)
: _method(method()), : _method(method()),
// Holds Compile_lock // Holds Compile_lock
_extra_data_lock(Mutex::nonleaf-2, "MDOExtraData_lock", Mutex::_safepoint_check_always), _extra_data_lock(Mutex::safepoint-2, "MDOExtraData_lock"),
_compiler_counters(), _compiler_counters(),
_parameters_type_data_di(parameters_uninitialized) { _parameters_type_data_di(parameters_uninitialized) {
initialize(); initialize();

View file

@ -72,7 +72,7 @@ bool JvmtiTagMap::_has_object_free_events = false;
// create a JvmtiTagMap // create a JvmtiTagMap
JvmtiTagMap::JvmtiTagMap(JvmtiEnv* env) : JvmtiTagMap::JvmtiTagMap(JvmtiEnv* env) :
_env(env), _env(env),
_lock(Mutex::nosafepoint, "JvmtiTagMap_lock", Mutex::_safepoint_check_never), _lock(Mutex::nosafepoint, "JvmtiTagMap_lock"),
_needs_rehashing(false), _needs_rehashing(false),
_needs_cleaning(false) { _needs_cleaning(false) {

View file

@ -408,7 +408,7 @@ void Handshake::execute(AsyncHandshakeClosure* hs_cl, JavaThread* target) {
HandshakeState::HandshakeState(JavaThread* target) : HandshakeState::HandshakeState(JavaThread* target) :
_handshakee(target), _handshakee(target),
_queue(), _queue(),
_lock(Monitor::nosafepoint, "HandshakeState_lock", Monitor::_safepoint_check_never), _lock(Monitor::nosafepoint, "HandshakeState_lock"),
_active_handshaker(), _active_handshaker(),
_suspended(false), _suspended(false),
_async_suspend_handshake(false) _async_suspend_handshake(false)

View file

@ -24,6 +24,7 @@
#include "precompiled.hpp" #include "precompiled.hpp"
#include "logging/log.hpp" #include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/interfaceSupport.inline.hpp" #include "runtime/interfaceSupport.inline.hpp"
#include "runtime/mutex.hpp" #include "runtime/mutex.hpp"
#include "runtime/os.inline.hpp" #include "runtime/os.inline.hpp"
@ -62,24 +63,21 @@ void Mutex::check_block_state(Thread* thread) {
void Mutex::check_safepoint_state(Thread* thread) { void Mutex::check_safepoint_state(Thread* thread) {
check_block_state(thread); check_block_state(thread);
// If the JavaThread checks for safepoint, verify that the lock wasn't created with safepoint_check_never. // If the lock acquisition checks for safepoint, verify that the lock was created with rank that
if (thread->is_active_Java_thread()) { // has safepoint checks. Technically this doesn't affect NonJavaThreads since they won't actually
assert(_safepoint_check_required != _safepoint_check_never, // check for safepoint, but let's make the rule unconditional unless there's a good reason not to.
"This lock should never have a safepoint check for Java threads: %s", assert(_rank > nosafepoint,
name()); "This lock should not be taken with a safepoint check: %s", name());
if (thread->is_active_Java_thread()) {
// Also check NoSafepointVerifier, and thread state is _thread_in_vm // Also check NoSafepointVerifier, and thread state is _thread_in_vm
JavaThread::cast(thread)->check_for_valid_safepoint_state(); JavaThread::cast(thread)->check_for_valid_safepoint_state();
} else {
// If initialized with safepoint_check_never, a NonJavaThread should never ask to safepoint check either.
assert(_safepoint_check_required != _safepoint_check_never,
"NonJavaThread should not check for safepoint");
} }
} }
void Mutex::check_no_safepoint_state(Thread* thread) { void Mutex::check_no_safepoint_state(Thread* thread) {
check_block_state(thread); check_block_state(thread);
assert(!thread->is_active_Java_thread() || _safepoint_check_required != _safepoint_check_always, assert(!thread->is_active_Java_thread() || _rank <= nosafepoint,
"This lock should always have a safepoint check for Java threads: %s", "This lock should always have a safepoint check for Java threads: %s",
name()); name());
} }
@ -167,7 +165,7 @@ bool Mutex::try_lock_inner(bool do_rank_checks) {
if (do_rank_checks) { if (do_rank_checks) {
check_rank(self); check_rank(self);
} }
// Some safepoint_check_always locks use try_lock, so cannot check // Some safepoint checking locks use try_lock, so cannot check
// safepoint state, but can check blocking state. // safepoint state, but can check blocking state.
check_block_state(self); check_block_state(self);
@ -274,29 +272,21 @@ Mutex::~Mutex() {
os::free(const_cast<char*>(_name)); os::free(const_cast<char*>(_name));
} }
Mutex::Mutex(int Rank, const char * name, SafepointCheckRequired safepoint_check_required, Mutex::Mutex(Rank rank, const char * name, bool allow_vm_block) : _owner(NULL) {
bool allow_vm_block) : _owner(NULL) {
assert(os::mutex_init_done(), "Too early!"); assert(os::mutex_init_done(), "Too early!");
assert(name != NULL, "Mutex requires a name"); assert(name != NULL, "Mutex requires a name");
_name = os::strdup(name, mtInternal); _name = os::strdup(name, mtInternal);
#ifdef ASSERT #ifdef ASSERT
_allow_vm_block = allow_vm_block; _allow_vm_block = allow_vm_block;
_rank = Rank; _rank = rank;
_safepoint_check_required = safepoint_check_required;
_skip_rank_check = false; _skip_rank_check = false;
assert(_rank >= 0 && _rank <= nonleaf, "Bad lock rank %d: %s", _rank, name); assert(_rank >= static_cast<Rank>(0) && _rank <= safepoint, "Bad lock rank %s: %s", rank_name(), name);
assert(_rank > nosafepoint || _safepoint_check_required == _safepoint_check_never,
"Locks below nosafepoint rank should never safepoint: %s", name);
assert(_rank <= nosafepoint || _safepoint_check_required == _safepoint_check_always,
"Locks above nosafepoint rank should safepoint: %s", name);
// The allow_vm_block also includes allowing other non-Java threads to block or // The allow_vm_block also includes allowing other non-Java threads to block or
// allowing Java threads to block in native. // allowing Java threads to block in native.
assert(_safepoint_check_required == _safepoint_check_always || _allow_vm_block, assert(_rank > nosafepoint || _allow_vm_block,
"Safepoint check never locks should always allow the vm to block: %s", name); "Locks that don't check for safepoint should always allow the vm to block: %s", name);
#endif #endif
} }
@ -312,23 +302,57 @@ void Mutex::print_on_error(outputStream* st) const {
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Non-product code // Non-product code
//
#ifdef ASSERT
static Mutex::Rank _ranks[] = { Mutex::event, Mutex::service, Mutex::stackwatermark, Mutex::tty, Mutex::oopstorage,
Mutex::nosafepoint, Mutex::safepoint };
static const char* _rank_names[] = { "event", "service", "stackwatermark", "tty", "oopstorage",
"nosafepoint", "safepoint" };
static const int _num_ranks = 7;
static const char* rank_name_internal(Mutex::Rank r) {
// Find closest rank and print out the name
stringStream st;
for (int i = 0; i < _num_ranks; i++) {
if (r == _ranks[i]) {
return _rank_names[i];
} else if (r > _ranks[i] && (i < _num_ranks-1 && r < _ranks[i+1])) {
int delta = static_cast<int>(_ranks[i+1]) - static_cast<int>(r);
st.print("%s-%d", _rank_names[i+1], delta);
return st.as_string();
}
}
return "fail";
}
const char* Mutex::rank_name() const {
return rank_name_internal(_rank);
}
void Mutex::assert_no_overlap(Rank orig, Rank adjusted, int adjust) {
int i = 0;
while (_ranks[i] < orig) i++;
// underflow is caught in constructor
if (i != 0 && adjusted > event && adjusted <= _ranks[i-1]) {
ResourceMark rm;
assert(adjusted > _ranks[i-1],
"Rank %s-%d overlaps with %s",
rank_name_internal(orig), adjust, rank_name_internal(adjusted));
}
}
#endif // ASSERT
#ifndef PRODUCT #ifndef PRODUCT
const char* print_safepoint_check(Mutex::SafepointCheckRequired safepoint_check) {
switch (safepoint_check) {
case Mutex::_safepoint_check_never: return "safepoint_check_never";
case Mutex::_safepoint_check_always: return "safepoint_check_always";
default: return "";
}
}
void Mutex::print_on(outputStream* st) const { void Mutex::print_on(outputStream* st) const {
st->print("Mutex: [" PTR_FORMAT "] %s - owner: " PTR_FORMAT, st->print("Mutex: [" PTR_FORMAT "] %s - owner: " PTR_FORMAT,
p2i(this), _name, p2i(owner())); p2i(this), _name, p2i(owner()));
if (_allow_vm_block) { if (_allow_vm_block) {
st->print("%s", " allow_vm_block"); st->print("%s", " allow_vm_block");
} }
st->print(" %s", print_safepoint_check(_safepoint_check_required)); DEBUG_ONLY(st->print(" %s", rank_name()));
st->cr(); st->cr();
} }
#endif // PRODUCT #endif // PRODUCT
@ -392,8 +416,9 @@ void Mutex::check_rank(Thread* thread) {
if (least != NULL && ((least->rank() <= Mutex::nosafepoint && thread->is_Java_thread()) || if (least != NULL && ((least->rank() <= Mutex::nosafepoint && thread->is_Java_thread()) ||
least->rank() <= Mutex::tty || least->rank() <= Mutex::tty ||
least->rank() <= this->rank())) { least->rank() <= this->rank())) {
assert(false, "Attempting to wait on monitor %s/%d while holding lock %s/%d -- " ResourceMark rm(thread);
"possible deadlock. %s", name(), rank(), least->name(), least->rank(), assert(false, "Attempting to wait on monitor %s/%s while holding lock %s/%s -- "
"possible deadlock. %s", name(), rank_name(), least->name(), least->rank_name(),
least->rank() <= this->rank() ? least->rank() <= this->rank() ?
"Should wait on the least ranked monitor from all owned locks." : "Should wait on the least ranked monitor from all owned locks." :
thread->is_Java_thread() ? thread->is_Java_thread() ?
@ -409,14 +434,15 @@ void Mutex::check_rank(Thread* thread) {
// to acquire, then deadlock prevention rules require that the rank // to acquire, then deadlock prevention rules require that the rank
// of m2 be less than the rank of m1. This prevents circular waits. // of m2 be less than the rank of m1. This prevents circular waits.
if (least != NULL && least->rank() <= this->rank()) { if (least != NULL && least->rank() <= this->rank()) {
ResourceMark rm(thread);
if (least->rank() > Mutex::tty) { if (least->rank() > Mutex::tty) {
// Printing owned locks acquires tty lock. If the least rank was below or equal // Printing owned locks acquires tty lock. If the least rank was below or equal
// tty, then deadlock detection code would circle back here, until we run // tty, then deadlock detection code would circle back here, until we run
// out of stack and crash hard. Print locks only when it is safe. // out of stack and crash hard. Print locks only when it is safe.
thread->print_owned_locks(); thread->print_owned_locks();
} }
assert(false, "Attempting to acquire lock %s/%d out of order with lock %s/%d -- " assert(false, "Attempting to acquire lock %s/%s out of order with lock %s/%s -- "
"possible deadlock", this->name(), this->rank(), least->name(), least->rank()); "possible deadlock", this->name(), this->rank_name(), least->name(), least->rank_name());
} }
} }
} }

View file

@ -46,17 +46,41 @@ class Mutex : public CHeapObj<mtSynchronizer> {
public: public:
// Special low level locks are given names and ranges avoid overlap. // Special low level locks are given names and ranges avoid overlap.
enum Rank { enum class Rank {
event, event,
service = event + 6, service = event + 6,
stackwatermark = service + 3, stackwatermark = service + 3,
tty = stackwatermark + 3, tty = stackwatermark + 3,
oopstorage = tty + 3, oopstorage = tty + 3,
nosafepoint = oopstorage + 6, nosafepoint = oopstorage + 6,
nonleaf = nosafepoint + 20, safepoint = nosafepoint + 20
max_nonleaf = nonleaf
}; };
// want C++later "using enum" directives.
static const Rank event = Rank::event;
static const Rank service = Rank::service;
static const Rank stackwatermark = Rank::stackwatermark;
static const Rank tty = Rank::tty;
static const Rank oopstorage = Rank::oopstorage;
static const Rank nosafepoint = Rank::nosafepoint;
static const Rank safepoint = Rank::safepoint;
static void assert_no_overlap(Rank orig, Rank adjusted, int adjust);
friend Rank operator-(Rank base, int adjust) {
Rank result = static_cast<Rank>(static_cast<int>(base) - adjust);
DEBUG_ONLY(assert_no_overlap(base, result, adjust));
return result;
}
friend constexpr bool operator<(Rank lhs, Rank rhs) {
return static_cast<int>(lhs) < static_cast<int>(rhs);
}
friend constexpr bool operator>(Rank lhs, Rank rhs) { return rhs < lhs; }
friend constexpr bool operator<=(Rank lhs, Rank rhs) { return !(lhs > rhs); }
friend constexpr bool operator>=(Rank lhs, Rank rhs) { return !(lhs < rhs); }
private: private:
// The _owner field is only set by the current thread, either to itself after it has acquired // The _owner field is only set by the current thread, either to itself after it has acquired
// the low-level _lock, or to NULL before it has released the _lock. Accesses by any thread other // the low-level _lock, or to NULL before it has released the _lock. Accesses by any thread other
@ -73,7 +97,7 @@ class Mutex : public CHeapObj<mtSynchronizer> {
bool _allow_vm_block; bool _allow_vm_block;
#endif #endif
#ifdef ASSERT #ifdef ASSERT
int _rank; // rank (to avoid/detect potential deadlocks) Rank _rank; // rank (to avoid/detect potential deadlocks)
Mutex* _next; // Used by a Thread to link up owned locks Mutex* _next; // Used by a Thread to link up owned locks
Thread* _last_owner; // the last thread to own the lock Thread* _last_owner; // the last thread to own the lock
bool _skip_rank_check; // read only by owner when doing rank checks bool _skip_rank_check; // read only by owner when doing rank checks
@ -87,7 +111,8 @@ class Mutex : public CHeapObj<mtSynchronizer> {
} }
public: public:
int rank() const { return _rank; } Rank rank() const { return _rank; }
const char* rank_name() const;
Mutex* next() const { return _next; } Mutex* next() const { return _next; }
void set_next(Mutex *next) { _next = next; } void set_next(Mutex *next) { _next = next; }
#endif // ASSERT #endif // ASSERT
@ -107,10 +132,10 @@ class Mutex : public CHeapObj<mtSynchronizer> {
// the safepoint protocol when acquiring locks. // the safepoint protocol when acquiring locks.
// Each lock can be acquired by only JavaThreads, only NonJavaThreads, or shared between // Each lock can be acquired by only JavaThreads, only NonJavaThreads, or shared between
// Java and NonJavaThreads. When the lock is initialized with _safepoint_check_always, // Java and NonJavaThreads. When the lock is initialized with rank > nosafepoint,
// that means that whenever the lock is acquired by a JavaThread, it will verify that // that means that whenever the lock is acquired by a JavaThread, it will verify that
// it is done with a safepoint check. In corollary, when the lock is initialized with // it is done with a safepoint check. In corollary, when the lock is initialized with
// _safepoint_check_never, that means that whenever the lock is acquired by a JavaThread // rank <= nosafepoint, that means that whenever the lock is acquired by a JavaThread
// it will verify that it is done without a safepoint check. // it will verify that it is done without a safepoint check.
// TODO: Locks that are shared between JavaThreads and NonJavaThreads // TODO: Locks that are shared between JavaThreads and NonJavaThreads
@ -128,26 +153,11 @@ class Mutex : public CHeapObj<mtSynchronizer> {
static const SafepointCheckFlag _no_safepoint_check_flag = static const SafepointCheckFlag _no_safepoint_check_flag =
SafepointCheckFlag::_no_safepoint_check_flag; SafepointCheckFlag::_no_safepoint_check_flag;
enum class SafepointCheckRequired {
_safepoint_check_never, // Mutexes with this value will cause errors
// when acquired by a JavaThread with a safepoint check.
_safepoint_check_always // Mutexes with this value will cause errors
// when acquired by a JavaThread without a safepoint check.
};
// Bring the enumerator names into class scope.
static const SafepointCheckRequired _safepoint_check_never =
SafepointCheckRequired::_safepoint_check_never;
static const SafepointCheckRequired _safepoint_check_always =
SafepointCheckRequired::_safepoint_check_always;
NOT_PRODUCT(SafepointCheckRequired _safepoint_check_required;)
public: public:
Mutex(int rank, const char *name, SafepointCheckRequired safepoint_check_required, bool allow_vm_block); Mutex(Rank rank, const char *name, bool allow_vm_block);
Mutex(int rank, const char *name, SafepointCheckRequired safepoint_check_required) : Mutex(Rank rank, const char *name) :
Mutex(rank, name, safepoint_check_required, Mutex(rank, name, rank > nosafepoint ? false : true) {}
safepoint_check_required == _safepoint_check_never ? true : false) {}
~Mutex(); ~Mutex();
@ -188,11 +198,11 @@ class Mutex : public CHeapObj<mtSynchronizer> {
class Monitor : public Mutex { class Monitor : public Mutex {
public: public:
Monitor(int rank, const char *name, SafepointCheckRequired safepoint_check_required, bool allow_vm_block) : Monitor(Rank rank, const char *name, bool allow_vm_block) :
Mutex(rank, name, safepoint_check_required, allow_vm_block) {} Mutex(rank, name, allow_vm_block) {}
Monitor(int rank, const char *name, SafepointCheckRequired safepoint_check_required) : Monitor(Rank rank, const char *name) :
Mutex(rank, name, safepoint_check_required) {} Mutex(rank, name) {}
// default destructor // default destructor
// Wait until monitor is notified (or times out). // Wait until monitor is notified (or times out).
@ -212,10 +222,8 @@ class PaddedMutex : public Mutex {
}; };
char _padding[PADDING_LEN]; char _padding[PADDING_LEN];
public: public:
PaddedMutex(int rank, const char *name, SafepointCheckRequired safepoint_check_required, bool allow_vm_block) : PaddedMutex(Rank rank, const char *name, bool allow_vm_block) : Mutex(rank, name, allow_vm_block) {};
Mutex(rank, name, safepoint_check_required, allow_vm_block) {}; PaddedMutex(Rank rank, const char *name) : Mutex(rank, name) {};
PaddedMutex(int rank, const char *name, SafepointCheckRequired safepoint_check_required) :
Mutex(rank, name, safepoint_check_required) {};
}; };
class PaddedMonitor : public Monitor { class PaddedMonitor : public Monitor {
@ -225,10 +233,8 @@ class PaddedMonitor : public Monitor {
}; };
char _padding[PADDING_LEN]; char _padding[PADDING_LEN];
public: public:
PaddedMonitor(int rank, const char *name, SafepointCheckRequired safepoint_check_required, bool allow_vm_block) : PaddedMonitor(Rank rank, const char *name, bool allow_vm_block) : Monitor(rank, name, allow_vm_block) {};
Monitor(rank, name, safepoint_check_required, allow_vm_block) {}; PaddedMonitor(Rank rank, const char *name) : Monitor(rank, name) {};
PaddedMonitor(int rank, const char *name, SafepointCheckRequired safepoint_check_required) :
Monitor(rank, name, safepoint_check_required) {};
}; };
#endif // SHARE_RUNTIME_MUTEX_HPP #endif // SHARE_RUNTIME_MUTEX_HPP

View file

@ -199,176 +199,175 @@ static void add_mutex(Mutex* var) {
_mutex_array[_num_mutex++] = var; _mutex_array[_num_mutex++] = var;
} }
#define def(var, type, pri, vm_block, safepoint_check_allowed ) { \ #define def(var, type, pri, vm_block) { \
var = new type(Mutex::pri, #var, Mutex::safepoint_check_allowed, vm_block); \ var = new type(Mutex::pri, #var, vm_block); \
add_mutex(var); \ add_mutex(var); \
} }
// Specify relative ranked lock // Specify relative ranked lock
#ifdef ASSERT #ifdef ASSERT
#define defl(var, type, held_lock, vm_block, safepoint_check_allowed) { \ #define defl(var, type, held_lock, vm_block) { \
var = new type(held_lock->rank()-1, #var, Mutex::safepoint_check_allowed, vm_block); \ var = new type(held_lock->rank()-1, #var, vm_block); \
add_mutex(var); \ add_mutex(var); \
} }
#else #else
#define defl(var, type, held_lock, vm_block, safepoint_check_allowed) { \ #define defl(var, type, held_lock, vm_block) { \
var = new type(Mutex::nonleaf, #var, Mutex::safepoint_check_allowed, vm_block); \ var = new type(Mutex::safepoint, #var, vm_block); \
add_mutex(var); \ add_mutex(var); \
} }
#endif #endif
// Using Padded subclasses to prevent false sharing of these global monitors and mutexes. // Using Padded subclasses to prevent false sharing of these global monitors and mutexes.
void mutex_init() { void mutex_init() {
def(tty_lock , PaddedMutex , tty, true, _safepoint_check_never); // allow to lock in VM def(tty_lock , PaddedMutex , tty, true); // allow to lock in VM
def(STS_lock , PaddedMonitor, nosafepoint, true, _safepoint_check_never); def(STS_lock , PaddedMonitor, nosafepoint, true);
if (UseG1GC) { if (UseG1GC) {
def(CGC_lock , PaddedMonitor, nosafepoint, true, _safepoint_check_never); def(CGC_lock , PaddedMonitor, nosafepoint, true);
def(G1DetachedRefinementStats_lock, PaddedMutex, nosafepoint-2, true, _safepoint_check_never); def(G1DetachedRefinementStats_lock, PaddedMutex, nosafepoint-2, true);
def(FreeList_lock , PaddedMutex , service-1, true, _safepoint_check_never); def(FreeList_lock , PaddedMutex , service-1, true);
def(OldSets_lock , PaddedMutex , nosafepoint, true, _safepoint_check_never); def(OldSets_lock , PaddedMutex , nosafepoint, true);
def(Uncommit_lock , PaddedMutex , service-2, true, _safepoint_check_never); def(Uncommit_lock , PaddedMutex , service-2, true);
def(RootRegionScan_lock , PaddedMonitor, nosafepoint-1, true, _safepoint_check_never); def(RootRegionScan_lock , PaddedMonitor, nosafepoint-1, true);
def(MarkStackFreeList_lock , PaddedMutex , nosafepoint, true, _safepoint_check_never); def(MarkStackFreeList_lock , PaddedMutex , nosafepoint, true);
def(MarkStackChunkList_lock , PaddedMutex , nosafepoint, true, _safepoint_check_never); def(MarkStackChunkList_lock , PaddedMutex , nosafepoint, true);
def(MonitoringSupport_lock , PaddedMutex , service-1, true, _safepoint_check_never); // used for serviceability monitoring support def(MonitoringSupport_lock , PaddedMutex , service-1, true); // used for serviceability monitoring support
} }
def(StringDedup_lock , PaddedMonitor, nosafepoint, true, _safepoint_check_never); def(StringDedup_lock , PaddedMonitor, nosafepoint, true);
def(StringDedupIntern_lock , PaddedMutex , nosafepoint, true, _safepoint_check_never); def(StringDedupIntern_lock , PaddedMutex , nosafepoint, true);
def(ParGCRareEvent_lock , PaddedMutex , nonleaf, true, _safepoint_check_always); def(ParGCRareEvent_lock , PaddedMutex , safepoint, true);
def(RawMonitor_lock , PaddedMutex , nosafepoint-1, true, _safepoint_check_never); def(RawMonitor_lock , PaddedMutex , nosafepoint-1, true);
def(Metaspace_lock , PaddedMutex , nosafepoint-3, true, _safepoint_check_never); def(Metaspace_lock , PaddedMutex , nosafepoint-3, true);
def(Patching_lock , PaddedMutex , nosafepoint, true, _safepoint_check_never); // used for safepointing and code patching. def(Patching_lock , PaddedMutex , nosafepoint, true); // used for safepointing and code patching.
def(MonitorDeflation_lock , PaddedMonitor, nosafepoint, true, _safepoint_check_never); // used for monitor deflation thread operations def(MonitorDeflation_lock , PaddedMonitor, nosafepoint, true); // used for monitor deflation thread operations
def(Service_lock , PaddedMonitor, service, true, _safepoint_check_never); // used for service thread operations def(Service_lock , PaddedMonitor, service, true); // used for service thread operations
if (UseNotificationThread) { if (UseNotificationThread) {
def(Notification_lock , PaddedMonitor, service, true, _safepoint_check_never); // used for notification thread operations def(Notification_lock , PaddedMonitor, service, true); // used for notification thread operations
} else { } else {
Notification_lock = Service_lock; Notification_lock = Service_lock;
} }
def(JmethodIdCreation_lock , PaddedMutex , nosafepoint-2, true, _safepoint_check_never); // used for creating jmethodIDs. def(JmethodIdCreation_lock , PaddedMutex , nosafepoint-2, true); // used for creating jmethodIDs.
def(SharedDictionary_lock , PaddedMutex , nonleaf, true, _safepoint_check_always); def(SharedDictionary_lock , PaddedMutex , safepoint, true);
def(VMStatistic_lock , PaddedMutex , nonleaf, false, _safepoint_check_always); def(VMStatistic_lock , PaddedMutex , safepoint, false);
def(JNIHandleBlockFreeList_lock , PaddedMutex , nosafepoint-1, true, _safepoint_check_never); // handles are used by VM thread def(JNIHandleBlockFreeList_lock , PaddedMutex , nosafepoint-1, true); // handles are used by VM thread
def(SignatureHandlerLibrary_lock , PaddedMutex , nonleaf, false, _safepoint_check_always); def(SignatureHandlerLibrary_lock , PaddedMutex , safepoint, false);
def(SymbolArena_lock , PaddedMutex , nosafepoint, true, _safepoint_check_never); def(SymbolArena_lock , PaddedMutex , nosafepoint, true);
def(ExceptionCache_lock , PaddedMutex , nonleaf, false, _safepoint_check_always); def(ExceptionCache_lock , PaddedMutex , safepoint, false);
#ifndef PRODUCT #ifndef PRODUCT
def(FullGCALot_lock , PaddedMutex , nonleaf, false, _safepoint_check_always); // a lock to make FullGCALot MT safe def(FullGCALot_lock , PaddedMutex , safepoint, false); // a lock to make FullGCALot MT safe
#endif #endif
def(BeforeExit_lock , PaddedMonitor, nonleaf, true, _safepoint_check_always); def(BeforeExit_lock , PaddedMonitor, safepoint, true);
def(NonJavaThreadsList_lock , PaddedMutex, nosafepoint-1, true, _safepoint_check_never); def(NonJavaThreadsList_lock , PaddedMutex, nosafepoint-1, true);
def(NonJavaThreadsListSync_lock , PaddedMutex, nosafepoint, true, _safepoint_check_never); def(NonJavaThreadsListSync_lock , PaddedMutex, nosafepoint, true);
def(RetData_lock , PaddedMutex , nonleaf, false, _safepoint_check_always); def(RetData_lock , PaddedMutex , safepoint, false);
def(Terminator_lock , PaddedMonitor, nonleaf, true, _safepoint_check_always); def(Terminator_lock , PaddedMonitor, safepoint, true);
def(InitCompleted_lock , PaddedMonitor, nosafepoint, true, _safepoint_check_never); def(InitCompleted_lock , PaddedMonitor, nosafepoint, true);
def(Notify_lock , PaddedMonitor, nonleaf, true, _safepoint_check_always); def(Notify_lock , PaddedMonitor, safepoint, true);
def(JNICritical_lock , PaddedMonitor, nonleaf, true, _safepoint_check_always); // used for JNI critical regions def(JNICritical_lock , PaddedMonitor, safepoint, true); // used for JNI critical regions
def(AdapterHandlerLibrary_lock , PaddedMutex , nonleaf, true, _safepoint_check_always); def(AdapterHandlerLibrary_lock , PaddedMutex , safepoint, true);
def(Heap_lock , PaddedMonitor, nonleaf, false, _safepoint_check_always); // Doesn't safepoint check during termination. def(Heap_lock , PaddedMonitor, safepoint, false); // Doesn't safepoint check during termination.
def(JfieldIdCreation_lock , PaddedMutex , nonleaf, true, _safepoint_check_always); // jfieldID, Used in VM_Operation def(JfieldIdCreation_lock , PaddedMutex , safepoint, true); // jfieldID, Used in VM_Operation
def(CompiledIC_lock , PaddedMutex , nosafepoint, true, _safepoint_check_never); // locks VtableStubs_lock, InlineCacheBuffer_lock def(CompiledIC_lock , PaddedMutex , nosafepoint, true); // locks VtableStubs_lock, InlineCacheBuffer_lock
def(MethodCompileQueue_lock , PaddedMonitor, nonleaf, false, _safepoint_check_always); def(MethodCompileQueue_lock , PaddedMonitor, safepoint, false);
def(CompileStatistics_lock , PaddedMutex , nonleaf, false, _safepoint_check_always); def(CompileStatistics_lock , PaddedMutex , safepoint, false);
def(DirectivesStack_lock , PaddedMutex , nosafepoint, true, _safepoint_check_never); def(DirectivesStack_lock , PaddedMutex , nosafepoint, true);
def(MultiArray_lock , PaddedMutex , nonleaf, false, _safepoint_check_always); def(MultiArray_lock , PaddedMutex , safepoint, false);
def(JvmtiThreadState_lock , PaddedMutex , nonleaf, false, _safepoint_check_always); // Used by JvmtiThreadState/JvmtiEventController def(JvmtiThreadState_lock , PaddedMutex , safepoint, false); // Used by JvmtiThreadState/JvmtiEventController
def(EscapeBarrier_lock , PaddedMonitor, nosafepoint, true, _safepoint_check_never); // Used to synchronize object reallocation/relocking triggered by JVMTI def(EscapeBarrier_lock , PaddedMonitor, nosafepoint, true); // Used to synchronize object reallocation/relocking triggered by JVMTI
def(Management_lock , PaddedMutex , nonleaf, false, _safepoint_check_always); // used for JVM management def(Management_lock , PaddedMutex , safepoint, false); // used for JVM management
def(ConcurrentGCBreakpoints_lock , PaddedMonitor, nonleaf, true, _safepoint_check_always); def(ConcurrentGCBreakpoints_lock , PaddedMonitor, safepoint, true);
def(MethodData_lock , PaddedMutex , nonleaf, false, _safepoint_check_always); def(MethodData_lock , PaddedMutex , safepoint, false);
def(TouchedMethodLog_lock , PaddedMutex , nonleaf, false, _safepoint_check_always); def(TouchedMethodLog_lock , PaddedMutex , safepoint, false);
def(CompileThread_lock , PaddedMonitor, nonleaf, false, _safepoint_check_always); def(CompileThread_lock , PaddedMonitor, safepoint, false);
def(PeriodicTask_lock , PaddedMonitor, nonleaf, true, _safepoint_check_always); def(PeriodicTask_lock , PaddedMonitor, safepoint, true);
def(RedefineClasses_lock , PaddedMonitor, nonleaf, true, _safepoint_check_always); def(RedefineClasses_lock , PaddedMonitor, safepoint, true);
def(Verify_lock , PaddedMutex, nonleaf, true, _safepoint_check_always); def(Verify_lock , PaddedMutex, safepoint, true);
if (WhiteBoxAPI) { if (WhiteBoxAPI) {
def(Compilation_lock , PaddedMonitor, nosafepoint, true, _safepoint_check_never); def(Compilation_lock , PaddedMonitor, nosafepoint, true);
} }
#if INCLUDE_JFR #if INCLUDE_JFR
def(JfrBuffer_lock , PaddedMutex , nosafepoint, true, _safepoint_check_never); def(JfrBuffer_lock , PaddedMutex , nosafepoint, true);
def(JfrStacktrace_lock , PaddedMutex , stackwatermark-1, true, _safepoint_check_never); def(JfrStacktrace_lock , PaddedMutex , stackwatermark-1, true);
def(JfrThreadSampler_lock , PaddedMonitor, nosafepoint, true, _safepoint_check_never); def(JfrThreadSampler_lock , PaddedMonitor, nosafepoint, true);
#endif #endif
#ifndef SUPPORTS_NATIVE_CX8 #ifndef SUPPORTS_NATIVE_CX8
def(UnsafeJlong_lock , PaddedMutex , nosafepoint, true, _safepoint_check_never); def(UnsafeJlong_lock , PaddedMutex , nosafepoint, true);
#endif #endif
def(CodeHeapStateAnalytics_lock , PaddedMutex , nonleaf, false, _safepoint_check_always); def(CodeHeapStateAnalytics_lock , PaddedMutex , safepoint, false);
def(NMethodSweeperStats_lock , PaddedMutex , nosafepoint, true, _safepoint_check_never); def(NMethodSweeperStats_lock , PaddedMutex , nosafepoint, true);
def(ThreadsSMRDelete_lock , PaddedMonitor, nosafepoint-3, true, _safepoint_check_never); // Holds ConcurrentHashTableResize_lock def(ThreadsSMRDelete_lock , PaddedMonitor, nosafepoint-3, true); // Holds ConcurrentHashTableResize_lock
def(ThreadIdTableCreate_lock , PaddedMutex , nonleaf, false, _safepoint_check_always); def(ThreadIdTableCreate_lock , PaddedMutex , safepoint, false);
def(SharedDecoder_lock , PaddedMutex , tty-1, true, _safepoint_check_never); def(SharedDecoder_lock , PaddedMutex , tty-1, true);
def(DCmdFactory_lock , PaddedMutex , nosafepoint, true, _safepoint_check_never); def(DCmdFactory_lock , PaddedMutex , nosafepoint, true);
#if INCLUDE_NMT #if INCLUDE_NMT
def(NMTQuery_lock , PaddedMutex , nonleaf, false, _safepoint_check_always); def(NMTQuery_lock , PaddedMutex , safepoint, false);
#endif #endif
#if INCLUDE_CDS #if INCLUDE_CDS
#if INCLUDE_JVMTI #if INCLUDE_JVMTI
def(CDSClassFileStream_lock , PaddedMutex , nonleaf, false, _safepoint_check_always); def(CDSClassFileStream_lock , PaddedMutex , safepoint, false);
#endif #endif
def(DumpTimeTable_lock , PaddedMutex , nosafepoint, true, _safepoint_check_never); def(DumpTimeTable_lock , PaddedMutex , nosafepoint, true);
def(CDSLambda_lock , PaddedMutex , nosafepoint, true, _safepoint_check_never); def(CDSLambda_lock , PaddedMutex , nosafepoint, true);
def(DumpRegion_lock , PaddedMutex , nosafepoint, true, _safepoint_check_never); def(DumpRegion_lock , PaddedMutex , nosafepoint, true);
def(ClassListFile_lock , PaddedMutex , nosafepoint, true, _safepoint_check_never); def(ClassListFile_lock , PaddedMutex , nosafepoint, true);
def(LambdaFormInvokers_lock , PaddedMutex , nonleaf, false, _safepoint_check_always); def(LambdaFormInvokers_lock , PaddedMutex , safepoint, false);
#endif // INCLUDE_CDS #endif // INCLUDE_CDS
def(Bootclasspath_lock , PaddedMutex , nosafepoint, true, _safepoint_check_never); def(Bootclasspath_lock , PaddedMutex , nosafepoint, true);
def(Zip_lock , PaddedMonitor, nosafepoint-1, true, _safepoint_check_never); // Holds DumpTimeTable_lock def(Zip_lock , PaddedMonitor, nosafepoint-1, true); // Holds DumpTimeTable_lock
#if INCLUDE_JVMCI #if INCLUDE_JVMCI
def(JVMCI_lock , PaddedMonitor, nonleaf, true, _safepoint_check_always); def(JVMCI_lock , PaddedMonitor, safepoint, true);
#endif #endif
// These locks have safepoint_check_never and relative rankings. // These locks have relative rankings, and inherit safepoint checking attributes from that rank.
defl(InlineCacheBuffer_lock , PaddedMutex , CompiledIC_lock, true, _safepoint_check_never); defl(InlineCacheBuffer_lock , PaddedMutex , CompiledIC_lock, true);
defl(VtableStubs_lock , PaddedMutex , CompiledIC_lock, true, _safepoint_check_never); // Also holds DumpTimeTable_lock defl(VtableStubs_lock , PaddedMutex , CompiledIC_lock, true); // Also holds DumpTimeTable_lock
defl(CodeCache_lock , PaddedMonitor, VtableStubs_lock, true, _safepoint_check_never); defl(CodeCache_lock , PaddedMonitor, VtableStubs_lock, true);
defl(CompiledMethod_lock , PaddedMutex , CodeCache_lock, true, _safepoint_check_never); defl(CompiledMethod_lock , PaddedMutex , CodeCache_lock, true);
defl(CodeSweeper_lock , PaddedMonitor, CompiledMethod_lock, true, _safepoint_check_never); defl(CodeSweeper_lock , PaddedMonitor, CompiledMethod_lock, true);
// These locks have safepoint_check_always and relative rankings. defl(Threads_lock , PaddedMonitor, CompileThread_lock, true);
defl(Threads_lock , PaddedMonitor, CompileThread_lock, true, _safepoint_check_always); defl(Heap_lock , PaddedMonitor, MultiArray_lock, false);
defl(Heap_lock , PaddedMonitor, MultiArray_lock, false, _safepoint_check_always); defl(Compile_lock , PaddedMutex , MethodCompileQueue_lock, false);
defl(Compile_lock , PaddedMutex , MethodCompileQueue_lock, false, _safepoint_check_always);
defl(PerfDataMemAlloc_lock , PaddedMutex , Heap_lock, true, _safepoint_check_always); defl(PerfDataMemAlloc_lock , PaddedMutex , Heap_lock, true);
defl(PerfDataManager_lock , PaddedMutex , Heap_lock, true, _safepoint_check_always); defl(PerfDataManager_lock , PaddedMutex , Heap_lock, true);
defl(ClassLoaderDataGraph_lock , PaddedMutex , MultiArray_lock, false, _safepoint_check_always); defl(ClassLoaderDataGraph_lock , PaddedMutex , MultiArray_lock, false);
defl(VMOperation_lock , PaddedMonitor, Compile_lock, true, _safepoint_check_always); defl(VMOperation_lock , PaddedMonitor, Compile_lock, true);
defl(ClassInitError_lock , PaddedMonitor, Threads_lock, true, _safepoint_check_always); defl(ClassInitError_lock , PaddedMonitor, Threads_lock, true);
if (UseG1GC) { if (UseG1GC) {
defl(G1OldGCCount_lock , PaddedMonitor, Threads_lock, true, _safepoint_check_always); defl(G1OldGCCount_lock , PaddedMonitor, Threads_lock, true);
} }
defl(CompileTaskAlloc_lock , PaddedMutex , MethodCompileQueue_lock, true, _safepoint_check_always); defl(CompileTaskAlloc_lock , PaddedMutex , MethodCompileQueue_lock, true);
defl(ExpandHeap_lock , PaddedMutex , Heap_lock, true, _safepoint_check_always); defl(ExpandHeap_lock , PaddedMutex , Heap_lock, true);
defl(OopMapCacheAlloc_lock , PaddedMutex , Threads_lock, true, _safepoint_check_always); defl(OopMapCacheAlloc_lock , PaddedMutex , Threads_lock, true);
defl(Module_lock , PaddedMutex , ClassLoaderDataGraph_lock, false, _safepoint_check_always); defl(Module_lock , PaddedMutex , ClassLoaderDataGraph_lock, false);
defl(SystemDictionary_lock , PaddedMonitor, Module_lock, true, _safepoint_check_always); defl(SystemDictionary_lock , PaddedMonitor, Module_lock, true);
#if INCLUDE_JFR #if INCLUDE_JFR
defl(JfrMsg_lock , PaddedMonitor, Module_lock, true, _safepoint_check_always); defl(JfrMsg_lock , PaddedMonitor, Module_lock, true);
#endif #endif
} }

View file

@ -164,7 +164,7 @@ StackWatermark::StackWatermark(JavaThread* jt, StackWatermarkKind kind, uint32_t
_next(NULL), _next(NULL),
_jt(jt), _jt(jt),
_iterator(NULL), _iterator(NULL),
_lock(Mutex::stackwatermark, "StackWatermark_lock", Mutex::_safepoint_check_never), _lock(Mutex::stackwatermark, "StackWatermark_lock"),
_kind(kind), _kind(kind),
_linked_watermark(NULL) { _linked_watermark(NULL) {
} }

View file

@ -368,7 +368,7 @@ int VM_Exit::wait_for_threads_in_native_to_block() {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already"); assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already");
Thread * thr_cur = Thread::current(); Thread * thr_cur = Thread::current();
Monitor timer(Mutex::nosafepoint, "VM_ExitTimer_lock", Monitor::_safepoint_check_never); Monitor timer(Mutex::nosafepoint, "VM_ExitTimer_lock");
// Compiler threads need longer wait because they can access VM data directly // Compiler threads need longer wait because they can access VM data directly
// while in native. If they are active and some structures being used are // while in native. If they are active and some structures being used are

View file

@ -128,8 +128,7 @@ void VMThread::create() {
assert(_timeout_task == NULL, "sanity"); assert(_timeout_task == NULL, "sanity");
} }
_terminate_lock = new Monitor(Mutex::nosafepoint, "VMThreadTerminate_lock", _terminate_lock = new Monitor(Mutex::nosafepoint, "VMThreadTerminate_lock");
Monitor::_safepoint_check_never);
if (UsePerfData) { if (UsePerfData) {
// jvmstat performance counters // jvmstat performance counters

View file

@ -748,7 +748,7 @@ class ParDumpWriter : public AbstractDumpWriter {
static void before_work() { static void before_work() {
assert(_lock == NULL, "ParDumpWriter lock must be initialized only once"); assert(_lock == NULL, "ParDumpWriter lock must be initialized only once");
_lock = new (std::nothrow) PaddedMonitor(Mutex::nonleaf, "ParallelHProfWriter_lock", Mutex::_safepoint_check_always); _lock = new (std::nothrow) PaddedMonitor(Mutex::safepoint, "ParallelHProfWriter_lock");
} }
static void after_work() { static void after_work() {
@ -1814,8 +1814,7 @@ class DumperController : public CHeapObj<mtInternal> {
public: public:
DumperController(uint number) : DumperController(uint number) :
_started(false), _started(false),
_lock(new (std::nothrow) PaddedMonitor(Mutex::nonleaf, "DumperController_lock", _lock(new (std::nothrow) PaddedMonitor(Mutex::safepoint, "DumperController_lock")),
Mutex::_safepoint_check_always)),
_dumper_number(number), _dumper_number(number),
_complete_number(0) { } _complete_number(0) { }

View file

@ -200,8 +200,7 @@ CompressionBackend::CompressionBackend(AbstractWriter* writer,
_written(0), _written(0),
_writer(writer), _writer(writer),
_compressor(compressor), _compressor(compressor),
_lock(new (std::nothrow) PaddedMonitor(Mutex::nosafepoint, "HProfCompressionBackend_lock", _lock(new (std::nothrow) PaddedMonitor(Mutex::nosafepoint, "HProfCompressionBackend_lock")) {
Mutex::_safepoint_check_never)) {
if (_writer == NULL) { if (_writer == NULL) {
set_error("Could not allocate writer"); set_error("Could not allocate writer");
} else if (_lock == NULL) { } else if (_lock == NULL) {

View file

@ -174,8 +174,7 @@ GCMemoryManager::GCMemoryManager(const char* name, const char* gc_end_message) :
MemoryManager(name), _gc_end_message(gc_end_message) { MemoryManager(name), _gc_end_message(gc_end_message) {
_num_collections = 0; _num_collections = 0;
_last_gc_stat = NULL; _last_gc_stat = NULL;
_last_gc_lock = new Mutex(Mutex::nosafepoint, "GCMemoryManager_lock", _last_gc_lock = new Mutex(Mutex::nosafepoint, "GCMemoryManager_lock");
Mutex::_safepoint_check_never);
_current_gc_stat = NULL; _current_gc_stat = NULL;
_num_gc_threads = 1; _num_gc_threads = 1;
_notification_enabled = false; _notification_enabled = false;

View file

@ -1014,8 +1014,7 @@ inline ConcurrentHashTable<CONFIG, F>::
{ {
_stats_rate = TableRateStatistics(); _stats_rate = TableRateStatistics();
_resize_lock = _resize_lock =
new Mutex(Mutex::nosafepoint-2, "ConcurrentHashTableResize_lock", new Mutex(Mutex::nosafepoint-2, "ConcurrentHashTableResize_lock");
Mutex::_safepoint_check_never);
_table = new InternalTable(log2size); _table = new InternalTable(log2size);
assert(log2size_limit >= log2size, "bad ergo"); assert(log2size_limit >= log2size, "bad ergo");
_size_limit_reached = _table->_log2_size == _log2_size_limit; _size_limit_reached = _table->_log2_size == _log2_size_limit;

View file

@ -100,7 +100,7 @@ template <class T> class EventLogBase : public EventLog {
public: public:
EventLogBase<T>(const char* name, const char* handle, int length = LogEventsBufferEntries): EventLogBase<T>(const char* name, const char* handle, int length = LogEventsBufferEntries):
_mutex(Mutex::event, name, Mutex::_safepoint_check_never), _mutex(Mutex::event, name),
_name(name), _name(name),
_handle(handle), _handle(handle),
_length(length), _length(length),

View file

@ -49,7 +49,7 @@ public:
} }
void do_test(Metaspace::MetadataType mdType) { void do_test(Metaspace::MetadataType mdType) {
_lock = new Mutex(Monitor::nosafepoint, "gtest-IsMetaspaceObjTest_lock", Monitor::_safepoint_check_never); _lock = new Mutex(Monitor::nosafepoint, "gtest-IsMetaspaceObjTest_lock");
{ {
MutexLocker ml(_lock, Mutex::_no_safepoint_check_flag); MutexLocker ml(_lock, Mutex::_no_safepoint_check_flag);
_ms = new ClassLoaderMetaspace(_lock, Metaspace::StandardMetaspaceType); _ms = new ClassLoaderMetaspace(_lock, Metaspace::StandardMetaspaceType);

View file

@ -66,7 +66,7 @@ class MetaspaceArenaTestHelper {
void initialize(const ArenaGrowthPolicy* growth_policy, const char* name = "gtest-MetaspaceArena") { void initialize(const ArenaGrowthPolicy* growth_policy, const char* name = "gtest-MetaspaceArena") {
_growth_policy = growth_policy; _growth_policy = growth_policy;
_lock = new Mutex(Monitor::nosafepoint, "gtest-MetaspaceArenaTest_lock", Monitor::_safepoint_check_never); _lock = new Mutex(Monitor::nosafepoint, "gtest-MetaspaceArenaTest_lock");
// Lock during space creation, since this is what happens in the VM too // Lock during space creation, since this is what happens in the VM too
// (see ClassLoaderData::metaspace_non_null(), which we mimick here). // (see ClassLoaderData::metaspace_non_null(), which we mimick here).
{ {

View file

@ -142,7 +142,7 @@ public:
_alloc_count(), _alloc_count(),
_dealloc_count() _dealloc_count()
{ {
_lock = new Mutex(Monitor::nosafepoint, "gtest-MetaspaceArenaTestBed_lock", Monitor::_safepoint_check_never); _lock = new Mutex(Monitor::nosafepoint, "gtest-MetaspaceArenaTestBed_lock");
// Lock during space creation, since this is what happens in the VM too // Lock during space creation, since this is what happens in the VM too
// (see ClassLoaderData::metaspace_non_null(), which we mimick here). // (see ClassLoaderData::metaspace_non_null(), which we mimick here).
MutexLocker ml(_lock, Mutex::_no_safepoint_check_flag); MutexLocker ml(_lock, Mutex::_no_safepoint_check_flag);

View file

@ -35,7 +35,7 @@ static Mutex* m[iterations];
static int i = 0; static int i = 0;
static void create_mutex(Thread* thr) { static void create_mutex(Thread* thr) {
m[i] = new Mutex(Mutex::nosafepoint, FormatBuffer<128>("MyLock#%u_lock", i), Mutex::_safepoint_check_never); m[i] = new Mutex(Mutex::nosafepoint, FormatBuffer<128>("MyLock#%u_lock", i));
i++; i++;
} }
@ -53,16 +53,16 @@ TEST_VM(MutexName, mutex_name) {
#ifdef ASSERT #ifdef ASSERT
const int rankA = Mutex::nonleaf-5; const Mutex::Rank rankA = Mutex::safepoint-5;
const int rankAplusOne = Mutex::nonleaf-4; const Mutex::Rank rankAplusOne = Mutex::safepoint-4;
const int rankAplusTwo = Mutex::nonleaf-3; const Mutex::Rank rankAplusTwo = Mutex::safepoint-3;
TEST_OTHER_VM(MutexRank, mutex_lock_rank_in_order) { TEST_OTHER_VM(MutexRank, mutex_lock_rank_in_order) {
JavaThread* THREAD = JavaThread::current(); JavaThread* THREAD = JavaThread::current();
ThreadInVMfromNative invm(THREAD); ThreadInVMfromNative invm(THREAD);
Mutex* mutex_rankA = new Mutex(rankA, "mutex_rankA", Mutex::_safepoint_check_always); Mutex* mutex_rankA = new Mutex(rankA, "mutex_rankA");
Mutex* mutex_rankA_plus_one = new Mutex(rankAplusOne, "mutex_rankA_plus_one", Mutex::_safepoint_check_always); Mutex* mutex_rankA_plus_one = new Mutex(rankAplusOne, "mutex_rankA_plus_one");
mutex_rankA_plus_one->lock(); mutex_rankA_plus_one->lock();
mutex_rankA->lock(); mutex_rankA->lock();
@ -71,12 +71,12 @@ TEST_OTHER_VM(MutexRank, mutex_lock_rank_in_order) {
} }
TEST_VM_ASSERT_MSG(MutexRank, mutex_lock_rank_out_of_orderA, TEST_VM_ASSERT_MSG(MutexRank, mutex_lock_rank_out_of_orderA,
".* Attempting to acquire lock mutex_rankA_plus_one/.* out of order with lock mutex_rankA/.* -- possible deadlock") { ".* Attempting to acquire lock mutex_rankA_plus_one/safepoint-4 out of order with lock mutex_rankA/safepoint-5 -- possible deadlock") {
JavaThread* THREAD = JavaThread::current(); JavaThread* THREAD = JavaThread::current();
ThreadInVMfromNative invm(THREAD); ThreadInVMfromNative invm(THREAD);
Mutex* mutex_rankA = new Mutex(rankA, "mutex_rankA", Mutex::_safepoint_check_always); Mutex* mutex_rankA = new Mutex(rankA, "mutex_rankA");
Mutex* mutex_rankA_plus_one = new Mutex(rankAplusOne, "mutex_rankA_plus_one", Mutex::_safepoint_check_always); Mutex* mutex_rankA_plus_one = new Mutex(rankAplusOne, "mutex_rankA_plus_one");
mutex_rankA->lock(); mutex_rankA->lock();
mutex_rankA_plus_one->lock(); mutex_rankA_plus_one->lock();
@ -89,8 +89,8 @@ TEST_VM_ASSERT_MSG(MutexRank, mutex_lock_rank_out_of_orderB,
JavaThread* THREAD = JavaThread::current(); JavaThread* THREAD = JavaThread::current();
ThreadInVMfromNative invm(THREAD); ThreadInVMfromNative invm(THREAD);
Mutex* mutex_rankA = new Mutex(rankA, "mutex_rankA", Mutex::_safepoint_check_always); Mutex* mutex_rankA = new Mutex(rankA, "mutex_rankA");
Mutex* mutex_rankB = new Mutex(rankA, "mutex_rankB", Mutex::_safepoint_check_always); Mutex* mutex_rankB = new Mutex(rankA, "mutex_rankB");
mutex_rankA->lock(); mutex_rankA->lock();
mutex_rankB->lock(); mutex_rankB->lock();
@ -102,9 +102,9 @@ TEST_OTHER_VM(MutexRank, mutex_trylock_rank_out_of_orderA) {
JavaThread* THREAD = JavaThread::current(); JavaThread* THREAD = JavaThread::current();
ThreadInVMfromNative invm(THREAD); ThreadInVMfromNative invm(THREAD);
Mutex* mutex_rankA = new Mutex(rankA, "mutex_rankA", Mutex::_safepoint_check_always); Mutex* mutex_rankA = new Mutex(rankA, "mutex_rankA");
Mutex* mutex_rankA_plus_one = new Mutex(rankAplusOne, "mutex_rankA_plus_one", Mutex::_safepoint_check_always); Mutex* mutex_rankA_plus_one = new Mutex(rankAplusOne, "mutex_rankA_plus_one");
Mutex* mutex_rankA_plus_two = new Mutex(rankAplusTwo, "mutex_rankA_plus_two", Mutex::_safepoint_check_always); Mutex* mutex_rankA_plus_two = new Mutex(rankAplusTwo, "mutex_rankA_plus_two");
mutex_rankA_plus_one->lock(); mutex_rankA_plus_one->lock();
mutex_rankA_plus_two->try_lock_without_rank_check(); mutex_rankA_plus_two->try_lock_without_rank_check();
@ -119,8 +119,8 @@ TEST_VM_ASSERT_MSG(MutexRank, mutex_trylock_rank_out_of_orderB,
JavaThread* THREAD = JavaThread::current(); JavaThread* THREAD = JavaThread::current();
ThreadInVMfromNative invm(THREAD); ThreadInVMfromNative invm(THREAD);
Mutex* mutex_rankA = new Mutex(rankA, "mutex_rankA", Mutex::_safepoint_check_always); Mutex* mutex_rankA = new Mutex(rankA, "mutex_rankA");
Mutex* mutex_rankA_plus_one = new Mutex(rankAplusOne, "mutex_rankA_plus_one", Mutex::_safepoint_check_always); Mutex* mutex_rankA_plus_one = new Mutex(rankAplusOne, "mutex_rankA_plus_one");
mutex_rankA->lock(); mutex_rankA->lock();
mutex_rankA_plus_one->try_lock_without_rank_check(); mutex_rankA_plus_one->try_lock_without_rank_check();
@ -131,28 +131,28 @@ TEST_VM_ASSERT_MSG(MutexRank, mutex_trylock_rank_out_of_orderB,
} }
TEST_VM_ASSERT_MSG(MutexRank, mutex_lock_event_nosafepoint, TEST_VM_ASSERT_MSG(MutexRank, mutex_lock_event_nosafepoint,
".* Attempting to acquire lock mutex_rank_nosafepoint/.* out of order with lock mutex_rank_event/0 " ".* Attempting to acquire lock mutex_rank_nosafepoint/nosafepoint out of order with lock mutex_rank_event/event "
"-- possible deadlock") { "-- possible deadlock") {
JavaThread* THREAD = JavaThread::current(); JavaThread* THREAD = JavaThread::current();
ThreadInVMfromNative invm(THREAD); ThreadInVMfromNative invm(THREAD);
Mutex* mutex_rank_event = new Mutex(Mutex::event, "mutex_rank_event", Mutex::_safepoint_check_never); Mutex* mutex_rank_event = new Mutex(Mutex::event, "mutex_rank_event");
Mutex* mutex_rank_nonleaf = new Mutex(Mutex::nosafepoint, "mutex_rank_nosafepoint", Mutex::_safepoint_check_never); Mutex* mutex_rank_safepoint = new Mutex(Mutex::nosafepoint, "mutex_rank_nosafepoint");
mutex_rank_event->lock_without_safepoint_check(); mutex_rank_event->lock_without_safepoint_check();
mutex_rank_nonleaf->lock_without_safepoint_check(); mutex_rank_safepoint->lock_without_safepoint_check();
mutex_rank_nonleaf->unlock(); mutex_rank_safepoint->unlock();
mutex_rank_event->unlock(); mutex_rank_event->unlock();
} }
TEST_VM_ASSERT_MSG(MutexRank, mutex_lock_tty_nosafepoint, TEST_VM_ASSERT_MSG(MutexRank, mutex_lock_tty_nosafepoint,
".* Attempting to acquire lock mutex_rank_nosafepoint/.* out of order with lock mutex_rank_tty/.*" ".* Attempting to acquire lock mutex_rank_nosafepoint/nosafepoint out of order with lock mutex_rank_tty/tty "
"-- possible deadlock") { "-- possible deadlock") {
JavaThread* THREAD = JavaThread::current(); JavaThread* THREAD = JavaThread::current();
ThreadInVMfromNative invm(THREAD); ThreadInVMfromNative invm(THREAD);
Mutex* mutex_rank_tty = new Mutex(Mutex::tty, "mutex_rank_tty", Mutex::_safepoint_check_never); Mutex* mutex_rank_tty = new Mutex(Mutex::tty, "mutex_rank_tty");
Mutex* mutex_rank_nosafepoint = new Mutex(Mutex::nosafepoint, "mutex_rank_nosafepoint", Mutex::_safepoint_check_never); Mutex* mutex_rank_nosafepoint = new Mutex(Mutex::nosafepoint, "mutex_rank_nosafepoint");
mutex_rank_tty->lock_without_safepoint_check(); mutex_rank_tty->lock_without_safepoint_check();
mutex_rank_nosafepoint->lock_without_safepoint_check(); mutex_rank_nosafepoint->lock_without_safepoint_check();
@ -164,8 +164,8 @@ TEST_OTHER_VM(MutexRank, monitor_wait_rank_in_order) {
JavaThread* THREAD = JavaThread::current(); JavaThread* THREAD = JavaThread::current();
ThreadInVMfromNative invm(THREAD); ThreadInVMfromNative invm(THREAD);
Monitor* monitor_rankA = new Monitor(rankA, "monitor_rankA", Mutex::_safepoint_check_always); Monitor* monitor_rankA = new Monitor(rankA, "monitor_rankA");
Monitor* monitor_rankA_plus_one = new Monitor(rankAplusOne, "monitor_rankA_plus_one", Mutex::_safepoint_check_always); Monitor* monitor_rankA_plus_one = new Monitor(rankAplusOne, "monitor_rankA_plus_one");
monitor_rankA_plus_one->lock(); monitor_rankA_plus_one->lock();
monitor_rankA->lock(); monitor_rankA->lock();
@ -180,8 +180,8 @@ TEST_VM_ASSERT_MSG(MutexRank, monitor_wait_rank_out_of_order,
JavaThread* THREAD = JavaThread::current(); JavaThread* THREAD = JavaThread::current();
ThreadInVMfromNative invm(THREAD); ThreadInVMfromNative invm(THREAD);
Monitor* monitor_rankA = new Monitor(rankA, "monitor_rankA", Mutex::_safepoint_check_always); Monitor* monitor_rankA = new Monitor(rankA, "monitor_rankA");
Monitor* monitor_rankA_plus_one = new Monitor(rankAplusOne, "monitor_rankA_plus_one", Mutex::_safepoint_check_always); Monitor* monitor_rankA_plus_one = new Monitor(rankAplusOne, "monitor_rankA_plus_one");
monitor_rankA_plus_one->lock(); monitor_rankA_plus_one->lock();
monitor_rankA->lock(); monitor_rankA->lock();
@ -196,8 +196,8 @@ TEST_VM_ASSERT_MSG(MutexRank, monitor_wait_rank_out_of_order_trylock,
JavaThread* THREAD = JavaThread::current(); JavaThread* THREAD = JavaThread::current();
ThreadInVMfromNative invm(THREAD); ThreadInVMfromNative invm(THREAD);
Monitor* monitor_rankA = new Monitor(rankA, "monitor_rankA", Mutex::_safepoint_check_always); Monitor* monitor_rankA = new Monitor(rankA, "monitor_rankA");
Monitor* monitor_rankA_plus_one = new Monitor(rankAplusOne, "monitor_rankA_plus_one", Mutex::_safepoint_check_always); Monitor* monitor_rankA_plus_one = new Monitor(rankAplusOne, "monitor_rankA_plus_one");
monitor_rankA->lock(); monitor_rankA->lock();
monitor_rankA_plus_one->try_lock_without_rank_check(); monitor_rankA_plus_one->try_lock_without_rank_check();
@ -212,8 +212,9 @@ TEST_VM_ASSERT_MSG(MutexRank, monitor_wait_rank_nosafepoint,
JavaThread* THREAD = JavaThread::current(); JavaThread* THREAD = JavaThread::current();
ThreadInVMfromNative invm(THREAD); ThreadInVMfromNative invm(THREAD);
Monitor* monitor_rank_nosafepoint = new Monitor(Mutex::nosafepoint, "monitor_rank_nosafepoint", Mutex::_safepoint_check_never); Monitor* monitor_rank_nosafepoint = new Monitor(Mutex::nosafepoint, "monitor_rank_nosafepoint");
Monitor* monitor_rank_nosafepoint_minus_one = new Monitor(Mutex::nosafepoint - 1, "monitor_rank_nosafepoint_minus_one", Mutex::_safepoint_check_never); Monitor* monitor_rank_nosafepoint_minus_one = new Monitor(Mutex::nosafepoint - 1,
"monitor_rank_nosafepoint_minus_one");
monitor_rank_nosafepoint->lock_without_safepoint_check(); monitor_rank_nosafepoint->lock_without_safepoint_check();
monitor_rank_nosafepoint_minus_one->lock_without_safepoint_check(); monitor_rank_nosafepoint_minus_one->lock_without_safepoint_check();
@ -226,8 +227,8 @@ TEST_VM_ASSERT_MSG(MutexRank, monitor_wait_rank_nosafepoint,
class VM_MutexWaitTTY : public VM_GTestExecuteAtSafepoint { class VM_MutexWaitTTY : public VM_GTestExecuteAtSafepoint {
public: public:
void doit() { void doit() {
Monitor* monitor_rank_tty = new Monitor(Mutex::tty, "monitor_rank_tty", Mutex::_safepoint_check_never); Monitor* monitor_rank_tty = new Monitor(Mutex::tty, "monitor_rank_tty");
Monitor* monitor_rank_event = new Monitor(Mutex::event, "monitor_rank_event", Mutex::_safepoint_check_never); Monitor* monitor_rank_event = new Monitor(Mutex::event, "monitor_rank_event");
monitor_rank_tty->lock_without_safepoint_check(); monitor_rank_tty->lock_without_safepoint_check();
monitor_rank_event->lock_without_safepoint_check(); monitor_rank_event->lock_without_safepoint_check();
@ -238,7 +239,7 @@ class VM_MutexWaitTTY : public VM_GTestExecuteAtSafepoint {
}; };
TEST_VM_ASSERT_MSG(MutexRank, monitor_wait_event_tty, TEST_VM_ASSERT_MSG(MutexRank, monitor_wait_event_tty,
".* Attempting to wait on monitor monitor_rank_event/0 while holding lock monitor_rank_tty/.*" ".* Attempting to wait on monitor monitor_rank_event/event while holding lock monitor_rank_tty/tty "
"-- possible deadlock. Should not block\\(wait\\) while holding a lock of rank tty or below.") { "-- possible deadlock. Should not block\\(wait\\) while holding a lock of rank tty or below.") {
VM_MutexWaitTTY op; VM_MutexWaitTTY op;
ThreadInVMfromNative invm(JavaThread::current()); ThreadInVMfromNative invm(JavaThread::current());
@ -251,8 +252,8 @@ TEST_VM_ASSERT_MSG(MutexRank, monitor_wait_tty_nosafepoint,
JavaThread* THREAD = JavaThread::current(); JavaThread* THREAD = JavaThread::current();
ThreadInVMfromNative invm(THREAD); ThreadInVMfromNative invm(THREAD);
Monitor* monitor_rank_nosafepoint = new Monitor(Mutex::nosafepoint, "monitor_rank_nosafepoint", Mutex::_safepoint_check_never); Monitor* monitor_rank_nosafepoint = new Monitor(Mutex::nosafepoint, "monitor_rank_nosafepoint");
Monitor* monitor_rank_tty = new Monitor(Mutex::tty, "monitor_rank_tty", Mutex::_safepoint_check_never); Monitor* monitor_rank_tty = new Monitor(Mutex::tty, "monitor_rank_tty");
monitor_rank_nosafepoint->lock_without_safepoint_check(); monitor_rank_nosafepoint->lock_without_safepoint_check();
monitor_rank_tty->lock_without_safepoint_check(); monitor_rank_tty->lock_without_safepoint_check();
@ -262,11 +263,11 @@ TEST_VM_ASSERT_MSG(MutexRank, monitor_wait_tty_nosafepoint,
} }
TEST_VM_ASSERT_MSG(MutexRank, monitor_nosafepoint_vm_block, TEST_VM_ASSERT_MSG(MutexRank, monitor_nosafepoint_vm_block,
".*Safepoint check never locks should always allow the vm to block") { ".*Locks that don't check for safepoint should always allow the vm to block: monitor_rank_nosafepoint") {
JavaThread* THREAD = JavaThread::current(); JavaThread* THREAD = JavaThread::current();
ThreadInVMfromNative invm(THREAD); ThreadInVMfromNative invm(THREAD);
Monitor* monitor_rank_nosafepoint = new Monitor(Mutex::nosafepoint, "monitor_rank_nosafepoint", Mutex::_safepoint_check_never, false); Monitor* monitor_rank_nosafepoint = new Monitor(Mutex::nosafepoint, "monitor_rank_nosafepoint", false);
monitor_rank_nosafepoint->lock_without_safepoint_check(); monitor_rank_nosafepoint->lock_without_safepoint_check();
monitor_rank_nosafepoint->unlock(); monitor_rank_nosafepoint->unlock();
} }
@ -276,18 +277,58 @@ TEST_VM_ASSERT_MSG(MutexRank, monitor_negative_rank,
JavaThread* THREAD = JavaThread::current(); JavaThread* THREAD = JavaThread::current();
ThreadInVMfromNative invm(THREAD); ThreadInVMfromNative invm(THREAD);
Monitor* monitor_rank_broken = new Monitor(Mutex::event-1, "monitor_rank_broken", Mutex::_safepoint_check_never); Monitor* monitor_rank_broken = new Monitor(Mutex::safepoint-100, "monitor_rank_broken");
monitor_rank_broken->lock_without_safepoint_check(); monitor_rank_broken->lock_without_safepoint_check();
monitor_rank_broken->unlock(); monitor_rank_broken->unlock();
} }
TEST_VM_ASSERT_MSG(MutexRank, monitor_nosafepoint_rank, TEST_VM_ASSERT_MSG(MutexRank, monitor_overlapping_oopstorage_rank,
".*failed: Locks above nosafepoint rank should safepoint: monitor_rank_nonleaf") { ".*Rank oopstorage-4 overlaps with tty-1") {
JavaThread* THREAD = JavaThread::current(); JavaThread* THREAD = JavaThread::current();
ThreadInVMfromNative invm(THREAD); ThreadInVMfromNative invm(THREAD);
Monitor* monitor_rank_nonleaf = new Monitor(Mutex::nonleaf, "monitor_rank_nonleaf", Mutex::_safepoint_check_never); Monitor* monitor_rank_broken = new Monitor(Mutex::oopstorage-4, "monitor_rank_broken");
monitor_rank_nonleaf->lock_without_safepoint_check(); }
monitor_rank_nonleaf->unlock();
TEST_VM_ASSERT_MSG(MutexRank, monitor_overlapping_safepoint_rank,
".*Rank safepoint-40 overlaps with service-5") {
JavaThread* THREAD = JavaThread::current();
ThreadInVMfromNative invm(THREAD);
Monitor* monitor_rank_broken = new Monitor(Mutex::safepoint-40, "monitor_rank_broken");
}
TEST_VM_ASSERT_MSG(MutexRank, monitor_overlapping_safepoint_rank2,
".*Rank safepoint-1-39 overlaps with service-5") {
JavaThread* THREAD = JavaThread::current();
ThreadInVMfromNative invm(THREAD);
Monitor* monitor_rank_ok = new Monitor(Mutex::safepoint-1, "monitor_rank_ok");
Monitor* monitor_rank_broken = new Monitor(monitor_rank_ok->rank()-39, "monitor_rank_broken");
}
// Test mismatched safepoint check flag on lock declaration vs. lock acquisition.
TEST_VM_ASSERT_MSG(MutexSafepoint, always_check,
".*This lock should always have a safepoint check for Java threads: SFPT_Test_lock") {
MutexLocker ml(new Mutex(Mutex::safepoint, "SFPT_Test_lock"),
Mutex::_no_safepoint_check_flag);
}
TEST_VM_ASSERT_MSG(MutexSafepoint, never_check,
".*This lock should not be taken with a safepoint check: SFPT_Test_lock") {
MutexLocker ml(new Mutex(Mutex::nosafepoint, "SFPT_Test_lock"),
Mutex::_safepoint_check_flag);
}
TEST_VM_ASSERT_MSG(MutexSafepoint, possible_safepoint_lock,
".* Possible safepoint reached by thread that does not allow it") {
JavaThread* thread = JavaThread::current();
ThreadInVMfromNative in_native(thread);
MutexLocker ml(new Mutex(Mutex::nosafepoint, "SpecialTest_lock"),
Mutex::_no_safepoint_check_flag);
thread->print_thread_state_on(tty);
// If the lock above succeeds, try to safepoint to test the NSV implied with this nosafepoint lock.
ThreadBlockInVM tbivm(thread);
thread->print_thread_state_on(tty);
} }
#endif // ASSERT #endif // ASSERT

View file

@ -1,63 +0,0 @@
/*
* Copyright (c) 2020, 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 "runtime/interfaceSupport.inline.hpp"
#include "runtime/mutex.hpp"
#include "runtime/mutexLocker.hpp"
#include "unittest.hpp"
#ifdef ASSERT
// Test mismatched safepoint check flag on lock declaration vs. lock acquisition.
TEST_VM_ASSERT_MSG(SafepointLockAssertTest, always_check,
".*This lock should always have a safepoint check for Java threads: SFPT_Test_lock") {
MutexLocker ml(new Mutex(Mutex::nonleaf, "SFPT_Test_lock", Mutex::_safepoint_check_always),
Mutex::_no_safepoint_check_flag);
}
TEST_VM_ASSERT_MSG(SafepointLockAssertTest, never_check,
".*This lock should never have a safepoint check for Java threads: SFPT_Test_lock") {
MutexLocker ml(new Mutex(Mutex::nosafepoint, "SFPT_Test_lock", Mutex::_safepoint_check_never),
Mutex::_safepoint_check_flag);
}
TEST_VM_ASSERT_MSG(SafepointLockAssertTest, nosafepoint_locks,
".*Locks below nosafepoint rank should never safepoint: SpecialTest_lock") {
MutexLocker ml(new Mutex(Mutex::nosafepoint, "SpecialTest_lock", Mutex::_safepoint_check_always),
Mutex::_safepoint_check_flag);
}
TEST_VM_ASSERT_MSG(SafepointLockAssertTest, possible_safepoint_lock,
".* Possible safepoint reached by thread that does not allow it") {
JavaThread* thread = JavaThread::current();
ThreadInVMfromNative in_native(thread);
MutexLocker ml(new Mutex(Mutex::nosafepoint, "SpecialTest_lock", Mutex::_safepoint_check_never),
Mutex::_no_safepoint_check_flag);
thread->print_thread_state_on(tty);
// If the lock above succeeds, try to safepoint to test the NSV implied with this nosafepoint lock.
ThreadBlockInVM tbivm(thread);
thread->print_thread_state_on(tty);
}
#endif // ASSERT

View file

@ -196,7 +196,7 @@ public:
TEST_VM(FilterQueue, stress) { TEST_VM(FilterQueue, stress) {
FilterQueue<uintptr_t> queue; FilterQueue<uintptr_t> queue;
Mutex lock(Mutex::nosafepoint, "Test_lock", Mutex::_safepoint_check_never); Mutex lock(Mutex::nosafepoint, "Test_lock");
static const int nthreads = 4; static const int nthreads = 4;
Semaphore post; Semaphore post;
FilterQueueTestThread* threads[nthreads] = {}; FilterQueueTestThread* threads[nthreads] = {};