1064 typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids)); 1065 typeArrayHandle ids_ah(THREAD, ta); 1066 1067 oop infoArray_obj = JNIHandles::resolve_non_null(infoArray); 1068 objArrayOop oa = objArrayOop(infoArray_obj); 1069 objArrayHandle infoArray_h(THREAD, oa); 1070 1071 // validate the thread id array 1072 validate_thread_id_array(ids_ah, CHECK_0); 1073 1074 // validate the ThreadInfo[] parameters 1075 validate_thread_info_array(infoArray_h, CHECK_0); 1076 1077 // infoArray must be of the same length as the given array of thread IDs 1078 int num_threads = ids_ah->length(); 1079 if (num_threads != infoArray_h->length()) { 1080 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), 1081 "The length of the given ThreadInfo array does not match the length of the given array of thread IDs", -1); 1082 } 1083 1084 // make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots 1085 java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_0); 1086 1087 // Must use ThreadDumpResult to store the ThreadSnapshot. 1088 // GC may occur after the thread snapshots are taken but before 1089 // this function returns. The threadObj and other oops kept 1090 // in the ThreadSnapshot are marked and adjusted during GC. 1091 ThreadDumpResult dump_result(num_threads); 1092 1093 if (maxDepth == 0) { 1094 // No stack trace to dump so we do not need to stop the world. 1095 // Since we never do the VM op here we must set the threads list. 1096 dump_result.set_t_list(); 1097 for (int i = 0; i < num_threads; i++) { 1098 jlong tid = ids_ah->long_at(i); 1099 JavaThread* jt = dump_result.t_list()->find_JavaThread_from_java_tid(tid); 1100 ThreadSnapshot* ts; 1101 if (jt == NULL) { 1102 // if the thread does not exist or now it is terminated, 1103 // create dummy snapshot 1104 ts = new ThreadSnapshot(); 1105 } else { 1106 ts = new ThreadSnapshot(dump_result.t_list(), jt); 1136 instanceOop info_obj = Management::create_thread_info_instance(ts, CHECK_0); 1137 infoArray_h->obj_at_put(index, info_obj); 1138 } 1139 return 0; 1140 JVM_END 1141 1142 // Dump thread info for the specified threads. 1143 // It returns an array of ThreadInfo objects. Each element is the ThreadInfo 1144 // for the thread ID specified in the corresponding entry in 1145 // the given array of thread IDs; or NULL if the thread does not exist 1146 // or has terminated. 1147 // 1148 // Input parameter: 1149 // ids - array of thread IDs; NULL indicates all live threads 1150 // locked_monitors - if true, dump locked object monitors 1151 // locked_synchronizers - if true, dump locked JSR-166 synchronizers 1152 // 1153 JVM_ENTRY(jobjectArray, jmm_DumpThreads(JNIEnv *env, jlongArray thread_ids, jboolean locked_monitors, 1154 jboolean locked_synchronizers, jint maxDepth)) 1155 ResourceMark rm(THREAD); 1156 1157 // make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots 1158 java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_NULL); 1159 1160 typeArrayOop ta = typeArrayOop(JNIHandles::resolve(thread_ids)); 1161 int num_threads = (ta != NULL ? ta->length() : 0); 1162 typeArrayHandle ids_ah(THREAD, ta); 1163 1164 ThreadDumpResult dump_result(num_threads); // can safepoint 1165 1166 if (ids_ah() != NULL) { 1167 1168 // validate the thread id array 1169 validate_thread_id_array(ids_ah, CHECK_NULL); 1170 1171 // obtain thread dump of a specific list of threads 1172 do_thread_dump(&dump_result, 1173 ids_ah, 1174 num_threads, 1175 maxDepth, /* stack depth */ 1176 (locked_monitors ? true : false), /* with locked monitors */ 1177 (locked_synchronizers ? true : false), /* with locked synchronizers */ 1178 CHECK_NULL); | 1064 typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids)); 1065 typeArrayHandle ids_ah(THREAD, ta); 1066 1067 oop infoArray_obj = JNIHandles::resolve_non_null(infoArray); 1068 objArrayOop oa = objArrayOop(infoArray_obj); 1069 objArrayHandle infoArray_h(THREAD, oa); 1070 1071 // validate the thread id array 1072 validate_thread_id_array(ids_ah, CHECK_0); 1073 1074 // validate the ThreadInfo[] parameters 1075 validate_thread_info_array(infoArray_h, CHECK_0); 1076 1077 // infoArray must be of the same length as the given array of thread IDs 1078 int num_threads = ids_ah->length(); 1079 if (num_threads != infoArray_h->length()) { 1080 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), 1081 "The length of the given ThreadInfo array does not match the length of the given array of thread IDs", -1); 1082 } 1083 1084 // Must use ThreadDumpResult to store the ThreadSnapshot. 1085 // GC may occur after the thread snapshots are taken but before 1086 // this function returns. The threadObj and other oops kept 1087 // in the ThreadSnapshot are marked and adjusted during GC. 1088 ThreadDumpResult dump_result(num_threads); 1089 1090 if (maxDepth == 0) { 1091 // No stack trace to dump so we do not need to stop the world. 1092 // Since we never do the VM op here we must set the threads list. 1093 dump_result.set_t_list(); 1094 for (int i = 0; i < num_threads; i++) { 1095 jlong tid = ids_ah->long_at(i); 1096 JavaThread* jt = dump_result.t_list()->find_JavaThread_from_java_tid(tid); 1097 ThreadSnapshot* ts; 1098 if (jt == NULL) { 1099 // if the thread does not exist or now it is terminated, 1100 // create dummy snapshot 1101 ts = new ThreadSnapshot(); 1102 } else { 1103 ts = new ThreadSnapshot(dump_result.t_list(), jt); 1133 instanceOop info_obj = Management::create_thread_info_instance(ts, CHECK_0); 1134 infoArray_h->obj_at_put(index, info_obj); 1135 } 1136 return 0; 1137 JVM_END 1138 1139 // Dump thread info for the specified threads. 1140 // It returns an array of ThreadInfo objects. Each element is the ThreadInfo 1141 // for the thread ID specified in the corresponding entry in 1142 // the given array of thread IDs; or NULL if the thread does not exist 1143 // or has terminated. 1144 // 1145 // Input parameter: 1146 // ids - array of thread IDs; NULL indicates all live threads 1147 // locked_monitors - if true, dump locked object monitors 1148 // locked_synchronizers - if true, dump locked JSR-166 synchronizers 1149 // 1150 JVM_ENTRY(jobjectArray, jmm_DumpThreads(JNIEnv *env, jlongArray thread_ids, jboolean locked_monitors, 1151 jboolean locked_synchronizers, jint maxDepth)) 1152 ResourceMark rm(THREAD); 1153 1154 typeArrayOop ta = typeArrayOop(JNIHandles::resolve(thread_ids)); 1155 int num_threads = (ta != NULL ? ta->length() : 0); 1156 typeArrayHandle ids_ah(THREAD, ta); 1157 1158 ThreadDumpResult dump_result(num_threads); // can safepoint 1159 1160 if (ids_ah() != NULL) { 1161 1162 // validate the thread id array 1163 validate_thread_id_array(ids_ah, CHECK_NULL); 1164 1165 // obtain thread dump of a specific list of threads 1166 do_thread_dump(&dump_result, 1167 ids_ah, 1168 num_threads, 1169 maxDepth, /* stack depth */ 1170 (locked_monitors ? true : false), /* with locked monitors */ 1171 (locked_synchronizers ? true : false), /* with locked synchronizers */ 1172 CHECK_NULL); |