1 /* |
1 /* |
2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
99 _optional_support.isOtherThreadCpuTimeSupported = 1; |
99 _optional_support.isOtherThreadCpuTimeSupported = 1; |
100 } else { |
100 } else { |
101 _optional_support.isCurrentThreadCpuTimeSupported = 0; |
101 _optional_support.isCurrentThreadCpuTimeSupported = 0; |
102 _optional_support.isOtherThreadCpuTimeSupported = 0; |
102 _optional_support.isOtherThreadCpuTimeSupported = 0; |
103 } |
103 } |
|
104 |
104 _optional_support.isBootClassPathSupported = 1; |
105 _optional_support.isBootClassPathSupported = 1; |
105 _optional_support.isObjectMonitorUsageSupported = 1; |
106 _optional_support.isObjectMonitorUsageSupported = 1; |
106 #ifndef SERVICES_KERNEL |
107 #ifndef SERVICES_KERNEL |
107 // This depends on the heap inspector |
108 // This depends on the heap inspector |
108 _optional_support.isSynchronizerUsageSupported = 1; |
109 _optional_support.isSynchronizerUsageSupported = 1; |
109 #endif // SERVICES_KERNEL |
110 #endif // SERVICES_KERNEL |
|
111 _optional_support.isThreadAllocatedMemorySupported = 1; |
110 } |
112 } |
111 |
113 |
112 void Management::initialize(TRAPS) { |
114 void Management::initialize(TRAPS) { |
113 // Start the low memory detector thread |
115 // Start the low memory detector thread |
114 LowMemoryDetector::initialize(); |
116 LowMemoryDetector::initialize(); |
384 return MemoryService::get_memory_pool(ph); |
386 return MemoryService::get_memory_pool(ph); |
385 } |
387 } |
386 |
388 |
387 static void validate_thread_id_array(typeArrayHandle ids_ah, TRAPS) { |
389 static void validate_thread_id_array(typeArrayHandle ids_ah, TRAPS) { |
388 int num_threads = ids_ah->length(); |
390 int num_threads = ids_ah->length(); |
389 // should be non-empty array |
|
390 if (num_threads == 0) { |
|
391 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
|
392 "Empty array of thread IDs"); |
|
393 } |
|
394 |
391 |
395 // Validate input thread IDs |
392 // Validate input thread IDs |
396 int i = 0; |
393 int i = 0; |
397 for (i = 0; i < num_threads; i++) { |
394 for (i = 0; i < num_threads; i++) { |
398 jlong tid = ids_ah->long_at(i); |
395 jlong tid = ids_ah->long_at(i); |
400 // throw exception if invalid thread id. |
397 // throw exception if invalid thread id. |
401 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
398 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
402 "Invalid thread ID entry"); |
399 "Invalid thread ID entry"); |
403 } |
400 } |
404 } |
401 } |
405 |
|
406 } |
402 } |
407 |
403 |
408 static void validate_thread_info_array(objArrayHandle infoArray_h, TRAPS) { |
404 static void validate_thread_info_array(objArrayHandle infoArray_h, TRAPS) { |
409 |
|
410 // check if the element of infoArray is of type ThreadInfo class |
405 // check if the element of infoArray is of type ThreadInfo class |
411 klassOop threadinfo_klass = Management::java_lang_management_ThreadInfo_klass(CHECK); |
406 klassOop threadinfo_klass = Management::java_lang_management_ThreadInfo_klass(CHECK); |
412 klassOop element_klass = objArrayKlass::cast(infoArray_h->klass())->element_klass(); |
407 klassOop element_klass = objArrayKlass::cast(infoArray_h->klass())->element_klass(); |
413 if (element_klass != threadinfo_klass) { |
408 if (element_klass != threadinfo_klass) { |
414 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
409 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
415 "infoArray element type is not ThreadInfo class"); |
410 "infoArray element type is not ThreadInfo class"); |
416 } |
411 } |
417 |
|
418 } |
412 } |
419 |
413 |
420 |
414 |
421 static MemoryManager* get_memory_manager_from_jobject(jobject obj, TRAPS) { |
415 static MemoryManager* get_memory_manager_from_jobject(jobject obj, TRAPS) { |
422 if (obj == NULL) { |
416 if (obj == NULL) { |
768 LowMemoryDetector::detect_low_memory(pool); |
762 LowMemoryDetector::detect_low_memory(pool); |
769 } |
763 } |
770 return prev; |
764 return prev; |
771 JVM_END |
765 JVM_END |
772 |
766 |
|
767 // Gets an array containing the amount of memory allocated on the Java |
|
768 // heap for a set of threads (in bytes). Each element of the array is |
|
769 // the amount of memory allocated for the thread ID specified in the |
|
770 // corresponding entry in the given array of thread IDs; or -1 if the |
|
771 // thread does not exist or has terminated. |
|
772 JVM_ENTRY(void, jmm_GetThreadAllocatedMemory(JNIEnv *env, jlongArray ids, |
|
773 jlongArray sizeArray)) |
|
774 // Check if threads is null |
|
775 if (ids == NULL || sizeArray == NULL) { |
|
776 THROW(vmSymbols::java_lang_NullPointerException()); |
|
777 } |
|
778 |
|
779 ResourceMark rm(THREAD); |
|
780 typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids)); |
|
781 typeArrayHandle ids_ah(THREAD, ta); |
|
782 |
|
783 typeArrayOop sa = typeArrayOop(JNIHandles::resolve_non_null(sizeArray)); |
|
784 typeArrayHandle sizeArray_h(THREAD, sa); |
|
785 |
|
786 // validate the thread id array |
|
787 validate_thread_id_array(ids_ah, CHECK); |
|
788 |
|
789 // sizeArray must be of the same length as the given array of thread IDs |
|
790 int num_threads = ids_ah->length(); |
|
791 if (num_threads != sizeArray_h->length()) { |
|
792 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
|
793 "The length of the given long array does not match the length of " |
|
794 "the given array of thread IDs"); |
|
795 } |
|
796 |
|
797 MutexLockerEx ml(Threads_lock); |
|
798 for (int i = 0; i < num_threads; i++) { |
|
799 JavaThread* java_thread = find_java_thread_from_id(ids_ah->long_at(i)); |
|
800 if (java_thread != NULL) { |
|
801 sizeArray_h->long_at_put(i, java_thread->cooked_allocated_bytes()); |
|
802 } |
|
803 } |
|
804 JVM_END |
|
805 |
773 // Returns a java/lang/management/MemoryUsage object representing |
806 // Returns a java/lang/management/MemoryUsage object representing |
774 // the memory usage for the heap or non-heap memory. |
807 // the memory usage for the heap or non-heap memory. |
775 JVM_ENTRY(jobject, jmm_GetMemoryUsage(JNIEnv* env, jboolean heap)) |
808 JVM_ENTRY(jobject, jmm_GetMemoryUsage(JNIEnv* env, jboolean heap)) |
776 ResourceMark rm(THREAD); |
809 ResourceMark rm(THREAD); |
777 |
810 |
832 return ClassLoadingService::get_verbose(); |
865 return ClassLoadingService::get_verbose(); |
833 case JMM_THREAD_CONTENTION_MONITORING: |
866 case JMM_THREAD_CONTENTION_MONITORING: |
834 return ThreadService::is_thread_monitoring_contention(); |
867 return ThreadService::is_thread_monitoring_contention(); |
835 case JMM_THREAD_CPU_TIME: |
868 case JMM_THREAD_CPU_TIME: |
836 return ThreadService::is_thread_cpu_time_enabled(); |
869 return ThreadService::is_thread_cpu_time_enabled(); |
|
870 case JMM_THREAD_ALLOCATED_MEMORY: |
|
871 return ThreadService::is_thread_allocated_memory_enabled(); |
837 default: |
872 default: |
838 assert(0, "Unrecognized attribute"); |
873 assert(0, "Unrecognized attribute"); |
839 return false; |
874 return false; |
840 } |
875 } |
841 JVM_END |
876 JVM_END |
849 return ClassLoadingService::set_verbose(flag != 0); |
884 return ClassLoadingService::set_verbose(flag != 0); |
850 case JMM_THREAD_CONTENTION_MONITORING: |
885 case JMM_THREAD_CONTENTION_MONITORING: |
851 return ThreadService::set_thread_monitoring_contention(flag != 0); |
886 return ThreadService::set_thread_monitoring_contention(flag != 0); |
852 case JMM_THREAD_CPU_TIME: |
887 case JMM_THREAD_CPU_TIME: |
853 return ThreadService::set_thread_cpu_time_enabled(flag != 0); |
888 return ThreadService::set_thread_cpu_time_enabled(flag != 0); |
|
889 case JMM_THREAD_ALLOCATED_MEMORY: |
|
890 return ThreadService::set_thread_allocated_memory_enabled(flag != 0); |
854 default: |
891 default: |
855 assert(0, "Unrecognized attribute"); |
892 assert(0, "Unrecognized attribute"); |
856 return false; |
893 return false; |
857 } |
894 } |
858 JVM_END |
895 JVM_END |
1094 // maxDepth - the maximum depth of stack traces to be dumped: |
1131 // maxDepth - the maximum depth of stack traces to be dumped: |
1095 // maxDepth == -1 requests to dump entire stack trace. |
1132 // maxDepth == -1 requests to dump entire stack trace. |
1096 // maxDepth == 0 requests no stack trace. |
1133 // maxDepth == 0 requests no stack trace. |
1097 // infoArray - array of ThreadInfo objects |
1134 // infoArray - array of ThreadInfo objects |
1098 // |
1135 // |
|
1136 // QQQ - Why does this method return a value instead of void? |
1099 JVM_ENTRY(jint, jmm_GetThreadInfo(JNIEnv *env, jlongArray ids, jint maxDepth, jobjectArray infoArray)) |
1137 JVM_ENTRY(jint, jmm_GetThreadInfo(JNIEnv *env, jlongArray ids, jint maxDepth, jobjectArray infoArray)) |
1100 // Check if threads is null |
1138 // Check if threads is null |
1101 if (ids == NULL || infoArray == NULL) { |
1139 if (ids == NULL || infoArray == NULL) { |
1102 THROW_(vmSymbols::java_lang_NullPointerException(), -1); |
1140 THROW_(vmSymbols::java_lang_NullPointerException(), -1); |
1103 } |
1141 } |
1249 if (ts->threadObj() == NULL) { |
1286 if (ts->threadObj() == NULL) { |
1250 // if the thread does not exist or now it is terminated, set threadinfo to NULL |
1287 // if the thread does not exist or now it is terminated, set threadinfo to NULL |
1251 result_h->obj_at_put(index, NULL); |
1288 result_h->obj_at_put(index, NULL); |
1252 continue; |
1289 continue; |
1253 } |
1290 } |
1254 |
|
1255 |
|
1256 |
1291 |
1257 ThreadStackTrace* stacktrace = ts->get_stack_trace(); |
1292 ThreadStackTrace* stacktrace = ts->get_stack_trace(); |
1258 assert(stacktrace != NULL, "Must have a stack trace dumped"); |
1293 assert(stacktrace != NULL, "Must have a stack trace dumped"); |
1259 |
1294 |
1260 // Create Object[] filled with locked monitors |
1295 // Create Object[] filled with locked monitors |
1496 if (java_thread != NULL) { |
1531 if (java_thread != NULL) { |
1497 return os::thread_cpu_time((Thread*) java_thread, user_sys_cpu_time != 0); |
1532 return os::thread_cpu_time((Thread*) java_thread, user_sys_cpu_time != 0); |
1498 } |
1533 } |
1499 } |
1534 } |
1500 return -1; |
1535 return -1; |
|
1536 JVM_END |
|
1537 |
|
1538 // Gets an array containing the CPU times consumed by a set of threads |
|
1539 // (in nanoseconds). Each element of the array is the CPU time for the |
|
1540 // thread ID specified in the corresponding entry in the given array |
|
1541 // of thread IDs; or -1 if the thread does not exist or has terminated. |
|
1542 // If user_sys_cpu_time = true, the sum of user level and system CPU time |
|
1543 // for the given thread is returned; otherwise, only user level CPU time |
|
1544 // is returned. |
|
1545 JVM_ENTRY(void, jmm_GetThreadCpuTimesWithKind(JNIEnv *env, jlongArray ids, |
|
1546 jlongArray timeArray, |
|
1547 jboolean user_sys_cpu_time)) |
|
1548 // Check if threads is null |
|
1549 if (ids == NULL || timeArray == NULL) { |
|
1550 THROW(vmSymbols::java_lang_NullPointerException()); |
|
1551 } |
|
1552 |
|
1553 ResourceMark rm(THREAD); |
|
1554 typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids)); |
|
1555 typeArrayHandle ids_ah(THREAD, ta); |
|
1556 |
|
1557 typeArrayOop tia = typeArrayOop(JNIHandles::resolve_non_null(timeArray)); |
|
1558 typeArrayHandle timeArray_h(THREAD, tia); |
|
1559 |
|
1560 // validate the thread id array |
|
1561 validate_thread_id_array(ids_ah, CHECK); |
|
1562 |
|
1563 // timeArray must be of the same length as the given array of thread IDs |
|
1564 int num_threads = ids_ah->length(); |
|
1565 if (num_threads != timeArray_h->length()) { |
|
1566 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
|
1567 "The length of the given long array does not match the length of " |
|
1568 "the given array of thread IDs"); |
|
1569 } |
|
1570 |
|
1571 MutexLockerEx ml(Threads_lock); |
|
1572 for (int i = 0; i < num_threads; i++) { |
|
1573 JavaThread* java_thread = find_java_thread_from_id(ids_ah->long_at(i)); |
|
1574 if (java_thread != NULL) { |
|
1575 timeArray_h->long_at_put(i, os::thread_cpu_time((Thread*)java_thread, |
|
1576 user_sys_cpu_time != 0)); |
|
1577 } |
|
1578 } |
1501 JVM_END |
1579 JVM_END |
1502 |
1580 |
1503 // Returns a String array of all VM global flag names |
1581 // Returns a String array of all VM global flag names |
1504 JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env)) |
1582 JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env)) |
1505 // last flag entry is always NULL, so subtract 1 |
1583 // last flag entry is always NULL, so subtract 1 |
2018 jmm_GetInputArgumentArray, |
2096 jmm_GetInputArgumentArray, |
2019 jmm_GetMemoryPools, |
2097 jmm_GetMemoryPools, |
2020 jmm_GetMemoryManagers, |
2098 jmm_GetMemoryManagers, |
2021 jmm_GetMemoryPoolUsage, |
2099 jmm_GetMemoryPoolUsage, |
2022 jmm_GetPeakMemoryPoolUsage, |
2100 jmm_GetPeakMemoryPoolUsage, |
2023 NULL, |
2101 jmm_GetThreadAllocatedMemory, |
2024 jmm_GetMemoryUsage, |
2102 jmm_GetMemoryUsage, |
2025 jmm_GetLongAttribute, |
2103 jmm_GetLongAttribute, |
2026 jmm_GetBoolAttribute, |
2104 jmm_GetBoolAttribute, |
2027 jmm_SetBoolAttribute, |
2105 jmm_SetBoolAttribute, |
2028 jmm_GetLongAttributes, |
2106 jmm_GetLongAttributes, |
2036 jmm_SetPoolThreshold, |
2114 jmm_SetPoolThreshold, |
2037 jmm_GetPoolCollectionUsage, |
2115 jmm_GetPoolCollectionUsage, |
2038 jmm_GetGCExtAttributeInfo, |
2116 jmm_GetGCExtAttributeInfo, |
2039 jmm_GetLastGCStat, |
2117 jmm_GetLastGCStat, |
2040 jmm_GetThreadCpuTimeWithKind, |
2118 jmm_GetThreadCpuTimeWithKind, |
2041 NULL, |
2119 jmm_GetThreadCpuTimesWithKind, |
2042 jmm_DumpHeap0, |
2120 jmm_DumpHeap0, |
2043 jmm_FindDeadlockedThreads, |
2121 jmm_FindDeadlockedThreads, |
2044 jmm_SetVMGlobal, |
2122 jmm_SetVMGlobal, |
2045 NULL, |
2123 NULL, |
2046 jmm_DumpThreads |
2124 jmm_DumpThreads |