< prev index next >

src/hotspot/share/services/management.cpp

Print this page
rev 47819 : imported patch 10.07.open.rebase_20171110.dcubed


  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,


< prev index next >