410 lines
18 KiB
Diff
410 lines
18 KiB
Diff
From f68539b01f6345809266cf57fe4bdc0f45c8ab37 Mon Sep 17 00:00:00 2001
|
|
From: eapen <zhangyipeng7@huawei.com>
|
|
Date: Fri, 16 Dec 2022 10:02:37 +0800
|
|
Subject: [PATCH 25/33] I68TO2: 8200720: Print additional information in thread dump
|
|
(times, allocated bytes etc.)
|
|
---
|
|
hotspot/src/share/vm/classfile/classFileParser.cpp | 4 ++
|
|
hotspot/src/share/vm/runtime/globals.hpp | 3 ++
|
|
hotspot/src/share/vm/runtime/thread.cpp | 29 ++++++++++---
|
|
hotspot/src/share/vm/runtime/thread.hpp | 15 +++++--
|
|
.../src/share/vm/runtime/threadStatisticalInfo.hpp | 49 ++++++++++++++++++++++
|
|
hotspot/src/share/vm/runtime/vm_operations.cpp | 2 +-
|
|
hotspot/src/share/vm/runtime/vm_operations.hpp | 13 ++++--
|
|
hotspot/src/share/vm/services/attachListener.cpp | 14 +++++--
|
|
.../src/share/vm/services/diagnosticCommand.cpp | 6 ++-
|
|
.../src/share/vm/services/diagnosticCommand.hpp | 1 +
|
|
jdk/src/share/classes/sun/tools/jstack/JStack.java | 19 ++++++---
|
|
11 files changed, 131 insertions(+), 24 deletions(-)
|
|
create mode 100644 hotspot/src/share/vm/runtime/threadStatisticalInfo.hpp
|
|
|
|
diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
|
|
index 3ec6aec..51ab4f5 100644
|
|
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
|
|
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
|
|
@@ -3843,6 +3843,10 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
|
ClassFileStream* cfs = stream();
|
|
// Timing
|
|
assert(THREAD->is_Java_thread(), "must be a JavaThread");
|
|
+
|
|
+ // increment counter
|
|
+ THREAD->statistical_info().incr_define_class_count();
|
|
+
|
|
JavaThread* jt = (JavaThread*) THREAD;
|
|
|
|
PerfClassTraceTime ctimer(ClassLoader::perf_class_parse_time(),
|
|
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
|
|
index 14c3c89..2631971 100644
|
|
--- a/hotspot/src/share/vm/runtime/globals.hpp
|
|
+++ b/hotspot/src/share/vm/runtime/globals.hpp
|
|
@@ -1001,6 +1001,9 @@ class CommandLineFlags {
|
|
product(bool, PrintCompilation, false, \
|
|
"Print compilations") \
|
|
\
|
|
+ product(bool, PrintExtendedThreadInfo, false, \
|
|
+ "Print more information in thread dump") \
|
|
+ \
|
|
diagnostic(bool, TraceNMethodInstalls, false, \
|
|
"Trace nmethod installation") \
|
|
\
|
|
diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp
|
|
index 61627e4..bd35e95 100644
|
|
--- a/hotspot/src/share/vm/runtime/thread.cpp
|
|
+++ b/hotspot/src/share/vm/runtime/thread.cpp
|
|
@@ -71,6 +71,7 @@
|
|
#include "runtime/thread.inline.hpp"
|
|
#include "runtime/threadCritical.hpp"
|
|
#include "runtime/threadLocalStorage.hpp"
|
|
+#include "runtime/threadStatisticalInfo.hpp"
|
|
#include "runtime/vframe.hpp"
|
|
#include "runtime/vframeArray.hpp"
|
|
#include "runtime/vframe_hp.hpp"
|
|
@@ -859,13 +860,29 @@ void Thread::metadata_do(void f(Metadata*)) {
|
|
}
|
|
}
|
|
|
|
-void Thread::print_on(outputStream* st) const {
|
|
+void Thread::print_on(outputStream* st, bool print_extended_info) const {
|
|
// get_priority assumes osthread initialized
|
|
if (osthread() != NULL) {
|
|
int os_prio;
|
|
if (os::get_native_priority(this, &os_prio) == OS_OK) {
|
|
st->print("os_prio=%d ", os_prio);
|
|
}
|
|
+
|
|
+ st->print("cpu=%.2fms ",
|
|
+ os::thread_cpu_time(const_cast<Thread*>(this), true) / 1000000.0
|
|
+ );
|
|
+ st->print("elapsed=%.2fs ",
|
|
+ _statistical_info.getElapsedTime() / 1000.0
|
|
+ );
|
|
+ if (is_Java_thread() && (PrintExtendedThreadInfo || print_extended_info)) {
|
|
+ size_t allocated_bytes = (size_t) const_cast<Thread*>(this)->cooked_allocated_bytes();
|
|
+ st->print("allocated=" SIZE_FORMAT "%s ",
|
|
+ byte_size_in_proper_unit(allocated_bytes),
|
|
+ proper_unit_for_byte_size(allocated_bytes)
|
|
+ );
|
|
+ st->print("defined_classes=" INT64_FORMAT " ", _statistical_info.getDefineClassCount());
|
|
+ }
|
|
+
|
|
st->print("tid=" INTPTR_FORMAT " ", this);
|
|
ext().print_on(st);
|
|
osthread()->print_on(st);
|
|
@@ -2856,7 +2873,7 @@ void JavaThread::print_thread_state() const {
|
|
#endif // PRODUCT
|
|
|
|
// Called by Threads::print() for VM_PrintThreads operation
|
|
-void JavaThread::print_on(outputStream *st) const {
|
|
+void JavaThread::print_on(outputStream *st, bool print_extended_info) const {
|
|
st->print("\"%s\" ", get_thread_name());
|
|
oop thread_oop = threadObj();
|
|
if (thread_oop != NULL) {
|
|
@@ -2864,7 +2881,7 @@ void JavaThread::print_on(outputStream *st) const {
|
|
if (java_lang_Thread::is_daemon(thread_oop)) st->print("daemon ");
|
|
st->print("prio=%d ", java_lang_Thread::priority(thread_oop));
|
|
}
|
|
- Thread::print_on(st);
|
|
+ Thread::print_on(st, print_extended_info);
|
|
// print guess for valid stack memory region (assume 4K pages); helps lock debugging
|
|
st->print_cr("[" INTPTR_FORMAT "]", (intptr_t)last_Java_sp() & ~right_n_bits(12));
|
|
if (thread_oop != NULL && JDK_Version::is_gte_jdk15x_version()) {
|
|
@@ -4344,7 +4361,9 @@ JavaThread *Threads::owning_thread_from_monitor_owner(address owner, bool doLock
|
|
}
|
|
|
|
// Threads::print_on() is called at safepoint by VM_PrintThreads operation.
|
|
-void Threads::print_on(outputStream* st, bool print_stacks, bool internal_format, bool print_concurrent_locks) {
|
|
+void Threads::print_on(outputStream* st, bool print_stacks,
|
|
+ bool internal_format, bool print_concurrent_locks,
|
|
+ bool print_extended_info) {
|
|
char buf[32];
|
|
st->print_cr("%s", os::local_time_string(buf, sizeof(buf)));
|
|
|
|
@@ -4365,7 +4384,7 @@ void Threads::print_on(outputStream* st, bool print_stacks, bool internal_format
|
|
|
|
ALL_JAVA_THREADS(p) {
|
|
ResourceMark rm;
|
|
- p->print_on(st);
|
|
+ p->print_on(st, print_extended_info);
|
|
if (print_stacks) {
|
|
if (internal_format) {
|
|
p->trace_stack();
|
|
diff --git a/hotspot/src/share/vm/runtime/thread.hpp b/hotspot/src/share/vm/runtime/thread.hpp
|
|
index 7d80daba..0e126964 100644
|
|
--- a/hotspot/src/share/vm/runtime/thread.hpp
|
|
+++ b/hotspot/src/share/vm/runtime/thread.hpp
|
|
@@ -41,6 +41,7 @@
|
|
#include "runtime/stubRoutines.hpp"
|
|
#include "runtime/threadLocalStorage.hpp"
|
|
#include "runtime/thread_ext.hpp"
|
|
+#include "runtime/threadStatisticalInfo.hpp"
|
|
#include "runtime/unhandledOops.hpp"
|
|
#include "utilities/exceptions.hpp"
|
|
#include "utilities/macros.hpp"
|
|
@@ -263,6 +264,8 @@ class Thread: public ThreadShadow {
|
|
// Thread-local buffer used by MetadataOnStackMark.
|
|
MetadataOnStackBuffer* _metadata_on_stack_buffer;
|
|
|
|
+ ThreadStatisticalInfo _statistical_info; // Statistics about the thread
|
|
+
|
|
JFR_ONLY(DEFINE_THREAD_LOCAL_FIELD_JFR;) // Thread-local data for jfr
|
|
|
|
ThreadExt _ext;
|
|
@@ -446,6 +449,8 @@ class Thread: public ThreadShadow {
|
|
void incr_allocated_bytes(jlong size) { _allocated_bytes += size; }
|
|
inline jlong cooked_allocated_bytes();
|
|
|
|
+ ThreadStatisticalInfo& statistical_info() { return _statistical_info; }
|
|
+
|
|
JFR_ONLY(DEFINE_THREAD_LOCAL_ACCESSOR_JFR;)
|
|
JFR_ONLY(DEFINE_TRACE_SUSPEND_FLAG_METHODS)
|
|
|
|
@@ -570,7 +575,8 @@ protected:
|
|
void set_lgrp_id(int value) { _lgrp_id = value; }
|
|
|
|
// Printing
|
|
- virtual void print_on(outputStream* st) const;
|
|
+ void print_on(outputStream* st, bool print_extended_info) const;
|
|
+ void print_on(outputStream* st) const { print_on(st, false); }
|
|
void print() const { print_on(tty); }
|
|
virtual void print_on_error(outputStream* st, char* buf, int buflen) const;
|
|
|
|
@@ -1464,7 +1470,8 @@ class JavaThread: public Thread {
|
|
|
|
// Misc. operations
|
|
char* name() const { return (char*)get_thread_name(); }
|
|
- void print_on(outputStream* st) const;
|
|
+ void print_on(outputStream* st, bool print_extended_info) const;
|
|
+ void print_on(outputStream* st) const { print_on(st, false); }
|
|
void print_value();
|
|
void print_thread_state_on(outputStream* ) const PRODUCT_RETURN;
|
|
void print_thread_state() const PRODUCT_RETURN;
|
|
@@ -1975,10 +1982,10 @@ class Threads: AllStatic {
|
|
|
|
// Verification
|
|
static void verify();
|
|
- static void print_on(outputStream* st, bool print_stacks, bool internal_format, bool print_concurrent_locks);
|
|
+ static void print_on(outputStream* st, bool print_stacks, bool internal_format, bool print_concurrent_locks, bool print_extended_info);
|
|
static void print(bool print_stacks, bool internal_format) {
|
|
// this function is only used by debug.cpp
|
|
- print_on(tty, print_stacks, internal_format, false /* no concurrent lock printed */);
|
|
+ print_on(tty, print_stacks, internal_format, false /* no concurrent lock printed */, false /* simple format */);
|
|
}
|
|
static void print_on_error(outputStream* st, Thread* current, char* buf, int buflen);
|
|
|
|
diff --git a/hotspot/src/share/vm/runtime/threadStatisticalInfo.hpp b/hotspot/src/share/vm/runtime/threadStatisticalInfo.hpp
|
|
new file mode 100644
|
|
index 0000000..9dbe62d
|
|
--- /dev/null
|
|
+++ b/hotspot/src/share/vm/runtime/threadStatisticalInfo.hpp
|
|
@@ -0,0 +1,49 @@
|
|
+/*
|
|
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
|
+ * Copyright (c) 2018 SAP SE. All rights reserved.
|
|
+ * Copyright (c) 2022, Huawei Technologies Co., Ltd. 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.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef SHARE_VM_RUNTIME_THREADSTATISTICS_HPP
|
|
+#define SHARE_VM_RUNTIME_THREADSTATISTICS_HPP
|
|
+
|
|
+#include "prims/jni.h"
|
|
+#include "runtime/os.hpp"
|
|
+#include "utilities/globalDefinitions.hpp"
|
|
+
|
|
+
|
|
+class ThreadStatisticalInfo {
|
|
+ // The time stamp the thread was started.
|
|
+ const uint64_t _start_time_stamp;
|
|
+ uint64_t _define_class_count;
|
|
+
|
|
+public:
|
|
+ ThreadStatisticalInfo() : _start_time_stamp(os::javaTimeMillis()), _define_class_count(0) {}
|
|
+ uint64_t getStartTime() const { return _start_time_stamp; }
|
|
+ uint64_t getDefineClassCount() const { return _define_class_count; }
|
|
+ void setDefineClassCount(uint64_t defineClassCount) { _define_class_count = defineClassCount; }
|
|
+ void incr_define_class_count() { _define_class_count += 1; }
|
|
+ uint64_t getElapsedTime() const { return os::javaTimeMillis() - getStartTime(); }
|
|
+};
|
|
+
|
|
+#endif // SHARE_VM_RUNTIME_THREADSTATISTICS_HPP
|
|
diff --git a/hotspot/src/share/vm/runtime/vm_operations.cpp b/hotspot/src/share/vm/runtime/vm_operations.cpp
|
|
index b42d18f..03c4249 100644
|
|
--- a/hotspot/src/share/vm/runtime/vm_operations.cpp
|
|
+++ b/hotspot/src/share/vm/runtime/vm_operations.cpp
|
|
@@ -195,7 +195,7 @@ bool VM_PrintThreads::doit_prologue() {
|
|
}
|
|
|
|
void VM_PrintThreads::doit() {
|
|
- Threads::print_on(_out, true, false, _print_concurrent_locks);
|
|
+ Threads::print_on(_out, true, false, _print_concurrent_locks, _print_extended_info);
|
|
}
|
|
|
|
void VM_PrintThreads::doit_epilogue() {
|
|
diff --git a/hotspot/src/share/vm/runtime/vm_operations.hpp b/hotspot/src/share/vm/runtime/vm_operations.hpp
|
|
index 19c33f8..baf6042 100644
|
|
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp
|
|
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp
|
|
@@ -311,10 +311,17 @@ class VM_PrintThreads: public VM_Operation {
|
|
private:
|
|
outputStream* _out;
|
|
bool _print_concurrent_locks;
|
|
+ bool _print_extended_info;
|
|
public:
|
|
- VM_PrintThreads() { _out = tty; _print_concurrent_locks = PrintConcurrentLocks; }
|
|
- VM_PrintThreads(outputStream* out, bool print_concurrent_locks) { _out = out; _print_concurrent_locks = print_concurrent_locks; }
|
|
- VMOp_Type type() const { return VMOp_PrintThreads; }
|
|
+ VM_PrintThreads()
|
|
+ : _out(tty), _print_concurrent_locks(PrintConcurrentLocks), _print_extended_info(false)
|
|
+ {}
|
|
+ VM_PrintThreads(outputStream* out, bool print_concurrent_locks, bool print_extended_info)
|
|
+ : _out(out), _print_concurrent_locks(print_concurrent_locks), _print_extended_info(print_extended_info)
|
|
+ {}
|
|
+ VMOp_Type type() const {
|
|
+ return VMOp_PrintThreads;
|
|
+ }
|
|
void doit();
|
|
bool doit_prologue();
|
|
void doit_epilogue();
|
|
diff --git a/hotspot/src/share/vm/services/attachListener.cpp b/hotspot/src/share/vm/services/attachListener.cpp
|
|
index d4dea71..7c57637 100644
|
|
--- a/hotspot/src/share/vm/services/attachListener.cpp
|
|
+++ b/hotspot/src/share/vm/services/attachListener.cpp
|
|
@@ -132,12 +132,20 @@ static jint data_dump(AttachOperation* op, outputStream* out) {
|
|
//
|
|
static jint thread_dump(AttachOperation* op, outputStream* out) {
|
|
bool print_concurrent_locks = false;
|
|
- if (op->arg(0) != NULL && strcmp(op->arg(0), "-l") == 0) {
|
|
- print_concurrent_locks = true;
|
|
+ bool print_extended_info = false;
|
|
+ if (op->arg(0) != NULL) {
|
|
+ for (int i = 0; op->arg(0)[i] != 0; ++i) {
|
|
+ if (op->arg(0)[i] == 'l') {
|
|
+ print_concurrent_locks = true;
|
|
+ }
|
|
+ if (op->arg(0)[i] == 'e') {
|
|
+ print_extended_info = true;
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
// thread stacks
|
|
- VM_PrintThreads op1(out, print_concurrent_locks);
|
|
+ VM_PrintThreads op1(out, print_concurrent_locks, print_extended_info);
|
|
VMThread::execute(&op1);
|
|
|
|
// JNI global handles
|
|
diff --git a/hotspot/src/share/vm/services/diagnosticCommand.cpp b/hotspot/src/share/vm/services/diagnosticCommand.cpp
|
|
index c9bc7d2..fb8e293 100644
|
|
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp
|
|
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp
|
|
@@ -535,13 +535,15 @@ int ClassStatsDCmd::num_arguments() {
|
|
|
|
ThreadDumpDCmd::ThreadDumpDCmd(outputStream* output, bool heap) :
|
|
DCmdWithParser(output, heap),
|
|
- _locks("-l", "print java.util.concurrent locks", "BOOLEAN", false, "false") {
|
|
+ _locks("-l", "print java.util.concurrent locks", "BOOLEAN", false, "false"),
|
|
+ _extended("-e", "print extended thread information", "BOOLEAN", false, "false") {
|
|
_dcmdparser.add_dcmd_option(&_locks);
|
|
+ _dcmdparser.add_dcmd_option(&_extended);
|
|
}
|
|
|
|
void ThreadDumpDCmd::execute(DCmdSource source, TRAPS) {
|
|
// thread stacks
|
|
- VM_PrintThreads op1(output(), _locks.value());
|
|
+ VM_PrintThreads op1(output(), _locks.value(), _extended.value());
|
|
VMThread::execute(&op1);
|
|
|
|
// JNI global handles
|
|
diff --git a/hotspot/src/share/vm/services/diagnosticCommand.hpp b/hotspot/src/share/vm/services/diagnosticCommand.hpp
|
|
index 275e053..87bff52 100644
|
|
--- a/hotspot/src/share/vm/services/diagnosticCommand.hpp
|
|
+++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp
|
|
@@ -362,6 +362,7 @@ public:
|
|
class ThreadDumpDCmd : public DCmdWithParser {
|
|
protected:
|
|
DCmdArgument<bool> _locks;
|
|
+ DCmdArgument<bool> _extended;
|
|
public:
|
|
ThreadDumpDCmd(outputStream* output, bool heap);
|
|
static const char* name() { return "Thread.print"; }
|
|
diff --git a/jdk/src/share/classes/sun/tools/jstack/JStack.java b/jdk/src/share/classes/sun/tools/jstack/JStack.java
|
|
index 6c96af2..3eea094 100644
|
|
--- a/jdk/src/share/classes/sun/tools/jstack/JStack.java
|
|
+++ b/jdk/src/share/classes/sun/tools/jstack/JStack.java
|
|
@@ -48,6 +48,7 @@ public class JStack {
|
|
boolean useSA = false;
|
|
boolean mixed = false;
|
|
boolean locks = false;
|
|
+ boolean extended = false;
|
|
|
|
// Parse the options (arguments starting with "-" )
|
|
int optionCount = 0;
|
|
@@ -69,7 +70,11 @@ public class JStack {
|
|
if (arg.equals("-l")) {
|
|
locks = true;
|
|
} else {
|
|
- usage(1);
|
|
+ if (arg.equals("-e")) {
|
|
+ extended = true;
|
|
+ } else {
|
|
+ usage(1);
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
@@ -107,11 +112,12 @@ public class JStack {
|
|
} else {
|
|
// pass -l to thread dump operation to get extra lock info
|
|
String pid = args[optionCount];
|
|
- String params[];
|
|
+ String params[]= new String[] { "" };
|
|
+ if (extended) {
|
|
+ params[0] += "-e ";
|
|
+ }
|
|
if (locks) {
|
|
- params = new String[] { "-l" };
|
|
- } else {
|
|
- params = new String[0];
|
|
+ params[0] += "-l";
|
|
}
|
|
runThreadDump(pid, params);
|
|
}
|
|
@@ -205,7 +211,7 @@ public class JStack {
|
|
// print usage message
|
|
private static void usage(int exit) {
|
|
System.err.println("Usage:");
|
|
- System.err.println(" jstack [-l] <pid>");
|
|
+ System.err.println(" jstack [-l][-e] <pid>");
|
|
System.err.println(" (to connect to running process)");
|
|
|
|
if (loadSAClass() != null) {
|
|
@@ -227,6 +233,7 @@ public class JStack {
|
|
}
|
|
|
|
System.err.println(" -l long listing. Prints additional information about locks");
|
|
+ System.err.println(" -e extended listing. Prints additional information about threads");
|
|
System.err.println(" -h or -help to print this help message");
|
|
System.exit(exit);
|
|
}
|
|
--
|
|
1.8.3.1
|