< prev index next >

src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java

Print this page
rev 54717 : imported patch 8223306

@@ -40,30 +40,59 @@
 import sun.jvm.hotspot.runtime.linux_sparc.LinuxSPARCJavaThreadPDAccess;
 import sun.jvm.hotspot.runtime.bsd_x86.BsdX86JavaThreadPDAccess;
 import sun.jvm.hotspot.runtime.bsd_amd64.BsdAMD64JavaThreadPDAccess;
 import sun.jvm.hotspot.utilities.*;
 
+class ThreadsList extends VMObject {
+
+    private static AddressField      threadsField;
+    private static CIntegerField     lengthField;
+
+    static {
+        VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
+    }
+
+    private static synchronized void initialize(TypeDataBase db) {
+        Type type = db.lookupType("ThreadsList");
+        lengthField = type.getCIntegerField("_length");
+        threadsField = type.getAddressField("_threads");
+    }
+
+    public Address getJavaThreadAddressAt(int i) {
+      Address threadAddr = threadsField.getValue(addr);
+      Address at = threadAddr.getAddressAt(VM.getVM().getAddressSize() * i);
+      return at;
+    }
+
+    public long length() {
+        return lengthField.getValue(addr);
+    }
+
+    public ThreadsList(Address addr) {
+        super(addr);
+    }
+}
+
+
 public class Threads {
     private static JavaThreadFactory threadFactory;
     private static AddressField      threadListField;
-    private static CIntegerField     numOfThreadsField;
     private static VirtualConstructor virtualConstructor;
     private static JavaThreadPDAccess access;
+    private static ThreadsList _list;
 
     static {
         VM.registerVMInitializedObserver(new Observer() {
             public void update(Observable o, Object data) {
                 initialize(VM.getVM().getTypeDataBase());
             }
         });
     }
 
     private static synchronized void initialize(TypeDataBase db) {
-        Type type = db.lookupType("Threads");
-
-        threadListField = type.getAddressField("_thread_list");
-        numOfThreadsField = type.getCIntegerField("_number_of_threads");
+        Type type = db.lookupType("ThreadsSMRSupport");
+        threadListField = type.getAddressField("_java_thread_list");
 
         // Instantiate appropriate platform-specific JavaThreadFactory
         String os  = VM.getVM().getOS();
         String cpu = VM.getVM().getCPU();
 

@@ -132,10 +161,11 @@
         virtualConstructor.addMapping("JvmtiAgentThread", JvmtiAgentThread.class);
         virtualConstructor.addMapping("ServiceThread", ServiceThread.class);
     }
 
     public Threads() {
+        _list = VMObjectFactory.newObject(ThreadsList.class, threadListField.getValue());
     }
 
     /** NOTE: this returns objects of type JavaThread, CompilerThread,
       JvmtiAgentThread, and ServiceThread.
       The latter four are subclasses of the former. Most operations

@@ -145,21 +175,29 @@
       changed from the definition in the VM (which returns true for
       all of these thread types) to return true for JavaThreads and
       false for the three subclasses. FIXME: should reconsider the
       inheritance hierarchy; see {@link
       sun.jvm.hotspot.runtime.JavaThread#isJavaThread}. */
-    public JavaThread first() {
-        Address threadAddr = threadListField.getValue();
-        if (threadAddr == null) {
+    public JavaThread getJavaThreadAt(int i) {
+        if (i < _list.length()) {
+            return createJavaThreadWrapper(_list.getJavaThreadAddressAt(i));
+        }
             return null;
         }
 
-        return createJavaThreadWrapper(threadAddr);
+    public int getNumberOfThreads() {
+        return (int) _list.length();
     }
 
-    public int getNumberOfThreads() {
-        return (int) numOfThreadsField.getValue();
+    public interface JavaThreadsDo {
+        void doJavaThread(JavaThread thread);
+    }
+
+    public void doJavaThreads(JavaThreadsDo jtDo) {
+        for (int i = 0; i < _list.length(); i++) {
+            jtDo.doJavaThread(getJavaThreadAt(i));
+        }
     }
 
     /** Routine for instantiating appropriately-typed wrapper for a
       JavaThread. Currently needs to be public for OopUtilities to
       access it. */

@@ -175,25 +213,25 @@
     }
 
     /** Memory operations */
     public void oopsDo(AddressVisitor oopVisitor) {
         // FIXME: add more of VM functionality
-        for (JavaThread thread = first(); thread != null; thread = thread.next()) {
-            thread.oopsDo(oopVisitor);
-        }
+        VM.getVM().getThreads().doJavaThreads((thread) -> thread.oopsDo(oopVisitor));
     }
 
     // refer to Threads::owning_thread_from_monitor_owner
     public JavaThread owningThreadFromMonitor(Address o) {
         if (o == null) return null;
-        for (JavaThread thread = first(); thread != null; thread = thread.next()) {
+        for (int i = 0; i < getNumberOfThreads(); i++) {
+            JavaThread thread = getJavaThreadAt(i);
             if (o.equals(thread.threadObjectAddress())) {
                 return thread;
             }
         }
 
-        for (JavaThread thread = first(); thread != null; thread = thread.next()) {
+        for (int i = 0; i < getNumberOfThreads(); i++) {
+            JavaThread thread = getJavaThreadAt(i);
           if (thread.isLockOwned(o))
             return thread;
         }
         return null;
     }

@@ -204,11 +242,12 @@
 
     // refer to Threads::get_pending_threads
     // Get list of Java threads that are waiting to enter the specified monitor.
     public List getPendingThreads(ObjectMonitor monitor) {
         List pendingThreads = new ArrayList();
-        for (JavaThread thread = first(); thread != null; thread = thread.next()) {
+        for (int i = 0; i < getNumberOfThreads(); i++) {
+            JavaThread thread = getJavaThreadAt(i);
             if (thread.isCompilerThread() || thread.isCodeCacheSweeperThread()) {
                 continue;
             }
             ObjectMonitor pending = thread.getCurrentPendingMonitor();
             if (monitor.equals(pending)) {

@@ -219,11 +258,12 @@
     }
 
     // Get list of Java threads that have called Object.wait on the specified monitor.
     public List getWaitingThreads(ObjectMonitor monitor) {
         List pendingThreads = new ArrayList();
-        for (JavaThread thread = first(); thread != null; thread = thread.next()) {
+        for (int i = 0; i < getNumberOfThreads(); i++) {
+            JavaThread thread = getJavaThreadAt(i);
             ObjectMonitor waiting = thread.getCurrentWaitingMonitor();
             if (monitor.equals(waiting)) {
                 pendingThreads.add(thread);
             }
         }
< prev index next >