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