1 /*
  2  * Copyright (c) 2000, 2021, 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  *
 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 import sun.jvm.hotspot.utilities.Observable;
 31 import sun.jvm.hotspot.utilities.Observer;
 32 
 33 public class Thread extends VMObject {
 34   private static long tlabFieldOffset;
 35 
 36   private static CIntegerField suspendFlagsField;
 37 
 38   private static AddressField currentPendingMonitorField;
 39   private static AddressField currentWaitingMonitorField;
 40 
 41   private static JLongField allocatedBytesField;
 42 
 43   static {
 44     VM.registerVMInitializedObserver(new Observer() {
 45         public void update(Observable o, Object data) {
 46           initialize(VM.getVM().getTypeDataBase());
 47         }
 48       });
 49   }
 50 
 51   private static synchronized void initialize(TypeDataBase db) {
 52     Type typeThread = db.lookupType("Thread");
 53     Type typeJavaThread = db.lookupType("JavaThread");
 54 
 55     suspendFlagsField = typeJavaThread.getCIntegerField("_suspend_flags");
 56 
 57     tlabFieldOffset    = typeThread.getField("_tlab").getOffset();
 58     currentPendingMonitorField = typeJavaThread.getAddressField("_current_pending_monitor");
 59     currentWaitingMonitorField = typeJavaThread.getAddressField("_current_waiting_monitor");
 60     allocatedBytesField = typeThread.getJLongField("_allocated_bytes");
 61   }
 62 
 63   public Thread(Address addr) {
 64     super(addr);
 65   }
 66 
 67   public int suspendFlags() {
 68     return (int) suspendFlagsField.getValue(addr);
 69   }
 70 
 71   public ThreadLocalAllocBuffer tlab() {
 72     return new ThreadLocalAllocBuffer(addr.addOffsetTo(tlabFieldOffset));
 73   }
 74 
 75   public long allocatedBytes() {
 76     return allocatedBytesField.getValue(addr);
 77   }
 78 
 79   public boolean   isVMThread()                  { return false; }
 80   public boolean   isJavaThread()                { return false; }
 81   public boolean   isCompilerThread()            { return false; }
 82   public boolean   isCodeCacheSweeperThread()    { return false; }
 83   public boolean   isHiddenFromExternalView()    { return false; }
 84   public boolean   isJvmtiAgentThread()          { return false; }
 85   public boolean   isWatcherThread()             { return false; }
 86   public boolean   isServiceThread()             { return false; }
 87   public boolean   isMonitorDeflationThread()    { return false; }
 88 
 89   /** Memory operations */
 90   public void oopsDo(AddressVisitor oopVisitor) {
 91     // FIXME: Empty for now; will later traverse JNI handles and
 92     // pending exception
 93   }
 94 
 95   public ObjectMonitor getCurrentPendingMonitor() {
 96     Address monitorAddr = currentPendingMonitorField.getValue(addr);
 97     if (monitorAddr == null) {
 98       return null;
 99     }
100     return new ObjectMonitor(monitorAddr);
101   }
102 
103   public ObjectMonitor getCurrentWaitingMonitor() {
104     Address monitorAddr = currentWaitingMonitorField.getValue(addr);
105     if (monitorAddr == null) {
106       return null;
107     }
108     return new ObjectMonitor(monitorAddr);
109   }
110 
111   public boolean isLockOwned(Address lock) {
112     if (isInStack(lock)) return true;
113     return false;
114   }
115 
116   public boolean isInStack(Address a) {
117     // In the Serviceability Agent we need access to the thread's
118     // stack pointer to be able to answer this question. Since it is
119     // only a debugging system at the moment we need access to the
120     // underlying thread, which is only present for Java threads; see
121     // JavaThread.java.
122     return false;
123   }
124 
125   /** Assistance for ObjectMonitor implementation */
126   Address threadObjectAddress() { return addr; }
127 }