mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-18 18:14:38 +02:00
8057535: add a thread extension class
Reviewed-by: mgerdin, bdelsart, jcoomes
This commit is contained in:
parent
bc3ffaa29f
commit
fed95a6860
5 changed files with 219 additions and 132 deletions
|
@ -826,6 +826,7 @@ void Thread::print_on(outputStream* st) const {
|
||||||
st->print("os_prio=%d ", os_prio);
|
st->print("os_prio=%d ", os_prio);
|
||||||
}
|
}
|
||||||
st->print("tid=" INTPTR_FORMAT " ", this);
|
st->print("tid=" INTPTR_FORMAT " ", this);
|
||||||
|
ext().print_on(st);
|
||||||
osthread()->print_on(st);
|
osthread()->print_on(st);
|
||||||
}
|
}
|
||||||
debug_only(if (WizardMode) print_owned_locks_on(st);)
|
debug_only(if (WizardMode) print_owned_locks_on(st);)
|
||||||
|
@ -2964,6 +2965,8 @@ void JavaThread::prepare(jobject jni_thread, ThreadPriority prio) {
|
||||||
// Push the Java priority down to the native thread; needs Threads_lock
|
// Push the Java priority down to the native thread; needs Threads_lock
|
||||||
Thread::set_priority(this, prio);
|
Thread::set_priority(this, prio);
|
||||||
|
|
||||||
|
prepare_ext();
|
||||||
|
|
||||||
// Add the new thread to the Threads list and set it in motion.
|
// Add the new thread to the Threads list and set it in motion.
|
||||||
// We must have threads lock in order to call Threads::add.
|
// We must have threads lock in order to call Threads::add.
|
||||||
// It is crucial that we do not block before the thread is
|
// It is crucial that we do not block before the thread is
|
||||||
|
@ -3795,6 +3798,24 @@ void Threads::create_vm_init_libraries() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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()
|
// Last thread running calls java.lang.Shutdown.shutdown()
|
||||||
void JavaThread::invoke_shutdown_hooks() {
|
void JavaThread::invoke_shutdown_hooks() {
|
||||||
HandleMark hm(this);
|
HandleMark hm(this);
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "runtime/safepoint.hpp"
|
#include "runtime/safepoint.hpp"
|
||||||
#include "runtime/stubRoutines.hpp"
|
#include "runtime/stubRoutines.hpp"
|
||||||
#include "runtime/threadLocalStorage.hpp"
|
#include "runtime/threadLocalStorage.hpp"
|
||||||
|
#include "runtime/thread_ext.hpp"
|
||||||
#include "runtime/unhandledOops.hpp"
|
#include "runtime/unhandledOops.hpp"
|
||||||
#include "utilities/macros.hpp"
|
#include "utilities/macros.hpp"
|
||||||
|
|
||||||
|
@ -256,6 +257,8 @@ class Thread: public ThreadShadow {
|
||||||
|
|
||||||
TRACE_DATA _trace_data; // Thread-local data for tracing
|
TRACE_DATA _trace_data; // Thread-local data for tracing
|
||||||
|
|
||||||
|
ThreadExt _ext;
|
||||||
|
|
||||||
int _vm_operation_started_count; // VM_Operation support
|
int _vm_operation_started_count; // VM_Operation support
|
||||||
int _vm_operation_completed_count; // VM_Operation support
|
int _vm_operation_completed_count; // VM_Operation support
|
||||||
|
|
||||||
|
@ -409,6 +412,9 @@ class Thread: public ThreadShadow {
|
||||||
|
|
||||||
TRACE_DATA* trace_data() { return &_trace_data; }
|
TRACE_DATA* trace_data() { return &_trace_data; }
|
||||||
|
|
||||||
|
const ThreadExt& ext() const { return _ext; }
|
||||||
|
ThreadExt& ext() { return _ext; }
|
||||||
|
|
||||||
// VM operation support
|
// VM operation support
|
||||||
int vm_operation_ticket() { return ++_vm_operation_started_count; }
|
int vm_operation_ticket() { return ++_vm_operation_started_count; }
|
||||||
int vm_operation_completed_count() { return _vm_operation_completed_count; }
|
int vm_operation_completed_count() { return _vm_operation_completed_count; }
|
||||||
|
@ -978,6 +984,7 @@ class JavaThread: public Thread {
|
||||||
// not specified, use the priority of the thread object. Threads_lock
|
// not specified, use the priority of the thread object. Threads_lock
|
||||||
// must be held while this function is called.
|
// must be held while this function is called.
|
||||||
void prepare(jobject jni_thread, ThreadPriority prio=NoPriority);
|
void prepare(jobject jni_thread, ThreadPriority prio=NoPriority);
|
||||||
|
void prepare_ext();
|
||||||
|
|
||||||
void set_saved_exception_pc(address pc) { _saved_exception_pc = pc; }
|
void set_saved_exception_pc(address pc) { _saved_exception_pc = pc; }
|
||||||
address saved_exception_pc() { return _saved_exception_pc; }
|
address saved_exception_pc() { return _saved_exception_pc; }
|
||||||
|
@ -1910,6 +1917,8 @@ class Threads: AllStatic {
|
||||||
// Deoptimizes all frames tied to marked nmethods
|
// Deoptimizes all frames tied to marked nmethods
|
||||||
static void deoptimized_wrt_marked_nmethods();
|
static void deoptimized_wrt_marked_nmethods();
|
||||||
|
|
||||||
|
static JavaThread* find_java_thread_from_java_tid(jlong java_tid);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
31
hotspot/src/share/vm/runtime/thread_ext.cpp
Normal file
31
hotspot/src/share/vm/runtime/thread_ext.cpp
Normal file
|
@ -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() {
|
||||||
|
}
|
||||||
|
|
35
hotspot/src/share/vm/runtime/thread_ext.hpp
Normal file
35
hotspot/src/share/vm/runtime/thread_ext.hpp
Normal file
|
@ -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
|
|
@ -392,23 +392,6 @@ instanceOop Management::create_thread_info_instance(ThreadSnapshot* snapshot,
|
||||||
return (instanceOop) element();
|
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) {
|
static GCMemoryManager* get_gc_memory_manager_from_jobject(jobject mgr, TRAPS) {
|
||||||
if (mgr == NULL) {
|
if (mgr == NULL) {
|
||||||
|
@ -445,6 +428,8 @@ static MemoryPool* get_memory_pool_from_jobject(jobject obj, TRAPS) {
|
||||||
return MemoryService::get_memory_pool(ph);
|
return MemoryService::get_memory_pool(ph);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // INCLUDE_MANAGEMENT
|
||||||
|
|
||||||
static void validate_thread_id_array(typeArrayHandle ids_ah, TRAPS) {
|
static void validate_thread_id_array(typeArrayHandle ids_ah, TRAPS) {
|
||||||
int num_threads = ids_ah->length();
|
int num_threads = ids_ah->length();
|
||||||
|
|
||||||
|
@ -460,6 +445,8 @@ static void validate_thread_id_array(typeArrayHandle ids_ah, TRAPS) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if INCLUDE_MANAGEMENT
|
||||||
|
|
||||||
static void validate_thread_info_array(objArrayHandle infoArray_h, TRAPS) {
|
static void validate_thread_info_array(objArrayHandle infoArray_h, TRAPS) {
|
||||||
// check if the element of infoArray is of type ThreadInfo class
|
// check if the element of infoArray is of type ThreadInfo class
|
||||||
Klass* threadinfo_klass = Management::java_lang_management_ThreadInfo_klass(CHECK);
|
Klass* threadinfo_klass = Management::java_lang_management_ThreadInfo_klass(CHECK);
|
||||||
|
@ -823,45 +810,6 @@ JVM_ENTRY(jlong, jmm_SetPoolThreshold(JNIEnv* env, jobject obj, jmmThresholdType
|
||||||
return prev;
|
return prev;
|
||||||
JVM_END
|
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
|
// Returns a java/lang/management/MemoryUsage object representing
|
||||||
// the memory usage for the heap or non-heap memory.
|
// the memory usage for the heap or non-heap memory.
|
||||||
JVM_ENTRY(jobject, jmm_GetMemoryUsage(JNIEnv* env, jboolean heap))
|
JVM_ENTRY(jobject, jmm_GetMemoryUsage(JNIEnv* env, jboolean heap))
|
||||||
|
@ -1167,7 +1115,7 @@ static void do_thread_dump(ThreadDumpResult* dump_result,
|
||||||
MutexLockerEx ml(Threads_lock);
|
MutexLockerEx ml(Threads_lock);
|
||||||
for (int i = 0; i < num_threads; i++) {
|
for (int i = 0; i < num_threads; i++) {
|
||||||
jlong tid = ids_ah->long_at(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);
|
oop thread_obj = (jt != NULL ? jt->threadObj() : (oop)NULL);
|
||||||
instanceHandle threadObj_h(THREAD, (instanceOop) thread_obj);
|
instanceHandle threadObj_h(THREAD, (instanceOop) thread_obj);
|
||||||
thread_handle_array->append(threadObj_h);
|
thread_handle_array->append(threadObj_h);
|
||||||
|
@ -1244,7 +1192,7 @@ JVM_ENTRY(jint, jmm_GetThreadInfo(JNIEnv *env, jlongArray ids, jint maxDepth, jo
|
||||||
MutexLockerEx ml(Threads_lock);
|
MutexLockerEx ml(Threads_lock);
|
||||||
for (int i = 0; i < num_threads; i++) {
|
for (int i = 0; i < num_threads; i++) {
|
||||||
jlong tid = ids_ah->long_at(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;
|
ThreadSnapshot* ts;
|
||||||
if (jt == NULL) {
|
if (jt == NULL) {
|
||||||
// if the thread does not exist or now it is terminated,
|
// if the thread does not exist or now it is terminated,
|
||||||
|
@ -1488,7 +1436,7 @@ JVM_ENTRY(jboolean, jmm_ResetStatistic(JNIEnv *env, jvalue obj, jmmStatisticType
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// reset contention statistics for a given thread
|
// 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) {
|
if (java_thread == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1557,7 +1505,7 @@ JVM_ENTRY(jlong, jmm_GetThreadCpuTime(JNIEnv *env, jlong thread_id))
|
||||||
return os::current_thread_cpu_time();
|
return os::current_thread_cpu_time();
|
||||||
} else {
|
} else {
|
||||||
MutexLockerEx ml(Threads_lock);
|
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) {
|
if (java_thread != NULL) {
|
||||||
return os::thread_cpu_time((Thread*) java_thread);
|
return os::thread_cpu_time((Thread*) java_thread);
|
||||||
}
|
}
|
||||||
|
@ -1565,78 +1513,6 @@ JVM_ENTRY(jlong, jmm_GetThreadCpuTime(JNIEnv *env, jlong thread_id))
|
||||||
return -1;
|
return -1;
|
||||||
JVM_END
|
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
|
// Returns a String array of all VM global flag names
|
||||||
JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))
|
JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))
|
||||||
// last flag entry is always NULL, so subtract 1
|
// last flag entry is always NULL, so subtract 1
|
||||||
|
@ -2331,7 +2207,122 @@ jlong Management::ticks_to_ms(jlong ticks) {
|
||||||
return (jlong)(((double)ticks / (double)os::elapsed_frequency())
|
return (jlong)(((double)ticks / (double)os::elapsed_frequency())
|
||||||
* (double)1000.0);
|
* (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 = {
|
const struct jmmInterface_1_ jmm_interface = {
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue