372
373 // initialize the arguments for the ThreadInfo constructor
374 initialize_ThreadInfo_constructor_arguments(&args, snapshot, CHECK_NULL);
375
376 // push the locked monitors and synchronizers in the arguments
377 args.push_oop(monitors_array);
378 args.push_oop(depths_array);
379 args.push_oop(synchronizers_array);
380
381 // Call ThreadInfo constructor with locked monitors and synchronizers
382 JavaCalls::call_special(&result,
383 ik,
384 vmSymbols::object_initializer_name(),
385 vmSymbols::java_lang_management_ThreadInfo_with_locks_constructor_signature(),
386 &args,
387 CHECK_NULL);
388
389 return (instanceOop) element();
390 }
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
410 static GCMemoryManager* get_gc_memory_manager_from_jobject(jobject mgr, TRAPS) {
411 if (mgr == NULL) {
412 THROW_(vmSymbols::java_lang_NullPointerException(), NULL);
413 }
414 oop mgr_obj = JNIHandles::resolve(mgr);
415 instanceHandle h(THREAD, (instanceOop) mgr_obj);
416
417 Klass* k = Management::java_lang_management_GarbageCollectorMXBean_klass(CHECK_NULL);
418 if (!h->is_a(k)) {
419 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
420 "the object is not an instance of java.lang.management.GarbageCollectorMXBean class",
421 NULL);
422 }
423
424 MemoryManager* gc = MemoryService::get_memory_manager(h);
425 if (gc == NULL || !gc->is_gc_memory_manager()) {
426 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
427 "Invalid GC memory manager",
428 NULL);
429 }
430 return (GCMemoryManager*) gc;
431 }
432
433 static MemoryPool* get_memory_pool_from_jobject(jobject obj, TRAPS) {
434 if (obj == NULL) {
435 THROW_(vmSymbols::java_lang_NullPointerException(), NULL);
436 }
437
438 oop pool_obj = JNIHandles::resolve(obj);
439 assert(pool_obj->is_instance(), "Should be an instanceOop");
440 instanceHandle ph(THREAD, (instanceOop) pool_obj);
441
442 return MemoryService::get_memory_pool(ph);
443 }
444
445 static void validate_thread_id_array(typeArrayHandle ids_ah, TRAPS) {
446 int num_threads = ids_ah->length();
447
448 // Validate input thread IDs
449 int i = 0;
450 for (i = 0; i < num_threads; i++) {
451 jlong tid = ids_ah->long_at(i);
452 if (tid <= 0) {
453 // throw exception if invalid thread id.
454 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
455 "Invalid thread ID entry");
456 }
457 }
458 }
459
460 static void validate_thread_info_array(objArrayHandle infoArray_h, TRAPS) {
461 // check if the element of infoArray is of type ThreadInfo class
462 Klass* threadinfo_klass = Management::java_lang_management_ThreadInfo_klass(CHECK);
463 Klass* element_klass = ObjArrayKlass::cast(infoArray_h->klass())->element_klass();
464 if (element_klass != threadinfo_klass) {
465 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
466 "infoArray element type is not ThreadInfo class");
467 }
468 }
469
470
471 static MemoryManager* get_memory_manager_from_jobject(jobject obj, TRAPS) {
472 if (obj == NULL) {
473 THROW_(vmSymbols::java_lang_NullPointerException(), NULL);
474 }
475
476 oop mgr_obj = JNIHandles::resolve(obj);
477 assert(mgr_obj->is_instance(), "Should be an instanceOop");
478 instanceHandle mh(THREAD, (instanceOop) mgr_obj);
479
803 if (!pool->gc_usage_threshold()->is_low_threshold_supported()) {
804 return -1;
805 }
806 // return and the new threshold is effective for the next GC
807 return pool->gc_usage_threshold()->set_low_threshold((size_t) threshold);
808
809 default:
810 assert(false, "Unrecognized type");
811 return -1;
812 }
813
814 // When the threshold is changed, reevaluate if the low memory
815 // detection is enabled.
816 if (prev != threshold) {
817 LowMemoryDetector::recompute_enabled_for_collected_pools();
818 LowMemoryDetector::detect_low_memory(pool);
819 }
820 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
861
862 // Returns a java/lang/management/MemoryUsage object representing
863 // the memory usage for the heap or non-heap memory.
864 JVM_ENTRY(jobject, jmm_GetMemoryUsage(JNIEnv* env, jboolean heap))
865 ResourceMark rm(THREAD);
866
867 // Calculate the memory usage
868 size_t total_init = 0;
869 size_t total_used = 0;
870 size_t total_committed = 0;
871 size_t total_max = 0;
872 bool has_undefined_init_size = false;
873 bool has_undefined_max_size = false;
874
875 for (int i = 0; i < MemoryService::num_memory_pools(); i++) {
876 MemoryPool* pool = MemoryService::get_memory_pool(i);
877 if ((heap && pool->is_heap()) || (!heap && pool->is_non_heap())) {
878 MemoryUsage u = pool->get_memory_usage();
879 total_used += u.used();
880 total_committed += u.committed();
881
1147 }
1148 return num_atts;
1149 JVM_END
1150
1151 // Helper function to do thread dump for a specific list of threads
1152 static void do_thread_dump(ThreadDumpResult* dump_result,
1153 typeArrayHandle ids_ah, // array of thread ID (long[])
1154 int num_threads,
1155 int max_depth,
1156 bool with_locked_monitors,
1157 bool with_locked_synchronizers,
1158 TRAPS) {
1159
1160 // First get an array of threadObj handles.
1161 // A JavaThread may terminate before we get the stack trace.
1162 GrowableArray<instanceHandle>* thread_handle_array = new GrowableArray<instanceHandle>(num_threads);
1163 {
1164 MutexLockerEx ml(Threads_lock);
1165 for (int i = 0; i < num_threads; i++) {
1166 jlong tid = ids_ah->long_at(i);
1167 JavaThread* jt = find_java_thread_from_id(tid);
1168 oop thread_obj = (jt != NULL ? jt->threadObj() : (oop)NULL);
1169 instanceHandle threadObj_h(THREAD, (instanceOop) thread_obj);
1170 thread_handle_array->append(threadObj_h);
1171 }
1172 }
1173
1174 // Obtain thread dumps and thread snapshot information
1175 VM_ThreadDump op(dump_result,
1176 thread_handle_array,
1177 num_threads,
1178 max_depth, /* stack depth */
1179 with_locked_monitors,
1180 with_locked_synchronizers);
1181 VMThread::execute(&op);
1182 }
1183
1184 // Gets an array of ThreadInfo objects. Each element is the ThreadInfo
1185 // for the thread ID specified in the corresponding entry in
1186 // the given array of thread IDs; or NULL if the thread does not exist
1187 // or has terminated.
1226 "The length of the given ThreadInfo array does not match the length of the given array of thread IDs", -1);
1227 }
1228
1229 if (JDK_Version::is_gte_jdk16x_version()) {
1230 // make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots
1231 java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_0);
1232 }
1233
1234 // Must use ThreadDumpResult to store the ThreadSnapshot.
1235 // GC may occur after the thread snapshots are taken but before
1236 // this function returns. The threadObj and other oops kept
1237 // in the ThreadSnapshot are marked and adjusted during GC.
1238 ThreadDumpResult dump_result(num_threads);
1239
1240 if (maxDepth == 0) {
1241 // no stack trace dumped - do not need to stop the world
1242 {
1243 MutexLockerEx ml(Threads_lock);
1244 for (int i = 0; i < num_threads; i++) {
1245 jlong tid = ids_ah->long_at(i);
1246 JavaThread* jt = find_java_thread_from_id(tid);
1247 ThreadSnapshot* ts;
1248 if (jt == NULL) {
1249 // if the thread does not exist or now it is terminated,
1250 // create dummy snapshot
1251 ts = new ThreadSnapshot();
1252 } else {
1253 ts = new ThreadSnapshot(jt);
1254 }
1255 dump_result.add_thread_snapshot(ts);
1256 }
1257 }
1258 } else {
1259 // obtain thread dump with the specific list of threads with stack trace
1260 do_thread_dump(&dump_result,
1261 ids_ah,
1262 num_threads,
1263 maxDepth,
1264 false, /* no locked monitor */
1265 false, /* no locked synchronizers */
1266 CHECK_0);
1472 case JMM_STAT_THREAD_CONTENTION_COUNT:
1473 case JMM_STAT_THREAD_CONTENTION_TIME: {
1474 jlong tid = obj.j;
1475 if (tid < 0) {
1476 THROW_(vmSymbols::java_lang_IllegalArgumentException(), JNI_FALSE);
1477 }
1478
1479 // Look for the JavaThread of this given tid
1480 MutexLockerEx ml(Threads_lock);
1481 if (tid == 0) {
1482 // reset contention statistics for all threads if tid == 0
1483 for (JavaThread* java_thread = Threads::first(); java_thread != NULL; java_thread = java_thread->next()) {
1484 if (type == JMM_STAT_THREAD_CONTENTION_COUNT) {
1485 ThreadService::reset_contention_count_stat(java_thread);
1486 } else {
1487 ThreadService::reset_contention_time_stat(java_thread);
1488 }
1489 }
1490 } else {
1491 // reset contention statistics for a given thread
1492 JavaThread* java_thread = find_java_thread_from_id(tid);
1493 if (java_thread == NULL) {
1494 return false;
1495 }
1496
1497 if (type == JMM_STAT_THREAD_CONTENTION_COUNT) {
1498 ThreadService::reset_contention_count_stat(java_thread);
1499 } else {
1500 ThreadService::reset_contention_time_stat(java_thread);
1501 }
1502 }
1503 return true;
1504 break;
1505 }
1506 case JMM_STAT_PEAK_POOL_USAGE: {
1507 jobject o = obj.l;
1508 if (o == NULL) {
1509 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE);
1510 }
1511
1512 oop pool_obj = JNIHandles::resolve(o);
1541
1542 // Returns the fast estimate of CPU time consumed by
1543 // a given thread (in nanoseconds).
1544 // If thread_id == 0, return CPU time for the current thread.
1545 JVM_ENTRY(jlong, jmm_GetThreadCpuTime(JNIEnv *env, jlong thread_id))
1546 if (!os::is_thread_cpu_time_supported()) {
1547 return -1;
1548 }
1549
1550 if (thread_id < 0) {
1551 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
1552 "Invalid thread ID", -1);
1553 }
1554
1555 JavaThread* java_thread = NULL;
1556 if (thread_id == 0) {
1557 // current thread
1558 return os::current_thread_cpu_time();
1559 } else {
1560 MutexLockerEx ml(Threads_lock);
1561 java_thread = find_java_thread_from_id(thread_id);
1562 if (java_thread != NULL) {
1563 return os::thread_cpu_time((Thread*) java_thread);
1564 }
1565 }
1566 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
1640
1641 // Returns a String array of all VM global flag names
1642 JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))
1643 // last flag entry is always NULL, so subtract 1
1644 int nFlags = (int) Flag::numFlags - 1;
1645 // allocate a temp array
1646 objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(),
1647 nFlags, CHECK_0);
1648 objArrayHandle flags_ah(THREAD, r);
1649 int num_entries = 0;
1650 for (int i = 0; i < nFlags; i++) {
1651 Flag* flag = &Flag::flags[i];
1652 // Exclude notproduct and develop flags in product builds.
1653 if (flag->is_constant_in_binary()) {
1654 continue;
1655 }
1656 // Exclude the locked (experimental, diagnostic) flags
1657 if (flag->is_unlocked() || flag->is_unlocker()) {
1658 Handle s = java_lang_String::create_from_str(flag->_name, CHECK_0);
1659 flags_ah->obj_at_put(num_entries, s());
1660 num_entries++;
2306 char* cmdline = java_lang_String::as_utf8_string(cmd);
2307 if (cmdline == NULL) {
2308 THROW_MSG_NULL(vmSymbols::java_lang_NullPointerException(),
2309 "Command line content cannot be null.");
2310 }
2311 bufferedStream output;
2312 DCmd::parse_and_execute(DCmd_Source_MBean, &output, cmdline, ' ', CHECK_NULL);
2313 oop result = java_lang_String::create_oop_from_str(output.as_string(), CHECK_NULL);
2314 return (jstring) JNIHandles::make_local(env, result);
2315 JVM_END
2316
2317 JVM_ENTRY(void, jmm_SetDiagnosticFrameworkNotificationEnabled(JNIEnv *env, jboolean enabled))
2318 DCmdFactory::set_jmx_notification_enabled(enabled?true:false);
2319 JVM_END
2320
2321 jlong Management::ticks_to_ms(jlong ticks) {
2322 assert(os::elapsed_frequency() > 0, "Must be non-zero");
2323 return (jlong)(((double)ticks / (double)os::elapsed_frequency())
2324 * (double)1000.0);
2325 }
2326
2327 const struct jmmInterface_1_ jmm_interface = {
2328 NULL,
2329 NULL,
2330 jmm_GetVersion,
2331 jmm_GetOptionalSupport,
2332 jmm_GetInputArguments,
2333 jmm_GetThreadInfo,
2334 jmm_GetInputArgumentArray,
2335 jmm_GetMemoryPools,
2336 jmm_GetMemoryManagers,
2337 jmm_GetMemoryPoolUsage,
2338 jmm_GetPeakMemoryPoolUsage,
2339 jmm_GetThreadAllocatedMemory,
2340 jmm_GetMemoryUsage,
2341 jmm_GetLongAttribute,
2342 jmm_GetBoolAttribute,
2343 jmm_SetBoolAttribute,
2344 jmm_GetLongAttributes,
2345 jmm_FindMonitorDeadlockedThreads,
2346 jmm_GetThreadCpuTime,
|
372
373 // initialize the arguments for the ThreadInfo constructor
374 initialize_ThreadInfo_constructor_arguments(&args, snapshot, CHECK_NULL);
375
376 // push the locked monitors and synchronizers in the arguments
377 args.push_oop(monitors_array);
378 args.push_oop(depths_array);
379 args.push_oop(synchronizers_array);
380
381 // Call ThreadInfo constructor with locked monitors and synchronizers
382 JavaCalls::call_special(&result,
383 ik,
384 vmSymbols::object_initializer_name(),
385 vmSymbols::java_lang_management_ThreadInfo_with_locks_constructor_signature(),
386 &args,
387 CHECK_NULL);
388
389 return (instanceOop) element();
390 }
391
392
393 static GCMemoryManager* get_gc_memory_manager_from_jobject(jobject mgr, TRAPS) {
394 if (mgr == NULL) {
395 THROW_(vmSymbols::java_lang_NullPointerException(), NULL);
396 }
397 oop mgr_obj = JNIHandles::resolve(mgr);
398 instanceHandle h(THREAD, (instanceOop) mgr_obj);
399
400 Klass* k = Management::java_lang_management_GarbageCollectorMXBean_klass(CHECK_NULL);
401 if (!h->is_a(k)) {
402 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
403 "the object is not an instance of java.lang.management.GarbageCollectorMXBean class",
404 NULL);
405 }
406
407 MemoryManager* gc = MemoryService::get_memory_manager(h);
408 if (gc == NULL || !gc->is_gc_memory_manager()) {
409 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
410 "Invalid GC memory manager",
411 NULL);
412 }
413 return (GCMemoryManager*) gc;
414 }
415
416 static MemoryPool* get_memory_pool_from_jobject(jobject obj, TRAPS) {
417 if (obj == NULL) {
418 THROW_(vmSymbols::java_lang_NullPointerException(), NULL);
419 }
420
421 oop pool_obj = JNIHandles::resolve(obj);
422 assert(pool_obj->is_instance(), "Should be an instanceOop");
423 instanceHandle ph(THREAD, (instanceOop) pool_obj);
424
425 return MemoryService::get_memory_pool(ph);
426 }
427
428 #endif // INCLUDE_MANAGEMENT
429
430 static void validate_thread_id_array(typeArrayHandle ids_ah, TRAPS) {
431 int num_threads = ids_ah->length();
432
433 // Validate input thread IDs
434 int i = 0;
435 for (i = 0; i < num_threads; i++) {
436 jlong tid = ids_ah->long_at(i);
437 if (tid <= 0) {
438 // throw exception if invalid thread id.
439 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
440 "Invalid thread ID entry");
441 }
442 }
443 }
444
445 #if INCLUDE_MANAGEMENT
446
447 static void validate_thread_info_array(objArrayHandle infoArray_h, TRAPS) {
448 // check if the element of infoArray is of type ThreadInfo class
449 Klass* threadinfo_klass = Management::java_lang_management_ThreadInfo_klass(CHECK);
450 Klass* element_klass = ObjArrayKlass::cast(infoArray_h->klass())->element_klass();
451 if (element_klass != threadinfo_klass) {
452 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
453 "infoArray element type is not ThreadInfo class");
454 }
455 }
456
457
458 static MemoryManager* get_memory_manager_from_jobject(jobject obj, TRAPS) {
459 if (obj == NULL) {
460 THROW_(vmSymbols::java_lang_NullPointerException(), NULL);
461 }
462
463 oop mgr_obj = JNIHandles::resolve(obj);
464 assert(mgr_obj->is_instance(), "Should be an instanceOop");
465 instanceHandle mh(THREAD, (instanceOop) mgr_obj);
466
790 if (!pool->gc_usage_threshold()->is_low_threshold_supported()) {
791 return -1;
792 }
793 // return and the new threshold is effective for the next GC
794 return pool->gc_usage_threshold()->set_low_threshold((size_t) threshold);
795
796 default:
797 assert(false, "Unrecognized type");
798 return -1;
799 }
800
801 // When the threshold is changed, reevaluate if the low memory
802 // detection is enabled.
803 if (prev != threshold) {
804 LowMemoryDetector::recompute_enabled_for_collected_pools();
805 LowMemoryDetector::detect_low_memory(pool);
806 }
807 return prev;
808 JVM_END
809
810 // Returns a java/lang/management/MemoryUsage object representing
811 // the memory usage for the heap or non-heap memory.
812 JVM_ENTRY(jobject, jmm_GetMemoryUsage(JNIEnv* env, jboolean heap))
813 ResourceMark rm(THREAD);
814
815 // Calculate the memory usage
816 size_t total_init = 0;
817 size_t total_used = 0;
818 size_t total_committed = 0;
819 size_t total_max = 0;
820 bool has_undefined_init_size = false;
821 bool has_undefined_max_size = false;
822
823 for (int i = 0; i < MemoryService::num_memory_pools(); i++) {
824 MemoryPool* pool = MemoryService::get_memory_pool(i);
825 if ((heap && pool->is_heap()) || (!heap && pool->is_non_heap())) {
826 MemoryUsage u = pool->get_memory_usage();
827 total_used += u.used();
828 total_committed += u.committed();
829
1095 }
1096 return num_atts;
1097 JVM_END
1098
1099 // Helper function to do thread dump for a specific list of threads
1100 static void do_thread_dump(ThreadDumpResult* dump_result,
1101 typeArrayHandle ids_ah, // array of thread ID (long[])
1102 int num_threads,
1103 int max_depth,
1104 bool with_locked_monitors,
1105 bool with_locked_synchronizers,
1106 TRAPS) {
1107
1108 // First get an array of threadObj handles.
1109 // A JavaThread may terminate before we get the stack trace.
1110 GrowableArray<instanceHandle>* thread_handle_array = new GrowableArray<instanceHandle>(num_threads);
1111 {
1112 MutexLockerEx ml(Threads_lock);
1113 for (int i = 0; i < num_threads; i++) {
1114 jlong tid = ids_ah->long_at(i);
1115 JavaThread* jt = Threads::find_java_thread_from_java_tid(tid);
1116 oop thread_obj = (jt != NULL ? jt->threadObj() : (oop)NULL);
1117 instanceHandle threadObj_h(THREAD, (instanceOop) thread_obj);
1118 thread_handle_array->append(threadObj_h);
1119 }
1120 }
1121
1122 // Obtain thread dumps and thread snapshot information
1123 VM_ThreadDump op(dump_result,
1124 thread_handle_array,
1125 num_threads,
1126 max_depth, /* stack depth */
1127 with_locked_monitors,
1128 with_locked_synchronizers);
1129 VMThread::execute(&op);
1130 }
1131
1132 // Gets an array of ThreadInfo objects. Each element is the ThreadInfo
1133 // for the thread ID specified in the corresponding entry in
1134 // the given array of thread IDs; or NULL if the thread does not exist
1135 // or has terminated.
1174 "The length of the given ThreadInfo array does not match the length of the given array of thread IDs", -1);
1175 }
1176
1177 if (JDK_Version::is_gte_jdk16x_version()) {
1178 // make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots
1179 java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_0);
1180 }
1181
1182 // Must use ThreadDumpResult to store the ThreadSnapshot.
1183 // GC may occur after the thread snapshots are taken but before
1184 // this function returns. The threadObj and other oops kept
1185 // in the ThreadSnapshot are marked and adjusted during GC.
1186 ThreadDumpResult dump_result(num_threads);
1187
1188 if (maxDepth == 0) {
1189 // no stack trace dumped - do not need to stop the world
1190 {
1191 MutexLockerEx ml(Threads_lock);
1192 for (int i = 0; i < num_threads; i++) {
1193 jlong tid = ids_ah->long_at(i);
1194 JavaThread* jt = Threads::find_java_thread_from_java_tid(tid);
1195 ThreadSnapshot* ts;
1196 if (jt == NULL) {
1197 // if the thread does not exist or now it is terminated,
1198 // create dummy snapshot
1199 ts = new ThreadSnapshot();
1200 } else {
1201 ts = new ThreadSnapshot(jt);
1202 }
1203 dump_result.add_thread_snapshot(ts);
1204 }
1205 }
1206 } else {
1207 // obtain thread dump with the specific list of threads with stack trace
1208 do_thread_dump(&dump_result,
1209 ids_ah,
1210 num_threads,
1211 maxDepth,
1212 false, /* no locked monitor */
1213 false, /* no locked synchronizers */
1214 CHECK_0);
1420 case JMM_STAT_THREAD_CONTENTION_COUNT:
1421 case JMM_STAT_THREAD_CONTENTION_TIME: {
1422 jlong tid = obj.j;
1423 if (tid < 0) {
1424 THROW_(vmSymbols::java_lang_IllegalArgumentException(), JNI_FALSE);
1425 }
1426
1427 // Look for the JavaThread of this given tid
1428 MutexLockerEx ml(Threads_lock);
1429 if (tid == 0) {
1430 // reset contention statistics for all threads if tid == 0
1431 for (JavaThread* java_thread = Threads::first(); java_thread != NULL; java_thread = java_thread->next()) {
1432 if (type == JMM_STAT_THREAD_CONTENTION_COUNT) {
1433 ThreadService::reset_contention_count_stat(java_thread);
1434 } else {
1435 ThreadService::reset_contention_time_stat(java_thread);
1436 }
1437 }
1438 } else {
1439 // reset contention statistics for a given thread
1440 JavaThread* java_thread = Threads::find_java_thread_from_java_tid(tid);
1441 if (java_thread == NULL) {
1442 return false;
1443 }
1444
1445 if (type == JMM_STAT_THREAD_CONTENTION_COUNT) {
1446 ThreadService::reset_contention_count_stat(java_thread);
1447 } else {
1448 ThreadService::reset_contention_time_stat(java_thread);
1449 }
1450 }
1451 return true;
1452 break;
1453 }
1454 case JMM_STAT_PEAK_POOL_USAGE: {
1455 jobject o = obj.l;
1456 if (o == NULL) {
1457 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE);
1458 }
1459
1460 oop pool_obj = JNIHandles::resolve(o);
1489
1490 // Returns the fast estimate of CPU time consumed by
1491 // a given thread (in nanoseconds).
1492 // If thread_id == 0, return CPU time for the current thread.
1493 JVM_ENTRY(jlong, jmm_GetThreadCpuTime(JNIEnv *env, jlong thread_id))
1494 if (!os::is_thread_cpu_time_supported()) {
1495 return -1;
1496 }
1497
1498 if (thread_id < 0) {
1499 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
1500 "Invalid thread ID", -1);
1501 }
1502
1503 JavaThread* java_thread = NULL;
1504 if (thread_id == 0) {
1505 // current thread
1506 return os::current_thread_cpu_time();
1507 } else {
1508 MutexLockerEx ml(Threads_lock);
1509 java_thread = Threads::find_java_thread_from_java_tid(thread_id);
1510 if (java_thread != NULL) {
1511 return os::thread_cpu_time((Thread*) java_thread);
1512 }
1513 }
1514 return -1;
1515 JVM_END
1516
1517 // Returns a String array of all VM global flag names
1518 JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))
1519 // last flag entry is always NULL, so subtract 1
1520 int nFlags = (int) Flag::numFlags - 1;
1521 // allocate a temp array
1522 objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(),
1523 nFlags, CHECK_0);
1524 objArrayHandle flags_ah(THREAD, r);
1525 int num_entries = 0;
1526 for (int i = 0; i < nFlags; i++) {
1527 Flag* flag = &Flag::flags[i];
1528 // Exclude notproduct and develop flags in product builds.
1529 if (flag->is_constant_in_binary()) {
1530 continue;
1531 }
1532 // Exclude the locked (experimental, diagnostic) flags
1533 if (flag->is_unlocked() || flag->is_unlocker()) {
1534 Handle s = java_lang_String::create_from_str(flag->_name, CHECK_0);
1535 flags_ah->obj_at_put(num_entries, s());
1536 num_entries++;
2182 char* cmdline = java_lang_String::as_utf8_string(cmd);
2183 if (cmdline == NULL) {
2184 THROW_MSG_NULL(vmSymbols::java_lang_NullPointerException(),
2185 "Command line content cannot be null.");
2186 }
2187 bufferedStream output;
2188 DCmd::parse_and_execute(DCmd_Source_MBean, &output, cmdline, ' ', CHECK_NULL);
2189 oop result = java_lang_String::create_oop_from_str(output.as_string(), CHECK_NULL);
2190 return (jstring) JNIHandles::make_local(env, result);
2191 JVM_END
2192
2193 JVM_ENTRY(void, jmm_SetDiagnosticFrameworkNotificationEnabled(JNIEnv *env, jboolean enabled))
2194 DCmdFactory::set_jmx_notification_enabled(enabled?true:false);
2195 JVM_END
2196
2197 jlong Management::ticks_to_ms(jlong ticks) {
2198 assert(os::elapsed_frequency() > 0, "Must be non-zero");
2199 return (jlong)(((double)ticks / (double)os::elapsed_frequency())
2200 * (double)1000.0);
2201 }
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
2318 const struct jmmInterface_1_ jmm_interface = {
2319 NULL,
2320 NULL,
2321 jmm_GetVersion,
2322 jmm_GetOptionalSupport,
2323 jmm_GetInputArguments,
2324 jmm_GetThreadInfo,
2325 jmm_GetInputArgumentArray,
2326 jmm_GetMemoryPools,
2327 jmm_GetMemoryManagers,
2328 jmm_GetMemoryPoolUsage,
2329 jmm_GetPeakMemoryPoolUsage,
2330 jmm_GetThreadAllocatedMemory,
2331 jmm_GetMemoryUsage,
2332 jmm_GetLongAttribute,
2333 jmm_GetBoolAttribute,
2334 jmm_SetBoolAttribute,
2335 jmm_GetLongAttributes,
2336 jmm_FindMonitorDeadlockedThreads,
2337 jmm_GetThreadCpuTime,
|