1 /*
2 * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
195 JavaThread thread = (JavaThread)virtualConstructor.instantiateWrapperFor(threadAddr);
196 thread.setThreadPDAccess(access);
197 return thread;
198 } catch (Exception e) {
199 throw new RuntimeException("Unable to deduce type of thread from address " + threadAddr +
200 " (expected type JavaThread, CompilerThread, MonitorDeflationThread, AttachListenerThread," +
201 " StringDedupThread, NotificationThread, ServiceThread or JvmtiAgentThread)", e);
202 }
203 }
204
205 /** Memory operations */
206 public void oopsDo(AddressVisitor oopVisitor) {
207 // FIXME: add more of VM functionality
208 Threads threads = VM.getVM().getThreads();
209 for (int i = 0; i < threads.getNumberOfThreads(); i++) {
210 JavaThread thread = threads.getJavaThreadAt(i);
211 thread.oopsDo(oopVisitor);
212 }
213 }
214
215 // refer to Threads::owning_thread_from_monitor_owner
216 public JavaThread owningThreadFromMonitor(Address o) {
217 assert(VM.getVM().getCommandLineFlag("LockingMode").getInt() != LockingMode.getLightweight());
218 if (o == null) return null;
219 for (int i = 0; i < getNumberOfThreads(); i++) {
220 JavaThread thread = getJavaThreadAt(i);
221 if (o.equals(thread.threadObjectAddress())) {
222 return thread;
223 }
224 }
225
226 for (int i = 0; i < getNumberOfThreads(); i++) {
227 JavaThread thread = getJavaThreadAt(i);
228 if (thread.isLockOwned(o))
229 return thread;
230 }
231 return null;
232 }
233
234 public JavaThread owningThreadFromMonitor(ObjectMonitor monitor) {
235 if (VM.getVM().getCommandLineFlag("LockingMode").getInt() == LockingMode.getLightweight()) {
236 if (monitor.isOwnedAnonymous()) {
237 OopHandle object = monitor.object();
238 for (int i = 0; i < getNumberOfThreads(); i++) {
239 JavaThread thread = getJavaThreadAt(i);
240 if (thread.isLockOwned(object)) {
241 return thread;
242 }
243 }
244 // We should have found the owner, however, as the VM could be in any state, including the middle
245 // of performing GC, it is not always possible to do so. Just return null if we can't locate it.
246 System.out.println("Warning: We failed to find a thread that owns an anonymous lock. This is likely");
247 System.out.println("due to the JVM currently running a GC. Locking information may not be accurate.");
248 return null;
249 }
250 // Owner can only be threads at this point.
251 Address o = monitor.owner();
252 if (o == null) return null;
253 return new JavaThread(o);
254 } else {
255 return owningThreadFromMonitor(monitor.owner());
256 }
257 }
258
259 // refer to Threads::get_pending_threads
260 // Get list of Java threads that are waiting to enter the specified monitor.
261 public List<JavaThread> getPendingThreads(ObjectMonitor monitor) {
262 List<JavaThread> pendingThreads = new ArrayList<>();
263 for (int i = 0; i < getNumberOfThreads(); i++) {
264 JavaThread thread = getJavaThreadAt(i);
265 if (thread.isCompilerThread() || thread.isCodeCacheSweeperThread()) {
266 continue;
267 }
268 ObjectMonitor pending = thread.getCurrentPendingMonitor();
269 if (monitor.equals(pending)) {
270 pendingThreads.add(thread);
271 }
272 }
273 return pendingThreads;
|
1 /*
2 * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
195 JavaThread thread = (JavaThread)virtualConstructor.instantiateWrapperFor(threadAddr);
196 thread.setThreadPDAccess(access);
197 return thread;
198 } catch (Exception e) {
199 throw new RuntimeException("Unable to deduce type of thread from address " + threadAddr +
200 " (expected type JavaThread, CompilerThread, MonitorDeflationThread, AttachListenerThread," +
201 " StringDedupThread, NotificationThread, ServiceThread or JvmtiAgentThread)", e);
202 }
203 }
204
205 /** Memory operations */
206 public void oopsDo(AddressVisitor oopVisitor) {
207 // FIXME: add more of VM functionality
208 Threads threads = VM.getVM().getThreads();
209 for (int i = 0; i < threads.getNumberOfThreads(); i++) {
210 JavaThread thread = threads.getJavaThreadAt(i);
211 thread.oopsDo(oopVisitor);
212 }
213 }
214
215 private JavaThread owningThreadFromMonitor(Address o) {
216 if (o == null) return null;
217 for (int i = 0; i < getNumberOfThreads(); i++) {
218 JavaThread thread = getJavaThreadAt(i);
219 if (o.equals(thread.getLockId())) {
220 return thread;
221 }
222 }
223 return null;
224 }
225
226 public JavaThread owningThreadFromMonitor(ObjectMonitor monitor) {
227 if (monitor.isOwnedAnonymous()) {
228 if (VM.getVM().getCommandLineFlag("LockingMode").getInt() == LockingMode.getLightweight()) {
229 OopHandle object = monitor.object();
230 for (int i = 0; i < getNumberOfThreads(); i++) {
231 JavaThread thread = getJavaThreadAt(i);
232 if (thread.isLockOwned(object)) {
233 return thread;
234 }
235 }
236 // We should have found the owner, however, as the VM could be in any state, including the middle
237 // of performing GC, it is not always possible to do so. Just return null if we can't locate it.
238 System.out.println("Warning: We failed to find a thread that owns an anonymous lock. This is likely");
239 System.out.println("due to the JVM currently running a GC. Locking information may not be accurate.");
240 return null;
241 } else {
242 assert(VM.getVM().getCommandLineFlag("LockingMode").getInt() == LockingMode.getLegacy());
243 Address o = (Address)monitor.stackLocker();
244 for (int i = 0; i < getNumberOfThreads(); i++) {
245 JavaThread thread = getJavaThreadAt(i);
246 if (thread.isLockOwned(o))
247 return thread;
248 }
249 return null;
250 }
251 } else {
252 return owningThreadFromMonitor(monitor.owner());
253 }
254 }
255
256 // refer to Threads::get_pending_threads
257 // Get list of Java threads that are waiting to enter the specified monitor.
258 public List<JavaThread> getPendingThreads(ObjectMonitor monitor) {
259 List<JavaThread> pendingThreads = new ArrayList<>();
260 for (int i = 0; i < getNumberOfThreads(); i++) {
261 JavaThread thread = getJavaThreadAt(i);
262 if (thread.isCompilerThread() || thread.isCodeCacheSweeperThread()) {
263 continue;
264 }
265 ObjectMonitor pending = thread.getCurrentPendingMonitor();
266 if (monitor.equals(pending)) {
267 pendingThreads.add(thread);
268 }
269 }
270 return pendingThreads;
|