comparison src/share/vm/services/management.cpp @ 20393:966601b12d4f

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