--- a/hotspot/src/share/vm/runtime/thread.cpp Mon Sep 22 16:22:21 2014 +0200
+++ b/hotspot/src/share/vm/runtime/thread.cpp Thu Sep 04 11:21:08 2014 +0200
@@ -826,6 +826,7 @@
st->print("os_prio=%d ", os_prio);
}
st->print("tid=" INTPTR_FORMAT " ", this);
+ ext().print_on(st);
osthread()->print_on(st);
}
debug_only(if (WizardMode) print_owned_locks_on(st);)
@@ -2964,6 +2965,8 @@
// Push the Java priority down to the native thread; needs Threads_lock
Thread::set_priority(this, prio);
+ prepare_ext();
+
// Add the new thread to the Threads list and set it in motion.
// We must have threads lock in order to call Threads::add.
// It is crucial that we do not block before the thread is
@@ -3795,6 +3798,24 @@
}
}
+JavaThread* Threads::find_java_thread_from_java_tid(jlong java_tid) {
+ assert(Threads_lock->owned_by_self(), "Must hold Threads_lock");
+
+ JavaThread* java_thread = NULL;
+ // Sequential search for now. Need to do better optimization later.
+ for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) {
+ oop tobj = thread->threadObj();
+ if (!thread->is_exiting() &&
+ tobj != NULL &&
+ java_tid == java_lang_Thread::thread_id(tobj)) {
+ java_thread = thread;
+ break;
+ }
+ }
+ return java_thread;
+}
+
+
// Last thread running calls java.lang.Shutdown.shutdown()
void JavaThread::invoke_shutdown_hooks() {
HandleMark hm(this);
--- a/hotspot/src/share/vm/runtime/thread.hpp Mon Sep 22 16:22:21 2014 +0200
+++ b/hotspot/src/share/vm/runtime/thread.hpp Thu Sep 04 11:21:08 2014 +0200
@@ -40,6 +40,7 @@
#include "runtime/safepoint.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/threadLocalStorage.hpp"
+#include "runtime/thread_ext.hpp"
#include "runtime/unhandledOops.hpp"
#include "utilities/macros.hpp"
@@ -256,6 +257,8 @@
TRACE_DATA _trace_data; // Thread-local data for tracing
+ ThreadExt _ext;
+
int _vm_operation_started_count; // VM_Operation support
int _vm_operation_completed_count; // VM_Operation support
@@ -409,6 +412,9 @@
TRACE_DATA* trace_data() { return &_trace_data; }
+ const ThreadExt& ext() const { return _ext; }
+ ThreadExt& ext() { return _ext; }
+
// VM operation support
int vm_operation_ticket() { return ++_vm_operation_started_count; }
int vm_operation_completed_count() { return _vm_operation_completed_count; }
@@ -978,6 +984,7 @@
// not specified, use the priority of the thread object. Threads_lock
// must be held while this function is called.
void prepare(jobject jni_thread, ThreadPriority prio=NoPriority);
+ void prepare_ext();
void set_saved_exception_pc(address pc) { _saved_exception_pc = pc; }
address saved_exception_pc() { return _saved_exception_pc; }
@@ -1910,6 +1917,8 @@
// Deoptimizes all frames tied to marked nmethods
static void deoptimized_wrt_marked_nmethods();
+ static JavaThread* find_java_thread_from_java_tid(jlong java_tid);
+
};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/thread_ext.cpp Thu Sep 04 11:21:08 2014 +0200
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "runtime/thread.hpp"
+#include "runtime/thread_ext.hpp"
+
+void JavaThread::prepare_ext() {
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/thread_ext.hpp Thu Sep 04 11:21:08 2014 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ */
+
+#ifndef SHARE_VM_RUNTIME_THREAD_EXT_HPP
+#define SHARE_VM_RUNTIME_THREAD_EXT_HPP
+
+#include "memory/allocation.hpp"
+
+class ThreadExt VALUE_OBJ_CLASS_SPEC {
+public:
+ void print_on(outputStream* st) const {};
+};
+
+#endif // SHARE_VM_RUNTIME_THREAD_EXT_HPP
--- a/hotspot/src/share/vm/services/management.cpp Mon Sep 22 16:22:21 2014 +0200
+++ b/hotspot/src/share/vm/services/management.cpp Thu Sep 04 11:21:08 2014 +0200
@@ -392,23 +392,6 @@
return (instanceOop) element();
}
-// Helper functions
-static JavaThread* find_java_thread_from_id(jlong thread_id) {
- assert(Threads_lock->owned_by_self(), "Must hold Threads_lock");
-
- JavaThread* java_thread = NULL;
- // Sequential search for now. Need to do better optimization later.
- for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) {
- oop tobj = thread->threadObj();
- if (!thread->is_exiting() &&
- tobj != NULL &&
- thread_id == java_lang_Thread::thread_id(tobj)) {
- java_thread = thread;
- break;
- }
- }
- return java_thread;
-}
static GCMemoryManager* get_gc_memory_manager_from_jobject(jobject mgr, TRAPS) {
if (mgr == NULL) {
@@ -445,6 +428,8 @@
return MemoryService::get_memory_pool(ph);
}
+#endif // INCLUDE_MANAGEMENT
+
static void validate_thread_id_array(typeArrayHandle ids_ah, TRAPS) {
int num_threads = ids_ah->length();
@@ -460,6 +445,8 @@
}
}
+#if INCLUDE_MANAGEMENT
+
static void validate_thread_info_array(objArrayHandle infoArray_h, TRAPS) {
// check if the element of infoArray is of type ThreadInfo class
Klass* threadinfo_klass = Management::java_lang_management_ThreadInfo_klass(CHECK);
@@ -823,45 +810,6 @@
return prev;
JVM_END
-// Gets an array containing the amount of memory allocated on the Java
-// heap for a set of threads (in bytes). Each element of the array is
-// the amount of memory allocated for the thread ID specified in the
-// corresponding entry in the given array of thread IDs; or -1 if the
-// thread does not exist or has terminated.
-JVM_ENTRY(void, jmm_GetThreadAllocatedMemory(JNIEnv *env, jlongArray ids,
- jlongArray sizeArray))
- // Check if threads is null
- if (ids == NULL || sizeArray == NULL) {
- THROW(vmSymbols::java_lang_NullPointerException());
- }
-
- ResourceMark rm(THREAD);
- typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
- typeArrayHandle ids_ah(THREAD, ta);
-
- typeArrayOop sa = typeArrayOop(JNIHandles::resolve_non_null(sizeArray));
- typeArrayHandle sizeArray_h(THREAD, sa);
-
- // validate the thread id array
- validate_thread_id_array(ids_ah, CHECK);
-
- // sizeArray must be of the same length as the given array of thread IDs
- int num_threads = ids_ah->length();
- if (num_threads != sizeArray_h->length()) {
- THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
- "The length of the given long array does not match the length of "
- "the given array of thread IDs");
- }
-
- MutexLockerEx ml(Threads_lock);
- for (int i = 0; i < num_threads; i++) {
- JavaThread* java_thread = find_java_thread_from_id(ids_ah->long_at(i));
- if (java_thread != NULL) {
- sizeArray_h->long_at_put(i, java_thread->cooked_allocated_bytes());
- }
- }
-JVM_END
-
// Returns a java/lang/management/MemoryUsage object representing
// the memory usage for the heap or non-heap memory.
JVM_ENTRY(jobject, jmm_GetMemoryUsage(JNIEnv* env, jboolean heap))
@@ -1167,7 +1115,7 @@
MutexLockerEx ml(Threads_lock);
for (int i = 0; i < num_threads; i++) {
jlong tid = ids_ah->long_at(i);
- JavaThread* jt = find_java_thread_from_id(tid);
+ JavaThread* jt = Threads::find_java_thread_from_java_tid(tid);
oop thread_obj = (jt != NULL ? jt->threadObj() : (oop)NULL);
instanceHandle threadObj_h(THREAD, (instanceOop) thread_obj);
thread_handle_array->append(threadObj_h);
@@ -1244,7 +1192,7 @@
MutexLockerEx ml(Threads_lock);
for (int i = 0; i < num_threads; i++) {
jlong tid = ids_ah->long_at(i);
- JavaThread* jt = find_java_thread_from_id(tid);
+ JavaThread* jt = Threads::find_java_thread_from_java_tid(tid);
ThreadSnapshot* ts;
if (jt == NULL) {
// if the thread does not exist or now it is terminated,
@@ -1488,7 +1436,7 @@
}
} else {
// reset contention statistics for a given thread
- JavaThread* java_thread = find_java_thread_from_id(tid);
+ JavaThread* java_thread = Threads::find_java_thread_from_java_tid(tid);
if (java_thread == NULL) {
return false;
}
@@ -1557,7 +1505,7 @@
return os::current_thread_cpu_time();
} else {
MutexLockerEx ml(Threads_lock);
- java_thread = find_java_thread_from_id(thread_id);
+ java_thread = Threads::find_java_thread_from_java_tid(thread_id);
if (java_thread != NULL) {
return os::thread_cpu_time((Thread*) java_thread);
}
@@ -1565,78 +1513,6 @@
return -1;
JVM_END
-// Returns the CPU time consumed by a given thread (in nanoseconds).
-// If thread_id == 0, CPU time for the current thread is returned.
-// If user_sys_cpu_time = true, user level and system CPU time of
-// a given thread is returned; otherwise, only user level CPU time
-// is returned.
-JVM_ENTRY(jlong, jmm_GetThreadCpuTimeWithKind(JNIEnv *env, jlong thread_id, jboolean user_sys_cpu_time))
- if (!os::is_thread_cpu_time_supported()) {
- return -1;
- }
-
- if (thread_id < 0) {
- THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
- "Invalid thread ID", -1);
- }
-
- JavaThread* java_thread = NULL;
- if (thread_id == 0) {
- // current thread
- return os::current_thread_cpu_time(user_sys_cpu_time != 0);
- } else {
- MutexLockerEx ml(Threads_lock);
- java_thread = find_java_thread_from_id(thread_id);
- if (java_thread != NULL) {
- return os::thread_cpu_time((Thread*) java_thread, user_sys_cpu_time != 0);
- }
- }
- return -1;
-JVM_END
-
-// Gets an array containing the CPU times consumed by a set of threads
-// (in nanoseconds). Each element of the array is the CPU time for the
-// thread ID specified in the corresponding entry in the given array
-// of thread IDs; or -1 if the thread does not exist or has terminated.
-// If user_sys_cpu_time = true, the sum of user level and system CPU time
-// for the given thread is returned; otherwise, only user level CPU time
-// is returned.
-JVM_ENTRY(void, jmm_GetThreadCpuTimesWithKind(JNIEnv *env, jlongArray ids,
- jlongArray timeArray,
- jboolean user_sys_cpu_time))
- // Check if threads is null
- if (ids == NULL || timeArray == NULL) {
- THROW(vmSymbols::java_lang_NullPointerException());
- }
-
- ResourceMark rm(THREAD);
- typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
- typeArrayHandle ids_ah(THREAD, ta);
-
- typeArrayOop tia = typeArrayOop(JNIHandles::resolve_non_null(timeArray));
- typeArrayHandle timeArray_h(THREAD, tia);
-
- // validate the thread id array
- validate_thread_id_array(ids_ah, CHECK);
-
- // timeArray must be of the same length as the given array of thread IDs
- int num_threads = ids_ah->length();
- if (num_threads != timeArray_h->length()) {
- THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
- "The length of the given long array does not match the length of "
- "the given array of thread IDs");
- }
-
- MutexLockerEx ml(Threads_lock);
- for (int i = 0; i < num_threads; i++) {
- JavaThread* java_thread = find_java_thread_from_id(ids_ah->long_at(i));
- if (java_thread != NULL) {
- timeArray_h->long_at_put(i, os::thread_cpu_time((Thread*)java_thread,
- user_sys_cpu_time != 0));
- }
- }
-JVM_END
-
// Returns a String array of all VM global flag names
JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))
// last flag entry is always NULL, so subtract 1
@@ -2331,7 +2207,122 @@
return (jlong)(((double)ticks / (double)os::elapsed_frequency())
* (double)1000.0);
}
+#endif // INCLUDE_MANAGEMENT
+// Gets an array containing the amount of memory allocated on the Java
+// heap for a set of threads (in bytes). Each element of the array is
+// the amount of memory allocated for the thread ID specified in the
+// corresponding entry in the given array of thread IDs; or -1 if the
+// thread does not exist or has terminated.
+JVM_ENTRY(void, jmm_GetThreadAllocatedMemory(JNIEnv *env, jlongArray ids,
+ jlongArray sizeArray))
+ // Check if threads is null
+ if (ids == NULL || sizeArray == NULL) {
+ THROW(vmSymbols::java_lang_NullPointerException());
+ }
+
+ ResourceMark rm(THREAD);
+ typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
+ typeArrayHandle ids_ah(THREAD, ta);
+
+ typeArrayOop sa = typeArrayOop(JNIHandles::resolve_non_null(sizeArray));
+ typeArrayHandle sizeArray_h(THREAD, sa);
+
+ // validate the thread id array
+ validate_thread_id_array(ids_ah, CHECK);
+
+ // sizeArray must be of the same length as the given array of thread IDs
+ int num_threads = ids_ah->length();
+ if (num_threads != sizeArray_h->length()) {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "The length of the given long array does not match the length of "
+ "the given array of thread IDs");
+ }
+
+ MutexLockerEx ml(Threads_lock);
+ for (int i = 0; i < num_threads; i++) {
+ JavaThread* java_thread = Threads::find_java_thread_from_java_tid(ids_ah->long_at(i));
+ if (java_thread != NULL) {
+ sizeArray_h->long_at_put(i, java_thread->cooked_allocated_bytes());
+ }
+ }
+JVM_END
+
+// Returns the CPU time consumed by a given thread (in nanoseconds).
+// If thread_id == 0, CPU time for the current thread is returned.
+// If user_sys_cpu_time = true, user level and system CPU time of
+// a given thread is returned; otherwise, only user level CPU time
+// is returned.
+JVM_ENTRY(jlong, jmm_GetThreadCpuTimeWithKind(JNIEnv *env, jlong thread_id, jboolean user_sys_cpu_time))
+ if (!os::is_thread_cpu_time_supported()) {
+ return -1;
+ }
+
+ if (thread_id < 0) {
+ THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
+ "Invalid thread ID", -1);
+ }
+
+ JavaThread* java_thread = NULL;
+ if (thread_id == 0) {
+ // current thread
+ return os::current_thread_cpu_time(user_sys_cpu_time != 0);
+ } else {
+ MutexLockerEx ml(Threads_lock);
+ java_thread = Threads::find_java_thread_from_java_tid(thread_id);
+ if (java_thread != NULL) {
+ return os::thread_cpu_time((Thread*) java_thread, user_sys_cpu_time != 0);
+ }
+ }
+ return -1;
+JVM_END
+
+// Gets an array containing the CPU times consumed by a set of threads
+// (in nanoseconds). Each element of the array is the CPU time for the
+// thread ID specified in the corresponding entry in the given array
+// of thread IDs; or -1 if the thread does not exist or has terminated.
+// If user_sys_cpu_time = true, the sum of user level and system CPU time
+// for the given thread is returned; otherwise, only user level CPU time
+// is returned.
+JVM_ENTRY(void, jmm_GetThreadCpuTimesWithKind(JNIEnv *env, jlongArray ids,
+ jlongArray timeArray,
+ jboolean user_sys_cpu_time))
+ // Check if threads is null
+ if (ids == NULL || timeArray == NULL) {
+ THROW(vmSymbols::java_lang_NullPointerException());
+ }
+
+ ResourceMark rm(THREAD);
+ typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
+ typeArrayHandle ids_ah(THREAD, ta);
+
+ typeArrayOop tia = typeArrayOop(JNIHandles::resolve_non_null(timeArray));
+ typeArrayHandle timeArray_h(THREAD, tia);
+
+ // validate the thread id array
+ validate_thread_id_array(ids_ah, CHECK);
+
+ // timeArray must be of the same length as the given array of thread IDs
+ int num_threads = ids_ah->length();
+ if (num_threads != timeArray_h->length()) {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "The length of the given long array does not match the length of "
+ "the given array of thread IDs");
+ }
+
+ MutexLockerEx ml(Threads_lock);
+ for (int i = 0; i < num_threads; i++) {
+ JavaThread* java_thread = Threads::find_java_thread_from_java_tid(ids_ah->long_at(i));
+ if (java_thread != NULL) {
+ timeArray_h->long_at_put(i, os::thread_cpu_time((Thread*)java_thread,
+ user_sys_cpu_time != 0));
+ }
+ }
+JVM_END
+
+
+
+#if INCLUDE_MANAGEMENT
const struct jmmInterface_1_ jmm_interface = {
NULL,
NULL,