8295849: Consolidate Threads::owning_thread*

Reviewed-by: dcubed, sspitsyn
This commit is contained in:
Roman Kennke 2022-10-28 20:23:21 +00:00
parent 1c86cf5507
commit a44ebd5fbc
7 changed files with 32 additions and 50 deletions

@ -1390,52 +1390,24 @@ JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject objec
uint32_t debug_bits = 0;
// first derive the object's owner and entry_count (if any)
{
address owner = NULL;
{
markWord mark = hobj()->mark();
owning_thread = ObjectSynchronizer::get_lock_owner(tlh.list(), hobj);
if (owning_thread != NULL) {
Handle th(current_thread, get_vthread_or_thread_oop(owning_thread));
ret.owner = (jthread)jni_reference(calling_thread, th);
if (!mark.has_monitor()) {
// this object has a lightweight monitor
if (mark.has_locker()) {
owner = (address)mark.locker(); // save the address of the Lock word
}
// implied else: no owner
} else {
// this object has a heavyweight monitor
mon = mark.monitor();
// The owner field of a heavyweight monitor may be NULL for no
// owner, a JavaThread * or it may still be the address of the
// Lock word in a JavaThread's stack. A monitor can be inflated
// by a non-owning JavaThread, but only the owning JavaThread
// can change the owner field from the Lock word to the
// JavaThread * and it may not have done that yet.
owner = (address)mon->owner();
}
}
if (owner != NULL) {
// This monitor is owned so we have to find the owning JavaThread.
owning_thread = Threads::owning_thread_from_monitor_owner(tlh.list(), owner);
assert(owning_thread != NULL, "owning JavaThread must not be NULL");
Handle th(current_thread, get_vthread_or_thread_oop(owning_thread));
ret.owner = (jthread)jni_reference(calling_thread, th);
}
if (owning_thread != NULL) { // monitor is owned
// The recursions field of a monitor does not reflect recursions
// as lightweight locks before inflating the monitor are not included.
// We have to count the number of recursive monitor entries the hard way.
// We pass a handle to survive any GCs along the way.
ret.entry_count = count_locked_objects(owning_thread, hobj);
}
// implied else: entry_count == 0
// The recursions field of a monitor does not reflect recursions
// as lightweight locks before inflating the monitor are not included.
// We have to count the number of recursive monitor entries the hard way.
// We pass a handle to survive any GCs along the way.
ret.entry_count = count_locked_objects(owning_thread, hobj);
}
// implied else: entry_count == 0
jint nWant = 0, nWait = 0;
if (mon != NULL) {
markWord mark = hobj->mark();
if (mark.has_monitor()) {
mon = mark.monitor();
assert(mon != NULL, "must have monitor");
// this object has a heavyweight monitor
nWant = mon->contentions(); // # of threads contending for monitor
nWait = mon->waiters(); // # of threads in Object.wait()

@ -246,6 +246,8 @@ class ObjectMonitor : public CHeapObj<mtObjectMonitor> {
intptr_t is_entered(JavaThread* current) const;
// Returns true if this OM has an owner, false otherwise.
bool has_owner() const;
void* owner() const; // Returns NULL if DEFLATER_MARKER is observed.
void* owner_raw() const;
// Returns true if owner field == DEFLATER_MARKER and false otherwise.

@ -56,6 +56,11 @@ inline int ObjectMonitor::waiters() const {
return _waiters;
}
inline bool ObjectMonitor::has_owner() const {
void* owner = owner_raw();
return owner != NULL && owner != DEFLATER_MARKER;
}
// Returns NULL if DEFLATER_MARKER is observed.
inline void* ObjectMonitor::owner() const {
void* owner = owner_raw();

@ -1008,7 +1008,6 @@ bool ObjectSynchronizer::current_thread_holds_lock(JavaThread* current,
return false;
}
// FIXME: jvmti should call this
JavaThread* ObjectSynchronizer::get_lock_owner(ThreadsList * t_list, Handle h_obj) {
oop obj = h_obj();
address owner = NULL;

@ -71,7 +71,7 @@
#include "runtime/monitorDeflationThread.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/nonJavaThread.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/objectMonitor.inline.hpp"
#include "runtime/osThread.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/safepointMechanism.inline.hpp"
@ -1408,6 +1408,11 @@ JavaThread *Threads::owning_thread_from_monitor_owner(ThreadsList * t_list,
return the_owner;
}
JavaThread* Threads::owning_thread_from_monitor(ThreadsList* t_list, ObjectMonitor* monitor) {
address owner = (address)monitor->owner();
return owning_thread_from_monitor_owner(t_list, owner);
}
class PrintOnClosure : public ThreadClosure {
private:
outputStream* _st;

@ -136,6 +136,8 @@ class Threads: AllStatic {
static JavaThread *owning_thread_from_monitor_owner(ThreadsList * t_list,
address owner);
static JavaThread* owning_thread_from_monitor(ThreadsList* t_list, ObjectMonitor* owner);
// Number of threads on the active threads list
static int number_of_threads() { return _number_of_threads; }
// Number of non-daemon threads on the active threads list

@ -455,10 +455,8 @@ DeadlockCycle* ThreadService::find_deadlocks_at_safepoint(ThreadsList * t_list,
currentThread = JavaThread::cast(owner);
}
} else if (waitingToLockMonitor != NULL) {
address currentOwner = (address)waitingToLockMonitor->owner();
if (currentOwner != NULL) {
currentThread = Threads::owning_thread_from_monitor_owner(t_list,
currentOwner);
if (waitingToLockMonitor->has_owner()) {
currentThread = Threads::owning_thread_from_monitor(t_list, waitingToLockMonitor);
if (currentThread == NULL) {
// This function is called at a safepoint so the JavaThread
// that owns waitingToLockMonitor should be findable, but
@ -1052,8 +1050,7 @@ void DeadlockCycle::print_on_with(ThreadsList * t_list, outputStream* st) const
if (!currentThread->current_pending_monitor_is_from_java()) {
owner_desc = "\n in JNI, which is held by";
}
currentThread = Threads::owning_thread_from_monitor_owner(t_list,
(address)waitingToLockMonitor->owner());
currentThread = Threads::owning_thread_from_monitor(t_list, waitingToLockMonitor);
if (currentThread == NULL) {
// The deadlock was detected at a safepoint so the JavaThread
// that owns waitingToLockMonitor should be findable, but