24
25 #include "precompiled.hpp"
26 #include "classfile/systemDictionary.hpp"
27 #include "compiler/compileBroker.hpp"
28 #include "memory/iterator.hpp"
29 #include "memory/oopFactory.hpp"
30 #include "memory/resourceArea.hpp"
31 #include "oops/klass.hpp"
32 #include "oops/objArrayKlass.hpp"
33 #include "oops/objArrayOop.inline.hpp"
34 #include "oops/oop.inline.hpp"
35 #include "runtime/arguments.hpp"
36 #include "runtime/globals.hpp"
37 #include "runtime/handles.inline.hpp"
38 #include "runtime/interfaceSupport.hpp"
39 #include "runtime/javaCalls.hpp"
40 #include "runtime/jniHandles.hpp"
41 #include "runtime/os.hpp"
42 #include "runtime/serviceThread.hpp"
43 #include "runtime/thread.inline.hpp"
44 #include "services/classLoadingService.hpp"
45 #include "services/diagnosticCommand.hpp"
46 #include "services/diagnosticFramework.hpp"
47 #include "services/writeableFlags.hpp"
48 #include "services/heapDumper.hpp"
49 #include "services/jmm.h"
50 #include "services/lowMemoryDetector.hpp"
51 #include "services/gcNotifier.hpp"
52 #include "services/nmtDCmd.hpp"
53 #include "services/management.hpp"
54 #include "services/memoryManager.hpp"
55 #include "services/memoryPool.hpp"
56 #include "services/memoryService.hpp"
57 #include "services/runtimeService.hpp"
58 #include "services/threadService.hpp"
59 #include "utilities/debug.hpp"
60 #include "utilities/formatBuffer.hpp"
61 #include "utilities/macros.hpp"
62
63 PerfVariable* Management::_begin_vm_creation_time = NULL;
1008 }
1009 }
1010 }
1011 return num_atts;
1012 JVM_END
1013
1014 // Helper function to do thread dump for a specific list of threads
1015 static void do_thread_dump(ThreadDumpResult* dump_result,
1016 typeArrayHandle ids_ah, // array of thread ID (long[])
1017 int num_threads,
1018 int max_depth,
1019 bool with_locked_monitors,
1020 bool with_locked_synchronizers,
1021 TRAPS) {
1022 // no need to actually perform thread dump if no TIDs are specified
1023 if (num_threads == 0) return;
1024
1025 // First get an array of threadObj handles.
1026 // A JavaThread may terminate before we get the stack trace.
1027 GrowableArray<instanceHandle>* thread_handle_array = new GrowableArray<instanceHandle>(num_threads);
1028 {
1029 MutexLockerEx ml(Threads_lock);
1030 for (int i = 0; i < num_threads; i++) {
1031 jlong tid = ids_ah->long_at(i);
1032 JavaThread* jt = Threads::find_java_thread_from_java_tid(tid);
1033 oop thread_obj = (jt != NULL ? jt->threadObj() : (oop)NULL);
1034 instanceHandle threadObj_h(THREAD, (instanceOop) thread_obj);
1035 thread_handle_array->append(threadObj_h);
1036 }
1037 }
1038
1039 // Obtain thread dumps and thread snapshot information
1040 VM_ThreadDump op(dump_result,
1041 thread_handle_array,
1042 num_threads,
1043 max_depth, /* stack depth */
1044 with_locked_monitors,
1045 with_locked_synchronizers);
1046 VMThread::execute(&op);
1047 }
1048
1049 // Gets an array of ThreadInfo objects. Each element is the ThreadInfo
1050 // for the thread ID specified in the corresponding entry in
1051 // the given array of thread IDs; or NULL if the thread does not exist
1052 // or has terminated.
1084 // validate the ThreadInfo[] parameters
1085 validate_thread_info_array(infoArray_h, CHECK_0);
1086
1087 // infoArray must be of the same length as the given array of thread IDs
1088 int num_threads = ids_ah->length();
1089 if (num_threads != infoArray_h->length()) {
1090 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
1091 "The length of the given ThreadInfo array does not match the length of the given array of thread IDs", -1);
1092 }
1093
1094 // make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots
1095 java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_0);
1096
1097 // Must use ThreadDumpResult to store the ThreadSnapshot.
1098 // GC may occur after the thread snapshots are taken but before
1099 // this function returns. The threadObj and other oops kept
1100 // in the ThreadSnapshot are marked and adjusted during GC.
1101 ThreadDumpResult dump_result(num_threads);
1102
1103 if (maxDepth == 0) {
1104 // no stack trace dumped - do not need to stop the world
1105 {
1106 MutexLockerEx ml(Threads_lock);
1107 for (int i = 0; i < num_threads; i++) {
1108 jlong tid = ids_ah->long_at(i);
1109 JavaThread* jt = Threads::find_java_thread_from_java_tid(tid);
1110 ThreadSnapshot* ts;
1111 if (jt == NULL) {
1112 // if the thread does not exist or now it is terminated,
1113 // create dummy snapshot
1114 ts = new ThreadSnapshot();
1115 } else {
1116 ts = new ThreadSnapshot(jt);
1117 }
1118 dump_result.add_thread_snapshot(ts);
1119 }
1120 }
1121 } else {
1122 // obtain thread dump with the specific list of threads with stack trace
1123 do_thread_dump(&dump_result,
1124 ids_ah,
1125 num_threads,
1126 maxDepth,
1127 false, /* no locked monitor */
1128 false, /* no locked synchronizers */
1129 CHECK_0);
1130 }
1131
1132 int num_snapshots = dump_result.num_snapshots();
1133 assert(num_snapshots == num_threads, "Must match the number of thread snapshots");
1134 int index = 0;
1135 for (ThreadSnapshot* ts = dump_result.snapshots(); ts != NULL; index++, ts = ts->next()) {
1136 // For each thread, create an java/lang/management/ThreadInfo object
1137 // and fill with the thread information
1138
1139 if (ts->threadObj() == NULL) {
1140 // if the thread does not exist or now it is terminated, set threadinfo to NULL
1141 infoArray_h->obj_at_put(index, NULL);
1142 continue;
1143 }
1144
1145 // Create java.lang.management.ThreadInfo object
1146 instanceOop info_obj = Management::create_thread_info_instance(ts, CHECK_0);
1147 infoArray_h->obj_at_put(index, info_obj);
1148 }
1149 return 0;
1150 JVM_END
1151
1152 // Dump thread info for the specified threads.
1153 // It returns an array of ThreadInfo objects. Each element is the ThreadInfo
1179 validate_thread_id_array(ids_ah, CHECK_NULL);
1180
1181 // obtain thread dump of a specific list of threads
1182 do_thread_dump(&dump_result,
1183 ids_ah,
1184 num_threads,
1185 maxDepth, /* stack depth */
1186 (locked_monitors ? true : false), /* with locked monitors */
1187 (locked_synchronizers ? true : false), /* with locked synchronizers */
1188 CHECK_NULL);
1189 } else {
1190 // obtain thread dump of all threads
1191 VM_ThreadDump op(&dump_result,
1192 maxDepth, /* stack depth */
1193 (locked_monitors ? true : false), /* with locked monitors */
1194 (locked_synchronizers ? true : false) /* with locked synchronizers */);
1195 VMThread::execute(&op);
1196 }
1197
1198 int num_snapshots = dump_result.num_snapshots();
1199
1200 // create the result ThreadInfo[] object
1201 InstanceKlass* ik = Management::java_lang_management_ThreadInfo_klass(CHECK_NULL);
1202 objArrayOop r = oopFactory::new_objArray(ik, num_snapshots, CHECK_NULL);
1203 objArrayHandle result_h(THREAD, r);
1204
1205 int index = 0;
1206 for (ThreadSnapshot* ts = dump_result.snapshots(); ts != NULL; ts = ts->next(), index++) {
1207 if (ts->threadObj() == NULL) {
1208 // if the thread does not exist or now it is terminated, set threadinfo to NULL
1209 result_h->obj_at_put(index, NULL);
1210 continue;
1211 }
1212
1213 ThreadStackTrace* stacktrace = ts->get_stack_trace();
1214 assert(stacktrace != NULL, "Must have a stack trace dumped");
1215
1216 // Create Object[] filled with locked monitors
1217 // Create int[] filled with the stack depth where a monitor was locked
1218 int num_frames = stacktrace->get_stack_depth();
1302 // For PEAK_POOL_USAGE stat, obj is required to be a memory pool object.
1303 // For THREAD_CONTENTION_COUNT and TIME stat, obj is required to be a thread ID.
1304 // type - the type of statistic to be reset
1305 //
1306 JVM_ENTRY(jboolean, jmm_ResetStatistic(JNIEnv *env, jvalue obj, jmmStatisticType type))
1307 ResourceMark rm(THREAD);
1308
1309 switch (type) {
1310 case JMM_STAT_PEAK_THREAD_COUNT:
1311 ThreadService::reset_peak_thread_count();
1312 return true;
1313
1314 case JMM_STAT_THREAD_CONTENTION_COUNT:
1315 case JMM_STAT_THREAD_CONTENTION_TIME: {
1316 jlong tid = obj.j;
1317 if (tid < 0) {
1318 THROW_(vmSymbols::java_lang_IllegalArgumentException(), JNI_FALSE);
1319 }
1320
1321 // Look for the JavaThread of this given tid
1322 MutexLockerEx ml(Threads_lock);
1323 if (tid == 0) {
1324 // reset contention statistics for all threads if tid == 0
1325 for (JavaThread* java_thread = Threads::first(); java_thread != NULL; java_thread = java_thread->next()) {
1326 if (type == JMM_STAT_THREAD_CONTENTION_COUNT) {
1327 ThreadService::reset_contention_count_stat(java_thread);
1328 } else {
1329 ThreadService::reset_contention_time_stat(java_thread);
1330 }
1331 }
1332 } else {
1333 // reset contention statistics for a given thread
1334 JavaThread* java_thread = Threads::find_java_thread_from_java_tid(tid);
1335 if (java_thread == NULL) {
1336 return false;
1337 }
1338
1339 if (type == JMM_STAT_THREAD_CONTENTION_COUNT) {
1340 ThreadService::reset_contention_count_stat(java_thread);
1341 } else {
1342 ThreadService::reset_contention_time_stat(java_thread);
1343 }
1344 }
1345 return true;
1346 break;
1347 }
1348 case JMM_STAT_PEAK_POOL_USAGE: {
1349 jobject o = obj.l;
1350 if (o == NULL) {
1351 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE);
1352 }
1353
1354 oop pool_obj = JNIHandles::resolve(o);
1382 JVM_END
1383
1384 // Returns the fast estimate of CPU time consumed by
1385 // a given thread (in nanoseconds).
1386 // If thread_id == 0, return CPU time for the current thread.
1387 JVM_ENTRY(jlong, jmm_GetThreadCpuTime(JNIEnv *env, jlong thread_id))
1388 if (!os::is_thread_cpu_time_supported()) {
1389 return -1;
1390 }
1391
1392 if (thread_id < 0) {
1393 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
1394 "Invalid thread ID", -1);
1395 }
1396
1397 JavaThread* java_thread = NULL;
1398 if (thread_id == 0) {
1399 // current thread
1400 return os::current_thread_cpu_time();
1401 } else {
1402 MutexLockerEx ml(Threads_lock);
1403 java_thread = Threads::find_java_thread_from_java_tid(thread_id);
1404 if (java_thread != NULL) {
1405 return os::thread_cpu_time((Thread*) java_thread);
1406 }
1407 }
1408 return -1;
1409 JVM_END
1410
1411 // Returns a String array of all VM global flag names
1412 JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))
1413 // last flag entry is always NULL, so subtract 1
1414 int nFlags = (int) Flag::numFlags - 1;
1415 // allocate a temp array
1416 objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(),
1417 nFlags, CHECK_0);
1418 objArrayHandle flags_ah(THREAD, r);
1419 int num_entries = 0;
1420 for (int i = 0; i < nFlags; i++) {
1421 Flag* flag = &Flag::flags[i];
1422 // Exclude notproduct and develop flags in product builds.
1423 if (flag->is_constant_in_binary()) {
1632 void do_unlocked();
1633 int count() { return _count; }
1634 };
1635
1636 ThreadTimesClosure::ThreadTimesClosure(objArrayHandle names,
1637 typeArrayHandle times) {
1638 assert(names() != NULL, "names was NULL");
1639 assert(times() != NULL, "times was NULL");
1640 _names_strings = names;
1641 _names_len = names->length();
1642 _names_chars = NEW_C_HEAP_ARRAY(char*, _names_len, mtInternal);
1643 _times = times;
1644 _times_len = times->length();
1645 _count = 0;
1646 }
1647
1648 //
1649 // Called with Threads_lock held
1650 //
1651 void ThreadTimesClosure::do_thread(Thread* thread) {
1652 assert(thread != NULL, "thread was NULL");
1653
1654 // exclude externally visible JavaThreads
1655 if (thread->is_Java_thread() && !thread->is_hidden_from_external_view()) {
1656 return;
1657 }
1658
1659 if (_count >= _names_len || _count >= _times_len) {
1660 // skip if the result array is not big enough
1661 return;
1662 }
1663
1664 EXCEPTION_MARK;
1665 ResourceMark rm(THREAD); // thread->name() uses ResourceArea
1666
1667 assert(thread->name() != NULL, "All threads should have a name");
1668 _names_chars[_count] = os::strdup(thread->name());
1669 _times->long_at_put(_count, os::is_thread_cpu_time_supported() ?
1670 os::thread_cpu_time(thread) : -1);
1671 _count++;
2092 }
2093
2094 ResourceMark rm(THREAD);
2095 typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
2096 typeArrayHandle ids_ah(THREAD, ta);
2097
2098 typeArrayOop sa = typeArrayOop(JNIHandles::resolve_non_null(sizeArray));
2099 typeArrayHandle sizeArray_h(THREAD, sa);
2100
2101 // validate the thread id array
2102 validate_thread_id_array(ids_ah, CHECK);
2103
2104 // sizeArray must be of the same length as the given array of thread IDs
2105 int num_threads = ids_ah->length();
2106 if (num_threads != sizeArray_h->length()) {
2107 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
2108 "The length of the given long array does not match the length of "
2109 "the given array of thread IDs");
2110 }
2111
2112 MutexLockerEx ml(Threads_lock);
2113 for (int i = 0; i < num_threads; i++) {
2114 JavaThread* java_thread = Threads::find_java_thread_from_java_tid(ids_ah->long_at(i));
2115 if (java_thread != NULL) {
2116 sizeArray_h->long_at_put(i, java_thread->cooked_allocated_bytes());
2117 }
2118 }
2119 JVM_END
2120
2121 // Returns the CPU time consumed by a given thread (in nanoseconds).
2122 // If thread_id == 0, CPU time for the current thread is returned.
2123 // If user_sys_cpu_time = true, user level and system CPU time of
2124 // a given thread is returned; otherwise, only user level CPU time
2125 // is returned.
2126 JVM_ENTRY(jlong, jmm_GetThreadCpuTimeWithKind(JNIEnv *env, jlong thread_id, jboolean user_sys_cpu_time))
2127 if (!os::is_thread_cpu_time_supported()) {
2128 return -1;
2129 }
2130
2131 if (thread_id < 0) {
2132 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
2133 "Invalid thread ID", -1);
2134 }
2135
2136 JavaThread* java_thread = NULL;
2137 if (thread_id == 0) {
2138 // current thread
2139 return os::current_thread_cpu_time(user_sys_cpu_time != 0);
2140 } else {
2141 MutexLockerEx ml(Threads_lock);
2142 java_thread = Threads::find_java_thread_from_java_tid(thread_id);
2143 if (java_thread != NULL) {
2144 return os::thread_cpu_time((Thread*) java_thread, user_sys_cpu_time != 0);
2145 }
2146 }
2147 return -1;
2148 JVM_END
2149
2150 // Gets an array containing the CPU times consumed by a set of threads
2151 // (in nanoseconds). Each element of the array is the CPU time for the
2152 // thread ID specified in the corresponding entry in the given array
2153 // of thread IDs; or -1 if the thread does not exist or has terminated.
2154 // If user_sys_cpu_time = true, the sum of user level and system CPU time
2155 // for the given thread is returned; otherwise, only user level CPU time
2156 // is returned.
2157 JVM_ENTRY(void, jmm_GetThreadCpuTimesWithKind(JNIEnv *env, jlongArray ids,
2158 jlongArray timeArray,
2159 jboolean user_sys_cpu_time))
2160 // Check if threads is null
2161 if (ids == NULL || timeArray == NULL) {
2162 THROW(vmSymbols::java_lang_NullPointerException());
2163 }
2164
2165 ResourceMark rm(THREAD);
2166 typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
2167 typeArrayHandle ids_ah(THREAD, ta);
2168
2169 typeArrayOop tia = typeArrayOop(JNIHandles::resolve_non_null(timeArray));
2170 typeArrayHandle timeArray_h(THREAD, tia);
2171
2172 // validate the thread id array
2173 validate_thread_id_array(ids_ah, CHECK);
2174
2175 // timeArray must be of the same length as the given array of thread IDs
2176 int num_threads = ids_ah->length();
2177 if (num_threads != timeArray_h->length()) {
2178 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
2179 "The length of the given long array does not match the length of "
2180 "the given array of thread IDs");
2181 }
2182
2183 MutexLockerEx ml(Threads_lock);
2184 for (int i = 0; i < num_threads; i++) {
2185 JavaThread* java_thread = Threads::find_java_thread_from_java_tid(ids_ah->long_at(i));
2186 if (java_thread != NULL) {
2187 timeArray_h->long_at_put(i, os::thread_cpu_time((Thread*)java_thread,
2188 user_sys_cpu_time != 0));
2189 }
2190 }
2191 JVM_END
2192
2193
2194
2195 #if INCLUDE_MANAGEMENT
2196 const struct jmmInterface_1_ jmm_interface = {
2197 NULL,
2198 NULL,
2199 jmm_GetVersion,
2200 jmm_GetOptionalSupport,
2201 jmm_GetThreadInfo,
2202 jmm_GetMemoryPools,
2203 jmm_GetMemoryManagers,
2204 jmm_GetMemoryPoolUsage,
2205 jmm_GetPeakMemoryPoolUsage,
|
24
25 #include "precompiled.hpp"
26 #include "classfile/systemDictionary.hpp"
27 #include "compiler/compileBroker.hpp"
28 #include "memory/iterator.hpp"
29 #include "memory/oopFactory.hpp"
30 #include "memory/resourceArea.hpp"
31 #include "oops/klass.hpp"
32 #include "oops/objArrayKlass.hpp"
33 #include "oops/objArrayOop.inline.hpp"
34 #include "oops/oop.inline.hpp"
35 #include "runtime/arguments.hpp"
36 #include "runtime/globals.hpp"
37 #include "runtime/handles.inline.hpp"
38 #include "runtime/interfaceSupport.hpp"
39 #include "runtime/javaCalls.hpp"
40 #include "runtime/jniHandles.hpp"
41 #include "runtime/os.hpp"
42 #include "runtime/serviceThread.hpp"
43 #include "runtime/thread.inline.hpp"
44 #include "runtime/threadSMR.hpp"
45 #include "services/classLoadingService.hpp"
46 #include "services/diagnosticCommand.hpp"
47 #include "services/diagnosticFramework.hpp"
48 #include "services/writeableFlags.hpp"
49 #include "services/heapDumper.hpp"
50 #include "services/jmm.h"
51 #include "services/lowMemoryDetector.hpp"
52 #include "services/gcNotifier.hpp"
53 #include "services/nmtDCmd.hpp"
54 #include "services/management.hpp"
55 #include "services/memoryManager.hpp"
56 #include "services/memoryPool.hpp"
57 #include "services/memoryService.hpp"
58 #include "services/runtimeService.hpp"
59 #include "services/threadService.hpp"
60 #include "utilities/debug.hpp"
61 #include "utilities/formatBuffer.hpp"
62 #include "utilities/macros.hpp"
63
64 PerfVariable* Management::_begin_vm_creation_time = NULL;
1009 }
1010 }
1011 }
1012 return num_atts;
1013 JVM_END
1014
1015 // Helper function to do thread dump for a specific list of threads
1016 static void do_thread_dump(ThreadDumpResult* dump_result,
1017 typeArrayHandle ids_ah, // array of thread ID (long[])
1018 int num_threads,
1019 int max_depth,
1020 bool with_locked_monitors,
1021 bool with_locked_synchronizers,
1022 TRAPS) {
1023 // no need to actually perform thread dump if no TIDs are specified
1024 if (num_threads == 0) return;
1025
1026 // First get an array of threadObj handles.
1027 // A JavaThread may terminate before we get the stack trace.
1028 GrowableArray<instanceHandle>* thread_handle_array = new GrowableArray<instanceHandle>(num_threads);
1029
1030 {
1031 // Need this ThreadsListHandle for converting Java thread IDs into
1032 // threadObj handles; dump_result->set_t_list() is called in the
1033 // VM op below so we can't use it yet.
1034 ThreadsListHandle tlh;
1035 for (int i = 0; i < num_threads; i++) {
1036 jlong tid = ids_ah->long_at(i);
1037 JavaThread* jt = tlh.list()->find_JavaThread_from_java_tid(tid);
1038 oop thread_obj = (jt != NULL ? jt->threadObj() : (oop)NULL);
1039 instanceHandle threadObj_h(THREAD, (instanceOop) thread_obj);
1040 thread_handle_array->append(threadObj_h);
1041 }
1042 }
1043
1044 // Obtain thread dumps and thread snapshot information
1045 VM_ThreadDump op(dump_result,
1046 thread_handle_array,
1047 num_threads,
1048 max_depth, /* stack depth */
1049 with_locked_monitors,
1050 with_locked_synchronizers);
1051 VMThread::execute(&op);
1052 }
1053
1054 // Gets an array of ThreadInfo objects. Each element is the ThreadInfo
1055 // for the thread ID specified in the corresponding entry in
1056 // the given array of thread IDs; or NULL if the thread does not exist
1057 // or has terminated.
1089 // validate the ThreadInfo[] parameters
1090 validate_thread_info_array(infoArray_h, CHECK_0);
1091
1092 // infoArray must be of the same length as the given array of thread IDs
1093 int num_threads = ids_ah->length();
1094 if (num_threads != infoArray_h->length()) {
1095 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
1096 "The length of the given ThreadInfo array does not match the length of the given array of thread IDs", -1);
1097 }
1098
1099 // make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots
1100 java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_0);
1101
1102 // Must use ThreadDumpResult to store the ThreadSnapshot.
1103 // GC may occur after the thread snapshots are taken but before
1104 // this function returns. The threadObj and other oops kept
1105 // in the ThreadSnapshot are marked and adjusted during GC.
1106 ThreadDumpResult dump_result(num_threads);
1107
1108 if (maxDepth == 0) {
1109 // No stack trace to dump so we do not need to stop the world.
1110 // Since we never do the VM op here we must set the threads list.
1111 dump_result.set_t_list();
1112 for (int i = 0; i < num_threads; i++) {
1113 jlong tid = ids_ah->long_at(i);
1114 JavaThread* jt = dump_result.t_list()->find_JavaThread_from_java_tid(tid);
1115 ThreadSnapshot* ts;
1116 if (jt == NULL) {
1117 // if the thread does not exist or now it is terminated,
1118 // create dummy snapshot
1119 ts = new ThreadSnapshot();
1120 } else {
1121 ts = new ThreadSnapshot(dump_result.t_list(), jt);
1122 }
1123 dump_result.add_thread_snapshot(ts);
1124 }
1125 } else {
1126 // obtain thread dump with the specific list of threads with stack trace
1127 do_thread_dump(&dump_result,
1128 ids_ah,
1129 num_threads,
1130 maxDepth,
1131 false, /* no locked monitor */
1132 false, /* no locked synchronizers */
1133 CHECK_0);
1134 }
1135
1136 int num_snapshots = dump_result.num_snapshots();
1137 assert(num_snapshots == num_threads, "Must match the number of thread snapshots");
1138 assert(num_snapshots == 0 || dump_result.t_list_has_been_set(), "ThreadsList must have been set if we have a snapshot");
1139 int index = 0;
1140 for (ThreadSnapshot* ts = dump_result.snapshots(); ts != NULL; index++, ts = ts->next()) {
1141 // For each thread, create an java/lang/management/ThreadInfo object
1142 // and fill with the thread information
1143
1144 if (ts->threadObj() == NULL) {
1145 // if the thread does not exist or now it is terminated, set threadinfo to NULL
1146 infoArray_h->obj_at_put(index, NULL);
1147 continue;
1148 }
1149
1150 // Create java.lang.management.ThreadInfo object
1151 instanceOop info_obj = Management::create_thread_info_instance(ts, CHECK_0);
1152 infoArray_h->obj_at_put(index, info_obj);
1153 }
1154 return 0;
1155 JVM_END
1156
1157 // Dump thread info for the specified threads.
1158 // It returns an array of ThreadInfo objects. Each element is the ThreadInfo
1184 validate_thread_id_array(ids_ah, CHECK_NULL);
1185
1186 // obtain thread dump of a specific list of threads
1187 do_thread_dump(&dump_result,
1188 ids_ah,
1189 num_threads,
1190 maxDepth, /* stack depth */
1191 (locked_monitors ? true : false), /* with locked monitors */
1192 (locked_synchronizers ? true : false), /* with locked synchronizers */
1193 CHECK_NULL);
1194 } else {
1195 // obtain thread dump of all threads
1196 VM_ThreadDump op(&dump_result,
1197 maxDepth, /* stack depth */
1198 (locked_monitors ? true : false), /* with locked monitors */
1199 (locked_synchronizers ? true : false) /* with locked synchronizers */);
1200 VMThread::execute(&op);
1201 }
1202
1203 int num_snapshots = dump_result.num_snapshots();
1204 assert(num_snapshots == 0 || dump_result.t_list_has_been_set(), "ThreadsList must have been set if we have a snapshot");
1205
1206 // create the result ThreadInfo[] object
1207 InstanceKlass* ik = Management::java_lang_management_ThreadInfo_klass(CHECK_NULL);
1208 objArrayOop r = oopFactory::new_objArray(ik, num_snapshots, CHECK_NULL);
1209 objArrayHandle result_h(THREAD, r);
1210
1211 int index = 0;
1212 for (ThreadSnapshot* ts = dump_result.snapshots(); ts != NULL; ts = ts->next(), index++) {
1213 if (ts->threadObj() == NULL) {
1214 // if the thread does not exist or now it is terminated, set threadinfo to NULL
1215 result_h->obj_at_put(index, NULL);
1216 continue;
1217 }
1218
1219 ThreadStackTrace* stacktrace = ts->get_stack_trace();
1220 assert(stacktrace != NULL, "Must have a stack trace dumped");
1221
1222 // Create Object[] filled with locked monitors
1223 // Create int[] filled with the stack depth where a monitor was locked
1224 int num_frames = stacktrace->get_stack_depth();
1308 // For PEAK_POOL_USAGE stat, obj is required to be a memory pool object.
1309 // For THREAD_CONTENTION_COUNT and TIME stat, obj is required to be a thread ID.
1310 // type - the type of statistic to be reset
1311 //
1312 JVM_ENTRY(jboolean, jmm_ResetStatistic(JNIEnv *env, jvalue obj, jmmStatisticType type))
1313 ResourceMark rm(THREAD);
1314
1315 switch (type) {
1316 case JMM_STAT_PEAK_THREAD_COUNT:
1317 ThreadService::reset_peak_thread_count();
1318 return true;
1319
1320 case JMM_STAT_THREAD_CONTENTION_COUNT:
1321 case JMM_STAT_THREAD_CONTENTION_TIME: {
1322 jlong tid = obj.j;
1323 if (tid < 0) {
1324 THROW_(vmSymbols::java_lang_IllegalArgumentException(), JNI_FALSE);
1325 }
1326
1327 // Look for the JavaThread of this given tid
1328 JavaThreadIteratorWithHandle jtiwh;
1329 if (tid == 0) {
1330 // reset contention statistics for all threads if tid == 0
1331 for (; JavaThread *java_thread = jtiwh.next(); ) {
1332 if (type == JMM_STAT_THREAD_CONTENTION_COUNT) {
1333 ThreadService::reset_contention_count_stat(java_thread);
1334 } else {
1335 ThreadService::reset_contention_time_stat(java_thread);
1336 }
1337 }
1338 } else {
1339 // reset contention statistics for a given thread
1340 JavaThread* java_thread = jtiwh.list()->find_JavaThread_from_java_tid(tid);
1341 if (java_thread == NULL) {
1342 return false;
1343 }
1344
1345 if (type == JMM_STAT_THREAD_CONTENTION_COUNT) {
1346 ThreadService::reset_contention_count_stat(java_thread);
1347 } else {
1348 ThreadService::reset_contention_time_stat(java_thread);
1349 }
1350 }
1351 return true;
1352 break;
1353 }
1354 case JMM_STAT_PEAK_POOL_USAGE: {
1355 jobject o = obj.l;
1356 if (o == NULL) {
1357 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE);
1358 }
1359
1360 oop pool_obj = JNIHandles::resolve(o);
1388 JVM_END
1389
1390 // Returns the fast estimate of CPU time consumed by
1391 // a given thread (in nanoseconds).
1392 // If thread_id == 0, return CPU time for the current thread.
1393 JVM_ENTRY(jlong, jmm_GetThreadCpuTime(JNIEnv *env, jlong thread_id))
1394 if (!os::is_thread_cpu_time_supported()) {
1395 return -1;
1396 }
1397
1398 if (thread_id < 0) {
1399 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
1400 "Invalid thread ID", -1);
1401 }
1402
1403 JavaThread* java_thread = NULL;
1404 if (thread_id == 0) {
1405 // current thread
1406 return os::current_thread_cpu_time();
1407 } else {
1408 ThreadsListHandle tlh;
1409 java_thread = tlh.list()->find_JavaThread_from_java_tid(thread_id);
1410 if (java_thread != NULL) {
1411 return os::thread_cpu_time((Thread*) java_thread);
1412 }
1413 }
1414 return -1;
1415 JVM_END
1416
1417 // Returns a String array of all VM global flag names
1418 JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))
1419 // last flag entry is always NULL, so subtract 1
1420 int nFlags = (int) Flag::numFlags - 1;
1421 // allocate a temp array
1422 objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(),
1423 nFlags, CHECK_0);
1424 objArrayHandle flags_ah(THREAD, r);
1425 int num_entries = 0;
1426 for (int i = 0; i < nFlags; i++) {
1427 Flag* flag = &Flag::flags[i];
1428 // Exclude notproduct and develop flags in product builds.
1429 if (flag->is_constant_in_binary()) {
1638 void do_unlocked();
1639 int count() { return _count; }
1640 };
1641
1642 ThreadTimesClosure::ThreadTimesClosure(objArrayHandle names,
1643 typeArrayHandle times) {
1644 assert(names() != NULL, "names was NULL");
1645 assert(times() != NULL, "times was NULL");
1646 _names_strings = names;
1647 _names_len = names->length();
1648 _names_chars = NEW_C_HEAP_ARRAY(char*, _names_len, mtInternal);
1649 _times = times;
1650 _times_len = times->length();
1651 _count = 0;
1652 }
1653
1654 //
1655 // Called with Threads_lock held
1656 //
1657 void ThreadTimesClosure::do_thread(Thread* thread) {
1658 assert(Threads_lock->owned_by_self(), "Must hold Threads_lock");
1659 assert(thread != NULL, "thread was NULL");
1660
1661 // exclude externally visible JavaThreads
1662 if (thread->is_Java_thread() && !thread->is_hidden_from_external_view()) {
1663 return;
1664 }
1665
1666 if (_count >= _names_len || _count >= _times_len) {
1667 // skip if the result array is not big enough
1668 return;
1669 }
1670
1671 EXCEPTION_MARK;
1672 ResourceMark rm(THREAD); // thread->name() uses ResourceArea
1673
1674 assert(thread->name() != NULL, "All threads should have a name");
1675 _names_chars[_count] = os::strdup(thread->name());
1676 _times->long_at_put(_count, os::is_thread_cpu_time_supported() ?
1677 os::thread_cpu_time(thread) : -1);
1678 _count++;
2099 }
2100
2101 ResourceMark rm(THREAD);
2102 typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
2103 typeArrayHandle ids_ah(THREAD, ta);
2104
2105 typeArrayOop sa = typeArrayOop(JNIHandles::resolve_non_null(sizeArray));
2106 typeArrayHandle sizeArray_h(THREAD, sa);
2107
2108 // validate the thread id array
2109 validate_thread_id_array(ids_ah, CHECK);
2110
2111 // sizeArray must be of the same length as the given array of thread IDs
2112 int num_threads = ids_ah->length();
2113 if (num_threads != sizeArray_h->length()) {
2114 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
2115 "The length of the given long array does not match the length of "
2116 "the given array of thread IDs");
2117 }
2118
2119 ThreadsListHandle tlh;
2120 for (int i = 0; i < num_threads; i++) {
2121 JavaThread* java_thread = tlh.list()->find_JavaThread_from_java_tid(ids_ah->long_at(i));
2122 if (java_thread != NULL) {
2123 sizeArray_h->long_at_put(i, java_thread->cooked_allocated_bytes());
2124 }
2125 }
2126 JVM_END
2127
2128 // Returns the CPU time consumed by a given thread (in nanoseconds).
2129 // If thread_id == 0, CPU time for the current thread is returned.
2130 // If user_sys_cpu_time = true, user level and system CPU time of
2131 // a given thread is returned; otherwise, only user level CPU time
2132 // is returned.
2133 JVM_ENTRY(jlong, jmm_GetThreadCpuTimeWithKind(JNIEnv *env, jlong thread_id, jboolean user_sys_cpu_time))
2134 if (!os::is_thread_cpu_time_supported()) {
2135 return -1;
2136 }
2137
2138 if (thread_id < 0) {
2139 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
2140 "Invalid thread ID", -1);
2141 }
2142
2143 JavaThread* java_thread = NULL;
2144 if (thread_id == 0) {
2145 // current thread
2146 return os::current_thread_cpu_time(user_sys_cpu_time != 0);
2147 } else {
2148 ThreadsListHandle tlh;
2149 java_thread = tlh.list()->find_JavaThread_from_java_tid(thread_id);
2150 if (java_thread != NULL) {
2151 return os::thread_cpu_time((Thread*) java_thread, user_sys_cpu_time != 0);
2152 }
2153 }
2154 return -1;
2155 JVM_END
2156
2157 // Gets an array containing the CPU times consumed by a set of threads
2158 // (in nanoseconds). Each element of the array is the CPU time for the
2159 // thread ID specified in the corresponding entry in the given array
2160 // of thread IDs; or -1 if the thread does not exist or has terminated.
2161 // If user_sys_cpu_time = true, the sum of user level and system CPU time
2162 // for the given thread is returned; otherwise, only user level CPU time
2163 // is returned.
2164 JVM_ENTRY(void, jmm_GetThreadCpuTimesWithKind(JNIEnv *env, jlongArray ids,
2165 jlongArray timeArray,
2166 jboolean user_sys_cpu_time))
2167 // Check if threads is null
2168 if (ids == NULL || timeArray == NULL) {
2169 THROW(vmSymbols::java_lang_NullPointerException());
2170 }
2171
2172 ResourceMark rm(THREAD);
2173 typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
2174 typeArrayHandle ids_ah(THREAD, ta);
2175
2176 typeArrayOop tia = typeArrayOop(JNIHandles::resolve_non_null(timeArray));
2177 typeArrayHandle timeArray_h(THREAD, tia);
2178
2179 // validate the thread id array
2180 validate_thread_id_array(ids_ah, CHECK);
2181
2182 // timeArray must be of the same length as the given array of thread IDs
2183 int num_threads = ids_ah->length();
2184 if (num_threads != timeArray_h->length()) {
2185 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
2186 "The length of the given long array does not match the length of "
2187 "the given array of thread IDs");
2188 }
2189
2190 ThreadsListHandle tlh;
2191 for (int i = 0; i < num_threads; i++) {
2192 JavaThread* java_thread = tlh.list()->find_JavaThread_from_java_tid(ids_ah->long_at(i));
2193 if (java_thread != NULL) {
2194 timeArray_h->long_at_put(i, os::thread_cpu_time((Thread*)java_thread,
2195 user_sys_cpu_time != 0));
2196 }
2197 }
2198 JVM_END
2199
2200
2201
2202 #if INCLUDE_MANAGEMENT
2203 const struct jmmInterface_1_ jmm_interface = {
2204 NULL,
2205 NULL,
2206 jmm_GetVersion,
2207 jmm_GetOptionalSupport,
2208 jmm_GetThreadInfo,
2209 jmm_GetMemoryPools,
2210 jmm_GetMemoryManagers,
2211 jmm_GetMemoryPoolUsage,
2212 jmm_GetPeakMemoryPoolUsage,
|