1 /* 2 * Copyright 2000-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20 * CA 95054 USA or visit www.sun.com if you need additional information or 21 * have any questions. 22 * 23 */ 24 25 package sun.jvm.hotspot.runtime; 26 27 import java.util.*; 28 import sun.jvm.hotspot.debugger.*; 29 import sun.jvm.hotspot.types.*; 30 31 public class Thread extends VMObject { 32 private static long tlabFieldOffset; 33 34 private static CIntegerField suspendFlagsField; 35 // Thread::SuspendFlags enum constants 36 private static int EXTERNAL_SUSPEND; 37 private static int EXT_SUSPENDED; 38 private static int HAS_ASYNC_EXCEPTION; 39 40 private static AddressField activeHandlesField; 41 private static AddressField highestLockField; 42 private static AddressField currentPendingMonitorField; 43 private static AddressField currentWaitingMonitorField; 44 45 static { 46 VM.registerVMInitializedObserver(new Observer() { 47 public void update(Observable o, Object data) { 48 initialize(VM.getVM().getTypeDataBase()); 49 } 50 }); 51 } 52 53 private static synchronized void initialize(TypeDataBase db) { 54 Type type = db.lookupType("Thread"); 55 56 suspendFlagsField = type.getCIntegerField("_suspend_flags"); 57 EXTERNAL_SUSPEND = db.lookupIntConstant("Thread::_external_suspend").intValue(); 58 EXT_SUSPENDED = db.lookupIntConstant("Thread::_ext_suspended").intValue(); 59 HAS_ASYNC_EXCEPTION = db.lookupIntConstant("Thread::_has_async_exception").intValue(); 60 61 tlabFieldOffset = type.getField("_tlab").getOffset(); 62 activeHandlesField = type.getAddressField("_active_handles"); 63 highestLockField = type.getAddressField("_highest_lock"); 64 currentPendingMonitorField = type.getAddressField("_current_pending_monitor"); 65 currentWaitingMonitorField = type.getAddressField("_current_waiting_monitor"); 66 } 67 68 public Thread(Address addr) { 69 super(addr); 70 } 71 72 public int suspendFlags() { 73 return (int) suspendFlagsField.getValue(addr); 74 } 75 76 public boolean isExternalSuspend() { 77 return (suspendFlags() & EXTERNAL_SUSPEND) != 0; 78 } 79 80 public boolean isExtSuspended() { 81 return (suspendFlags() & EXT_SUSPENDED) != 0; 82 } 83 84 public boolean isBeingExtSuspended() { 85 return isExtSuspended() || isExternalSuspend(); 86 } 87 88 // historical usage: checked for VM or external suspension 89 public boolean isAnySuspended() { 90 return isExtSuspended(); 91 } 92 93 public boolean hasAsyncException() { 94 return (suspendFlags() & HAS_ASYNC_EXCEPTION) != 0; 95 } 96 97 public ThreadLocalAllocBuffer tlab() { 98 return new ThreadLocalAllocBuffer(addr.addOffsetTo(tlabFieldOffset)); 99 } 100 101 public JNIHandleBlock activeHandles() { 102 Address a = activeHandlesField.getAddress(addr); 103 if (a == null) { 104 return null; 105 } 106 return new JNIHandleBlock(a); 107 } 108 109 public boolean isVMThread() { return false; } 110 public boolean isJavaThread() { return false; } 111 public boolean isCompilerThread() { return false; } 112 public boolean isHiddenFromExternalView() { return false; } 113 public boolean isJvmtiAgentThread() { return false; } 114 public boolean isWatcherThread() { return false; } 115 public boolean isConcurrentMarkSweepThread() { return false; } 116 public boolean isLowMemoryDetectorThread() { return false; } 117 118 /** Memory operations */ 119 public void oopsDo(AddressVisitor oopVisitor) { 120 // FIXME: Empty for now; will later traverse JNI handles and 121 // pending exception 122 } 123 124 public Address highestLock() { 125 return highestLockField.getValue(addr); 126 } 127 128 public ObjectMonitor getCurrentPendingMonitor() { 129 Address monitorAddr = currentPendingMonitorField.getValue(addr); 130 if (monitorAddr == null) { 131 return null; 132 } 133 return new ObjectMonitor(monitorAddr); 134 } 135 136 public ObjectMonitor getCurrentWaitingMonitor() { 137 Address monitorAddr = currentWaitingMonitorField.getValue(addr); 138 if (monitorAddr == null) { 139 return null; 140 } 141 return new ObjectMonitor(monitorAddr); 142 } 143 144 public boolean isLockOwned(Address lock) { 145 if (isInStack(lock)) return true; 146 return false; 147 } 148 149 public boolean isInStack(Address a) { 150 // In the Serviceability Agent we need access to the thread's 151 // stack pointer to be able to answer this question. Since it is 152 // only a debugging system at the moment we need access to the 153 // underlying thread, which is only present for Java threads; see 154 // JavaThread.java. 155 return false; 156 } 157 158 /** Assistance for ObjectMonitor implementation */ 159 Address threadObjectAddress() { return addr; } 160 }