hotspot/src/share/vm/services/management.cpp
changeset 26834 41332d860d6a
parent 25960 729cd80956ae
child 27466 36c9a91eb418
equal deleted inserted replaced
26833:fa1e0d1c960f 26834:41332d860d6a
   390                           CHECK_NULL);
   390                           CHECK_NULL);
   391 
   391 
   392   return (instanceOop) element();
   392   return (instanceOop) element();
   393 }
   393 }
   394 
   394 
   395 // Helper functions
       
   396 static JavaThread* find_java_thread_from_id(jlong thread_id) {
       
   397   assert(Threads_lock->owned_by_self(), "Must hold Threads_lock");
       
   398 
       
   399   JavaThread* java_thread = NULL;
       
   400   // Sequential search for now.  Need to do better optimization later.
       
   401   for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) {
       
   402     oop tobj = thread->threadObj();
       
   403     if (!thread->is_exiting() &&
       
   404         tobj != NULL &&
       
   405         thread_id == java_lang_Thread::thread_id(tobj)) {
       
   406       java_thread = thread;
       
   407       break;
       
   408     }
       
   409   }
       
   410   return java_thread;
       
   411 }
       
   412 
   395 
   413 static GCMemoryManager* get_gc_memory_manager_from_jobject(jobject mgr, TRAPS) {
   396 static GCMemoryManager* get_gc_memory_manager_from_jobject(jobject mgr, TRAPS) {
   414   if (mgr == NULL) {
   397   if (mgr == NULL) {
   415     THROW_(vmSymbols::java_lang_NullPointerException(), NULL);
   398     THROW_(vmSymbols::java_lang_NullPointerException(), NULL);
   416   }
   399   }
   442   assert(pool_obj->is_instance(), "Should be an instanceOop");
   425   assert(pool_obj->is_instance(), "Should be an instanceOop");
   443   instanceHandle ph(THREAD, (instanceOop) pool_obj);
   426   instanceHandle ph(THREAD, (instanceOop) pool_obj);
   444 
   427 
   445   return MemoryService::get_memory_pool(ph);
   428   return MemoryService::get_memory_pool(ph);
   446 }
   429 }
       
   430 
       
   431 #endif // INCLUDE_MANAGEMENT
   447 
   432 
   448 static void validate_thread_id_array(typeArrayHandle ids_ah, TRAPS) {
   433 static void validate_thread_id_array(typeArrayHandle ids_ah, TRAPS) {
   449   int num_threads = ids_ah->length();
   434   int num_threads = ids_ah->length();
   450 
   435 
   451   // Validate input thread IDs
   436   // Validate input thread IDs
   457       THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   442       THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   458                 "Invalid thread ID entry");
   443                 "Invalid thread ID entry");
   459     }
   444     }
   460   }
   445   }
   461 }
   446 }
       
   447 
       
   448 #if INCLUDE_MANAGEMENT
   462 
   449 
   463 static void validate_thread_info_array(objArrayHandle infoArray_h, TRAPS) {
   450 static void validate_thread_info_array(objArrayHandle infoArray_h, TRAPS) {
   464   // check if the element of infoArray is of type ThreadInfo class
   451   // check if the element of infoArray is of type ThreadInfo class
   465   Klass* threadinfo_klass = Management::java_lang_management_ThreadInfo_klass(CHECK);
   452   Klass* threadinfo_klass = Management::java_lang_management_ThreadInfo_klass(CHECK);
   466   Klass* element_klass = ObjArrayKlass::cast(infoArray_h->klass())->element_klass();
   453   Klass* element_klass = ObjArrayKlass::cast(infoArray_h->klass())->element_klass();
   819   if (prev != threshold) {
   806   if (prev != threshold) {
   820     LowMemoryDetector::recompute_enabled_for_collected_pools();
   807     LowMemoryDetector::recompute_enabled_for_collected_pools();
   821     LowMemoryDetector::detect_low_memory(pool);
   808     LowMemoryDetector::detect_low_memory(pool);
   822   }
   809   }
   823   return prev;
   810   return prev;
   824 JVM_END
       
   825 
       
   826 // Gets an array containing the amount of memory allocated on the Java
       
   827 // heap for a set of threads (in bytes).  Each element of the array is
       
   828 // the amount of memory allocated for the thread ID specified in the
       
   829 // corresponding entry in the given array of thread IDs; or -1 if the
       
   830 // thread does not exist or has terminated.
       
   831 JVM_ENTRY(void, jmm_GetThreadAllocatedMemory(JNIEnv *env, jlongArray ids,
       
   832                                              jlongArray sizeArray))
       
   833   // Check if threads is null
       
   834   if (ids == NULL || sizeArray == NULL) {
       
   835     THROW(vmSymbols::java_lang_NullPointerException());
       
   836   }
       
   837 
       
   838   ResourceMark rm(THREAD);
       
   839   typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
       
   840   typeArrayHandle ids_ah(THREAD, ta);
       
   841 
       
   842   typeArrayOop sa = typeArrayOop(JNIHandles::resolve_non_null(sizeArray));
       
   843   typeArrayHandle sizeArray_h(THREAD, sa);
       
   844 
       
   845   // validate the thread id array
       
   846   validate_thread_id_array(ids_ah, CHECK);
       
   847 
       
   848   // sizeArray must be of the same length as the given array of thread IDs
       
   849   int num_threads = ids_ah->length();
       
   850   if (num_threads != sizeArray_h->length()) {
       
   851     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
       
   852               "The length of the given long array does not match the length of "
       
   853               "the given array of thread IDs");
       
   854   }
       
   855 
       
   856   MutexLockerEx ml(Threads_lock);
       
   857   for (int i = 0; i < num_threads; i++) {
       
   858     JavaThread* java_thread = find_java_thread_from_id(ids_ah->long_at(i));
       
   859     if (java_thread != NULL) {
       
   860       sizeArray_h->long_at_put(i, java_thread->cooked_allocated_bytes());
       
   861     }
       
   862   }
       
   863 JVM_END
   811 JVM_END
   864 
   812 
   865 // Returns a java/lang/management/MemoryUsage object representing
   813 // Returns a java/lang/management/MemoryUsage object representing
   866 // the memory usage for the heap or non-heap memory.
   814 // the memory usage for the heap or non-heap memory.
   867 JVM_ENTRY(jobject, jmm_GetMemoryUsage(JNIEnv* env, jboolean heap))
   815 JVM_ENTRY(jobject, jmm_GetMemoryUsage(JNIEnv* env, jboolean heap))
  1165   GrowableArray<instanceHandle>* thread_handle_array = new GrowableArray<instanceHandle>(num_threads);
  1113   GrowableArray<instanceHandle>* thread_handle_array = new GrowableArray<instanceHandle>(num_threads);
  1166   {
  1114   {
  1167     MutexLockerEx ml(Threads_lock);
  1115     MutexLockerEx ml(Threads_lock);
  1168     for (int i = 0; i < num_threads; i++) {
  1116     for (int i = 0; i < num_threads; i++) {
  1169       jlong tid = ids_ah->long_at(i);
  1117       jlong tid = ids_ah->long_at(i);
  1170       JavaThread* jt = find_java_thread_from_id(tid);
  1118       JavaThread* jt = Threads::find_java_thread_from_java_tid(tid);
  1171       oop thread_obj = (jt != NULL ? jt->threadObj() : (oop)NULL);
  1119       oop thread_obj = (jt != NULL ? jt->threadObj() : (oop)NULL);
  1172       instanceHandle threadObj_h(THREAD, (instanceOop) thread_obj);
  1120       instanceHandle threadObj_h(THREAD, (instanceOop) thread_obj);
  1173       thread_handle_array->append(threadObj_h);
  1121       thread_handle_array->append(threadObj_h);
  1174     }
  1122     }
  1175   }
  1123   }
  1242     // no stack trace dumped - do not need to stop the world
  1190     // no stack trace dumped - do not need to stop the world
  1243     {
  1191     {
  1244       MutexLockerEx ml(Threads_lock);
  1192       MutexLockerEx ml(Threads_lock);
  1245       for (int i = 0; i < num_threads; i++) {
  1193       for (int i = 0; i < num_threads; i++) {
  1246         jlong tid = ids_ah->long_at(i);
  1194         jlong tid = ids_ah->long_at(i);
  1247         JavaThread* jt = find_java_thread_from_id(tid);
  1195         JavaThread* jt = Threads::find_java_thread_from_java_tid(tid);
  1248         ThreadSnapshot* ts;
  1196         ThreadSnapshot* ts;
  1249         if (jt == NULL) {
  1197         if (jt == NULL) {
  1250           // if the thread does not exist or now it is terminated,
  1198           // if the thread does not exist or now it is terminated,
  1251           // create dummy snapshot
  1199           // create dummy snapshot
  1252           ts = new ThreadSnapshot();
  1200           ts = new ThreadSnapshot();
  1486             ThreadService::reset_contention_time_stat(java_thread);
  1434             ThreadService::reset_contention_time_stat(java_thread);
  1487           }
  1435           }
  1488         }
  1436         }
  1489       } else {
  1437       } else {
  1490         // reset contention statistics for a given thread
  1438         // reset contention statistics for a given thread
  1491         JavaThread* java_thread = find_java_thread_from_id(tid);
  1439         JavaThread* java_thread = Threads::find_java_thread_from_java_tid(tid);
  1492         if (java_thread == NULL) {
  1440         if (java_thread == NULL) {
  1493           return false;
  1441           return false;
  1494         }
  1442         }
  1495 
  1443 
  1496         if (type == JMM_STAT_THREAD_CONTENTION_COUNT) {
  1444         if (type == JMM_STAT_THREAD_CONTENTION_COUNT) {
  1555   if (thread_id == 0) {
  1503   if (thread_id == 0) {
  1556     // current thread
  1504     // current thread
  1557     return os::current_thread_cpu_time();
  1505     return os::current_thread_cpu_time();
  1558   } else {
  1506   } else {
  1559     MutexLockerEx ml(Threads_lock);
  1507     MutexLockerEx ml(Threads_lock);
  1560     java_thread = find_java_thread_from_id(thread_id);
  1508     java_thread = Threads::find_java_thread_from_java_tid(thread_id);
  1561     if (java_thread != NULL) {
  1509     if (java_thread != NULL) {
  1562       return os::thread_cpu_time((Thread*) java_thread);
  1510       return os::thread_cpu_time((Thread*) java_thread);
  1563     }
  1511     }
  1564   }
  1512   }
  1565   return -1;
  1513   return -1;
  1566 JVM_END
       
  1567 
       
  1568 // Returns the CPU time consumed by a given thread (in nanoseconds).
       
  1569 // If thread_id == 0, CPU time for the current thread is returned.
       
  1570 // If user_sys_cpu_time = true, user level and system CPU time of
       
  1571 // a given thread is returned; otherwise, only user level CPU time
       
  1572 // is returned.
       
  1573 JVM_ENTRY(jlong, jmm_GetThreadCpuTimeWithKind(JNIEnv *env, jlong thread_id, jboolean user_sys_cpu_time))
       
  1574   if (!os::is_thread_cpu_time_supported()) {
       
  1575     return -1;
       
  1576   }
       
  1577 
       
  1578   if (thread_id < 0) {
       
  1579     THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
       
  1580                "Invalid thread ID", -1);
       
  1581   }
       
  1582 
       
  1583   JavaThread* java_thread = NULL;
       
  1584   if (thread_id == 0) {
       
  1585     // current thread
       
  1586     return os::current_thread_cpu_time(user_sys_cpu_time != 0);
       
  1587   } else {
       
  1588     MutexLockerEx ml(Threads_lock);
       
  1589     java_thread = find_java_thread_from_id(thread_id);
       
  1590     if (java_thread != NULL) {
       
  1591       return os::thread_cpu_time((Thread*) java_thread, user_sys_cpu_time != 0);
       
  1592     }
       
  1593   }
       
  1594   return -1;
       
  1595 JVM_END
       
  1596 
       
  1597 // Gets an array containing the CPU times consumed by a set of threads
       
  1598 // (in nanoseconds).  Each element of the array is the CPU time for the
       
  1599 // thread ID specified in the corresponding entry in the given array
       
  1600 // of thread IDs; or -1 if the thread does not exist or has terminated.
       
  1601 // If user_sys_cpu_time = true, the sum of user level and system CPU time
       
  1602 // for the given thread is returned; otherwise, only user level CPU time
       
  1603 // is returned.
       
  1604 JVM_ENTRY(void, jmm_GetThreadCpuTimesWithKind(JNIEnv *env, jlongArray ids,
       
  1605                                               jlongArray timeArray,
       
  1606                                               jboolean user_sys_cpu_time))
       
  1607   // Check if threads is null
       
  1608   if (ids == NULL || timeArray == NULL) {
       
  1609     THROW(vmSymbols::java_lang_NullPointerException());
       
  1610   }
       
  1611 
       
  1612   ResourceMark rm(THREAD);
       
  1613   typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
       
  1614   typeArrayHandle ids_ah(THREAD, ta);
       
  1615 
       
  1616   typeArrayOop tia = typeArrayOop(JNIHandles::resolve_non_null(timeArray));
       
  1617   typeArrayHandle timeArray_h(THREAD, tia);
       
  1618 
       
  1619   // validate the thread id array
       
  1620   validate_thread_id_array(ids_ah, CHECK);
       
  1621 
       
  1622   // timeArray must be of the same length as the given array of thread IDs
       
  1623   int num_threads = ids_ah->length();
       
  1624   if (num_threads != timeArray_h->length()) {
       
  1625     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
       
  1626               "The length of the given long array does not match the length of "
       
  1627               "the given array of thread IDs");
       
  1628   }
       
  1629 
       
  1630   MutexLockerEx ml(Threads_lock);
       
  1631   for (int i = 0; i < num_threads; i++) {
       
  1632     JavaThread* java_thread = find_java_thread_from_id(ids_ah->long_at(i));
       
  1633     if (java_thread != NULL) {
       
  1634       timeArray_h->long_at_put(i, os::thread_cpu_time((Thread*)java_thread,
       
  1635                                                       user_sys_cpu_time != 0));
       
  1636     }
       
  1637   }
       
  1638 JVM_END
  1514 JVM_END
  1639 
  1515 
  1640 // Returns a String array of all VM global flag names
  1516 // Returns a String array of all VM global flag names
  1641 JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))
  1517 JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))
  1642   // last flag entry is always NULL, so subtract 1
  1518   // last flag entry is always NULL, so subtract 1
  2329 jlong Management::ticks_to_ms(jlong ticks) {
  2205 jlong Management::ticks_to_ms(jlong ticks) {
  2330   assert(os::elapsed_frequency() > 0, "Must be non-zero");
  2206   assert(os::elapsed_frequency() > 0, "Must be non-zero");
  2331   return (jlong)(((double)ticks / (double)os::elapsed_frequency())
  2207   return (jlong)(((double)ticks / (double)os::elapsed_frequency())
  2332                  * (double)1000.0);
  2208                  * (double)1000.0);
  2333 }
  2209 }
  2334 
  2210 #endif // INCLUDE_MANAGEMENT
       
  2211 
       
  2212 // Gets an array containing the amount of memory allocated on the Java
       
  2213 // heap for a set of threads (in bytes).  Each element of the array is
       
  2214 // the amount of memory allocated for the thread ID specified in the
       
  2215 // corresponding entry in the given array of thread IDs; or -1 if the
       
  2216 // thread does not exist or has terminated.
       
  2217 JVM_ENTRY(void, jmm_GetThreadAllocatedMemory(JNIEnv *env, jlongArray ids,
       
  2218                                              jlongArray sizeArray))
       
  2219   // Check if threads is null
       
  2220   if (ids == NULL || sizeArray == NULL) {
       
  2221     THROW(vmSymbols::java_lang_NullPointerException());
       
  2222   }
       
  2223 
       
  2224   ResourceMark rm(THREAD);
       
  2225   typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
       
  2226   typeArrayHandle ids_ah(THREAD, ta);
       
  2227 
       
  2228   typeArrayOop sa = typeArrayOop(JNIHandles::resolve_non_null(sizeArray));
       
  2229   typeArrayHandle sizeArray_h(THREAD, sa);
       
  2230 
       
  2231   // validate the thread id array
       
  2232   validate_thread_id_array(ids_ah, CHECK);
       
  2233 
       
  2234   // sizeArray must be of the same length as the given array of thread IDs
       
  2235   int num_threads = ids_ah->length();
       
  2236   if (num_threads != sizeArray_h->length()) {
       
  2237     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
       
  2238               "The length of the given long array does not match the length of "
       
  2239               "the given array of thread IDs");
       
  2240   }
       
  2241 
       
  2242   MutexLockerEx ml(Threads_lock);
       
  2243   for (int i = 0; i < num_threads; i++) {
       
  2244     JavaThread* java_thread = Threads::find_java_thread_from_java_tid(ids_ah->long_at(i));
       
  2245     if (java_thread != NULL) {
       
  2246       sizeArray_h->long_at_put(i, java_thread->cooked_allocated_bytes());
       
  2247     }
       
  2248   }
       
  2249 JVM_END
       
  2250 
       
  2251 // Returns the CPU time consumed by a given thread (in nanoseconds).
       
  2252 // If thread_id == 0, CPU time for the current thread is returned.
       
  2253 // If user_sys_cpu_time = true, user level and system CPU time of
       
  2254 // a given thread is returned; otherwise, only user level CPU time
       
  2255 // is returned.
       
  2256 JVM_ENTRY(jlong, jmm_GetThreadCpuTimeWithKind(JNIEnv *env, jlong thread_id, jboolean user_sys_cpu_time))
       
  2257   if (!os::is_thread_cpu_time_supported()) {
       
  2258     return -1;
       
  2259   }
       
  2260 
       
  2261   if (thread_id < 0) {
       
  2262     THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
       
  2263                "Invalid thread ID", -1);
       
  2264   }
       
  2265 
       
  2266   JavaThread* java_thread = NULL;
       
  2267   if (thread_id == 0) {
       
  2268     // current thread
       
  2269     return os::current_thread_cpu_time(user_sys_cpu_time != 0);
       
  2270   } else {
       
  2271     MutexLockerEx ml(Threads_lock);
       
  2272     java_thread = Threads::find_java_thread_from_java_tid(thread_id);
       
  2273     if (java_thread != NULL) {
       
  2274       return os::thread_cpu_time((Thread*) java_thread, user_sys_cpu_time != 0);
       
  2275     }
       
  2276   }
       
  2277   return -1;
       
  2278 JVM_END
       
  2279 
       
  2280 // Gets an array containing the CPU times consumed by a set of threads
       
  2281 // (in nanoseconds).  Each element of the array is the CPU time for the
       
  2282 // thread ID specified in the corresponding entry in the given array
       
  2283 // of thread IDs; or -1 if the thread does not exist or has terminated.
       
  2284 // If user_sys_cpu_time = true, the sum of user level and system CPU time
       
  2285 // for the given thread is returned; otherwise, only user level CPU time
       
  2286 // is returned.
       
  2287 JVM_ENTRY(void, jmm_GetThreadCpuTimesWithKind(JNIEnv *env, jlongArray ids,
       
  2288                                               jlongArray timeArray,
       
  2289                                               jboolean user_sys_cpu_time))
       
  2290   // Check if threads is null
       
  2291   if (ids == NULL || timeArray == NULL) {
       
  2292     THROW(vmSymbols::java_lang_NullPointerException());
       
  2293   }
       
  2294 
       
  2295   ResourceMark rm(THREAD);
       
  2296   typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
       
  2297   typeArrayHandle ids_ah(THREAD, ta);
       
  2298 
       
  2299   typeArrayOop tia = typeArrayOop(JNIHandles::resolve_non_null(timeArray));
       
  2300   typeArrayHandle timeArray_h(THREAD, tia);
       
  2301 
       
  2302   // validate the thread id array
       
  2303   validate_thread_id_array(ids_ah, CHECK);
       
  2304 
       
  2305   // timeArray must be of the same length as the given array of thread IDs
       
  2306   int num_threads = ids_ah->length();
       
  2307   if (num_threads != timeArray_h->length()) {
       
  2308     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
       
  2309               "The length of the given long array does not match the length of "
       
  2310               "the given array of thread IDs");
       
  2311   }
       
  2312 
       
  2313   MutexLockerEx ml(Threads_lock);
       
  2314   for (int i = 0; i < num_threads; i++) {
       
  2315     JavaThread* java_thread = Threads::find_java_thread_from_java_tid(ids_ah->long_at(i));
       
  2316     if (java_thread != NULL) {
       
  2317       timeArray_h->long_at_put(i, os::thread_cpu_time((Thread*)java_thread,
       
  2318                                                       user_sys_cpu_time != 0));
       
  2319     }
       
  2320   }
       
  2321 JVM_END
       
  2322 
       
  2323 
       
  2324 
       
  2325 #if INCLUDE_MANAGEMENT
  2335 const struct jmmInterface_1_ jmm_interface = {
  2326 const struct jmmInterface_1_ jmm_interface = {
  2336   NULL,
  2327   NULL,
  2337   NULL,
  2328   NULL,
  2338   jmm_GetVersion,
  2329   jmm_GetVersion,
  2339   jmm_GetOptionalSupport,
  2330   jmm_GetOptionalSupport,