@@ -1161,9 +1161,11 @@ class GetThreadSnapshotClosure: public HandshakeClosure {
11611161 Type _type;
11621162 // park blocker or an object the thread waiting on/trying to lock
11631163 OopHandle _obj;
1164+ // thread that owns park blocker object when park blocker is AbstractOwnableSynchronizer
1165+ OopHandle _owner;
11641166
1165- Blocker (Type type, OopHandle obj): _type(type), _obj(obj) {}
1166- Blocker (): _type(NOTHING), _obj(nullptr ) {}
1167+ Blocker (Type type, OopHandle obj): _type(type), _obj(obj), _owner() {}
1168+ Blocker (): _type(NOTHING), _obj(), _owner( ) {}
11671169
11681170 bool is_empty () const {
11691171 return _type == NOTHING;
@@ -1198,6 +1200,7 @@ class GetThreadSnapshotClosure: public HandshakeClosure {
11981200 delete _locks;
11991201 }
12001202 _blocker._obj .release (oop_storage ());
1203+ _blocker._owner .release (oop_storage ());
12011204 }
12021205
12031206private:
@@ -1299,6 +1302,13 @@ class GetThreadSnapshotClosure: public HandshakeClosure {
12991302 oop park_blocker = java_lang_Thread::park_blocker (_thread_h ());
13001303 if (park_blocker != nullptr ) {
13011304 _blocker = Blocker (Blocker::PARK_BLOCKER, OopHandle (oop_storage (), park_blocker));
1305+ if (park_blocker->is_a (vmClasses::java_util_concurrent_locks_AbstractOwnableSynchronizer_klass ())) {
1306+ // could be stale (unlikely in practice), but it's good enough to see deadlocks
1307+ oop ownerObj = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj (park_blocker);
1308+ if (ownerObj != nullptr ) {
1309+ _blocker._owner = OopHandle (oop_storage (), ownerObj);
1310+ }
1311+ }
13021312 }
13031313
13041314 ResourceMark rm (current);
@@ -1380,6 +1390,7 @@ class jdk_internal_vm_ThreadSnapshot: AllStatic {
13801390 static int _locks_offset;
13811391 static int _blockerTypeOrdinal_offset;
13821392 static int _blockerObject_offset;
1393+ static int _parkBlockerOwner_offset;
13831394
13841395 static void compute_offsets (InstanceKlass* klass, TRAPS) {
13851396 JavaClasses::compute_offset (_name_offset, klass, " name" , vmSymbols::string_signature (), false );
@@ -1389,6 +1400,7 @@ class jdk_internal_vm_ThreadSnapshot: AllStatic {
13891400 JavaClasses::compute_offset (_locks_offset, klass, " locks" , vmSymbols::jdk_internal_vm_ThreadLock_array (), false );
13901401 JavaClasses::compute_offset (_blockerTypeOrdinal_offset, klass, " blockerTypeOrdinal" , vmSymbols::int_signature (), false );
13911402 JavaClasses::compute_offset (_blockerObject_offset, klass, " blockerObject" , vmSymbols::object_signature (), false );
1403+ JavaClasses::compute_offset (_parkBlockerOwner_offset, klass, " parkBlockerOwner" , vmSymbols::thread_signature (), false );
13921404 }
13931405public:
13941406 static void init (InstanceKlass* klass, TRAPS) {
@@ -1419,9 +1431,10 @@ class jdk_internal_vm_ThreadSnapshot: AllStatic {
14191431 static void set_locks (oop snapshot, oop locks) {
14201432 snapshot->obj_field_put (_locks_offset, locks);
14211433 }
1422- static void set_blocker (oop snapshot, int type_ordinal, oop lock) {
1434+ static void set_blocker (oop snapshot, int type_ordinal, oop lock, oop owner ) {
14231435 snapshot->int_field_put (_blockerTypeOrdinal_offset, type_ordinal);
14241436 snapshot->obj_field_put (_blockerObject_offset, lock);
1437+ snapshot->obj_field_put (_parkBlockerOwner_offset, owner);
14251438 }
14261439};
14271440
@@ -1433,6 +1446,7 @@ int jdk_internal_vm_ThreadSnapshot::_stackTrace_offset;
14331446int jdk_internal_vm_ThreadSnapshot::_locks_offset;
14341447int jdk_internal_vm_ThreadSnapshot::_blockerTypeOrdinal_offset;
14351448int jdk_internal_vm_ThreadSnapshot::_blockerObject_offset;
1449+ int jdk_internal_vm_ThreadSnapshot::_parkBlockerOwner_offset;
14361450
14371451oop ThreadSnapshotFactory::get_thread_snapshot (jobject jthread, TRAPS) {
14381452 ThreadsListHandle tlh (THREAD);
@@ -1548,7 +1562,8 @@ oop ThreadSnapshotFactory::get_thread_snapshot(jobject jthread, TRAPS) {
15481562 jdk_internal_vm_ThreadSnapshot::set_stack_trace (snapshot (), trace ());
15491563 jdk_internal_vm_ThreadSnapshot::set_locks (snapshot (), locks ());
15501564 if (!cl._blocker .is_empty ()) {
1551- jdk_internal_vm_ThreadSnapshot::set_blocker (snapshot (), cl._blocker ._type , cl._blocker ._obj .resolve ());
1565+ jdk_internal_vm_ThreadSnapshot::set_blocker (snapshot (),
1566+ cl._blocker ._type , cl._blocker ._obj .resolve (), cl._blocker ._owner .resolve ());
15521567 }
15531568 return snapshot ();
15541569}
0 commit comments