annotate agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java @ 774:f1f3a2719a55

6843580: JavaThread.getStackBase throws sun.jvm.hotspot.WrongTypeException invoked by jstack Reviewed-by: phh, dice, never, swamyv
author xlu
date Fri, 22 May 2009 16:40:38 -0700
parents b9fba36710f2
children bd02caa94611
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2 * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 package sun.jvm.hotspot.runtime;
a61af66fc99e Initial load
duke
parents:
diff changeset
26
a61af66fc99e Initial load
duke
parents:
diff changeset
27 import java.io.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
28 import java.util.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
29 import sun.jvm.hotspot.debugger.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
30 import sun.jvm.hotspot.oops.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
31 import sun.jvm.hotspot.types.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
32 import sun.jvm.hotspot.utilities.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
33
a61af66fc99e Initial load
duke
parents:
diff changeset
34 /** This is an abstract class because there are certain OS- and
a61af66fc99e Initial load
duke
parents:
diff changeset
35 CPU-specific operations (like the setting and getting of the last
a61af66fc99e Initial load
duke
parents:
diff changeset
36 Java frame pointer) which need to be factored out. These
a61af66fc99e Initial load
duke
parents:
diff changeset
37 operations are implemented by, for example,
a61af66fc99e Initial load
duke
parents:
diff changeset
38 SolarisSPARCJavaThread, and the concrete subclasses are
a61af66fc99e Initial load
duke
parents:
diff changeset
39 instantiated by the JavaThreadFactory in the Threads class. */
a61af66fc99e Initial load
duke
parents:
diff changeset
40
a61af66fc99e Initial load
duke
parents:
diff changeset
41 public class JavaThread extends Thread {
a61af66fc99e Initial load
duke
parents:
diff changeset
42 private static final boolean DEBUG = System.getProperty("sun.jvm.hotspot.runtime.JavaThread.DEBUG") != null;
a61af66fc99e Initial load
duke
parents:
diff changeset
43
a61af66fc99e Initial load
duke
parents:
diff changeset
44 private static AddressField nextField;
a61af66fc99e Initial load
duke
parents:
diff changeset
45 private static sun.jvm.hotspot.types.OopField threadObjField;
a61af66fc99e Initial load
duke
parents:
diff changeset
46 private static AddressField anchorField;
a61af66fc99e Initial load
duke
parents:
diff changeset
47 private static AddressField lastJavaSPField;
a61af66fc99e Initial load
duke
parents:
diff changeset
48 private static AddressField lastJavaPCField;
a61af66fc99e Initial load
duke
parents:
diff changeset
49 private static CIntegerField threadStateField;
a61af66fc99e Initial load
duke
parents:
diff changeset
50 private static AddressField osThreadField;
702
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 218
diff changeset
51 private static AddressField stackBaseField;
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 218
diff changeset
52 private static CIntegerField stackSizeField;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
53
a61af66fc99e Initial load
duke
parents:
diff changeset
54 private static JavaThreadPDAccess access;
a61af66fc99e Initial load
duke
parents:
diff changeset
55
a61af66fc99e Initial load
duke
parents:
diff changeset
56 // JavaThreadStates read from underlying process
a61af66fc99e Initial load
duke
parents:
diff changeset
57 private static int UNINITIALIZED;
a61af66fc99e Initial load
duke
parents:
diff changeset
58 private static int NEW;
a61af66fc99e Initial load
duke
parents:
diff changeset
59 private static int NEW_TRANS;
a61af66fc99e Initial load
duke
parents:
diff changeset
60 private static int IN_NATIVE;
a61af66fc99e Initial load
duke
parents:
diff changeset
61 private static int IN_NATIVE_TRANS;
a61af66fc99e Initial load
duke
parents:
diff changeset
62 private static int IN_VM;
a61af66fc99e Initial load
duke
parents:
diff changeset
63 private static int IN_VM_TRANS;
a61af66fc99e Initial load
duke
parents:
diff changeset
64 private static int IN_JAVA;
a61af66fc99e Initial load
duke
parents:
diff changeset
65 private static int IN_JAVA_TRANS;
a61af66fc99e Initial load
duke
parents:
diff changeset
66 private static int BLOCKED;
a61af66fc99e Initial load
duke
parents:
diff changeset
67 private static int BLOCKED_TRANS;
a61af66fc99e Initial load
duke
parents:
diff changeset
68
a61af66fc99e Initial load
duke
parents:
diff changeset
69 static {
a61af66fc99e Initial load
duke
parents:
diff changeset
70 VM.registerVMInitializedObserver(new Observer() {
a61af66fc99e Initial load
duke
parents:
diff changeset
71 public void update(Observable o, Object data) {
a61af66fc99e Initial load
duke
parents:
diff changeset
72 initialize(VM.getVM().getTypeDataBase());
a61af66fc99e Initial load
duke
parents:
diff changeset
73 }
a61af66fc99e Initial load
duke
parents:
diff changeset
74 });
a61af66fc99e Initial load
duke
parents:
diff changeset
75 }
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 private static synchronized void initialize(TypeDataBase db) {
a61af66fc99e Initial load
duke
parents:
diff changeset
78 Type type = db.lookupType("JavaThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
79 Type anchorType = db.lookupType("JavaFrameAnchor");
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81 nextField = type.getAddressField("_next");
a61af66fc99e Initial load
duke
parents:
diff changeset
82 threadObjField = type.getOopField("_threadObj");
a61af66fc99e Initial load
duke
parents:
diff changeset
83 anchorField = type.getAddressField("_anchor");
a61af66fc99e Initial load
duke
parents:
diff changeset
84 lastJavaSPField = anchorType.getAddressField("_last_Java_sp");
a61af66fc99e Initial load
duke
parents:
diff changeset
85 lastJavaPCField = anchorType.getAddressField("_last_Java_pc");
a61af66fc99e Initial load
duke
parents:
diff changeset
86 threadStateField = type.getCIntegerField("_thread_state");
a61af66fc99e Initial load
duke
parents:
diff changeset
87 osThreadField = type.getAddressField("_osthread");
702
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 218
diff changeset
88 stackBaseField = type.getAddressField("_stack_base");
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 218
diff changeset
89 stackSizeField = type.getCIntegerField("_stack_size");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 UNINITIALIZED = db.lookupIntConstant("_thread_uninitialized").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
92 NEW = db.lookupIntConstant("_thread_new").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
93 NEW_TRANS = db.lookupIntConstant("_thread_new_trans").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
94 IN_NATIVE = db.lookupIntConstant("_thread_in_native").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
95 IN_NATIVE_TRANS = db.lookupIntConstant("_thread_in_native_trans").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
96 IN_VM = db.lookupIntConstant("_thread_in_vm").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
97 IN_VM_TRANS = db.lookupIntConstant("_thread_in_vm_trans").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
98 IN_JAVA = db.lookupIntConstant("_thread_in_Java").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
99 IN_JAVA_TRANS = db.lookupIntConstant("_thread_in_Java_trans").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
100 BLOCKED = db.lookupIntConstant("_thread_blocked").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
101 BLOCKED_TRANS = db.lookupIntConstant("_thread_blocked_trans").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
103
a61af66fc99e Initial load
duke
parents:
diff changeset
104 public JavaThread(Address addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
105 super(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
107
a61af66fc99e Initial load
duke
parents:
diff changeset
108 void setThreadPDAccess(JavaThreadPDAccess access) {
a61af66fc99e Initial load
duke
parents:
diff changeset
109 this.access = access;
a61af66fc99e Initial load
duke
parents:
diff changeset
110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
111
a61af66fc99e Initial load
duke
parents:
diff changeset
112 public JavaThread next() {
a61af66fc99e Initial load
duke
parents:
diff changeset
113 Address threadAddr = nextField.getValue(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
114 if (threadAddr == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
115 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
117
a61af66fc99e Initial load
duke
parents:
diff changeset
118 return VM.getVM().getThreads().createJavaThreadWrapper(threadAddr);
a61af66fc99e Initial load
duke
parents:
diff changeset
119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
120
a61af66fc99e Initial load
duke
parents:
diff changeset
121 /** NOTE: for convenience, this differs in definition from the
a61af66fc99e Initial load
duke
parents:
diff changeset
122 underlying VM. Only "pure" JavaThreads return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
123 CompilerThreads and JVMDIDebuggerThreads return false. FIXME:
a61af66fc99e Initial load
duke
parents:
diff changeset
124 consider encapsulating platform-specific functionality in an
a61af66fc99e Initial load
duke
parents:
diff changeset
125 object instead of using inheritance (which is the primary reason
a61af66fc99e Initial load
duke
parents:
diff changeset
126 we can't traverse CompilerThreads, etc; didn't want to have, for
a61af66fc99e Initial load
duke
parents:
diff changeset
127 example, "SolarisSPARCCompilerThread".) */
a61af66fc99e Initial load
duke
parents:
diff changeset
128 public boolean isJavaThread() { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
129
a61af66fc99e Initial load
duke
parents:
diff changeset
130 public static AddressField getAnchorField() { return anchorField; }
a61af66fc99e Initial load
duke
parents:
diff changeset
131
a61af66fc99e Initial load
duke
parents:
diff changeset
132 /** Get the last Java stack pointer */
a61af66fc99e Initial load
duke
parents:
diff changeset
133 public Address getLastJavaSP() {
a61af66fc99e Initial load
duke
parents:
diff changeset
134 Address sp = lastJavaSPField.getValue(addr.addOffsetTo(anchorField.getOffset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
135 return sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
137
a61af66fc99e Initial load
duke
parents:
diff changeset
138 public Address getLastJavaPC() {
a61af66fc99e Initial load
duke
parents:
diff changeset
139 Address pc = lastJavaPCField.getValue(addr.addOffsetTo(anchorField.getOffset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
140 return pc;
a61af66fc99e Initial load
duke
parents:
diff changeset
141 }
a61af66fc99e Initial load
duke
parents:
diff changeset
142
a61af66fc99e Initial load
duke
parents:
diff changeset
143 /** Abstract accessor to last Java frame pointer, implemented by
a61af66fc99e Initial load
duke
parents:
diff changeset
144 OS/CPU-specific JavaThread implementation. May return null if
a61af66fc99e Initial load
duke
parents:
diff changeset
145 there is no frame pointer or if it is not necessary on this
a61af66fc99e Initial load
duke
parents:
diff changeset
146 platform. */
a61af66fc99e Initial load
duke
parents:
diff changeset
147 public Address getLastJavaFP(){
a61af66fc99e Initial load
duke
parents:
diff changeset
148 return access.getLastJavaFP(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
149 }
a61af66fc99e Initial load
duke
parents:
diff changeset
150
a61af66fc99e Initial load
duke
parents:
diff changeset
151 /** Abstract accessor to last Java pc, implemented by
a61af66fc99e Initial load
duke
parents:
diff changeset
152 OS/CPU-specific JavaThread implementation. May return null if
a61af66fc99e Initial load
duke
parents:
diff changeset
153 there is no frame pointer or if it is not necessary on this
a61af66fc99e Initial load
duke
parents:
diff changeset
154 platform. */
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
157 public Address getLastJavaPC(){
a61af66fc99e Initial load
duke
parents:
diff changeset
158 return access.getLastJavaPC(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
160 */
a61af66fc99e Initial load
duke
parents:
diff changeset
161
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // FIXME: not yet implementable
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // public abstract void setLastJavaFP(Address fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 /** A stack pointer older than any java frame stack pointer. Only
a61af66fc99e Initial load
duke
parents:
diff changeset
166 needed on some platforms; for example, see
a61af66fc99e Initial load
duke
parents:
diff changeset
167 thread_solaris_sparc.hpp. */
a61af66fc99e Initial load
duke
parents:
diff changeset
168 public Address getBaseOfStackPointer(){
a61af66fc99e Initial load
duke
parents:
diff changeset
169 return access.getBaseOfStackPointer(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
170 }
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // FIXME: not yet implementable
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // public abstract void setBaseOfStackPointer(Address fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
173
a61af66fc99e Initial load
duke
parents:
diff changeset
174 /** Tells whether the last Java frame is set */
a61af66fc99e Initial load
duke
parents:
diff changeset
175 public boolean hasLastJavaFrame() {
a61af66fc99e Initial load
duke
parents:
diff changeset
176 return (getLastJavaSP() != null);
a61af66fc99e Initial load
duke
parents:
diff changeset
177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
178
a61af66fc99e Initial load
duke
parents:
diff changeset
179 /** Accessing frames */
a61af66fc99e Initial load
duke
parents:
diff changeset
180 public Frame getLastFrame() {
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // FIXME: would need to implement runtime routine
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // "cacheStatePD(boolean)" for reflective system to be able to
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // flush register windows on SPARC
a61af66fc99e Initial load
duke
parents:
diff changeset
184 return cookLastFrame(getLastFramePD());
a61af66fc99e Initial load
duke
parents:
diff changeset
185 }
a61af66fc99e Initial load
duke
parents:
diff changeset
186
a61af66fc99e Initial load
duke
parents:
diff changeset
187 /** Internal routine implemented by platform-dependent subclasses */
a61af66fc99e Initial load
duke
parents:
diff changeset
188 protected Frame getLastFramePD(){
a61af66fc99e Initial load
duke
parents:
diff changeset
189 return access.getLastFramePD(this, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
190 }
a61af66fc99e Initial load
duke
parents:
diff changeset
191
a61af66fc99e Initial load
duke
parents:
diff changeset
192 /** Accessing frames. Returns the last Java VFrame or null if none
a61af66fc99e Initial load
duke
parents:
diff changeset
193 was present. (NOTE that this is mostly unusable in a debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
194 system; see getLastJavaVFrameDbg, below, which provides very
a61af66fc99e Initial load
duke
parents:
diff changeset
195 different functionality.) */
a61af66fc99e Initial load
duke
parents:
diff changeset
196 public JavaVFrame getLastJavaVFrame(RegisterMap regMap) {
a61af66fc99e Initial load
duke
parents:
diff changeset
197 if (Assert.ASSERTS_ENABLED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
198 Assert.that(regMap != null, "a map must be given");
a61af66fc99e Initial load
duke
parents:
diff changeset
199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
200 Frame f = getLastFrame();
a61af66fc99e Initial load
duke
parents:
diff changeset
201 if (f == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
202 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
204 for (VFrame vf = VFrame.newVFrame(f, regMap, this); vf != null; vf = vf.sender()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
205 if (vf.isJavaFrame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
206 return (JavaVFrame) vf;
a61af66fc99e Initial load
duke
parents:
diff changeset
207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
209 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
211
a61af66fc99e Initial load
duke
parents:
diff changeset
212 /** This should only be used by a debugger. Uses the current frame
a61af66fc99e Initial load
duke
parents:
diff changeset
213 guess to attempt to get the topmost JavaVFrame.
a61af66fc99e Initial load
duke
parents:
diff changeset
214 (getLastJavaVFrame, as a port of the VM's routine, assumes the
a61af66fc99e Initial load
duke
parents:
diff changeset
215 VM is at a safepoint.) */
a61af66fc99e Initial load
duke
parents:
diff changeset
216 public JavaVFrame getLastJavaVFrameDbg() {
a61af66fc99e Initial load
duke
parents:
diff changeset
217 RegisterMap regMap = newRegisterMap(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
218 sun.jvm.hotspot.runtime.Frame f = getCurrentFrameGuess();
a61af66fc99e Initial load
duke
parents:
diff changeset
219 if (f == null) return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
220 boolean imprecise = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
221 if (f.isInterpretedFrame() && !f.isInterpretedFrameValid()) {
218
a5838065ab24 6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents: 0
diff changeset
222 if (DEBUG) {
a5838065ab24 6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents: 0
diff changeset
223 System.out.println("Correcting for invalid interpreter frame");
a5838065ab24 6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents: 0
diff changeset
224 }
a5838065ab24 6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents: 0
diff changeset
225 f = f.sender(regMap);
a5838065ab24 6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents: 0
diff changeset
226 imprecise = false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
228 VFrame vf = VFrame.newVFrame(f, regMap, this, true, imprecise);
a61af66fc99e Initial load
duke
parents:
diff changeset
229 if (vf == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
230 if (DEBUG) {
a61af66fc99e Initial load
duke
parents:
diff changeset
231 System.out.println(" (Unable to create vframe for topmost frame guess)");
a61af66fc99e Initial load
duke
parents:
diff changeset
232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
233 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
234 }
218
a5838065ab24 6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents: 0
diff changeset
235 return vf.isJavaFrame() ? (JavaVFrame)vf : vf.javaSender();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
237
a61af66fc99e Initial load
duke
parents:
diff changeset
238 /** In this system, a JavaThread is the top-level factory for a
a61af66fc99e Initial load
duke
parents:
diff changeset
239 RegisterMap, since the JavaThread implementation is already
a61af66fc99e Initial load
duke
parents:
diff changeset
240 platform-specific and RegisterMap is also necessarily
a61af66fc99e Initial load
duke
parents:
diff changeset
241 platform-specific. The updateMap argument indicates whether the
a61af66fc99e Initial load
duke
parents:
diff changeset
242 register map needs to be updated, for example during stack
a61af66fc99e Initial load
duke
parents:
diff changeset
243 traversal -- see frame.hpp. */
a61af66fc99e Initial load
duke
parents:
diff changeset
244 public RegisterMap newRegisterMap(boolean updateMap){
a61af66fc99e Initial load
duke
parents:
diff changeset
245 return access.newRegisterMap(this, updateMap);
a61af66fc99e Initial load
duke
parents:
diff changeset
246 }
a61af66fc99e Initial load
duke
parents:
diff changeset
247
a61af66fc99e Initial load
duke
parents:
diff changeset
248 /** This is only designed to be used by the debugging system.
a61af66fc99e Initial load
duke
parents:
diff changeset
249 Returns a "best guess" of the topmost frame on the stack. This
a61af66fc99e Initial load
duke
parents:
diff changeset
250 guess should be as "raw" as possible. For example, if the
a61af66fc99e Initial load
duke
parents:
diff changeset
251 topmost frame is an interpreter frame (the return PC is in the
a61af66fc99e Initial load
duke
parents:
diff changeset
252 interpreter) but is not a valid frame (i.e., the BCI has not yet
a61af66fc99e Initial load
duke
parents:
diff changeset
253 been set up) this should still return the topmost frame and not
a61af66fc99e Initial load
duke
parents:
diff changeset
254 the sender. Validity checks are done at higher levels. */
a61af66fc99e Initial load
duke
parents:
diff changeset
255 public Frame getCurrentFrameGuess(){
a61af66fc99e Initial load
duke
parents:
diff changeset
256 return access.getCurrentFrameGuess(this, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
258
a61af66fc99e Initial load
duke
parents:
diff changeset
259 /** Also only intended for use by the debugging system. Provides the
a61af66fc99e Initial load
duke
parents:
diff changeset
260 same effect of OSThread::print(); that is, prints a value which
a61af66fc99e Initial load
duke
parents:
diff changeset
261 allows the user to intuitively understand which native OS thread
a61af66fc99e Initial load
duke
parents:
diff changeset
262 maps to this Java thread. Does not print a newline or leading or
a61af66fc99e Initial load
duke
parents:
diff changeset
263 trailing spaces. */
a61af66fc99e Initial load
duke
parents:
diff changeset
264 public void printThreadIDOn(PrintStream tty) {
a61af66fc99e Initial load
duke
parents:
diff changeset
265 access.printThreadIDOn(addr,tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
267
a61af66fc99e Initial load
duke
parents:
diff changeset
268 public void printThreadID() {
a61af66fc99e Initial load
duke
parents:
diff changeset
269 printThreadIDOn(System.out);
a61af66fc99e Initial load
duke
parents:
diff changeset
270 }
a61af66fc99e Initial load
duke
parents:
diff changeset
271
a61af66fc99e Initial load
duke
parents:
diff changeset
272 public ThreadProxy getThreadProxy() {
a61af66fc99e Initial load
duke
parents:
diff changeset
273 return access.getThreadProxy(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 //
a61af66fc99e Initial load
duke
parents:
diff changeset
277 // Safepoint support
a61af66fc99e Initial load
duke
parents:
diff changeset
278 //
a61af66fc99e Initial load
duke
parents:
diff changeset
279
a61af66fc99e Initial load
duke
parents:
diff changeset
280 public JavaThreadState getThreadState() {
a61af66fc99e Initial load
duke
parents:
diff changeset
281 int val = (int) threadStateField.getValue(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
282 if (val == UNINITIALIZED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
283 return JavaThreadState.UNINITIALIZED;
a61af66fc99e Initial load
duke
parents:
diff changeset
284 } else if (val == NEW) {
a61af66fc99e Initial load
duke
parents:
diff changeset
285 return JavaThreadState.NEW;
a61af66fc99e Initial load
duke
parents:
diff changeset
286 } else if (val == NEW_TRANS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
287 return JavaThreadState.NEW_TRANS;
a61af66fc99e Initial load
duke
parents:
diff changeset
288 } else if (val == IN_NATIVE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
289 return JavaThreadState.IN_NATIVE;
a61af66fc99e Initial load
duke
parents:
diff changeset
290 } else if (val == IN_NATIVE_TRANS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
291 return JavaThreadState.IN_NATIVE_TRANS;
a61af66fc99e Initial load
duke
parents:
diff changeset
292 } else if (val == IN_VM) {
a61af66fc99e Initial load
duke
parents:
diff changeset
293 return JavaThreadState.IN_VM;
a61af66fc99e Initial load
duke
parents:
diff changeset
294 } else if (val == IN_VM_TRANS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
295 return JavaThreadState.IN_VM_TRANS;
a61af66fc99e Initial load
duke
parents:
diff changeset
296 } else if (val == IN_JAVA) {
a61af66fc99e Initial load
duke
parents:
diff changeset
297 return JavaThreadState.IN_JAVA;
a61af66fc99e Initial load
duke
parents:
diff changeset
298 } else if (val == IN_JAVA_TRANS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
299 return JavaThreadState.IN_JAVA_TRANS;
a61af66fc99e Initial load
duke
parents:
diff changeset
300 } else if (val == BLOCKED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
301 return JavaThreadState.BLOCKED;
a61af66fc99e Initial load
duke
parents:
diff changeset
302 } else if (val == BLOCKED_TRANS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
303 return JavaThreadState.BLOCKED_TRANS;
a61af66fc99e Initial load
duke
parents:
diff changeset
304 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
305 throw new RuntimeException("Illegal thread state " + val);
a61af66fc99e Initial load
duke
parents:
diff changeset
306 }
a61af66fc99e Initial load
duke
parents:
diff changeset
307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
308 // FIXME: not yet implementable
a61af66fc99e Initial load
duke
parents:
diff changeset
309 // public void setThreadState(JavaThreadState s);
a61af66fc99e Initial load
duke
parents:
diff changeset
310
a61af66fc99e Initial load
duke
parents:
diff changeset
311 //
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // Miscellaneous operations
a61af66fc99e Initial load
duke
parents:
diff changeset
313 //
a61af66fc99e Initial load
duke
parents:
diff changeset
314
a61af66fc99e Initial load
duke
parents:
diff changeset
315 public OSThread getOSThread() {
a61af66fc99e Initial load
duke
parents:
diff changeset
316 return (OSThread) VMObjectFactory.newObject(OSThread.class, osThreadField.getValue(addr));
a61af66fc99e Initial load
duke
parents:
diff changeset
317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
318
702
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 218
diff changeset
319 public Address getStackBase() {
774
f1f3a2719a55 6843580: JavaThread.getStackBase throws sun.jvm.hotspot.WrongTypeException invoked by jstack
xlu
parents: 702
diff changeset
320 return stackBaseField.getValue(addr);
702
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 218
diff changeset
321 }
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 218
diff changeset
322
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 218
diff changeset
323 public long getStackSize() {
774
f1f3a2719a55 6843580: JavaThread.getStackBase throws sun.jvm.hotspot.WrongTypeException invoked by jstack
xlu
parents: 702
diff changeset
324 return stackSizeField.getValue(addr);
702
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 218
diff changeset
325 }
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 218
diff changeset
326
0
a61af66fc99e Initial load
duke
parents:
diff changeset
327 /** Gets the Java-side thread object for this JavaThread */
a61af66fc99e Initial load
duke
parents:
diff changeset
328 public Oop getThreadObj() {
a61af66fc99e Initial load
duke
parents:
diff changeset
329 return VM.getVM().getObjectHeap().newOop(threadObjField.getValue(addr));
a61af66fc99e Initial load
duke
parents:
diff changeset
330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
331
a61af66fc99e Initial load
duke
parents:
diff changeset
332 /** Get the Java-side name of this thread */
a61af66fc99e Initial load
duke
parents:
diff changeset
333 public String getThreadName() {
a61af66fc99e Initial load
duke
parents:
diff changeset
334 Oop threadObj = getThreadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
335 if (threadObj == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
336 return "<null>";
a61af66fc99e Initial load
duke
parents:
diff changeset
337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
338 return OopUtilities.threadOopGetName(threadObj);
a61af66fc99e Initial load
duke
parents:
diff changeset
339 }
a61af66fc99e Initial load
duke
parents:
diff changeset
340
a61af66fc99e Initial load
duke
parents:
diff changeset
341 //
a61af66fc99e Initial load
duke
parents:
diff changeset
342 // Oop traversal
a61af66fc99e Initial load
duke
parents:
diff changeset
343 //
a61af66fc99e Initial load
duke
parents:
diff changeset
344
a61af66fc99e Initial load
duke
parents:
diff changeset
345 public void oopsDo(AddressVisitor oopVisitor) {
a61af66fc99e Initial load
duke
parents:
diff changeset
346 super.oopsDo(oopVisitor);
a61af66fc99e Initial load
duke
parents:
diff changeset
347
a61af66fc99e Initial load
duke
parents:
diff changeset
348 // FIXME: add in the rest of the routine from the VM
a61af66fc99e Initial load
duke
parents:
diff changeset
349
a61af66fc99e Initial load
duke
parents:
diff changeset
350 // Traverse the execution stack
a61af66fc99e Initial load
duke
parents:
diff changeset
351 for(StackFrameStream fst = new StackFrameStream(this); !fst.isDone(); fst.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
352 fst.getCurrent().oopsDo(oopVisitor, fst.getRegisterMap());
a61af66fc99e Initial load
duke
parents:
diff changeset
353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
354 }
a61af66fc99e Initial load
duke
parents:
diff changeset
355
a61af66fc99e Initial load
duke
parents:
diff changeset
356 public boolean isInStack(Address a) {
a61af66fc99e Initial load
duke
parents:
diff changeset
357 if (Assert.ASSERTS_ENABLED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
358 Assert.that(VM.getVM().isDebugging(), "Not yet implemented for non-debugging system");
a61af66fc99e Initial load
duke
parents:
diff changeset
359 }
a61af66fc99e Initial load
duke
parents:
diff changeset
360 Address sp = lastSPDbg();
702
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 218
diff changeset
361 Address stackBase = getStackBase();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // Be robust
702
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 218
diff changeset
363 if (sp == null) return false;
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 218
diff changeset
364 return stackBase.greaterThanOrEqual(a) && sp.lessThanOrEqual(a);
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 218
diff changeset
365 }
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 218
diff changeset
366
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 218
diff changeset
367 public boolean isLockOwned(Address a) {
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 218
diff changeset
368 Address stackBase = getStackBase();
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 218
diff changeset
369 Address stackLimit = stackBase.addOffsetTo(-getStackSize());
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 218
diff changeset
370
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 218
diff changeset
371 return stackBase.greaterThanOrEqual(a) && stackLimit.lessThanOrEqual(a);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
372
a61af66fc99e Initial load
duke
parents:
diff changeset
373 // FIXME: should traverse MonitorArray/MonitorChunks as in VM
a61af66fc99e Initial load
duke
parents:
diff changeset
374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
375
a61af66fc99e Initial load
duke
parents:
diff changeset
376 public Oop getCurrentParkBlocker() {
a61af66fc99e Initial load
duke
parents:
diff changeset
377 Oop threadObj = getThreadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
378 if (threadObj != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
379 return OopUtilities.threadOopGetParkBlocker(threadObj);
a61af66fc99e Initial load
duke
parents:
diff changeset
380 }
a61af66fc99e Initial load
duke
parents:
diff changeset
381 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
382 }
a61af66fc99e Initial load
duke
parents:
diff changeset
383
a61af66fc99e Initial load
duke
parents:
diff changeset
384 public void printInfoOn(PrintStream tty) {
a61af66fc99e Initial load
duke
parents:
diff changeset
385
a61af66fc99e Initial load
duke
parents:
diff changeset
386 tty.println("State: " + getThreadState().toString());
a61af66fc99e Initial load
duke
parents:
diff changeset
387 // Attempt to figure out the addresses covered by Java frames.
a61af66fc99e Initial load
duke
parents:
diff changeset
388 // NOTE: we should make this a method and let the Stackwalk panel use the result too.
a61af66fc99e Initial load
duke
parents:
diff changeset
389 //
a61af66fc99e Initial load
duke
parents:
diff changeset
390 sun.jvm.hotspot.runtime.Frame tmpFrame = getCurrentFrameGuess();
a61af66fc99e Initial load
duke
parents:
diff changeset
391 if (tmpFrame != null ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
392 Address sp = tmpFrame.getSP();
a61af66fc99e Initial load
duke
parents:
diff changeset
393 Address maxSP = sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
394 Address minSP = sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
395 RegisterMap tmpMap = newRegisterMap(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
396 while ((tmpFrame != null) && (!tmpFrame.isFirstFrame())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
397 tmpFrame = tmpFrame.sender(tmpMap);
a61af66fc99e Initial load
duke
parents:
diff changeset
398 if (tmpFrame != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
399 sp = tmpFrame.getSP();
a61af66fc99e Initial load
duke
parents:
diff changeset
400 maxSP = AddressOps.max(maxSP, sp);
a61af66fc99e Initial load
duke
parents:
diff changeset
401 minSP = AddressOps.min(minSP, sp);
a61af66fc99e Initial load
duke
parents:
diff changeset
402 }
a61af66fc99e Initial load
duke
parents:
diff changeset
403 }
a61af66fc99e Initial load
duke
parents:
diff changeset
404 tty.println("Stack in use by Java: " + minSP + " .. " + maxSP);
a61af66fc99e Initial load
duke
parents:
diff changeset
405 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
406 tty.println("No Java frames present");
a61af66fc99e Initial load
duke
parents:
diff changeset
407 }
a61af66fc99e Initial load
duke
parents:
diff changeset
408 tty.println("Base of Stack: " + getBaseOfStackPointer());
a61af66fc99e Initial load
duke
parents:
diff changeset
409 tty.println("Last_Java_SP: " + getLastJavaSP());
a61af66fc99e Initial load
duke
parents:
diff changeset
410 tty.println("Last_Java_FP: " + getLastJavaFP());
a61af66fc99e Initial load
duke
parents:
diff changeset
411 tty.println("Last_Java_PC: " + getLastJavaPC());
a61af66fc99e Initial load
duke
parents:
diff changeset
412 // More stuff like saved_execption_pc, safepoint_state, ...
a61af66fc99e Initial load
duke
parents:
diff changeset
413 access.printInfoOn(addr, tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
414
a61af66fc99e Initial load
duke
parents:
diff changeset
415 }
a61af66fc99e Initial load
duke
parents:
diff changeset
416
a61af66fc99e Initial load
duke
parents:
diff changeset
417 ///////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
418 // //
a61af66fc99e Initial load
duke
parents:
diff changeset
419 // FIXME: add more accessors //
a61af66fc99e Initial load
duke
parents:
diff changeset
420 // //
a61af66fc99e Initial load
duke
parents:
diff changeset
421 ///////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
422
a61af66fc99e Initial load
duke
parents:
diff changeset
423 //--------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
424 // Internals only below this point
a61af66fc99e Initial load
duke
parents:
diff changeset
425 //
a61af66fc99e Initial load
duke
parents:
diff changeset
426
a61af66fc99e Initial load
duke
parents:
diff changeset
427 private Frame cookLastFrame(Frame fr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
428 if (fr == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
429 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
430 }
a61af66fc99e Initial load
duke
parents:
diff changeset
431
a61af66fc99e Initial load
duke
parents:
diff changeset
432 Address pc = fr.getPC();
a61af66fc99e Initial load
duke
parents:
diff changeset
433
a61af66fc99e Initial load
duke
parents:
diff changeset
434 if (Assert.ASSERTS_ENABLED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
435 if (pc == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
436 Assert.that(VM.getVM().isDebugging(), "must have PC");
a61af66fc99e Initial load
duke
parents:
diff changeset
437 }
a61af66fc99e Initial load
duke
parents:
diff changeset
438 }
a61af66fc99e Initial load
duke
parents:
diff changeset
439 return fr;
a61af66fc99e Initial load
duke
parents:
diff changeset
440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
441
a61af66fc99e Initial load
duke
parents:
diff changeset
442 private Address lastSPDbg() {
a61af66fc99e Initial load
duke
parents:
diff changeset
443 return access.getLastSP(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
444 }
a61af66fc99e Initial load
duke
parents:
diff changeset
445
a61af66fc99e Initial load
duke
parents:
diff changeset
446 }