# HG changeset patch # User rehn # Date 1558427697 -7200 # Node ID 46409371a6914258db520e61f41b19b63e185e6c # Parent 6ec71a88b68e99210799fd196578aa588dc4c63a 8223306: Remove threads linked list (use ThreadsList's array in SA) Reviewed-by: coleenp, dholmes, dcubed diff -r 6ec71a88b68e -r 46409371a691 src/hotspot/share/runtime/thread.cpp --- a/src/hotspot/share/runtime/thread.cpp Tue May 21 00:52:04 2019 -0700 +++ b/src/hotspot/share/runtime/thread.cpp Tue May 21 10:34:57 2019 +0200 @@ -1613,7 +1613,6 @@ set_deopt_compiled_method(NULL); clear_must_deopt_id(); set_monitor_chunks(NULL); - set_next(NULL); _on_thread_list = false; set_thread_state(_thread_new); _terminated = _not_terminated; @@ -3457,7 +3456,6 @@ // would like. We are actively migrating Threads_lock uses to other // mechanisms in order to reduce Threads_lock contention. -JavaThread* Threads::_thread_list = NULL; int Threads::_number_of_threads = 0; int Threads::_number_of_non_daemon_threads = 0; int Threads::_return_code = 0; @@ -3764,7 +3762,6 @@ } // Initialize Threads state - _thread_list = NULL; _number_of_threads = 0; _number_of_non_daemon_threads = 0; @@ -4423,9 +4420,6 @@ BarrierSet::barrier_set()->on_thread_attach(p); - p->set_next(_thread_list); - _thread_list = p; - // Once a JavaThread is added to the Threads list, smr_delete() has // to be used to delete it. Otherwise we can just delete it directly. p->set_on_thread_list(); @@ -4463,20 +4457,6 @@ // Maintain fast thread list ThreadsSMRSupport::remove_thread(p); - JavaThread* current = _thread_list; - JavaThread* prev = NULL; - - while (current != p) { - prev = current; - current = current->next(); - } - - if (prev) { - prev->set_next(current->next()); - } else { - _thread_list = p->next(); - } - _number_of_threads--; if (!is_daemon) { _number_of_non_daemon_threads--; diff -r 6ec71a88b68e -r 46409371a691 src/hotspot/share/runtime/thread.hpp --- a/src/hotspot/share/runtime/thread.hpp Tue May 21 00:52:04 2019 -0700 +++ b/src/hotspot/share/runtime/thread.hpp Tue May 21 10:34:57 2019 +0200 @@ -983,7 +983,6 @@ friend class JVMCIVMStructs; friend class WhiteBox; private: - JavaThread* _next; // The next thread in the Threads list bool _on_thread_list; // Is set when this JavaThread is added to the Threads list oop _threadObj; // The Java level thread object @@ -1247,10 +1246,6 @@ virtual bool is_Java_thread() const { return true; } virtual bool can_call_java() const { return true; } - // Thread chain operations - JavaThread* next() const { return _next; } - void set_next(JavaThread* p) { _next = p; } - // Thread oop. threadObj() can be NULL for initial JavaThread // (or for threads attached via JNI) oop threadObj() const { return _threadObj; } @@ -2213,7 +2208,6 @@ class Threads: AllStatic { friend class VMStructs; private: - static JavaThread* _thread_list; static int _number_of_threads; static int _number_of_non_daemon_threads; static int _return_code; diff -r 6ec71a88b68e -r 46409371a691 src/hotspot/share/runtime/threadSMR.hpp --- a/src/hotspot/share/runtime/threadSMR.hpp Tue May 21 00:52:04 2019 -0700 +++ b/src/hotspot/share/runtime/threadSMR.hpp Tue May 21 10:34:57 2019 +0200 @@ -86,6 +86,7 @@ // SMR Support for the Threads class. // class ThreadsSMRSupport : AllStatic { + friend class VMStructs; friend class SafeThreadsListPtr; // for _nested_thread_list_max, delete_notify(), release_stable_list_wake_up() access // The coordination between ThreadsSMRSupport::release_stable_list() and @@ -158,6 +159,7 @@ // A fast list of JavaThreads. // class ThreadsList : public CHeapObj { + friend class VMStructs; friend class SafeThreadsListPtr; // for {dec,inc}_nested_handle_cnt() access friend class ThreadsSMRSupport; // for _nested_handle_cnt, {add,remove}_thread(), {,set_}next_list() access diff -r 6ec71a88b68e -r 46409371a691 src/hotspot/share/runtime/vmStructs.cpp --- a/src/hotspot/share/runtime/vmStructs.cpp Tue May 21 00:52:04 2019 -0700 +++ b/src/hotspot/share/runtime/vmStructs.cpp Tue May 21 10:34:57 2019 +0200 @@ -94,6 +94,7 @@ #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" #include "runtime/thread.inline.hpp" +#include "runtime/threadSMR.hpp" #include "runtime/vframeArray.hpp" #include "runtime/vmStructs.hpp" #include "utilities/globalDefinitions.hpp" @@ -740,10 +741,13 @@ /* Threads (NOTE: incomplete) */ \ /******************************/ \ \ - static_field(Threads, _thread_list, JavaThread*) \ - static_field(Threads, _number_of_threads, int) \ - static_field(Threads, _number_of_non_daemon_threads, int) \ - static_field(Threads, _return_code, int) \ + static_field(Threads, _number_of_threads, int) \ + static_field(Threads, _number_of_non_daemon_threads, int) \ + static_field(Threads, _return_code, int) \ + \ + static_ptr_volatile_field(ThreadsSMRSupport, _java_thread_list, ThreadsList*) \ + nonstatic_field(ThreadsList, _length, const uint) \ + nonstatic_field(ThreadsList, _threads, JavaThread *const *const) \ \ nonstatic_field(ThreadShadow, _pending_exception, oop) \ nonstatic_field(ThreadShadow, _exception_file, const char*) \ @@ -757,7 +761,6 @@ nonstatic_field(Thread, _current_waiting_monitor, ObjectMonitor*) \ nonstatic_field(NamedThread, _name, char*) \ nonstatic_field(NamedThread, _processed_thread, JavaThread*) \ - nonstatic_field(JavaThread, _next, JavaThread*) \ nonstatic_field(JavaThread, _threadObj, oop) \ nonstatic_field(JavaThread, _anchor, JavaFrameAnchor) \ nonstatic_field(JavaThread, _vm_result, oop) \ @@ -1371,6 +1374,9 @@ declare_toplevel_type(OSThread) \ declare_toplevel_type(JavaFrameAnchor) \ \ + declare_toplevel_type(ThreadsSMRSupport) \ + declare_toplevel_type(ThreadsList) \ + \ /***************/ \ /* Interpreter */ \ /***************/ \ @@ -1964,6 +1970,7 @@ declare_toplevel_type(intptr_t*) \ declare_unsigned_integer_type(InvocationCounter) /* FIXME: wrong type (not integer) */ \ declare_toplevel_type(JavaThread*) \ + declare_toplevel_type(JavaThread *const *const) \ declare_toplevel_type(java_lang_Class) \ declare_integer_type(JavaThread::AsyncRequests) \ declare_integer_type(JavaThread::TerminatedTypes) \ diff -r 6ec71a88b68e -r 46409371a691 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java Tue May 21 00:52:04 2019 -0700 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java Tue May 21 10:34:57 2019 +0200 @@ -536,7 +536,8 @@ // Not an address boolean all = name.equals("-a"); Threads threads = VM.getVM().getThreads(); - for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) { + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread thread = threads.getJavaThreadAt(i); ByteArrayOutputStream bos = new ByteArrayOutputStream(); thread.printThreadIDOn(new PrintStream(bos)); if (all || bos.toString().equals(name)) { @@ -898,7 +899,8 @@ String name = t.nextToken(); boolean all = name.equals("-a"); Threads threads = VM.getVM().getThreads(); - for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) { + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread thread = threads.getJavaThreadAt(i); ByteArrayOutputStream bos = new ByteArrayOutputStream(); thread.printThreadIDOn(new PrintStream(bos)); if (all || bos.toString().equals(name)) { @@ -927,7 +929,8 @@ String name = t.nextToken(); boolean all = name.equals("-a"); Threads threads = VM.getVM().getThreads(); - for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) { + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread thread = threads.getJavaThreadAt(i); ByteArrayOutputStream bos = new ByteArrayOutputStream(); thread.printThreadIDOn(new PrintStream(bos)); if (all || bos.toString().equals(name)) { @@ -954,7 +957,8 @@ String name = t.nextToken(); boolean all = name.equals("-a"); Threads threads = VM.getVM().getThreads(); - for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) { + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread thread = threads.getJavaThreadAt(i); ByteArrayOutputStream bos = new ByteArrayOutputStream(); thread.printThreadIDOn(new PrintStream(bos)); if (all || bos.toString().equals(name)) { @@ -1437,7 +1441,8 @@ final long stride = VM.getVM().getAddressSize(); if (type.equals("threads")) { Threads threads = VM.getVM().getThreads(); - for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) { + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread thread = threads.getJavaThreadAt(i); Address base = thread.getStackBase(); Address end = thread.getLastJavaSP(); if (end == null) continue; @@ -1561,7 +1566,8 @@ String name = t.nextToken(); Threads threads = VM.getVM().getThreads(); boolean all = name.equals("-a"); - for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) { + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread thread = threads.getJavaThreadAt(i); ByteArrayOutputStream bos = new ByteArrayOutputStream(); thread.printThreadIDOn(new PrintStream(bos)); if (all || bos.toString().equals(name)) { @@ -1590,7 +1596,8 @@ String name = t.nextToken(); Threads threads = VM.getVM().getThreads(); boolean all = name.equals("-a"); - for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) { + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread thread = threads.getJavaThreadAt(i); ByteArrayOutputStream bos = new ByteArrayOutputStream(); thread.printThreadIDOn(new PrintStream(bos)); if (all || bos.toString().equals(name)) { @@ -1613,7 +1620,8 @@ usage(); } else { Threads threads = VM.getVM().getThreads(); - for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) { + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread thread = threads.getJavaThreadAt(i); thread.printThreadIDOn(out); out.println(" " + thread.getThreadName()); thread.printInfoOn(out); @@ -1631,7 +1639,8 @@ ArrayList nmethods = new ArrayList(); Threads threads = VM.getVM().getThreads(); HTMLGenerator gen = new HTMLGenerator(false); - for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) { + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread thread = threads.getJavaThreadAt(i); try { for (JavaVFrame vf = thread.getLastJavaVFrameDbg(); vf != null; vf = vf.javaSender()) { if (vf instanceof CompiledVFrame) { diff -r 6ec71a88b68e -r 46409371a691 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java Tue May 21 00:52:04 2019 -0700 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java Tue May 21 10:34:57 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -619,10 +619,10 @@ Threads threads = VM.getVM().getThreads(); int len = threads.getNumberOfThreads(); long[] result = new long[len * 3]; // triple - JavaThread t = threads.first(); long beg, end; int i = 0; - while (t != null) { + for (int k = 0; k < threads.getNumberOfThreads(); k++) { + JavaThread t = threads.getJavaThreadAt(k); end = t.getStackBaseValue(); beg = end - t.getStackSize(); BsdThread bsdt = (BsdThread)t.getThreadProxy(); @@ -631,7 +631,6 @@ result[i] = uid; result[i + 1] = beg; result[i + 2] = end; - t = t.next(); i += 3; } return result; diff -r 6ec71a88b68e -r 46409371a691 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Tue May 21 00:52:04 2019 -0700 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Tue May 21 10:34:57 2019 +0200 @@ -357,7 +357,9 @@ // end. if (VM.getVM().getUseTLAB()) { - for (JavaThread thread = VM.getVM().getThreads().first(); thread != null; thread = thread.next()) { + Threads threads = VM.getVM().getThreads(); + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread thread = threads.getJavaThreadAt(i); ThreadLocalAllocBuffer tlab = thread.tlab(); if (tlab.start() != null) { if ((tlab.top() == null) || (tlab.end() == null)) { diff -r 6ec71a88b68e -r 46409371a691 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/DeadlockDetector.java --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/DeadlockDetector.java Tue May 21 00:52:04 2019 -0700 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/DeadlockDetector.java Tue May 21 10:34:57 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -146,7 +146,9 @@ private static void createThreadTable() { threadTable = new HashMap(); - for (JavaThread cur = threads.first(); cur != null; cur = cur.next()) { + Threads threads = VM.getVM().getThreads(); + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread cur = threads.getJavaThreadAt(i); // initialize dfn for each thread to -1 threadTable.put(cur, new Integer(-1)); } diff -r 6ec71a88b68e -r 46409371a691 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.java --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.java Tue May 21 00:52:04 2019 -0700 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.java Tue May 21 10:34:57 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,6 @@ public class JavaThread extends Thread { private static final boolean DEBUG = System.getProperty("sun.jvm.hotspot.runtime.JavaThread.DEBUG") != null; - private static AddressField nextField; private static sun.jvm.hotspot.types.OopField threadObjField; private static AddressField anchorField; private static AddressField lastJavaSPField; @@ -84,7 +83,6 @@ Type type = db.lookupType("JavaThread"); Type anchorType = db.lookupType("JavaFrameAnchor"); - nextField = type.getAddressField("_next"); threadObjField = type.getOopField("_threadObj"); anchorField = type.getAddressField("_anchor"); lastJavaSPField = anchorType.getAddressField("_last_Java_sp"); @@ -120,15 +118,6 @@ this.access = access; } - public JavaThread next() { - Address threadAddr = nextField.getValue(addr); - if (threadAddr == null) { - return null; - } - - return VM.getVM().getThreads().createJavaThreadWrapper(threadAddr); - } - /** NOTE: for convenience, this differs in definition from the underlying VM. Only "pure" JavaThreads return true; CompilerThreads, the CodeCacheSweeperThread, JVMDIDebuggerThreads return false. diff -r 6ec71a88b68e -r 46409371a691 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java Tue May 21 00:52:04 2019 -0700 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java Tue May 21 10:34:57 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,12 +42,41 @@ 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() { @@ -58,10 +87,8 @@ } 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(); @@ -134,6 +161,7 @@ } public Threads() { + _list = VMObjectFactory.newObject(ThreadsList.class, threadListField.getValue()); } /** NOTE: this returns objects of type JavaThread, CompilerThread, @@ -147,17 +175,15 @@ 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) { - return null; + public JavaThread getJavaThreadAt(int i) { + if (i < _list.length()) { + return createJavaThreadWrapper(_list.getJavaThreadAddressAt(i)); } - - return createJavaThreadWrapper(threadAddr); + return null; } public int getNumberOfThreads() { - return (int) numOfThreadsField.getValue(); + return (int) _list.length(); } /** Routine for instantiating appropriately-typed wrapper for a @@ -177,7 +203,9 @@ /** Memory operations */ public void oopsDo(AddressVisitor oopVisitor) { // FIXME: add more of VM functionality - for (JavaThread thread = first(); thread != null; thread = thread.next()) { + Threads threads = VM.getVM().getThreads(); + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread thread = threads.getJavaThreadAt(i); thread.oopsDo(oopVisitor); } } @@ -185,15 +213,17 @@ // 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()) { - if (thread.isLockOwned(o)) - return thread; + for (int i = 0; i < getNumberOfThreads(); i++) { + JavaThread thread = getJavaThreadAt(i); + if (thread.isLockOwned(o)) + return thread; } return null; } @@ -206,7 +236,8 @@ // 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; } @@ -221,7 +252,8 @@ // 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); diff -r 6ec71a88b68e -r 46409371a691 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java Tue May 21 00:52:04 2019 -0700 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java Tue May 21 10:34:57 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -201,7 +201,8 @@ jframeCache = new HashMap(); proxyToThread = new HashMap(); Threads threads = VM.getVM().getThreads(); - for (JavaThread cur = threads.first(); cur != null; cur = cur.next()) { + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread cur = threads.getJavaThreadAt(i); List tmp = new ArrayList(10); try { for (JavaVFrame vf = cur.getLastJavaVFrameDbg(); vf != null; vf = vf.javaSender()) { diff -r 6ec71a88b68e -r 46409371a691 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.java --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.java Tue May 21 00:52:04 2019 -0700 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.java Tue May 21 10:34:57 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,8 +71,8 @@ concLocksPrinter = new ConcurrentLocksPrinter(); } Threads threads = VM.getVM().getThreads(); - int i = 1; - for (JavaThread cur = threads.first(); cur != null; cur = cur.next(), i++) { + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread cur = threads.getJavaThreadAt(i); if (cur.isJavaThread()) { cur.printThreadInfoOn(tty); try { diff -r 6ec71a88b68e -r 46409371a691 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/JavaThreadsPanel.java --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/JavaThreadsPanel.java Tue May 21 00:52:04 2019 -0700 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/JavaThreadsPanel.java Tue May 21 10:34:57 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -459,12 +459,13 @@ } private void cache() { - Threads threads = VM.getVM().getThreads(); - for (JavaThread t = threads.first(); t != null; t = t.next()) { - if (t.isJavaThread()) { - cachedThreads.add(new CachedThread(t)); - } + Threads threads = VM.getVM().getThreads(); + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread t = threads.getJavaThreadAt(i); + if (t.isJavaThread()) { + cachedThreads.add(new CachedThread(t)); } + } } private void decache() { diff -r 6ec71a88b68e -r 46409371a691 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/AbstractHeapGraphWriter.java --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/AbstractHeapGraphWriter.java Tue May 21 00:52:04 2019 -0700 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/AbstractHeapGraphWriter.java Tue May 21 10:34:57 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -129,15 +129,12 @@ protected void writeJavaThreads() throws IOException { Threads threads = VM.getVM().getThreads(); - JavaThread jt = threads.first(); - int index = 1; - while (jt != null) { + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread jt = threads.getJavaThreadAt(i); if (jt.getThreadObj() != null) { // Note that the thread serial number range is 1-to-N - writeJavaThread(jt, index); - index++; + writeJavaThread(jt, i + 1); } - jt = jt.next(); } } diff -r 6ec71a88b68e -r 46409371a691 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java Tue May 21 00:52:04 2019 -0700 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java Tue May 21 10:34:57 2019 +0200 @@ -708,8 +708,8 @@ int frameSerialNum = 0; int numThreads = 0; Threads threads = VM.getVM().getThreads(); - - for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) { + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread thread = threads.getJavaThreadAt(i); Oop threadObj = thread.getThreadObj(); if (threadObj != null && !thread.isExiting() && !thread.isHiddenFromExternalView()) { diff -r 6ec71a88b68e -r 46409371a691 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerFinder.java --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerFinder.java Tue May 21 00:52:04 2019 -0700 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerFinder.java Tue May 21 10:34:57 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,9 @@ if (VM.getVM().getUseTLAB()) { // Try to find thread containing it - for (JavaThread t = VM.getVM().getThreads().first(); t != null; t = t.next()) { + Threads threads = VM.getVM().getThreads(); + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread t = threads.getJavaThreadAt(i); ThreadLocalAllocBuffer tlab = t.tlab(); if (tlab.contains(a)) { loc.inTLAB = true; @@ -125,7 +127,9 @@ return loc; } // Look in thread-local handles - for (JavaThread t = VM.getVM().getThreads().first(); t != null; t = t.next()) { + Threads threads = VM.getVM().getThreads(); + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread t = threads.getJavaThreadAt(i); JNIHandleBlock handleBlock = t.activeHandles(); if (handleBlock != null) { handleBlock = handleBlock.blockContainingHandle(a); diff -r 6ec71a88b68e -r 46409371a691 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/ReversePtrsAnalysis.java --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/ReversePtrsAnalysis.java Tue May 21 00:52:04 2019 -0700 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/ReversePtrsAnalysis.java Tue May 21 10:34:57 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,9 +92,9 @@ heap = vm.getObjectHeap(); // Do each thread's roots - for (JavaThread thread = VM.getVM().getThreads().first(); - thread != null; - thread = thread.next()) { + Threads threads = VM.getVM().getThreads(); + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread thread = threads.getJavaThreadAt(i); ByteArrayOutputStream bos = new ByteArrayOutputStream(); thread.printThreadIDOn(new PrintStream(bos)); String threadDesc = diff -r 6ec71a88b68e -r 46409371a691 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaVM.java --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaVM.java Tue May 21 00:52:04 2019 -0700 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaVM.java Tue May 21 10:34:57 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -189,12 +189,12 @@ private synchronized JSList getThreads() { if (threadsCache == null) { - List threads = new ArrayList(0); - threadsCache = factory.newJSList(threads); - JavaThread jthread = vm.getThreads().first(); - while (jthread != null) { - threads.add(jthread); - jthread = jthread.next(); + List threadsList = new ArrayList(0); + threadsCache = factory.newJSList(threadsList); + Threads threads = VM.getVM().getThreads(); + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread thread = threads.getJavaThreadAt(i); + threadsList.add(thread); } } return threadsCache; diff -r 6ec71a88b68e -r 46409371a691 test/hotspot/jtreg/serviceability/sa/ClhsdbField.java --- a/test/hotspot/jtreg/serviceability/sa/ClhsdbField.java Tue May 21 00:52:04 2019 -0700 +++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbField.java Tue May 21 10:34:57 2019 +0200 @@ -55,7 +55,6 @@ "field InstanceKlass _methods Array*", "field InstanceKlass _constants ConstantPool*", "field Klass _name Symbol*", - "field JavaThread _next JavaThread*", "field JavaThread _osthread OSThread*", "field JVMState _bci", "field TenuredGeneration _the_space ContiguousSpace*", diff -r 6ec71a88b68e -r 46409371a691 test/hotspot/jtreg/serviceability/sa/ClhsdbPrintStatics.java --- a/test/hotspot/jtreg/serviceability/sa/ClhsdbPrintStatics.java Tue May 21 00:52:04 2019 -0700 +++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbPrintStatics.java Tue May 21 10:34:57 2019 +0200 @@ -68,8 +68,7 @@ "SystemDictionary::Object_klass_knum")); expStrMap.put("printstatics Threads", List.of( "Static fields of Threads", - "_number_of_threads", "_number_of_non_daemon_threads", - "JavaThread\\* Threads")); + "_number_of_threads", "_number_of_non_daemon_threads")); expStrMap.put("printstatics Universe", List.of( "Static fields of Universe", "uintptr_t Universe::_verify_oop_mask", diff -r 6ec71a88b68e -r 46409371a691 test/hotspot/jtreg/serviceability/sa/ClhsdbVmStructsDump.java --- a/test/hotspot/jtreg/serviceability/sa/ClhsdbVmStructsDump.java Tue May 21 00:52:04 2019 -0700 +++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbVmStructsDump.java Tue May 21 10:34:57 2019 +0200 @@ -57,7 +57,6 @@ "field Klass _name Symbol*", "type ClassLoaderData* null", "type DictionaryEntry KlassHashtableEntry", - "field JavaThread _next JavaThread*", "field JavaThread _osthread OSThread*", "type TenuredGeneration CardGeneration", "field JVMState _bci",