8213150: Add verification for locking by VMThread

Extend verification for all locking not just VMOperations, and fix CLDG lock to not be taken by VM thread.

Reviewed-by: rehn, dholmes
This commit is contained in:
Coleen Phillimore 2019-09-24 10:12:56 -04:00
parent 11d43732bc
commit e49e9292d3
14 changed files with 148 additions and 125 deletions

View file

@ -973,6 +973,7 @@ void Thread::check_possible_safepoint() {
if (!is_Java_thread()) return;
if (_no_safepoint_count > 0) {
print_owned_locks();
fatal("Possible safepoint reached by thread that does not allow it");
}
#ifdef CHECK_UNHANDLED_OOPS
@ -981,37 +982,18 @@ void Thread::check_possible_safepoint() {
#endif // CHECK_UNHANDLED_OOPS
}
// The flag: potential_vm_operation notifies if this particular safepoint state could potentially
// invoke the vm-thread (e.g., an oop allocation). In that case, we also have to make sure that
// no locks which allow_vm_block's are held
void Thread::check_for_valid_safepoint_state(bool potential_vm_operation) {
void Thread::check_for_valid_safepoint_state() {
if (!is_Java_thread()) return;
// Check NoSafepointVerifier, which is implied by locks taken that can be
// shared with the VM thread. This makes sure that no locks with allow_vm_block
// are held.
check_possible_safepoint();
if (((JavaThread*)this)->thread_state() != _thread_in_vm) {
fatal("LEAF method calling lock?");
}
if (potential_vm_operation && !Universe::is_bootstrapping()) {
// Make sure we do not hold any locks that the VM thread also uses.
// This could potentially lead to deadlocks
for (Mutex* cur = _owned_locks; cur; cur = cur->next()) {
// Threads_lock is special, since the safepoint synchronization will not start before this is
// acquired. Hence, a JavaThread cannot be holding it at a safepoint. So is VMOperationRequest_lock,
// since it is used to transfer control between JavaThreads and the VMThread
// Do not *exclude* any locks unless you are absolutely sure it is correct. Ask someone else first!
if ((cur->allow_vm_block() &&
cur != Threads_lock &&
cur != Compile_lock && // Temporary: should not be necessary when we get separate compilation
cur != VMOperationRequest_lock &&
cur != VMOperationQueue_lock) ||
cur->rank() == Mutex::special) {
fatal("Thread holding lock at safepoint that vm can block on: %s", cur->name());
}
}
}
if (GCALotAtAllSafepoints) {
// We could enter a safepoint here and thus have a gc
InterfaceSupport::check_gc_alot();