8348347: Cleanup JavaThread subclass support in SA

Reviewed-by: kevinw, sspitsyn
This commit is contained in:
Chris Plummer 2025-02-14 19:40:47 +00:00
parent ba6c96599a
commit b6443f6ff9
15 changed files with 63 additions and 335 deletions

View File

@ -1,41 +0,0 @@
/*
* Copyright (c) 2023, Alibaba Group Holding Limited. 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.runtime;
import java.io.*;
import sun.jvm.hotspot.debugger.Address;
public class AttachListenerThread extends JavaThread {
public AttachListenerThread (Address addr) {
super(addr);
}
public boolean isJavaThread() { return false; }
public boolean isAttachListenerThread() { return true; }
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2025, 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
@ -65,8 +65,17 @@ public class CompilerThread extends JavaThread {
super(addr);
}
public boolean isJavaThread() { return false; }
public boolean isHiddenFromExternalView() { return true; }
public boolean isCompilerThread() { return true; }
@Override
public boolean isHiddenFromExternalView() {
/*
* See JDK-8348317. CompilerThreads are sometimes hidden and sometimes not. They
* are not when JVMCI is enabled and a compiler implemented in java is running
* on the CompilerThread. This is hard for SA to determine, and not something a customer
* is likely to ever run across or care about, so by default all CompilerThreads
* are considered to be hidden. However, we allow this behaviour to be overridden
* in case the user has a need to make the CompilerThreads visible.
*/
return !Boolean.getBoolean("sun.jvm.hotspot.runtime.CompilerThread.visible");
}
}

View File

@ -1,42 +0,0 @@
/*
* Copyright (c) 2025, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.runtime;
import java.io.*;
import sun.jvm.hotspot.debugger.Address;
public class DeoptimizeObjectsALotThread extends JavaThread {
public DeoptimizeObjectsALotThread (Address addr) {
super(addr);
}
public boolean isJavaThread() { return false; }
public boolean isHiddenFromExternalView() { return true; }
public boolean isDeoptimizeObjectsALotThread() { return true; }
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2025, 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
@ -26,11 +26,13 @@ package sun.jvm.hotspot.runtime;
import sun.jvm.hotspot.debugger.Address;
public class StringDedupThread extends JavaThread {
public StringDedupThread(Address addr) {
public class HiddenJavaThread extends JavaThread {
public HiddenJavaThread(Address addr) {
super(addr);
}
public boolean isJavaThread() { return false; }
@Override
public boolean isHiddenFromExternalView() { return true; }
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2025, 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
@ -33,13 +33,6 @@ import sun.jvm.hotspot.utilities.*;
import sun.jvm.hotspot.utilities.Observable;
import sun.jvm.hotspot.utilities.Observer;
/** This is an abstract class because there are certain OS- and
CPU-specific operations (like the setting and getting of the last
Java frame pointer) which need to be factored out. These
operations are implemented by, for example,
SolarisSPARCJavaThread, and the concrete subclasses are
instantiated by the JavaThreadFactory in the Threads class. */
public class JavaThread extends Thread {
private static final boolean DEBUG = System.getProperty("sun.jvm.hotspot.runtime.JavaThread.DEBUG") != null;
@ -58,6 +51,7 @@ public class JavaThread extends Thread {
private static CIntegerField monitorOwnerIDField;
private static long oopPtrSize;
// For accessing platform dependent functionality
private static JavaThreadPDAccess access;
// JavaThreadStates read from underlying process
@ -133,16 +127,6 @@ public class JavaThread extends Thread {
this.access = access;
}
/** NOTE: for convenience, this differs in definition from the underlying VM.
Only "pure" JavaThreads return true; CompilerThreads,
JVMDIDebuggerThreads return false.
FIXME:
consider encapsulating platform-specific functionality in an
object instead of using inheritance (which is the primary reason
we can't traverse CompilerThreads, etc; didn't want to have, for
example, "SolarisSPARCCompilerThread".) */
public boolean isJavaThread() { return true; }
public boolean isExiting () {
return (getTerminated() == EXITING) || isTerminated();
}

View File

@ -1,44 +0,0 @@
/*
* Copyright (c) 2000, 2003, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.runtime;
import java.io.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.types.*;
/** FIXME: should be in ../prims dir if that directory existed; for
now keep it in runtime dir */
public class JvmtiAgentThread extends JavaThread {
public JvmtiAgentThread(Address addr) {
super(addr);
}
public boolean isJavaThread() { return false; }
public boolean isJvmtiAgentThread() { return true; }
}

View File

@ -1,41 +0,0 @@
/*
* Copyright (c) 2020, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.runtime;
import java.io.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.types.*;
public class MonitorDeflationThread extends JavaThread {
public MonitorDeflationThread(Address addr) {
super(addr);
}
public boolean isJavaThread() { return false; }
public boolean isHiddenFromExternalView() { return true; }
public boolean isMonitorDeflationThread() { return true; }
}

View File

@ -1,37 +0,0 @@
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.runtime;
import sun.jvm.hotspot.debugger.Address;
public class NotificationThread extends JavaThread {
public NotificationThread(Address addr) {
super(addr);
}
public boolean isJavaThread() { return false; }
}

View File

@ -1,41 +0,0 @@
/*
* Copyright (c) 2003, 2011, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.runtime;
import java.io.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.types.*;
public class ServiceThread extends JavaThread {
public ServiceThread(Address addr) {
super(addr);
}
public boolean isJavaThread() { return false; }
public boolean isHiddenFromExternalView() { return true; }
public boolean isServiceThread() { return true; }
}

View File

@ -80,16 +80,7 @@ public class Thread extends VMObject {
}
public boolean isVMThread() { return false; }
public boolean isJavaThread() { return false; }
public boolean isCompilerThread() { return false; }
public boolean isCodeCacheSweeperThread() { return false; }
public boolean isHiddenFromExternalView() { return false; }
public boolean isJvmtiAgentThread() { return false; }
public boolean isWatcherThread() { return false; }
public boolean isServiceThread() { return false; }
public boolean isMonitorDeflationThread() { return false; }
public boolean isAttachListenerThread() { return false; }
public boolean isDeoptimizeObjectsALotThread() { return false; }
/** Memory operations */
public void oopsDo(AddressVisitor oopVisitor) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2025, 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
@ -46,9 +46,6 @@ public class ThreadStackTrace {
}
public void dumpStack(int maxDepth) {
if (!thread.isJavaThread()) {
return;
}
try {
for (JavaVFrame vf = thread.getLastJavaVFrameDbg(); vf != null; vf = vf.javaSender()) {
StackFrameInfo frame = new StackFrameInfo(vf);

View File

@ -142,21 +142,29 @@ public class Threads {
}
virtualConstructor = new VirtualConstructor(db);
// Add mappings for all known thread types
/*
* Add mappings for JavaThread types
*/
virtualConstructor.addMapping("JavaThread", JavaThread.class);
if (!VM.getVM().isCore()) {
virtualConstructor.addMapping("CompilerThread", CompilerThread.class);
}
virtualConstructor.addMapping("JvmtiAgentThread", JvmtiAgentThread.class);
virtualConstructor.addMapping("ServiceThread", ServiceThread.class);
virtualConstructor.addMapping("MonitorDeflationThread", MonitorDeflationThread.class);
virtualConstructor.addMapping("NotificationThread", NotificationThread.class);
virtualConstructor.addMapping("StringDedupThread", StringDedupThread.class);
virtualConstructor.addMapping("AttachListenerThread", AttachListenerThread.class);
/* Only add DeoptimizeObjectsALotThread if it is actually present in the type database. */
// These are all the visible JavaThread subclasses that execute java code.
virtualConstructor.addMapping("JvmtiAgentThread", JavaThread.class);
virtualConstructor.addMapping("NotificationThread", JavaThread.class);
virtualConstructor.addMapping("AttachListenerThread", JavaThread.class);
// These are all the hidden JavaThread subclasses that don't execute java code.
virtualConstructor.addMapping("StringDedupThread", HiddenJavaThread.class);
virtualConstructor.addMapping("ServiceThread", HiddenJavaThread.class);
virtualConstructor.addMapping("MonitorDeflationThread", HiddenJavaThread.class);
// Only add DeoptimizeObjectsALotThread if it is actually present in the type database.
if (db.lookupType("DeoptimizeObjectsALotThread", false) != null) {
virtualConstructor.addMapping("DeoptimizeObjectsALotThread", DeoptimizeObjectsALotThread.class);
virtualConstructor.addMapping("DeoptimizeObjectsALotThread", HiddenJavaThread.class);
}
}
@ -164,17 +172,6 @@ public class Threads {
_list = VMObjectFactory.newObject(ThreadsList.class, threadListField.getValue());
}
/** NOTE: this returns objects of type JavaThread or one if its subclasses:
CompilerThread, JvmtiAgentThread, NotificationThread, MonitorDeflationThread,
StringDedupThread, AttachListenerThread, DeoptimizeObjectsALotThread and
ServiceThread. Most operations (fetching the top frame, etc.) are only
allowed to be performed on a "pure" JavaThread. For this reason,
{@link sun.jvm.hotspot.runtime.JavaThread#isJavaThread} has been
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 seven subclasses. FIXME: should reconsider the
inheritance hierarchy; see {@link
sun.jvm.hotspot.runtime.JavaThread#isJavaThread}. */
public JavaThread getJavaThreadAt(int i) {
if (i < _list.length()) {
return createJavaThreadWrapper(_list.getJavaThreadAddressAt(i));
@ -258,7 +255,7 @@ public class Threads {
List<JavaThread> pendingThreads = new ArrayList<>();
for (int i = 0; i < getNumberOfThreads(); i++) {
JavaThread thread = getJavaThreadAt(i);
if (thread.isCompilerThread() || thread.isCodeCacheSweeperThread()) {
if (thread.isHiddenFromExternalView()) {
continue;
}
ObjectMonitor pending = thread.getCurrentPendingMonitor();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2025, 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
@ -73,7 +73,7 @@ public class StackTrace extends Tool {
Threads threads = VM.getVM().getThreads();
for (int i = 0; i < threads.getNumberOfThreads(); i++) {
JavaThread cur = threads.getJavaThreadAt(i);
if (cur.isJavaThread()) {
if (!cur.isHiddenFromExternalView()) {
cur.printThreadInfoOn(tty);
try {
int count = 0;
@ -126,20 +126,19 @@ public class StackTrace extends Tool {
concLocksPrinter.print(cur);
tty.println();
}
}
}
}
catch (AddressException e) {
System.err.println("Error accessing address 0x" + Long.toHexString(e.getAddress()));
e.printStackTrace();
}
}
}
}
} catch (AddressException e) {
System.err.println("Error accessing address 0x" + Long.toHexString(e.getAddress()));
e.printStackTrace();
}
}
public static void main(String[] args) {
StackTrace st = new StackTrace();
st.execute(args);
}
public static void main(String[] args) {
StackTrace st = new StackTrace();
st.execute(args);
}
private boolean verbose;
private boolean concurrentLocks;
private boolean verbose;
private boolean concurrentLocks;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2025, 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
@ -464,7 +464,7 @@ public class JavaThreadsPanel extends SAPanel implements ActionListener {
Threads threads = VM.getVM().getThreads();
for (int i = 0; i < threads.getNumberOfThreads(); i++) {
JavaThread t = threads.getJavaThreadAt(i);
if (t.isJavaThread()) {
if (!t.isHiddenFromExternalView()) {
cachedThreads.add(new CachedThread(t));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2025, 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
@ -86,7 +86,7 @@ public class PointerLocation {
boolean inLocalJNIHandleBlock;
JNIHandleBlock handleBlock;
sun.jvm.hotspot.runtime.Thread handleThread;
JavaThread handleThread;
public PointerLocation(Address addr) {
this.addr = addr;
@ -200,7 +200,7 @@ public class PointerLocation {
}
/** Only valid if isInLocalJNIHandleBlock is true */
public sun.jvm.hotspot.runtime.Thread getJNIHandleThread() {
public JavaThread getJNIHandleThread() {
assert isInLocalJNIHandleBlock();
return handleThread;
}
@ -356,14 +356,9 @@ public class PointerLocation {
tty.println("In JNI weak global");
} else if (isInLocalJNIHandleBlock()) {
tty.print("In thread-local");
tty.print(" JNI handle block (" + handleBlock.top() + " handle slots present)");
if (handleThread.isJavaThread()) {
tty.print(" for JavaThread ");
((JavaThread) handleThread).printThreadIDOn(tty);
tty.println();
} else {
tty.println(" for a non-Java Thread");
}
tty.print(" JNI handle block (" + handleBlock.top() + " handle slots present) for JavaThread ");
handleThread.printThreadIDOn(tty);
tty.println();
} else {
// This must be last
if (Assert.ASSERTS_ENABLED) {