Mercurial > hg > truffle
annotate agent/src/share/classes/sun/jvm/hotspot/runtime/DeadlockDetector.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 | c18cbe5936b8 |
children |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
2 * Copyright (c) 2004, 2006, 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:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
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:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 package sun.jvm.hotspot.runtime; | |
26 | |
27 import sun.jvm.hotspot.debugger.*; | |
28 import sun.jvm.hotspot.memory.*; | |
29 import sun.jvm.hotspot.oops.*; | |
30 import java.io.*; | |
31 import java.util.*; | |
32 import java.util.Map.Entry; | |
33 | |
34 /** Prints information about Java-level deadlocks in supplied 'tty'. */ | |
35 | |
36 public class DeadlockDetector { | |
37 | |
38 public static void print(PrintStream tty) { | |
39 print(tty, true); | |
40 } | |
41 | |
42 /** prints zero or more deadlocks into 'tty' taking current | |
43 snapshot of Java threads and locks */ | |
44 public static void print(PrintStream tty, boolean concurrentLocks) { | |
45 tty.println("Deadlock Detection:"); | |
46 tty.println(); | |
47 | |
48 int globalDfn = 0, thisDfn; | |
49 int numberOfDeadlocks = 0; | |
50 JavaThread currentThread = null, previousThread = null; | |
51 ObjectMonitor waitingToLockMonitor = null; | |
52 Oop waitingToLockBlocker = null; | |
53 | |
54 threads = VM.getVM().getThreads(); | |
55 heap = VM.getVM().getObjectHeap(); | |
56 createThreadTable(); | |
57 | |
58 Iterator i = threadTable.entrySet().iterator(); | |
59 while (i.hasNext()) { | |
60 Entry e = (Entry)i.next(); | |
61 if (dfn(e) >= 0) { | |
62 // this thread was already visited | |
63 continue; | |
64 } | |
65 | |
66 thisDfn = globalDfn; | |
67 JavaThread thread = (JavaThread)e.getKey(); | |
68 previousThread = thread; | |
69 | |
70 // When there is a deadlock, all the monitors involved in the dependency | |
71 // cycle must be contended and heavyweight. So we only care about the | |
72 // heavyweight monitor a thread is waiting to lock. | |
73 try { | |
74 waitingToLockMonitor = thread.getCurrentPendingMonitor(); | |
75 } catch (RuntimeException re) { | |
76 tty.println("This version of HotSpot VM doesn't support deadlock detection."); | |
77 return; | |
78 } | |
79 | |
80 Klass abstractOwnableSyncKlass = null; | |
81 if (concurrentLocks) { | |
82 waitingToLockBlocker = thread.getCurrentParkBlocker(); | |
83 SystemDictionary sysDict = VM.getVM().getSystemDictionary(); | |
84 abstractOwnableSyncKlass = sysDict.getAbstractOwnableSynchronizerKlass(); | |
85 } | |
86 | |
87 while (waitingToLockMonitor != null || | |
88 waitingToLockBlocker != null) { | |
89 if (waitingToLockMonitor != null) { | |
90 currentThread = threads.owningThreadFromMonitor(waitingToLockMonitor); | |
91 } else { | |
92 if (concurrentLocks) { | |
93 if (waitingToLockBlocker.isA(abstractOwnableSyncKlass)) { | |
94 Oop threadOop = OopUtilities.abstractOwnableSynchronizerGetOwnerThread(waitingToLockBlocker); | |
95 if (threadOop != null) { | |
96 currentThread = OopUtilities.threadOopGetJavaThread(threadOop); | |
97 } | |
98 } | |
99 } | |
100 } | |
101 if (currentThread == null) { | |
102 // No dependency on another thread | |
103 break; | |
104 } | |
105 if (dfn(currentThread) < 0) { | |
106 // First visit to this thread | |
107 threadTable.put(currentThread, new Integer(globalDfn++)); | |
108 } else if (dfn(currentThread) < thisDfn) { | |
109 // Thread already visited, and not on a (new) cycle | |
110 break; | |
111 } else if (currentThread == previousThread) { | |
112 // Self-loop, ignore | |
113 break; | |
114 } else { | |
115 // We have a (new) cycle | |
116 numberOfDeadlocks ++; | |
117 printOneDeadlock(tty, currentThread, concurrentLocks); | |
118 break; | |
119 } | |
120 previousThread = currentThread; | |
121 waitingToLockMonitor = (ObjectMonitor)currentThread.getCurrentPendingMonitor(); | |
122 if (concurrentLocks) { | |
123 waitingToLockBlocker = currentThread.getCurrentParkBlocker(); | |
124 } | |
125 } | |
126 } | |
127 | |
128 switch (numberOfDeadlocks) { | |
129 case 0: | |
130 tty.println("No deadlocks found."); | |
131 break; | |
132 case 1: | |
133 tty.println("Found a total of 1 deadlock."); | |
134 break; | |
135 default: | |
136 tty.println("Found a total of " + numberOfDeadlocks + " deadlocks."); | |
137 break; | |
138 } | |
139 tty.println(); | |
140 } | |
141 | |
142 //-- Internals only below this point | |
143 private static Threads threads; | |
144 private static ObjectHeap heap; | |
145 private static HashMap threadTable; | |
146 | |
147 private static void createThreadTable() { | |
148 threadTable = new HashMap(); | |
149 for (JavaThread cur = threads.first(); cur != null; cur = cur.next()) { | |
150 // initialize dfn for each thread to -1 | |
151 threadTable.put(cur, new Integer(-1)); | |
152 } | |
153 } | |
154 | |
155 private static int dfn(JavaThread thread) { | |
156 Object obj = threadTable.get(thread); | |
157 if (obj != null) { | |
158 return ((Integer)obj).intValue(); | |
159 } | |
160 return -1; | |
161 } | |
162 | |
163 private static int dfn(Entry e) { | |
164 return ((Integer)e.getValue()).intValue(); | |
165 } | |
166 | |
167 private static void printOneDeadlock(PrintStream tty, JavaThread thread, | |
168 boolean concurrentLocks) { | |
169 tty.println("Found one Java-level deadlock:"); | |
170 tty.println("============================="); | |
171 ObjectMonitor waitingToLockMonitor = null; | |
172 Oop waitingToLockBlocker = null; | |
173 JavaThread currentThread = thread; | |
174 do { | |
175 tty.println(); | |
176 tty.println("\"" + currentThread.getThreadName() + "\":"); | |
177 waitingToLockMonitor = currentThread.getCurrentPendingMonitor(); | |
178 if (waitingToLockMonitor != null) { | |
179 tty.print(" waiting to lock Monitor@" + waitingToLockMonitor.getAddress()); | |
180 OopHandle obj = waitingToLockMonitor.object(); | |
181 Oop oop = heap.newOop(obj); | |
182 if (obj != null) { | |
183 tty.print(" (Object@"); | |
184 Oop.printOopAddressOn(oop, tty); | |
185 tty.print(", a " + oop.getKlass().getName().asString() + ")" ); | |
186 tty.print(",\n which is held by"); | |
187 } else { | |
188 // No Java object associated - a raw monitor | |
189 tty.print(" (raw monitor),\n which is held by"); | |
190 } | |
191 currentThread = threads.owningThreadFromMonitor(waitingToLockMonitor); | |
192 tty.print(" \"" + currentThread.getThreadName() + "\""); | |
193 } else if (concurrentLocks) { | |
194 waitingToLockBlocker = currentThread.getCurrentParkBlocker(); | |
195 tty.print(" waiting for ownable synchronizer "); | |
196 Oop.printOopAddressOn(waitingToLockBlocker, tty); | |
197 tty.print(", (a " + waitingToLockBlocker.getKlass().getName().asString() + ")" ); | |
198 Oop threadOop = OopUtilities.abstractOwnableSynchronizerGetOwnerThread(waitingToLockBlocker); | |
199 currentThread = OopUtilities.threadOopGetJavaThread(threadOop); | |
200 tty.print(",\n which is held by"); | |
201 tty.print(" \"" + currentThread.getThreadName() + "\""); | |
202 } | |
203 } while (!currentThread.equals(thread)); | |
204 tty.println(); | |
205 tty.println(); | |
206 } | |
207 } |