13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package jdk.internal.vm;
26
27 import java.util.Arrays;
28 import java.util.stream.Stream;
29
30 /**
31 * Represents a snapshot of information about a Thread.
32 */
33 class ThreadSnapshot {
34 private static final StackTraceElement[] EMPTY_STACK = new StackTraceElement[0];
35 private static final ThreadLock[] EMPTY_LOCKS = new ThreadLock[0];
36
37 // filled by VM
38 private String name;
39 private int threadStatus;
40 private Thread carrierThread;
41 private StackTraceElement[] stackTrace;
42 // owned monitors
43 private ThreadLock[] locks;
44 // an object the thread is blocked/waiting on, converted to ThreadBlocker by ThreadSnapshot.of()
45 private int blockerTypeOrdinal;
46 private Object blockerObject;
47 // the owner of the blockerObject when the object is park blocker and is AbstractOwnableSynchronizer
48 private Thread parkBlockerOwner;
49
50 // set by ThreadSnapshot.of()
51 private ThreadBlocker blocker;
52
53 private ThreadSnapshot() {}
54
55 /**
56 * Take a snapshot of a Thread to get all information about the thread.
57 * Return null if a ThreadSnapshot is not created, for example if the
58 * thread has terminated.
59 * @throws UnsupportedOperationException if not supported by VM
60 */
61 static ThreadSnapshot of(Thread thread) {
62 ThreadSnapshot snapshot = create(thread);
63 if (snapshot == null) {
64 return null; // thread terminated
65 }
66 if (snapshot.stackTrace == null) {
67 snapshot.stackTrace = EMPTY_STACK;
68 }
69 if (snapshot.locks != null) {
70 Arrays.stream(snapshot.locks).forEach(ThreadLock::finishInit);
71 } else {
72 snapshot.locks = EMPTY_LOCKS;
73 }
74 if (snapshot.blockerObject != null) {
75 snapshot.blocker = new ThreadBlocker(snapshot.blockerTypeOrdinal,
76 snapshot.blockerObject,
77 snapshot.parkBlockerOwner);
78 snapshot.blockerObject = null; // release
79 snapshot.parkBlockerOwner = null;
80 }
81 return snapshot;
82 }
83
84 /**
85 * Returns the thread name.
86 */
87 String threadName() {
88 return name;
89 }
90
91 /**
92 * Returns the thread state.
93 */
94 Thread.State threadState() {
95 return jdk.internal.misc.VM.toThreadState(threadStatus);
96 }
97
98 /**
99 * Returns the thread stack trace.
100 */
101 StackTraceElement[] stackTrace() {
102 return stackTrace;
103 }
104
105 /**
106 * Returns the thread's parkBlocker.
107 */
108 Object parkBlocker() {
109 return getBlocker(BlockerLockType.PARK_BLOCKER);
110 }
111
112 /**
113 * Returns the owner of the parkBlocker if the parkBlocker is an AbstractOwnableSynchronizer.
114 */
115 Thread parkBlockerOwner() {
116 return (blocker != null && blocker.type == BlockerLockType.PARK_BLOCKER) ? blocker.owner : null;
117 }
118
119 /**
120 * Returns the object that the thread is blocked on.
121 * @throws IllegalStateException if not in the blocked state
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package jdk.internal.vm;
26
27 import java.util.Arrays;
28 import java.util.stream.Stream;
29
30 /**
31 * Represents a snapshot of information about a Thread.
32 */
33 public class ThreadSnapshot {
34 private static final StackTraceElement[] EMPTY_STACK = new StackTraceElement[0];
35 private static final ThreadLock[] EMPTY_LOCKS = new ThreadLock[0];
36
37 // filled by VM
38 private String name;
39 private int threadStatus;
40 private Thread carrierThread;
41 private StackTraceElement[] stackTrace;
42 // owned monitors
43 private ThreadLock[] locks;
44 // an object the thread is blocked/waiting on, converted to ThreadBlocker by ThreadSnapshot.of()
45 private int blockerTypeOrdinal;
46 private Object blockerObject;
47 // the owner of the blockerObject when the object is park blocker and is AbstractOwnableSynchronizer
48 private Thread parkBlockerOwner;
49
50 // set by ThreadSnapshot.of()
51 private ThreadBlocker blocker;
52
53 private ThreadSnapshot() {}
54
55 /**
56 * Take a snapshot of a Thread to get all information about the thread.
57 * Return null if the thread is not alive.
58 */
59 public static ThreadSnapshot of(Thread thread) {
60 ThreadSnapshot snapshot = create(thread);
61 if (snapshot == null) {
62 return null; // thread not alive
63 }
64 if (snapshot.stackTrace == null) {
65 snapshot.stackTrace = EMPTY_STACK;
66 }
67 if (snapshot.locks != null) {
68 Arrays.stream(snapshot.locks).forEach(ThreadLock::finishInit);
69 } else {
70 snapshot.locks = EMPTY_LOCKS;
71 }
72 if (snapshot.blockerObject != null) {
73 snapshot.blocker = new ThreadBlocker(snapshot.blockerTypeOrdinal,
74 snapshot.blockerObject,
75 snapshot.parkBlockerOwner);
76 snapshot.blockerObject = null; // release
77 snapshot.parkBlockerOwner = null;
78 }
79 return snapshot;
80 }
81
82 /**
83 * Returns the thread name.
84 */
85 String threadName() {
86 return name;
87 }
88
89 /**
90 * Returns the thread state.
91 */
92 Thread.State threadState() {
93 return jdk.internal.misc.VM.toThreadState(threadStatus);
94 }
95
96 /**
97 * Returns the thread stack trace.
98 */
99 public StackTraceElement[] stackTrace() {
100 return stackTrace;
101 }
102
103 /**
104 * Returns the thread's parkBlocker.
105 */
106 Object parkBlocker() {
107 return getBlocker(BlockerLockType.PARK_BLOCKER);
108 }
109
110 /**
111 * Returns the owner of the parkBlocker if the parkBlocker is an AbstractOwnableSynchronizer.
112 */
113 Thread parkBlockerOwner() {
114 return (blocker != null && blocker.type == BlockerLockType.PARK_BLOCKER) ? blocker.owner : null;
115 }
116
117 /**
118 * Returns the object that the thread is blocked on.
119 * @throws IllegalStateException if not in the blocked state
|