< prev index next >

src/hotspot/share/services/management.cpp

Print this page
rev 47287 : Port 09.17.Thread_SMR_logging_update from JDK9 to JDK10
rev 47289 : eosterlund, stefank CR - refactor code into threadSMR.cpp and threadSMR.hpp


  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


1178     validate_thread_id_array(ids_ah, CHECK_NULL);
1179 
1180     // obtain thread dump of a specific list of threads
1181     do_thread_dump(&dump_result,
1182                    ids_ah,
1183                    num_threads,
1184                    -1, /* entire stack */
1185                    (locked_monitors ? true : false),      /* with locked monitors */
1186                    (locked_synchronizers ? true : false), /* with locked synchronizers */
1187                    CHECK_NULL);
1188   } else {
1189     // obtain thread dump of all threads
1190     VM_ThreadDump op(&dump_result,
1191                      -1, /* entire stack */
1192                      (locked_monitors ? true : false),     /* with locked monitors */
1193                      (locked_synchronizers ? true : false) /* with locked synchronizers */);
1194     VMThread::execute(&op);
1195   }
1196 
1197   int num_snapshots = dump_result.num_snapshots();

1198 
1199   // create the result ThreadInfo[] object
1200   InstanceKlass* ik = Management::java_lang_management_ThreadInfo_klass(CHECK_NULL);
1201   objArrayOop r = oopFactory::new_objArray(ik, num_snapshots, CHECK_NULL);
1202   objArrayHandle result_h(THREAD, r);
1203 
1204   int index = 0;
1205   for (ThreadSnapshot* ts = dump_result.snapshots(); ts != NULL; ts = ts->next(), index++) {
1206     if (ts->threadObj() == NULL) {
1207      // if the thread does not exist or now it is terminated, set threadinfo to NULL
1208       result_h->obj_at_put(index, NULL);
1209       continue;
1210     }
1211 
1212     ThreadStackTrace* stacktrace = ts->get_stack_trace();
1213     assert(stacktrace != NULL, "Must have a stack trace dumped");
1214 
1215     // Create Object[] filled with locked monitors
1216     // Create int[] filled with the stack depth where a monitor was locked
1217     int num_frames = stacktrace->get_stack_depth();


1301 //         For PEAK_POOL_USAGE stat, obj is required to be a memory pool object.
1302 //         For THREAD_CONTENTION_COUNT and TIME stat, obj is required to be a thread ID.
1303 //  type - the type of statistic to be reset
1304 //
1305 JVM_ENTRY(jboolean, jmm_ResetStatistic(JNIEnv *env, jvalue obj, jmmStatisticType type))
1306   ResourceMark rm(THREAD);
1307 
1308   switch (type) {
1309     case JMM_STAT_PEAK_THREAD_COUNT:
1310       ThreadService::reset_peak_thread_count();
1311       return true;
1312 
1313     case JMM_STAT_THREAD_CONTENTION_COUNT:
1314     case JMM_STAT_THREAD_CONTENTION_TIME: {
1315       jlong tid = obj.j;
1316       if (tid < 0) {
1317         THROW_(vmSymbols::java_lang_IllegalArgumentException(), JNI_FALSE);
1318       }
1319 
1320       // Look for the JavaThread of this given tid
1321       MutexLockerEx ml(Threads_lock);
1322       if (tid == 0) {

1323         // reset contention statistics for all threads if tid == 0
1324         for (JavaThread* java_thread = Threads::first(); java_thread != NULL; java_thread = java_thread->next()) {
1325           if (type == JMM_STAT_THREAD_CONTENTION_COUNT) {
1326             ThreadService::reset_contention_count_stat(java_thread);
1327           } else {
1328             ThreadService::reset_contention_time_stat(java_thread);
1329           }
1330         }
1331       } else {
1332         // reset contention statistics for a given thread
1333         JavaThread* java_thread = Threads::find_java_thread_from_java_tid(tid);
1334         if (java_thread == NULL) {
1335           return false;
1336         }
1337 
1338         if (type == JMM_STAT_THREAD_CONTENTION_COUNT) {
1339           ThreadService::reset_contention_count_stat(java_thread);
1340         } else {
1341           ThreadService::reset_contention_time_stat(java_thread);
1342         }
1343       }
1344       return true;
1345       break;
1346     }
1347     case JMM_STAT_PEAK_POOL_USAGE: {
1348       jobject o = obj.l;
1349       if (o == NULL) {
1350         THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE);
1351       }
1352 
1353       oop pool_obj = JNIHandles::resolve(o);


1381 JVM_END
1382 
1383 // Returns the fast estimate of CPU time consumed by
1384 // a given thread (in nanoseconds).
1385 // If thread_id == 0, return CPU time for the current thread.
1386 JVM_ENTRY(jlong, jmm_GetThreadCpuTime(JNIEnv *env, jlong thread_id))
1387   if (!os::is_thread_cpu_time_supported()) {
1388     return -1;
1389   }
1390 
1391   if (thread_id < 0) {
1392     THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
1393                "Invalid thread ID", -1);
1394   }
1395 
1396   JavaThread* java_thread = NULL;
1397   if (thread_id == 0) {
1398     // current thread
1399     return os::current_thread_cpu_time();
1400   } else {
1401     MutexLockerEx ml(Threads_lock);
1402     java_thread = Threads::find_java_thread_from_java_tid(thread_id);
1403     if (java_thread != NULL) {
1404       return os::thread_cpu_time((Thread*) java_thread);
1405     }
1406   }
1407   return -1;
1408 JVM_END
1409 
1410 // Returns a String array of all VM global flag names
1411 JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))
1412   // last flag entry is always NULL, so subtract 1
1413   int nFlags = (int) Flag::numFlags - 1;
1414   // allocate a temp array
1415   objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(),
1416                                            nFlags, CHECK_0);
1417   objArrayHandle flags_ah(THREAD, r);
1418   int num_entries = 0;
1419   for (int i = 0; i < nFlags; i++) {
1420     Flag* flag = &Flag::flags[i];
1421     // Exclude notproduct and develop flags in product builds.
1422     if (flag->is_constant_in_binary()) {


1631   void do_unlocked();
1632   int count() { return _count; }
1633 };
1634 
1635 ThreadTimesClosure::ThreadTimesClosure(objArrayHandle names,
1636                                        typeArrayHandle times) {
1637   assert(names() != NULL, "names was NULL");
1638   assert(times() != NULL, "times was NULL");
1639   _names_strings = names;
1640   _names_len = names->length();
1641   _names_chars = NEW_C_HEAP_ARRAY(char*, _names_len, mtInternal);
1642   _times = times;
1643   _times_len = times->length();
1644   _count = 0;
1645 }
1646 
1647 //
1648 // Called with Threads_lock held
1649 //
1650 void ThreadTimesClosure::do_thread(Thread* thread) {

1651   assert(thread != NULL, "thread was NULL");
1652 
1653   // exclude externally visible JavaThreads
1654   if (thread->is_Java_thread() && !thread->is_hidden_from_external_view()) {
1655     return;
1656   }
1657 
1658   if (_count >= _names_len || _count >= _times_len) {
1659     // skip if the result array is not big enough
1660     return;
1661   }
1662 
1663   EXCEPTION_MARK;
1664   ResourceMark rm(THREAD); // thread->name() uses ResourceArea
1665 
1666   assert(thread->name() != NULL, "All threads should have a name");
1667   _names_chars[_count] = os::strdup(thread->name());
1668   _times->long_at_put(_count, os::is_thread_cpu_time_supported() ?
1669                         os::thread_cpu_time(thread) : -1);
1670   _count++;


2091   }
2092 
2093   ResourceMark rm(THREAD);
2094   typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
2095   typeArrayHandle ids_ah(THREAD, ta);
2096 
2097   typeArrayOop sa = typeArrayOop(JNIHandles::resolve_non_null(sizeArray));
2098   typeArrayHandle sizeArray_h(THREAD, sa);
2099 
2100   // validate the thread id array
2101   validate_thread_id_array(ids_ah, CHECK);
2102 
2103   // sizeArray must be of the same length as the given array of thread IDs
2104   int num_threads = ids_ah->length();
2105   if (num_threads != sizeArray_h->length()) {
2106     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
2107               "The length of the given long array does not match the length of "
2108               "the given array of thread IDs");
2109   }
2110 
2111   MutexLockerEx ml(Threads_lock);
2112   for (int i = 0; i < num_threads; i++) {
2113     JavaThread* java_thread = Threads::find_java_thread_from_java_tid(ids_ah->long_at(i));
2114     if (java_thread != NULL) {
2115       sizeArray_h->long_at_put(i, java_thread->cooked_allocated_bytes());
2116     }
2117   }
2118 JVM_END
2119 
2120 // Returns the CPU time consumed by a given thread (in nanoseconds).
2121 // If thread_id == 0, CPU time for the current thread is returned.
2122 // If user_sys_cpu_time = true, user level and system CPU time of
2123 // a given thread is returned; otherwise, only user level CPU time
2124 // is returned.
2125 JVM_ENTRY(jlong, jmm_GetThreadCpuTimeWithKind(JNIEnv *env, jlong thread_id, jboolean user_sys_cpu_time))
2126   if (!os::is_thread_cpu_time_supported()) {
2127     return -1;
2128   }
2129 
2130   if (thread_id < 0) {
2131     THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
2132                "Invalid thread ID", -1);
2133   }
2134 
2135   JavaThread* java_thread = NULL;
2136   if (thread_id == 0) {
2137     // current thread
2138     return os::current_thread_cpu_time(user_sys_cpu_time != 0);
2139   } else {
2140     MutexLockerEx ml(Threads_lock);
2141     java_thread = Threads::find_java_thread_from_java_tid(thread_id);
2142     if (java_thread != NULL) {
2143       return os::thread_cpu_time((Thread*) java_thread, user_sys_cpu_time != 0);
2144     }
2145   }
2146   return -1;
2147 JVM_END
2148 
2149 // Gets an array containing the CPU times consumed by a set of threads
2150 // (in nanoseconds).  Each element of the array is the CPU time for the
2151 // thread ID specified in the corresponding entry in the given array
2152 // of thread IDs; or -1 if the thread does not exist or has terminated.
2153 // If user_sys_cpu_time = true, the sum of user level and system CPU time
2154 // for the given thread is returned; otherwise, only user level CPU time
2155 // is returned.
2156 JVM_ENTRY(void, jmm_GetThreadCpuTimesWithKind(JNIEnv *env, jlongArray ids,
2157                                               jlongArray timeArray,
2158                                               jboolean user_sys_cpu_time))
2159   // Check if threads is null
2160   if (ids == NULL || timeArray == NULL) {
2161     THROW(vmSymbols::java_lang_NullPointerException());
2162   }
2163 
2164   ResourceMark rm(THREAD);
2165   typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
2166   typeArrayHandle ids_ah(THREAD, ta);
2167 
2168   typeArrayOop tia = typeArrayOop(JNIHandles::resolve_non_null(timeArray));
2169   typeArrayHandle timeArray_h(THREAD, tia);
2170 
2171   // validate the thread id array
2172   validate_thread_id_array(ids_ah, CHECK);
2173 
2174   // timeArray must be of the same length as the given array of thread IDs
2175   int num_threads = ids_ah->length();
2176   if (num_threads != timeArray_h->length()) {
2177     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
2178               "The length of the given long array does not match the length of "
2179               "the given array of thread IDs");
2180   }
2181 
2182   MutexLockerEx ml(Threads_lock);
2183   for (int i = 0; i < num_threads; i++) {
2184     JavaThread* java_thread = Threads::find_java_thread_from_java_tid(ids_ah->long_at(i));
2185     if (java_thread != NULL) {
2186       timeArray_h->long_at_put(i, os::thread_cpu_time((Thread*)java_thread,
2187                                                       user_sys_cpu_time != 0));
2188     }
2189   }
2190 JVM_END
2191 
2192 
2193 
2194 #if INCLUDE_MANAGEMENT
2195 const struct jmmInterface_1_ jmm_interface = {
2196   NULL,
2197   NULL,
2198   jmm_GetVersion,
2199   jmm_GetOptionalSupport,
2200   jmm_GetThreadInfo,
2201   jmm_GetMemoryPools,
2202   jmm_GetMemoryManagers,
2203   jmm_GetMemoryPoolUsage,
2204   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


1183     validate_thread_id_array(ids_ah, CHECK_NULL);
1184 
1185     // obtain thread dump of a specific list of threads
1186     do_thread_dump(&dump_result,
1187                    ids_ah,
1188                    num_threads,
1189                    -1, /* entire stack */
1190                    (locked_monitors ? true : false),      /* with locked monitors */
1191                    (locked_synchronizers ? true : false), /* with locked synchronizers */
1192                    CHECK_NULL);
1193   } else {
1194     // obtain thread dump of all threads
1195     VM_ThreadDump op(&dump_result,
1196                      -1, /* entire stack */
1197                      (locked_monitors ? true : false),     /* with locked monitors */
1198                      (locked_synchronizers ? true : false) /* with locked synchronizers */);
1199     VMThread::execute(&op);
1200   }
1201 
1202   int num_snapshots = dump_result.num_snapshots();
1203   assert(num_snapshots == 0 || dump_result.t_list_has_been_set(), "ThreadsList must have been set if we have a snapshot");
1204 
1205   // create the result ThreadInfo[] object
1206   InstanceKlass* ik = Management::java_lang_management_ThreadInfo_klass(CHECK_NULL);
1207   objArrayOop r = oopFactory::new_objArray(ik, num_snapshots, CHECK_NULL);
1208   objArrayHandle result_h(THREAD, r);
1209 
1210   int index = 0;
1211   for (ThreadSnapshot* ts = dump_result.snapshots(); ts != NULL; ts = ts->next(), index++) {
1212     if (ts->threadObj() == NULL) {
1213      // if the thread does not exist or now it is terminated, set threadinfo to NULL
1214       result_h->obj_at_put(index, NULL);
1215       continue;
1216     }
1217 
1218     ThreadStackTrace* stacktrace = ts->get_stack_trace();
1219     assert(stacktrace != NULL, "Must have a stack trace dumped");
1220 
1221     // Create Object[] filled with locked monitors
1222     // Create int[] filled with the stack depth where a monitor was locked
1223     int num_frames = stacktrace->get_stack_depth();


1307 //         For PEAK_POOL_USAGE stat, obj is required to be a memory pool object.
1308 //         For THREAD_CONTENTION_COUNT and TIME stat, obj is required to be a thread ID.
1309 //  type - the type of statistic to be reset
1310 //
1311 JVM_ENTRY(jboolean, jmm_ResetStatistic(JNIEnv *env, jvalue obj, jmmStatisticType type))
1312   ResourceMark rm(THREAD);
1313 
1314   switch (type) {
1315     case JMM_STAT_PEAK_THREAD_COUNT:
1316       ThreadService::reset_peak_thread_count();
1317       return true;
1318 
1319     case JMM_STAT_THREAD_CONTENTION_COUNT:
1320     case JMM_STAT_THREAD_CONTENTION_TIME: {
1321       jlong tid = obj.j;
1322       if (tid < 0) {
1323         THROW_(vmSymbols::java_lang_IllegalArgumentException(), JNI_FALSE);
1324       }
1325 
1326       // Look for the JavaThread of this given tid
1327       ThreadsListHandle tlh;
1328       if (tid == 0) {
1329         JavaThreadIterator jti(tlh.list());
1330         // reset contention statistics for all threads if tid == 0
1331         for (JavaThread* java_thread = jti.first(); java_thread != NULL; java_thread = jti.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 = tlh.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,


< prev index next >