0
|
1 /*
|
|
2 * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
|
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
4 *
|
|
5 * This code is free software; you can redistribute it and/or modify it
|
|
6 * under the terms of the GNU General Public License version 2 only, as
|
|
7 * published by the Free Software Foundation.
|
|
8 *
|
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT
|
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
12 * version 2 for more details (a copy is included in the LICENSE file that
|
|
13 * accompanied this code).
|
|
14 *
|
|
15 * You should have received a copy of the GNU General Public License version
|
|
16 * 2 along with this work; if not, write to the Free Software Foundation,
|
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
18 *
|
|
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
20 * CA 95054 USA or visit www.sun.com if you need additional information or
|
|
21 * have any questions.
|
|
22 *
|
|
23 */
|
|
24
|
|
25 package sun.jvm.hotspot.utilities.soql;
|
|
26
|
|
27 import java.util.*;
|
|
28 import sun.jvm.hotspot.debugger.*;
|
|
29 import sun.jvm.hotspot.oops.*;
|
|
30 import sun.jvm.hotspot.runtime.*;
|
|
31
|
|
32 /**
|
|
33 * Wraps a JavaThread instance in the target VM.
|
|
34 */
|
|
35 public class JSJavaThread extends JSJavaInstance {
|
|
36 public JSJavaThread(Instance threadOop, JSJavaFactory fac) {
|
|
37 super(threadOop, fac);
|
|
38 // JavaThread retrieved from java.lang.Thread instance may be null.
|
|
39 // This is the case for threads not-started and for zombies. Wherever
|
|
40 // appropriate, check for null instead of resulting in NullPointerException.
|
|
41 this.jthread = OopUtilities.threadOopGetJavaThread(threadOop);
|
|
42 }
|
|
43
|
|
44 public JSJavaThread(JavaThread jt, JSJavaFactory fac) {
|
|
45 super((Instance) jt.getThreadObj(), fac);
|
|
46 this.jthread = jt;
|
|
47 }
|
|
48
|
|
49 public String toString() {
|
|
50 String name = getName();
|
|
51 StringBuffer buf = new StringBuffer();
|
|
52 buf.append("Thread (address=");
|
|
53 buf.append(getOop().getHandle());
|
|
54 buf.append(", name=");
|
|
55 if (name != null) {
|
|
56 buf.append(name);
|
|
57 } else {
|
|
58 buf.append("<unnamed>");
|
|
59 }
|
|
60 buf.append(')');
|
|
61 return buf.toString();
|
|
62 }
|
|
63
|
|
64 protected Object getFieldValue(String name) {
|
|
65 if (name.equals("name")) {
|
|
66 return getName();
|
|
67 } else if (name.equals("frames")) {
|
|
68 return getFrames();
|
|
69 } else if (name.equals("monitors")) {
|
|
70 return getOwnedMonitors();
|
|
71 } else {
|
|
72 return super.getFieldValue(name);
|
|
73 }
|
|
74 }
|
|
75
|
|
76 protected String[] getFieldNames() {
|
|
77 String[] flds = super.getFieldNames();
|
|
78 String[] res = new String[flds.length + 2];
|
|
79 System.arraycopy(flds, 0, res, 0, flds.length);
|
|
80 res[flds.length] = "frames";
|
|
81 res[flds.length + 1] = "monitors";
|
|
82 return res;
|
|
83 }
|
|
84
|
|
85 protected boolean hasField(String name) {
|
|
86 if (name.equals("frames") || name.equals("monitors")) {
|
|
87 return true;
|
|
88 } else {
|
|
89 return super.hasField(name);
|
|
90 }
|
|
91 }
|
|
92
|
|
93 //-- Internals only below this point
|
|
94 private String getName() {
|
|
95 return OopUtilities.threadOopGetName(getOop());
|
|
96 }
|
|
97
|
|
98 private synchronized JSList getFrames() {
|
|
99 if (framesCache == null) {
|
|
100 final List list = new ArrayList(0);
|
|
101 if (jthread != null) {
|
|
102 JavaVFrame jvf = jthread.getLastJavaVFrameDbg();
|
|
103 while (jvf != null) {
|
|
104 list.add(jvf);
|
|
105 jvf = jvf.javaSender();
|
|
106 }
|
|
107 }
|
|
108 framesCache = factory.newJSList(list);
|
|
109 }
|
|
110 return framesCache;
|
|
111 }
|
|
112
|
|
113 private synchronized JSList getOwnedMonitors() {
|
|
114 if (monitorsCache == null) {
|
|
115 final List ownedMonitors = new ArrayList(0);
|
|
116 if (jthread != null) {
|
|
117 List lockedObjects = new ArrayList(); // List<OopHandle>
|
|
118
|
|
119 ObjectMonitor waitingMonitor = jthread.getCurrentWaitingMonitor();
|
|
120 OopHandle waitingObj = null;
|
|
121 if (waitingMonitor != null) {
|
|
122 // save object of current wait() call (if any) for later comparison
|
|
123 waitingObj = waitingMonitor.object();
|
|
124 }
|
|
125
|
|
126 ObjectMonitor pendingMonitor = jthread.getCurrentPendingMonitor();
|
|
127 OopHandle pendingObj = null;
|
|
128 if (pendingMonitor != null) {
|
|
129 // save object of current enter() call (if any) for later comparison
|
|
130 pendingObj = pendingMonitor.object();
|
|
131 }
|
|
132
|
|
133 JavaVFrame frame = jthread.getLastJavaVFrameDbg();
|
|
134 while (frame != null) {
|
|
135 List frameMonitors = frame.getMonitors(); // List<MonitorInfo>
|
|
136 for (Iterator miItr = frameMonitors.iterator(); miItr.hasNext(); ) {
|
|
137 MonitorInfo mi = (MonitorInfo) miItr.next();
|
|
138 OopHandle obj = mi.owner();
|
|
139 if (obj == null) {
|
|
140 // this monitor doesn't have an owning object so skip it
|
|
141 continue;
|
|
142 }
|
|
143
|
|
144 if (obj.equals(waitingObj)) {
|
|
145 // the thread is waiting on this monitor so it isn't really owned
|
|
146 continue;
|
|
147 }
|
|
148
|
|
149 if (obj.equals(pendingObj)) {
|
|
150 // the thread is pending on this monitor so it isn't really owned
|
|
151 continue;
|
|
152 }
|
|
153
|
|
154 boolean found = false;
|
|
155 for (Iterator loItr = lockedObjects.iterator(); loItr.hasNext(); ) {
|
|
156 // check for recursive locks
|
|
157 if (obj.equals(loItr.next())) {
|
|
158 found = true;
|
|
159 break;
|
|
160 }
|
|
161 }
|
|
162 if (found) {
|
|
163 // already have this object so don't include it
|
|
164 continue;
|
|
165 }
|
|
166 // add the owning object to our list
|
|
167 lockedObjects.add(obj);
|
|
168 }
|
|
169 frame = (JavaVFrame) frame.javaSender();
|
|
170 }
|
|
171
|
|
172 // now convert List<OopHandle> to List<Oop>
|
|
173 ObjectHeap heap = VM.getVM().getObjectHeap();
|
|
174 for (Iterator loItr = lockedObjects.iterator(); loItr.hasNext(); ) {
|
|
175 ownedMonitors.add(heap.newOop((OopHandle)loItr.next()));
|
|
176 }
|
|
177 }
|
|
178 monitorsCache = factory.newJSList(ownedMonitors);
|
|
179 }
|
|
180 return monitorsCache;
|
|
181 }
|
|
182
|
|
183 private JavaThread jthread;
|
|
184 private JSList framesCache;
|
|
185 private JSList monitorsCache;
|
|
186 }
|