annotate agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java @ 113:ba764ed4b6f2

6420645: Create a vm that uses compressed oops for up to 32gb heapsizes Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold
author coleenp
date Sun, 13 Apr 2008 17:43:42 -0400
parents a61af66fc99e
children a5838065ab24
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;
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 private static JavaThreadPDAccess access;
a61af66fc99e Initial load
duke
parents:
diff changeset
53
a61af66fc99e Initial load
duke
parents:
diff changeset
54 // JavaThreadStates read from underlying process
a61af66fc99e Initial load
duke
parents:
diff changeset
55 private static int UNINITIALIZED;
a61af66fc99e Initial load
duke
parents:
diff changeset
56 private static int NEW;
a61af66fc99e Initial load
duke
parents:
diff changeset
57 private static int NEW_TRANS;
a61af66fc99e Initial load
duke
parents:
diff changeset
58 private static int IN_NATIVE;
a61af66fc99e Initial load
duke
parents:
diff changeset
59 private static int IN_NATIVE_TRANS;
a61af66fc99e Initial load
duke
parents:
diff changeset
60 private static int IN_VM;
a61af66fc99e Initial load
duke
parents:
diff changeset
61 private static int IN_VM_TRANS;
a61af66fc99e Initial load
duke
parents:
diff changeset
62 private static int IN_JAVA;
a61af66fc99e Initial load
duke
parents:
diff changeset
63 private static int IN_JAVA_TRANS;
a61af66fc99e Initial load
duke
parents:
diff changeset
64 private static int BLOCKED;
a61af66fc99e Initial load
duke
parents:
diff changeset
65 private static int BLOCKED_TRANS;
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 static {
a61af66fc99e Initial load
duke
parents:
diff changeset
68 VM.registerVMInitializedObserver(new Observer() {
a61af66fc99e Initial load
duke
parents:
diff changeset
69 public void update(Observable o, Object data) {
a61af66fc99e Initial load
duke
parents:
diff changeset
70 initialize(VM.getVM().getTypeDataBase());
a61af66fc99e Initial load
duke
parents:
diff changeset
71 }
a61af66fc99e Initial load
duke
parents:
diff changeset
72 });
a61af66fc99e Initial load
duke
parents:
diff changeset
73 }
a61af66fc99e Initial load
duke
parents:
diff changeset
74
a61af66fc99e Initial load
duke
parents:
diff changeset
75 private static synchronized void initialize(TypeDataBase db) {
a61af66fc99e Initial load
duke
parents:
diff changeset
76 Type type = db.lookupType("JavaThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
77 Type anchorType = db.lookupType("JavaFrameAnchor");
a61af66fc99e Initial load
duke
parents:
diff changeset
78
a61af66fc99e Initial load
duke
parents:
diff changeset
79 nextField = type.getAddressField("_next");
a61af66fc99e Initial load
duke
parents:
diff changeset
80 threadObjField = type.getOopField("_threadObj");
a61af66fc99e Initial load
duke
parents:
diff changeset
81 anchorField = type.getAddressField("_anchor");
a61af66fc99e Initial load
duke
parents:
diff changeset
82 lastJavaSPField = anchorType.getAddressField("_last_Java_sp");
a61af66fc99e Initial load
duke
parents:
diff changeset
83 lastJavaPCField = anchorType.getAddressField("_last_Java_pc");
a61af66fc99e Initial load
duke
parents:
diff changeset
84 threadStateField = type.getCIntegerField("_thread_state");
a61af66fc99e Initial load
duke
parents:
diff changeset
85 osThreadField = type.getAddressField("_osthread");
a61af66fc99e Initial load
duke
parents:
diff changeset
86
a61af66fc99e Initial load
duke
parents:
diff changeset
87 UNINITIALIZED = db.lookupIntConstant("_thread_uninitialized").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
88 NEW = db.lookupIntConstant("_thread_new").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
89 NEW_TRANS = db.lookupIntConstant("_thread_new_trans").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
90 IN_NATIVE = db.lookupIntConstant("_thread_in_native").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
91 IN_NATIVE_TRANS = db.lookupIntConstant("_thread_in_native_trans").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
92 IN_VM = db.lookupIntConstant("_thread_in_vm").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
93 IN_VM_TRANS = db.lookupIntConstant("_thread_in_vm_trans").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
94 IN_JAVA = db.lookupIntConstant("_thread_in_Java").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
95 IN_JAVA_TRANS = db.lookupIntConstant("_thread_in_Java_trans").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
96 BLOCKED = db.lookupIntConstant("_thread_blocked").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
97 BLOCKED_TRANS = db.lookupIntConstant("_thread_blocked_trans").intValue();
a61af66fc99e Initial load
duke
parents:
diff changeset
98 }
a61af66fc99e Initial load
duke
parents:
diff changeset
99
a61af66fc99e Initial load
duke
parents:
diff changeset
100 public JavaThread(Address addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
101 super(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
103
a61af66fc99e Initial load
duke
parents:
diff changeset
104 void setThreadPDAccess(JavaThreadPDAccess access) {
a61af66fc99e Initial load
duke
parents:
diff changeset
105 this.access = access;
a61af66fc99e Initial load
duke
parents:
diff changeset
106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
107
a61af66fc99e Initial load
duke
parents:
diff changeset
108 public JavaThread next() {
a61af66fc99e Initial load
duke
parents:
diff changeset
109 Address threadAddr = nextField.getValue(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
110 if (threadAddr == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
111 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
112 }
a61af66fc99e Initial load
duke
parents:
diff changeset
113
a61af66fc99e Initial load
duke
parents:
diff changeset
114 return VM.getVM().getThreads().createJavaThreadWrapper(threadAddr);
a61af66fc99e Initial load
duke
parents:
diff changeset
115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
116
a61af66fc99e Initial load
duke
parents:
diff changeset
117 /** NOTE: for convenience, this differs in definition from the
a61af66fc99e Initial load
duke
parents:
diff changeset
118 underlying VM. Only "pure" JavaThreads return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
119 CompilerThreads and JVMDIDebuggerThreads return false. FIXME:
a61af66fc99e Initial load
duke
parents:
diff changeset
120 consider encapsulating platform-specific functionality in an
a61af66fc99e Initial load
duke
parents:
diff changeset
121 object instead of using inheritance (which is the primary reason
a61af66fc99e Initial load
duke
parents:
diff changeset
122 we can't traverse CompilerThreads, etc; didn't want to have, for
a61af66fc99e Initial load
duke
parents:
diff changeset
123 example, "SolarisSPARCCompilerThread".) */
a61af66fc99e Initial load
duke
parents:
diff changeset
124 public boolean isJavaThread() { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
125
a61af66fc99e Initial load
duke
parents:
diff changeset
126 public static AddressField getAnchorField() { return anchorField; }
a61af66fc99e Initial load
duke
parents:
diff changeset
127
a61af66fc99e Initial load
duke
parents:
diff changeset
128 /** Get the last Java stack pointer */
a61af66fc99e Initial load
duke
parents:
diff changeset
129 public Address getLastJavaSP() {
a61af66fc99e Initial load
duke
parents:
diff changeset
130 Address sp = lastJavaSPField.getValue(addr.addOffsetTo(anchorField.getOffset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
131 return sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
132 }
a61af66fc99e Initial load
duke
parents:
diff changeset
133
a61af66fc99e Initial load
duke
parents:
diff changeset
134 public Address getLastJavaPC() {
a61af66fc99e Initial load
duke
parents:
diff changeset
135 Address pc = lastJavaPCField.getValue(addr.addOffsetTo(anchorField.getOffset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
136 return pc;
a61af66fc99e Initial load
duke
parents:
diff changeset
137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 /** Abstract accessor to last Java frame pointer, implemented by
a61af66fc99e Initial load
duke
parents:
diff changeset
140 OS/CPU-specific JavaThread implementation. May return null if
a61af66fc99e Initial load
duke
parents:
diff changeset
141 there is no frame pointer or if it is not necessary on this
a61af66fc99e Initial load
duke
parents:
diff changeset
142 platform. */
a61af66fc99e Initial load
duke
parents:
diff changeset
143 public Address getLastJavaFP(){
a61af66fc99e Initial load
duke
parents:
diff changeset
144 return access.getLastJavaFP(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
146
a61af66fc99e Initial load
duke
parents:
diff changeset
147 /** Abstract accessor to last Java pc, implemented by
a61af66fc99e Initial load
duke
parents:
diff changeset
148 OS/CPU-specific JavaThread implementation. May return null if
a61af66fc99e Initial load
duke
parents:
diff changeset
149 there is no frame pointer or if it is not necessary on this
a61af66fc99e Initial load
duke
parents:
diff changeset
150 platform. */
a61af66fc99e Initial load
duke
parents:
diff changeset
151
a61af66fc99e Initial load
duke
parents:
diff changeset
152 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
153 public Address getLastJavaPC(){
a61af66fc99e Initial load
duke
parents:
diff changeset
154 return access.getLastJavaPC(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
156 */
a61af66fc99e Initial load
duke
parents:
diff changeset
157
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // FIXME: not yet implementable
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // public abstract void setLastJavaFP(Address fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161 /** A stack pointer older than any java frame stack pointer. Only
a61af66fc99e Initial load
duke
parents:
diff changeset
162 needed on some platforms; for example, see
a61af66fc99e Initial load
duke
parents:
diff changeset
163 thread_solaris_sparc.hpp. */
a61af66fc99e Initial load
duke
parents:
diff changeset
164 public Address getBaseOfStackPointer(){
a61af66fc99e Initial load
duke
parents:
diff changeset
165 return access.getBaseOfStackPointer(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
167 // FIXME: not yet implementable
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // public abstract void setBaseOfStackPointer(Address fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 /** Tells whether the last Java frame is set */
a61af66fc99e Initial load
duke
parents:
diff changeset
171 public boolean hasLastJavaFrame() {
a61af66fc99e Initial load
duke
parents:
diff changeset
172 return (getLastJavaSP() != null);
a61af66fc99e Initial load
duke
parents:
diff changeset
173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
174
a61af66fc99e Initial load
duke
parents:
diff changeset
175 /** Accessing frames */
a61af66fc99e Initial load
duke
parents:
diff changeset
176 public Frame getLastFrame() {
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // FIXME: would need to implement runtime routine
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // "cacheStatePD(boolean)" for reflective system to be able to
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // flush register windows on SPARC
a61af66fc99e Initial load
duke
parents:
diff changeset
180 return cookLastFrame(getLastFramePD());
a61af66fc99e Initial load
duke
parents:
diff changeset
181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
182
a61af66fc99e Initial load
duke
parents:
diff changeset
183 /** Internal routine implemented by platform-dependent subclasses */
a61af66fc99e Initial load
duke
parents:
diff changeset
184 protected Frame getLastFramePD(){
a61af66fc99e Initial load
duke
parents:
diff changeset
185 return access.getLastFramePD(this, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
187
a61af66fc99e Initial load
duke
parents:
diff changeset
188 /** Accessing frames. Returns the last Java VFrame or null if none
a61af66fc99e Initial load
duke
parents:
diff changeset
189 was present. (NOTE that this is mostly unusable in a debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
190 system; see getLastJavaVFrameDbg, below, which provides very
a61af66fc99e Initial load
duke
parents:
diff changeset
191 different functionality.) */
a61af66fc99e Initial load
duke
parents:
diff changeset
192 public JavaVFrame getLastJavaVFrame(RegisterMap regMap) {
a61af66fc99e Initial load
duke
parents:
diff changeset
193 if (Assert.ASSERTS_ENABLED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
194 Assert.that(regMap != null, "a map must be given");
a61af66fc99e Initial load
duke
parents:
diff changeset
195 }
a61af66fc99e Initial load
duke
parents:
diff changeset
196 Frame f = getLastFrame();
a61af66fc99e Initial load
duke
parents:
diff changeset
197 if (f == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
198 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
200 for (VFrame vf = VFrame.newVFrame(f, regMap, this); vf != null; vf = vf.sender()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
201 if (vf.isJavaFrame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
202 return (JavaVFrame) vf;
a61af66fc99e Initial load
duke
parents:
diff changeset
203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
205 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
206 }
a61af66fc99e Initial load
duke
parents:
diff changeset
207
a61af66fc99e Initial load
duke
parents:
diff changeset
208 /** This should only be used by a debugger. Uses the current frame
a61af66fc99e Initial load
duke
parents:
diff changeset
209 guess to attempt to get the topmost JavaVFrame.
a61af66fc99e Initial load
duke
parents:
diff changeset
210 (getLastJavaVFrame, as a port of the VM's routine, assumes the
a61af66fc99e Initial load
duke
parents:
diff changeset
211 VM is at a safepoint.) */
a61af66fc99e Initial load
duke
parents:
diff changeset
212 public JavaVFrame getLastJavaVFrameDbg() {
a61af66fc99e Initial load
duke
parents:
diff changeset
213 RegisterMap regMap = newRegisterMap(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
214 sun.jvm.hotspot.runtime.Frame f = getCurrentFrameGuess();
a61af66fc99e Initial load
duke
parents:
diff changeset
215 if (f == null) return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
216 boolean imprecise = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
217 if (f.isInterpretedFrame() && !f.isInterpretedFrameValid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
218 if (DEBUG) {
a61af66fc99e Initial load
duke
parents:
diff changeset
219 System.out.println("Correcting for invalid interpreter frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
221 f = f.sender(regMap);
a61af66fc99e Initial load
duke
parents:
diff changeset
222 imprecise = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
224 VFrame vf = VFrame.newVFrame(f, regMap, this, true, imprecise);
a61af66fc99e Initial load
duke
parents:
diff changeset
225 if (vf == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
226 if (DEBUG) {
a61af66fc99e Initial load
duke
parents:
diff changeset
227 System.out.println(" (Unable to create vframe for topmost frame guess)");
a61af66fc99e Initial load
duke
parents:
diff changeset
228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
229 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
231 if (vf.isJavaFrame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
232 return (JavaVFrame) vf;
a61af66fc99e Initial load
duke
parents:
diff changeset
233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
234 return (JavaVFrame) vf.javaSender();
a61af66fc99e Initial load
duke
parents:
diff changeset
235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
236
a61af66fc99e Initial load
duke
parents:
diff changeset
237 /** In this system, a JavaThread is the top-level factory for a
a61af66fc99e Initial load
duke
parents:
diff changeset
238 RegisterMap, since the JavaThread implementation is already
a61af66fc99e Initial load
duke
parents:
diff changeset
239 platform-specific and RegisterMap is also necessarily
a61af66fc99e Initial load
duke
parents:
diff changeset
240 platform-specific. The updateMap argument indicates whether the
a61af66fc99e Initial load
duke
parents:
diff changeset
241 register map needs to be updated, for example during stack
a61af66fc99e Initial load
duke
parents:
diff changeset
242 traversal -- see frame.hpp. */
a61af66fc99e Initial load
duke
parents:
diff changeset
243 public RegisterMap newRegisterMap(boolean updateMap){
a61af66fc99e Initial load
duke
parents:
diff changeset
244 return access.newRegisterMap(this, updateMap);
a61af66fc99e Initial load
duke
parents:
diff changeset
245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
246
a61af66fc99e Initial load
duke
parents:
diff changeset
247 /** This is only designed to be used by the debugging system.
a61af66fc99e Initial load
duke
parents:
diff changeset
248 Returns a "best guess" of the topmost frame on the stack. This
a61af66fc99e Initial load
duke
parents:
diff changeset
249 guess should be as "raw" as possible. For example, if the
a61af66fc99e Initial load
duke
parents:
diff changeset
250 topmost frame is an interpreter frame (the return PC is in the
a61af66fc99e Initial load
duke
parents:
diff changeset
251 interpreter) but is not a valid frame (i.e., the BCI has not yet
a61af66fc99e Initial load
duke
parents:
diff changeset
252 been set up) this should still return the topmost frame and not
a61af66fc99e Initial load
duke
parents:
diff changeset
253 the sender. Validity checks are done at higher levels. */
a61af66fc99e Initial load
duke
parents:
diff changeset
254 public Frame getCurrentFrameGuess(){
a61af66fc99e Initial load
duke
parents:
diff changeset
255 return access.getCurrentFrameGuess(this, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
257
a61af66fc99e Initial load
duke
parents:
diff changeset
258 /** Also only intended for use by the debugging system. Provides the
a61af66fc99e Initial load
duke
parents:
diff changeset
259 same effect of OSThread::print(); that is, prints a value which
a61af66fc99e Initial load
duke
parents:
diff changeset
260 allows the user to intuitively understand which native OS thread
a61af66fc99e Initial load
duke
parents:
diff changeset
261 maps to this Java thread. Does not print a newline or leading or
a61af66fc99e Initial load
duke
parents:
diff changeset
262 trailing spaces. */
a61af66fc99e Initial load
duke
parents:
diff changeset
263 public void printThreadIDOn(PrintStream tty) {
a61af66fc99e Initial load
duke
parents:
diff changeset
264 access.printThreadIDOn(addr,tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
265 }
a61af66fc99e Initial load
duke
parents:
diff changeset
266
a61af66fc99e Initial load
duke
parents:
diff changeset
267 public void printThreadID() {
a61af66fc99e Initial load
duke
parents:
diff changeset
268 printThreadIDOn(System.out);
a61af66fc99e Initial load
duke
parents:
diff changeset
269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
270
a61af66fc99e Initial load
duke
parents:
diff changeset
271 public ThreadProxy getThreadProxy() {
a61af66fc99e Initial load
duke
parents:
diff changeset
272 return access.getThreadProxy(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
273 }
a61af66fc99e Initial load
duke
parents:
diff changeset
274
a61af66fc99e Initial load
duke
parents:
diff changeset
275 //
a61af66fc99e Initial load
duke
parents:
diff changeset
276 // Safepoint support
a61af66fc99e Initial load
duke
parents:
diff changeset
277 //
a61af66fc99e Initial load
duke
parents:
diff changeset
278
a61af66fc99e Initial load
duke
parents:
diff changeset
279 public JavaThreadState getThreadState() {
a61af66fc99e Initial load
duke
parents:
diff changeset
280 int val = (int) threadStateField.getValue(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
281 if (val == UNINITIALIZED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
282 return JavaThreadState.UNINITIALIZED;
a61af66fc99e Initial load
duke
parents:
diff changeset
283 } else if (val == NEW) {
a61af66fc99e Initial load
duke
parents:
diff changeset
284 return JavaThreadState.NEW;
a61af66fc99e Initial load
duke
parents:
diff changeset
285 } else if (val == NEW_TRANS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
286 return JavaThreadState.NEW_TRANS;
a61af66fc99e Initial load
duke
parents:
diff changeset
287 } else if (val == IN_NATIVE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
288 return JavaThreadState.IN_NATIVE;
a61af66fc99e Initial load
duke
parents:
diff changeset
289 } else if (val == IN_NATIVE_TRANS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
290 return JavaThreadState.IN_NATIVE_TRANS;
a61af66fc99e Initial load
duke
parents:
diff changeset
291 } else if (val == IN_VM) {
a61af66fc99e Initial load
duke
parents:
diff changeset
292 return JavaThreadState.IN_VM;
a61af66fc99e Initial load
duke
parents:
diff changeset
293 } else if (val == IN_VM_TRANS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
294 return JavaThreadState.IN_VM_TRANS;
a61af66fc99e Initial load
duke
parents:
diff changeset
295 } else if (val == IN_JAVA) {
a61af66fc99e Initial load
duke
parents:
diff changeset
296 return JavaThreadState.IN_JAVA;
a61af66fc99e Initial load
duke
parents:
diff changeset
297 } else if (val == IN_JAVA_TRANS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
298 return JavaThreadState.IN_JAVA_TRANS;
a61af66fc99e Initial load
duke
parents:
diff changeset
299 } else if (val == BLOCKED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
300 return JavaThreadState.BLOCKED;
a61af66fc99e Initial load
duke
parents:
diff changeset
301 } else if (val == BLOCKED_TRANS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
302 return JavaThreadState.BLOCKED_TRANS;
a61af66fc99e Initial load
duke
parents:
diff changeset
303 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
304 throw new RuntimeException("Illegal thread state " + val);
a61af66fc99e Initial load
duke
parents:
diff changeset
305 }
a61af66fc99e Initial load
duke
parents:
diff changeset
306 }
a61af66fc99e Initial load
duke
parents:
diff changeset
307 // FIXME: not yet implementable
a61af66fc99e Initial load
duke
parents:
diff changeset
308 // public void setThreadState(JavaThreadState s);
a61af66fc99e Initial load
duke
parents:
diff changeset
309
a61af66fc99e Initial load
duke
parents:
diff changeset
310 //
a61af66fc99e Initial load
duke
parents:
diff changeset
311 // Miscellaneous operations
a61af66fc99e Initial load
duke
parents:
diff changeset
312 //
a61af66fc99e Initial load
duke
parents:
diff changeset
313
a61af66fc99e Initial load
duke
parents:
diff changeset
314 public OSThread getOSThread() {
a61af66fc99e Initial load
duke
parents:
diff changeset
315 return (OSThread) VMObjectFactory.newObject(OSThread.class, osThreadField.getValue(addr));
a61af66fc99e Initial load
duke
parents:
diff changeset
316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
317
a61af66fc99e Initial load
duke
parents:
diff changeset
318 /** Gets the Java-side thread object for this JavaThread */
a61af66fc99e Initial load
duke
parents:
diff changeset
319 public Oop getThreadObj() {
a61af66fc99e Initial load
duke
parents:
diff changeset
320 return VM.getVM().getObjectHeap().newOop(threadObjField.getValue(addr));
a61af66fc99e Initial load
duke
parents:
diff changeset
321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
322
a61af66fc99e Initial load
duke
parents:
diff changeset
323 /** Get the Java-side name of this thread */
a61af66fc99e Initial load
duke
parents:
diff changeset
324 public String getThreadName() {
a61af66fc99e Initial load
duke
parents:
diff changeset
325 Oop threadObj = getThreadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
326 if (threadObj == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
327 return "<null>";
a61af66fc99e Initial load
duke
parents:
diff changeset
328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
329 return OopUtilities.threadOopGetName(threadObj);
a61af66fc99e Initial load
duke
parents:
diff changeset
330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
331
a61af66fc99e Initial load
duke
parents:
diff changeset
332 //
a61af66fc99e Initial load
duke
parents:
diff changeset
333 // Oop traversal
a61af66fc99e Initial load
duke
parents:
diff changeset
334 //
a61af66fc99e Initial load
duke
parents:
diff changeset
335
a61af66fc99e Initial load
duke
parents:
diff changeset
336 public void oopsDo(AddressVisitor oopVisitor) {
a61af66fc99e Initial load
duke
parents:
diff changeset
337 super.oopsDo(oopVisitor);
a61af66fc99e Initial load
duke
parents:
diff changeset
338
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // FIXME: add in the rest of the routine from the VM
a61af66fc99e Initial load
duke
parents:
diff changeset
340
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // Traverse the execution stack
a61af66fc99e Initial load
duke
parents:
diff changeset
342 for(StackFrameStream fst = new StackFrameStream(this); !fst.isDone(); fst.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
343 fst.getCurrent().oopsDo(oopVisitor, fst.getRegisterMap());
a61af66fc99e Initial load
duke
parents:
diff changeset
344 }
a61af66fc99e Initial load
duke
parents:
diff changeset
345 }
a61af66fc99e Initial load
duke
parents:
diff changeset
346
a61af66fc99e Initial load
duke
parents:
diff changeset
347 public boolean isInStack(Address a) {
a61af66fc99e Initial load
duke
parents:
diff changeset
348 if (Assert.ASSERTS_ENABLED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
349 Assert.that(VM.getVM().isDebugging(), "Not yet implemented for non-debugging system");
a61af66fc99e Initial load
duke
parents:
diff changeset
350 }
a61af66fc99e Initial load
duke
parents:
diff changeset
351 Address highest = highestLock();
a61af66fc99e Initial load
duke
parents:
diff changeset
352 Address sp = lastSPDbg();
a61af66fc99e Initial load
duke
parents:
diff changeset
353 // Be robust
a61af66fc99e Initial load
duke
parents:
diff changeset
354 if ((highest == null) || (sp == null)) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
355 return (highest.greaterThanOrEqual(a) && sp.lessThanOrEqual(a));
a61af66fc99e Initial load
duke
parents:
diff changeset
356
a61af66fc99e Initial load
duke
parents:
diff changeset
357 // FIXME: should traverse MonitorArray/MonitorChunks as in VM
a61af66fc99e Initial load
duke
parents:
diff changeset
358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
359
a61af66fc99e Initial load
duke
parents:
diff changeset
360 public Oop getCurrentParkBlocker() {
a61af66fc99e Initial load
duke
parents:
diff changeset
361 Oop threadObj = getThreadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
362 if (threadObj != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
363 return OopUtilities.threadOopGetParkBlocker(threadObj);
a61af66fc99e Initial load
duke
parents:
diff changeset
364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
365 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
366 }
a61af66fc99e Initial load
duke
parents:
diff changeset
367
a61af66fc99e Initial load
duke
parents:
diff changeset
368 public void printInfoOn(PrintStream tty) {
a61af66fc99e Initial load
duke
parents:
diff changeset
369
a61af66fc99e Initial load
duke
parents:
diff changeset
370 tty.println("State: " + getThreadState().toString());
a61af66fc99e Initial load
duke
parents:
diff changeset
371 // Attempt to figure out the addresses covered by Java frames.
a61af66fc99e Initial load
duke
parents:
diff changeset
372 // NOTE: we should make this a method and let the Stackwalk panel use the result too.
a61af66fc99e Initial load
duke
parents:
diff changeset
373 //
a61af66fc99e Initial load
duke
parents:
diff changeset
374 sun.jvm.hotspot.runtime.Frame tmpFrame = getCurrentFrameGuess();
a61af66fc99e Initial load
duke
parents:
diff changeset
375 if (tmpFrame != null ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
376 Address sp = tmpFrame.getSP();
a61af66fc99e Initial load
duke
parents:
diff changeset
377 Address maxSP = sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
378 Address minSP = sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
379 RegisterMap tmpMap = newRegisterMap(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
380 while ((tmpFrame != null) && (!tmpFrame.isFirstFrame())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
381 tmpFrame = tmpFrame.sender(tmpMap);
a61af66fc99e Initial load
duke
parents:
diff changeset
382 if (tmpFrame != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
383 sp = tmpFrame.getSP();
a61af66fc99e Initial load
duke
parents:
diff changeset
384 maxSP = AddressOps.max(maxSP, sp);
a61af66fc99e Initial load
duke
parents:
diff changeset
385 minSP = AddressOps.min(minSP, sp);
a61af66fc99e Initial load
duke
parents:
diff changeset
386 }
a61af66fc99e Initial load
duke
parents:
diff changeset
387 }
a61af66fc99e Initial load
duke
parents:
diff changeset
388 tty.println("Stack in use by Java: " + minSP + " .. " + maxSP);
a61af66fc99e Initial load
duke
parents:
diff changeset
389 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
390 tty.println("No Java frames present");
a61af66fc99e Initial load
duke
parents:
diff changeset
391 }
a61af66fc99e Initial load
duke
parents:
diff changeset
392 tty.println("Base of Stack: " + getBaseOfStackPointer());
a61af66fc99e Initial load
duke
parents:
diff changeset
393 tty.println("Last_Java_SP: " + getLastJavaSP());
a61af66fc99e Initial load
duke
parents:
diff changeset
394 tty.println("Last_Java_FP: " + getLastJavaFP());
a61af66fc99e Initial load
duke
parents:
diff changeset
395 tty.println("Last_Java_PC: " + getLastJavaPC());
a61af66fc99e Initial load
duke
parents:
diff changeset
396 // More stuff like saved_execption_pc, safepoint_state, ...
a61af66fc99e Initial load
duke
parents:
diff changeset
397 access.printInfoOn(addr, tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
398
a61af66fc99e Initial load
duke
parents:
diff changeset
399 }
a61af66fc99e Initial load
duke
parents:
diff changeset
400
a61af66fc99e Initial load
duke
parents:
diff changeset
401 ///////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
402 // //
a61af66fc99e Initial load
duke
parents:
diff changeset
403 // FIXME: add more accessors //
a61af66fc99e Initial load
duke
parents:
diff changeset
404 // //
a61af66fc99e Initial load
duke
parents:
diff changeset
405 ///////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
406
a61af66fc99e Initial load
duke
parents:
diff changeset
407 //--------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
408 // Internals only below this point
a61af66fc99e Initial load
duke
parents:
diff changeset
409 //
a61af66fc99e Initial load
duke
parents:
diff changeset
410
a61af66fc99e Initial load
duke
parents:
diff changeset
411 private Frame cookLastFrame(Frame fr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
412 if (fr == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
413 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
414 }
a61af66fc99e Initial load
duke
parents:
diff changeset
415
a61af66fc99e Initial load
duke
parents:
diff changeset
416 Address pc = fr.getPC();
a61af66fc99e Initial load
duke
parents:
diff changeset
417
a61af66fc99e Initial load
duke
parents:
diff changeset
418 if (Assert.ASSERTS_ENABLED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
419 if (pc == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
420 Assert.that(VM.getVM().isDebugging(), "must have PC");
a61af66fc99e Initial load
duke
parents:
diff changeset
421 }
a61af66fc99e Initial load
duke
parents:
diff changeset
422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
423 return fr;
a61af66fc99e Initial load
duke
parents:
diff changeset
424 }
a61af66fc99e Initial load
duke
parents:
diff changeset
425
a61af66fc99e Initial load
duke
parents:
diff changeset
426 private Address lastSPDbg() {
a61af66fc99e Initial load
duke
parents:
diff changeset
427 return access.getLastSP(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
429
a61af66fc99e Initial load
duke
parents:
diff changeset
430 }