Mercurial > hg > truffle
annotate src/share/vm/services/management.cpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | f6f3eef8a521 |
children | 1c63587d925b |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1326
diff
changeset
|
2 * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
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 | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1326
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1326
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1326
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 # include "incls/_precompiled.incl" | |
26 # include "incls/_management.cpp.incl" | |
27 | |
28 PerfVariable* Management::_begin_vm_creation_time = NULL; | |
29 PerfVariable* Management::_end_vm_creation_time = NULL; | |
30 PerfVariable* Management::_vm_init_done_time = NULL; | |
31 | |
32 klassOop Management::_sensor_klass = NULL; | |
33 klassOop Management::_threadInfo_klass = NULL; | |
34 klassOop Management::_memoryUsage_klass = NULL; | |
35 klassOop Management::_memoryPoolMXBean_klass = NULL; | |
36 klassOop Management::_memoryManagerMXBean_klass = NULL; | |
37 klassOop Management::_garbageCollectorMXBean_klass = NULL; | |
38 klassOop Management::_managementFactory_klass = NULL; | |
39 | |
40 jmmOptionalSupport Management::_optional_support = {0}; | |
41 TimeStamp Management::_stamp; | |
42 | |
43 void management_init() { | |
44 Management::init(); | |
45 ThreadService::init(); | |
46 RuntimeService::init(); | |
47 ClassLoadingService::init(); | |
48 } | |
49 | |
50 void Management::init() { | |
51 EXCEPTION_MARK; | |
52 | |
53 // These counters are for java.lang.management API support. | |
54 // They are created even if -XX:-UsePerfData is set and in | |
55 // that case, they will be allocated on C heap. | |
56 | |
57 _begin_vm_creation_time = | |
58 PerfDataManager::create_variable(SUN_RT, "createVmBeginTime", | |
59 PerfData::U_None, CHECK); | |
60 | |
61 _end_vm_creation_time = | |
62 PerfDataManager::create_variable(SUN_RT, "createVmEndTime", | |
63 PerfData::U_None, CHECK); | |
64 | |
65 _vm_init_done_time = | |
66 PerfDataManager::create_variable(SUN_RT, "vmInitDoneTime", | |
67 PerfData::U_None, CHECK); | |
68 | |
69 // Initialize optional support | |
70 _optional_support.isLowMemoryDetectionSupported = 1; | |
71 _optional_support.isCompilationTimeMonitoringSupported = 1; | |
72 _optional_support.isThreadContentionMonitoringSupported = 1; | |
73 | |
74 if (os::is_thread_cpu_time_supported()) { | |
75 _optional_support.isCurrentThreadCpuTimeSupported = 1; | |
76 _optional_support.isOtherThreadCpuTimeSupported = 1; | |
77 } else { | |
78 _optional_support.isCurrentThreadCpuTimeSupported = 0; | |
79 _optional_support.isOtherThreadCpuTimeSupported = 0; | |
80 } | |
81 _optional_support.isBootClassPathSupported = 1; | |
82 _optional_support.isObjectMonitorUsageSupported = 1; | |
83 #ifndef SERVICES_KERNEL | |
84 // This depends on the heap inspector | |
85 _optional_support.isSynchronizerUsageSupported = 1; | |
86 #endif // SERVICES_KERNEL | |
87 } | |
88 | |
89 void Management::initialize(TRAPS) { | |
90 // Start the low memory detector thread | |
91 LowMemoryDetector::initialize(); | |
92 | |
93 if (ManagementServer) { | |
94 ResourceMark rm(THREAD); | |
95 HandleMark hm(THREAD); | |
96 | |
97 // Load and initialize the sun.management.Agent class | |
98 // invoke startAgent method to start the management server | |
99 Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); | |
100 klassOop k = SystemDictionary::resolve_or_fail(vmSymbolHandles::sun_management_Agent(), | |
101 loader, | |
102 Handle(), | |
103 true, | |
104 CHECK); | |
105 instanceKlassHandle ik (THREAD, k); | |
106 | |
107 JavaValue result(T_VOID); | |
108 JavaCalls::call_static(&result, | |
109 ik, | |
110 vmSymbolHandles::startAgent_name(), | |
111 vmSymbolHandles::void_method_signature(), | |
112 CHECK); | |
113 } | |
114 } | |
115 | |
116 void Management::get_optional_support(jmmOptionalSupport* support) { | |
117 memcpy(support, &_optional_support, sizeof(jmmOptionalSupport)); | |
118 } | |
119 | |
120 klassOop Management::load_and_initialize_klass(symbolHandle sh, TRAPS) { | |
121 klassOop k = SystemDictionary::resolve_or_fail(sh, true, CHECK_NULL); | |
122 instanceKlassHandle ik (THREAD, k); | |
123 if (ik->should_be_initialized()) { | |
124 ik->initialize(CHECK_NULL); | |
125 } | |
126 return ik(); | |
127 } | |
128 | |
129 void Management::record_vm_startup_time(jlong begin, jlong duration) { | |
130 // if the performance counter is not initialized, | |
131 // then vm initialization failed; simply return. | |
132 if (_begin_vm_creation_time == NULL) return; | |
133 | |
134 _begin_vm_creation_time->set_value(begin); | |
135 _end_vm_creation_time->set_value(begin + duration); | |
136 PerfMemory::set_accessible(true); | |
137 } | |
138 | |
139 jlong Management::timestamp() { | |
140 TimeStamp t; | |
141 t.update(); | |
142 return t.ticks() - _stamp.ticks(); | |
143 } | |
144 | |
145 void Management::oops_do(OopClosure* f) { | |
146 MemoryService::oops_do(f); | |
147 ThreadService::oops_do(f); | |
148 | |
149 f->do_oop((oop*) &_sensor_klass); | |
150 f->do_oop((oop*) &_threadInfo_klass); | |
151 f->do_oop((oop*) &_memoryUsage_klass); | |
152 f->do_oop((oop*) &_memoryPoolMXBean_klass); | |
153 f->do_oop((oop*) &_memoryManagerMXBean_klass); | |
154 f->do_oop((oop*) &_garbageCollectorMXBean_klass); | |
155 f->do_oop((oop*) &_managementFactory_klass); | |
156 } | |
157 | |
158 klassOop Management::java_lang_management_ThreadInfo_klass(TRAPS) { | |
159 if (_threadInfo_klass == NULL) { | |
160 _threadInfo_klass = load_and_initialize_klass(vmSymbolHandles::java_lang_management_ThreadInfo(), CHECK_NULL); | |
161 } | |
162 return _threadInfo_klass; | |
163 } | |
164 | |
165 klassOop Management::java_lang_management_MemoryUsage_klass(TRAPS) { | |
166 if (_memoryUsage_klass == NULL) { | |
167 _memoryUsage_klass = load_and_initialize_klass(vmSymbolHandles::java_lang_management_MemoryUsage(), CHECK_NULL); | |
168 } | |
169 return _memoryUsage_klass; | |
170 } | |
171 | |
172 klassOop Management::java_lang_management_MemoryPoolMXBean_klass(TRAPS) { | |
173 if (_memoryPoolMXBean_klass == NULL) { | |
174 _memoryPoolMXBean_klass = load_and_initialize_klass(vmSymbolHandles::java_lang_management_MemoryPoolMXBean(), CHECK_NULL); | |
175 } | |
176 return _memoryPoolMXBean_klass; | |
177 } | |
178 | |
179 klassOop Management::java_lang_management_MemoryManagerMXBean_klass(TRAPS) { | |
180 if (_memoryManagerMXBean_klass == NULL) { | |
181 _memoryManagerMXBean_klass = load_and_initialize_klass(vmSymbolHandles::java_lang_management_MemoryManagerMXBean(), CHECK_NULL); | |
182 } | |
183 return _memoryManagerMXBean_klass; | |
184 } | |
185 | |
186 klassOop Management::java_lang_management_GarbageCollectorMXBean_klass(TRAPS) { | |
187 if (_garbageCollectorMXBean_klass == NULL) { | |
188 _garbageCollectorMXBean_klass = load_and_initialize_klass(vmSymbolHandles::java_lang_management_GarbageCollectorMXBean(), CHECK_NULL); | |
189 } | |
190 return _garbageCollectorMXBean_klass; | |
191 } | |
192 | |
193 klassOop Management::sun_management_Sensor_klass(TRAPS) { | |
194 if (_sensor_klass == NULL) { | |
195 _sensor_klass = load_and_initialize_klass(vmSymbolHandles::sun_management_Sensor(), CHECK_NULL); | |
196 } | |
197 return _sensor_klass; | |
198 } | |
199 | |
200 klassOop Management::sun_management_ManagementFactory_klass(TRAPS) { | |
201 if (_managementFactory_klass == NULL) { | |
202 _managementFactory_klass = load_and_initialize_klass(vmSymbolHandles::sun_management_ManagementFactory(), CHECK_NULL); | |
203 } | |
204 return _managementFactory_klass; | |
205 } | |
206 | |
207 static void initialize_ThreadInfo_constructor_arguments(JavaCallArguments* args, ThreadSnapshot* snapshot, TRAPS) { | |
208 Handle snapshot_thread(THREAD, snapshot->threadObj()); | |
209 | |
210 jlong contended_time; | |
211 jlong waited_time; | |
212 if (ThreadService::is_thread_monitoring_contention()) { | |
213 contended_time = Management::ticks_to_ms(snapshot->contended_enter_ticks()); | |
214 waited_time = Management::ticks_to_ms(snapshot->monitor_wait_ticks() + snapshot->sleep_ticks()); | |
215 } else { | |
216 // set them to -1 if thread contention monitoring is disabled. | |
217 contended_time = max_julong; | |
218 waited_time = max_julong; | |
219 } | |
220 | |
221 int thread_status = snapshot->thread_status(); | |
222 assert((thread_status & JMM_THREAD_STATE_FLAG_MASK) == 0, "Flags already set in thread_status in Thread object"); | |
223 if (snapshot->is_ext_suspended()) { | |
224 thread_status |= JMM_THREAD_STATE_FLAG_SUSPENDED; | |
225 } | |
226 if (snapshot->is_in_native()) { | |
227 thread_status |= JMM_THREAD_STATE_FLAG_NATIVE; | |
228 } | |
229 | |
230 ThreadStackTrace* st = snapshot->get_stack_trace(); | |
231 Handle stacktrace_h; | |
232 if (st != NULL) { | |
233 stacktrace_h = st->allocate_fill_stack_trace_element_array(CHECK); | |
234 } else { | |
235 stacktrace_h = Handle(); | |
236 } | |
237 | |
238 args->push_oop(snapshot_thread); | |
239 args->push_int(thread_status); | |
240 args->push_oop(Handle(THREAD, snapshot->blocker_object())); | |
241 args->push_oop(Handle(THREAD, snapshot->blocker_object_owner())); | |
242 args->push_long(snapshot->contended_enter_count()); | |
243 args->push_long(contended_time); | |
244 args->push_long(snapshot->monitor_wait_count() + snapshot->sleep_count()); | |
245 args->push_long(waited_time); | |
246 args->push_oop(stacktrace_h); | |
247 } | |
248 | |
249 // Helper function to construct a ThreadInfo object | |
250 instanceOop Management::create_thread_info_instance(ThreadSnapshot* snapshot, TRAPS) { | |
251 klassOop k = Management::java_lang_management_ThreadInfo_klass(CHECK_NULL); | |
252 instanceKlassHandle ik (THREAD, k); | |
253 | |
254 JavaValue result(T_VOID); | |
255 JavaCallArguments args(14); | |
256 | |
257 // First allocate a ThreadObj object and | |
258 // push the receiver as the first argument | |
259 Handle element = ik->allocate_instance_handle(CHECK_NULL); | |
260 args.push_oop(element); | |
261 | |
262 // initialize the arguments for the ThreadInfo constructor | |
263 initialize_ThreadInfo_constructor_arguments(&args, snapshot, CHECK_NULL); | |
264 | |
265 // Call ThreadInfo constructor with no locked monitors and synchronizers | |
266 JavaCalls::call_special(&result, | |
267 ik, | |
268 vmSymbolHandles::object_initializer_name(), | |
269 vmSymbolHandles::java_lang_management_ThreadInfo_constructor_signature(), | |
270 &args, | |
271 CHECK_NULL); | |
272 | |
273 return (instanceOop) element(); | |
274 } | |
275 | |
276 instanceOop Management::create_thread_info_instance(ThreadSnapshot* snapshot, | |
277 objArrayHandle monitors_array, | |
278 typeArrayHandle depths_array, | |
279 objArrayHandle synchronizers_array, | |
280 TRAPS) { | |
281 klassOop k = Management::java_lang_management_ThreadInfo_klass(CHECK_NULL); | |
282 instanceKlassHandle ik (THREAD, k); | |
283 | |
284 JavaValue result(T_VOID); | |
285 JavaCallArguments args(17); | |
286 | |
287 // First allocate a ThreadObj object and | |
288 // push the receiver as the first argument | |
289 Handle element = ik->allocate_instance_handle(CHECK_NULL); | |
290 args.push_oop(element); | |
291 | |
292 // initialize the arguments for the ThreadInfo constructor | |
293 initialize_ThreadInfo_constructor_arguments(&args, snapshot, CHECK_NULL); | |
294 | |
295 // push the locked monitors and synchronizers in the arguments | |
296 args.push_oop(monitors_array); | |
297 args.push_oop(depths_array); | |
298 args.push_oop(synchronizers_array); | |
299 | |
300 // Call ThreadInfo constructor with locked monitors and synchronizers | |
301 JavaCalls::call_special(&result, | |
302 ik, | |
303 vmSymbolHandles::object_initializer_name(), | |
304 vmSymbolHandles::java_lang_management_ThreadInfo_with_locks_constructor_signature(), | |
305 &args, | |
306 CHECK_NULL); | |
307 | |
308 return (instanceOop) element(); | |
309 } | |
310 | |
311 // Helper functions | |
312 static JavaThread* find_java_thread_from_id(jlong thread_id) { | |
313 assert(Threads_lock->owned_by_self(), "Must hold Threads_lock"); | |
314 | |
315 JavaThread* java_thread = NULL; | |
316 // Sequential search for now. Need to do better optimization later. | |
317 for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) { | |
318 oop tobj = thread->threadObj(); | |
319 if (!thread->is_exiting() && | |
320 tobj != NULL && | |
321 thread_id == java_lang_Thread::thread_id(tobj)) { | |
322 java_thread = thread; | |
323 break; | |
324 } | |
325 } | |
326 return java_thread; | |
327 } | |
328 | |
329 static GCMemoryManager* get_gc_memory_manager_from_jobject(jobject mgr, TRAPS) { | |
330 if (mgr == NULL) { | |
331 THROW_(vmSymbols::java_lang_NullPointerException(), NULL); | |
332 } | |
333 oop mgr_obj = JNIHandles::resolve(mgr); | |
334 instanceHandle h(THREAD, (instanceOop) mgr_obj); | |
335 | |
336 klassOop k = Management::java_lang_management_GarbageCollectorMXBean_klass(CHECK_NULL); | |
337 if (!h->is_a(k)) { | |
338 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), | |
339 "the object is not an instance of java.lang.management.GarbageCollectorMXBean class", | |
340 NULL); | |
341 } | |
342 | |
343 MemoryManager* gc = MemoryService::get_memory_manager(h); | |
344 if (gc == NULL || !gc->is_gc_memory_manager()) { | |
345 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), | |
346 "Invalid GC memory manager", | |
347 NULL); | |
348 } | |
349 return (GCMemoryManager*) gc; | |
350 } | |
351 | |
352 static MemoryPool* get_memory_pool_from_jobject(jobject obj, TRAPS) { | |
353 if (obj == NULL) { | |
354 THROW_(vmSymbols::java_lang_NullPointerException(), NULL); | |
355 } | |
356 | |
357 oop pool_obj = JNIHandles::resolve(obj); | |
358 assert(pool_obj->is_instance(), "Should be an instanceOop"); | |
359 instanceHandle ph(THREAD, (instanceOop) pool_obj); | |
360 | |
361 return MemoryService::get_memory_pool(ph); | |
362 } | |
363 | |
364 static void validate_thread_id_array(typeArrayHandle ids_ah, TRAPS) { | |
365 int num_threads = ids_ah->length(); | |
366 // should be non-empty array | |
367 if (num_threads == 0) { | |
368 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), | |
369 "Empty array of thread IDs"); | |
370 } | |
371 | |
372 // Validate input thread IDs | |
373 int i = 0; | |
374 for (i = 0; i < num_threads; i++) { | |
375 jlong tid = ids_ah->long_at(i); | |
376 if (tid <= 0) { | |
377 // throw exception if invalid thread id. | |
378 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), | |
379 "Invalid thread ID entry"); | |
380 } | |
381 } | |
382 | |
383 } | |
384 | |
385 static void validate_thread_info_array(objArrayHandle infoArray_h, TRAPS) { | |
386 | |
387 // check if the element of infoArray is of type ThreadInfo class | |
388 klassOop threadinfo_klass = Management::java_lang_management_ThreadInfo_klass(CHECK); | |
389 klassOop element_klass = objArrayKlass::cast(infoArray_h->klass())->element_klass(); | |
390 if (element_klass != threadinfo_klass) { | |
391 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), | |
392 "infoArray element type is not ThreadInfo class"); | |
393 } | |
394 | |
395 } | |
396 | |
397 | |
398 static MemoryManager* get_memory_manager_from_jobject(jobject obj, TRAPS) { | |
399 if (obj == NULL) { | |
400 THROW_(vmSymbols::java_lang_NullPointerException(), NULL); | |
401 } | |
402 | |
403 oop mgr_obj = JNIHandles::resolve(obj); | |
404 assert(mgr_obj->is_instance(), "Should be an instanceOop"); | |
405 instanceHandle mh(THREAD, (instanceOop) mgr_obj); | |
406 | |
407 return MemoryService::get_memory_manager(mh); | |
408 } | |
409 | |
410 // Returns a version string and sets major and minor version if | |
411 // the input parameters are non-null. | |
412 JVM_LEAF(jint, jmm_GetVersion(JNIEnv *env)) | |
413 return JMM_VERSION; | |
414 JVM_END | |
415 | |
416 // Gets the list of VM monitoring and management optional supports | |
417 // Returns 0 if succeeded; otherwise returns non-zero. | |
418 JVM_LEAF(jint, jmm_GetOptionalSupport(JNIEnv *env, jmmOptionalSupport* support)) | |
419 if (support == NULL) { | |
420 return -1; | |
421 } | |
422 Management::get_optional_support(support); | |
423 return 0; | |
424 JVM_END | |
425 | |
426 // Returns a java.lang.String object containing the input arguments to the VM. | |
427 JVM_ENTRY(jobject, jmm_GetInputArguments(JNIEnv *env)) | |
428 ResourceMark rm(THREAD); | |
429 | |
430 if (Arguments::num_jvm_args() == 0 && Arguments::num_jvm_flags() == 0) { | |
431 return NULL; | |
432 } | |
433 | |
434 char** vm_flags = Arguments::jvm_flags_array(); | |
435 char** vm_args = Arguments::jvm_args_array(); | |
436 int num_flags = Arguments::num_jvm_flags(); | |
437 int num_args = Arguments::num_jvm_args(); | |
438 | |
439 size_t length = 1; // null terminator | |
440 int i; | |
441 for (i = 0; i < num_flags; i++) { | |
442 length += strlen(vm_flags[i]); | |
443 } | |
444 for (i = 0; i < num_args; i++) { | |
445 length += strlen(vm_args[i]); | |
446 } | |
447 // add a space between each argument | |
448 length += num_flags + num_args - 1; | |
449 | |
450 // Return the list of input arguments passed to the VM | |
451 // and preserve the order that the VM processes. | |
452 char* args = NEW_RESOURCE_ARRAY(char, length); | |
453 args[0] = '\0'; | |
454 // concatenate all jvm_flags | |
455 if (num_flags > 0) { | |
456 strcat(args, vm_flags[0]); | |
457 for (i = 1; i < num_flags; i++) { | |
458 strcat(args, " "); | |
459 strcat(args, vm_flags[i]); | |
460 } | |
461 } | |
462 | |
463 if (num_args > 0 && num_flags > 0) { | |
464 // append a space if args already contains one or more jvm_flags | |
465 strcat(args, " "); | |
466 } | |
467 | |
468 // concatenate all jvm_args | |
469 if (num_args > 0) { | |
470 strcat(args, vm_args[0]); | |
471 for (i = 1; i < num_args; i++) { | |
472 strcat(args, " "); | |
473 strcat(args, vm_args[i]); | |
474 } | |
475 } | |
476 | |
477 Handle hargs = java_lang_String::create_from_platform_dependent_str(args, CHECK_NULL); | |
478 return JNIHandles::make_local(env, hargs()); | |
479 JVM_END | |
480 | |
481 // Returns an array of java.lang.String object containing the input arguments to the VM. | |
482 JVM_ENTRY(jobjectArray, jmm_GetInputArgumentArray(JNIEnv *env)) | |
483 ResourceMark rm(THREAD); | |
484 | |
485 if (Arguments::num_jvm_args() == 0 && Arguments::num_jvm_flags() == 0) { | |
486 return NULL; | |
487 } | |
488 | |
489 char** vm_flags = Arguments::jvm_flags_array(); | |
490 char** vm_args = Arguments::jvm_args_array(); | |
491 int num_flags = Arguments::num_jvm_flags(); | |
492 int num_args = Arguments::num_jvm_args(); | |
493 | |
1142 | 494 instanceKlassHandle ik (THREAD, SystemDictionary::String_klass()); |
0 | 495 objArrayOop r = oopFactory::new_objArray(ik(), num_args + num_flags, CHECK_NULL); |
496 objArrayHandle result_h(THREAD, r); | |
497 | |
498 int index = 0; | |
499 for (int j = 0; j < num_flags; j++, index++) { | |
500 Handle h = java_lang_String::create_from_platform_dependent_str(vm_flags[j], CHECK_NULL); | |
501 result_h->obj_at_put(index, h()); | |
502 } | |
503 for (int i = 0; i < num_args; i++, index++) { | |
504 Handle h = java_lang_String::create_from_platform_dependent_str(vm_args[i], CHECK_NULL); | |
505 result_h->obj_at_put(index, h()); | |
506 } | |
507 return (jobjectArray) JNIHandles::make_local(env, result_h()); | |
508 JVM_END | |
509 | |
510 // Returns an array of java/lang/management/MemoryPoolMXBean object | |
511 // one for each memory pool if obj == null; otherwise returns | |
512 // an array of memory pools for a given memory manager if | |
513 // it is a valid memory manager. | |
514 JVM_ENTRY(jobjectArray, jmm_GetMemoryPools(JNIEnv* env, jobject obj)) | |
515 ResourceMark rm(THREAD); | |
516 | |
517 int num_memory_pools; | |
518 MemoryManager* mgr = NULL; | |
519 if (obj == NULL) { | |
520 num_memory_pools = MemoryService::num_memory_pools(); | |
521 } else { | |
522 mgr = get_memory_manager_from_jobject(obj, CHECK_NULL); | |
523 if (mgr == NULL) { | |
524 return NULL; | |
525 } | |
526 num_memory_pools = mgr->num_memory_pools(); | |
527 } | |
528 | |
529 // Allocate the resulting MemoryPoolMXBean[] object | |
530 klassOop k = Management::java_lang_management_MemoryPoolMXBean_klass(CHECK_NULL); | |
531 instanceKlassHandle ik (THREAD, k); | |
532 objArrayOop r = oopFactory::new_objArray(ik(), num_memory_pools, CHECK_NULL); | |
533 objArrayHandle poolArray(THREAD, r); | |
534 | |
535 if (mgr == NULL) { | |
536 // Get all memory pools | |
537 for (int i = 0; i < num_memory_pools; i++) { | |
538 MemoryPool* pool = MemoryService::get_memory_pool(i); | |
539 instanceOop p = pool->get_memory_pool_instance(CHECK_NULL); | |
540 instanceHandle ph(THREAD, p); | |
541 poolArray->obj_at_put(i, ph()); | |
542 } | |
543 } else { | |
544 // Get memory pools managed by a given memory manager | |
545 for (int i = 0; i < num_memory_pools; i++) { | |
546 MemoryPool* pool = mgr->get_memory_pool(i); | |
547 instanceOop p = pool->get_memory_pool_instance(CHECK_NULL); | |
548 instanceHandle ph(THREAD, p); | |
549 poolArray->obj_at_put(i, ph()); | |
550 } | |
551 } | |
552 return (jobjectArray) JNIHandles::make_local(env, poolArray()); | |
553 JVM_END | |
554 | |
555 // Returns an array of java/lang/management/MemoryManagerMXBean object | |
556 // one for each memory manager if obj == null; otherwise returns | |
557 // an array of memory managers for a given memory pool if | |
558 // it is a valid memory pool. | |
559 JVM_ENTRY(jobjectArray, jmm_GetMemoryManagers(JNIEnv* env, jobject obj)) | |
560 ResourceMark rm(THREAD); | |
561 | |
562 int num_mgrs; | |
563 MemoryPool* pool = NULL; | |
564 if (obj == NULL) { | |
565 num_mgrs = MemoryService::num_memory_managers(); | |
566 } else { | |
567 pool = get_memory_pool_from_jobject(obj, CHECK_NULL); | |
568 if (pool == NULL) { | |
569 return NULL; | |
570 } | |
571 num_mgrs = pool->num_memory_managers(); | |
572 } | |
573 | |
574 // Allocate the resulting MemoryManagerMXBean[] object | |
575 klassOop k = Management::java_lang_management_MemoryManagerMXBean_klass(CHECK_NULL); | |
576 instanceKlassHandle ik (THREAD, k); | |
577 objArrayOop r = oopFactory::new_objArray(ik(), num_mgrs, CHECK_NULL); | |
578 objArrayHandle mgrArray(THREAD, r); | |
579 | |
580 if (pool == NULL) { | |
581 // Get all memory managers | |
582 for (int i = 0; i < num_mgrs; i++) { | |
583 MemoryManager* mgr = MemoryService::get_memory_manager(i); | |
584 instanceOop p = mgr->get_memory_manager_instance(CHECK_NULL); | |
585 instanceHandle ph(THREAD, p); | |
586 mgrArray->obj_at_put(i, ph()); | |
587 } | |
588 } else { | |
589 // Get memory managers for a given memory pool | |
590 for (int i = 0; i < num_mgrs; i++) { | |
591 MemoryManager* mgr = pool->get_memory_manager(i); | |
592 instanceOop p = mgr->get_memory_manager_instance(CHECK_NULL); | |
593 instanceHandle ph(THREAD, p); | |
594 mgrArray->obj_at_put(i, ph()); | |
595 } | |
596 } | |
597 return (jobjectArray) JNIHandles::make_local(env, mgrArray()); | |
598 JVM_END | |
599 | |
600 | |
601 // Returns a java/lang/management/MemoryUsage object containing the memory usage | |
602 // of a given memory pool. | |
603 JVM_ENTRY(jobject, jmm_GetMemoryPoolUsage(JNIEnv* env, jobject obj)) | |
604 ResourceMark rm(THREAD); | |
605 | |
606 MemoryPool* pool = get_memory_pool_from_jobject(obj, CHECK_NULL); | |
607 if (pool != NULL) { | |
608 MemoryUsage usage = pool->get_memory_usage(); | |
609 Handle h = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL); | |
610 return JNIHandles::make_local(env, h()); | |
611 } else { | |
612 return NULL; | |
613 } | |
614 JVM_END | |
615 | |
616 // Returns a java/lang/management/MemoryUsage object containing the memory usage | |
617 // of a given memory pool. | |
618 JVM_ENTRY(jobject, jmm_GetPeakMemoryPoolUsage(JNIEnv* env, jobject obj)) | |
619 ResourceMark rm(THREAD); | |
620 | |
621 MemoryPool* pool = get_memory_pool_from_jobject(obj, CHECK_NULL); | |
622 if (pool != NULL) { | |
623 MemoryUsage usage = pool->get_peak_memory_usage(); | |
624 Handle h = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL); | |
625 return JNIHandles::make_local(env, h()); | |
626 } else { | |
627 return NULL; | |
628 } | |
629 JVM_END | |
630 | |
631 // Returns a java/lang/management/MemoryUsage object containing the memory usage | |
632 // of a given memory pool after most recent GC. | |
633 JVM_ENTRY(jobject, jmm_GetPoolCollectionUsage(JNIEnv* env, jobject obj)) | |
634 ResourceMark rm(THREAD); | |
635 | |
636 MemoryPool* pool = get_memory_pool_from_jobject(obj, CHECK_NULL); | |
637 if (pool != NULL && pool->is_collected_pool()) { | |
638 MemoryUsage usage = pool->get_last_collection_usage(); | |
639 Handle h = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL); | |
640 return JNIHandles::make_local(env, h()); | |
641 } else { | |
642 return NULL; | |
643 } | |
644 JVM_END | |
645 | |
646 // Sets the memory pool sensor for a threshold type | |
647 JVM_ENTRY(void, jmm_SetPoolSensor(JNIEnv* env, jobject obj, jmmThresholdType type, jobject sensorObj)) | |
648 if (obj == NULL || sensorObj == NULL) { | |
649 THROW(vmSymbols::java_lang_NullPointerException()); | |
650 } | |
651 | |
652 klassOop sensor_klass = Management::sun_management_Sensor_klass(CHECK); | |
653 oop s = JNIHandles::resolve(sensorObj); | |
654 assert(s->is_instance(), "Sensor should be an instanceOop"); | |
655 instanceHandle sensor_h(THREAD, (instanceOop) s); | |
656 if (!sensor_h->is_a(sensor_klass)) { | |
657 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), | |
658 "Sensor is not an instance of sun.management.Sensor class"); | |
659 } | |
660 | |
661 MemoryPool* mpool = get_memory_pool_from_jobject(obj, CHECK); | |
662 assert(mpool != NULL, "MemoryPool should exist"); | |
663 | |
664 switch (type) { | |
665 case JMM_USAGE_THRESHOLD_HIGH: | |
666 case JMM_USAGE_THRESHOLD_LOW: | |
667 // have only one sensor for threshold high and low | |
668 mpool->set_usage_sensor_obj(sensor_h); | |
669 break; | |
670 case JMM_COLLECTION_USAGE_THRESHOLD_HIGH: | |
671 case JMM_COLLECTION_USAGE_THRESHOLD_LOW: | |
672 // have only one sensor for threshold high and low | |
673 mpool->set_gc_usage_sensor_obj(sensor_h); | |
674 break; | |
675 default: | |
676 assert(false, "Unrecognized type"); | |
677 } | |
678 | |
679 JVM_END | |
680 | |
681 | |
682 // Sets the threshold of a given memory pool. | |
683 // Returns the previous threshold. | |
684 // | |
685 // Input parameters: | |
686 // pool - the MemoryPoolMXBean object | |
687 // type - threshold type | |
688 // threshold - the new threshold (must not be negative) | |
689 // | |
690 JVM_ENTRY(jlong, jmm_SetPoolThreshold(JNIEnv* env, jobject obj, jmmThresholdType type, jlong threshold)) | |
691 if (threshold < 0) { | |
692 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), | |
693 "Invalid threshold value", | |
694 -1); | |
695 } | |
696 | |
489
2494ab195856
6653214: MemoryPoolMXBean.setUsageThreshold() does not support large heap sizes.
swamyv
parents:
350
diff
changeset
|
697 if ((size_t)threshold > max_uintx) { |
2494ab195856
6653214: MemoryPoolMXBean.setUsageThreshold() does not support large heap sizes.
swamyv
parents:
350
diff
changeset
|
698 stringStream st; |
2494ab195856
6653214: MemoryPoolMXBean.setUsageThreshold() does not support large heap sizes.
swamyv
parents:
350
diff
changeset
|
699 st.print("Invalid valid threshold value. Threshold value (" UINT64_FORMAT ") > max value of size_t (" SIZE_FORMAT ")", (size_t)threshold, max_uintx); |
2494ab195856
6653214: MemoryPoolMXBean.setUsageThreshold() does not support large heap sizes.
swamyv
parents:
350
diff
changeset
|
700 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), st.as_string(), -1); |
0 | 701 } |
702 | |
703 MemoryPool* pool = get_memory_pool_from_jobject(obj, CHECK_(0L)); | |
704 assert(pool != NULL, "MemoryPool should exist"); | |
705 | |
706 jlong prev = 0; | |
707 switch (type) { | |
708 case JMM_USAGE_THRESHOLD_HIGH: | |
709 if (!pool->usage_threshold()->is_high_threshold_supported()) { | |
710 return -1; | |
711 } | |
712 prev = pool->usage_threshold()->set_high_threshold((size_t) threshold); | |
713 break; | |
714 | |
715 case JMM_USAGE_THRESHOLD_LOW: | |
716 if (!pool->usage_threshold()->is_low_threshold_supported()) { | |
717 return -1; | |
718 } | |
719 prev = pool->usage_threshold()->set_low_threshold((size_t) threshold); | |
720 break; | |
721 | |
722 case JMM_COLLECTION_USAGE_THRESHOLD_HIGH: | |
723 if (!pool->gc_usage_threshold()->is_high_threshold_supported()) { | |
724 return -1; | |
725 } | |
726 // return and the new threshold is effective for the next GC | |
727 return pool->gc_usage_threshold()->set_high_threshold((size_t) threshold); | |
728 | |
729 case JMM_COLLECTION_USAGE_THRESHOLD_LOW: | |
730 if (!pool->gc_usage_threshold()->is_low_threshold_supported()) { | |
731 return -1; | |
732 } | |
733 // return and the new threshold is effective for the next GC | |
734 return pool->gc_usage_threshold()->set_low_threshold((size_t) threshold); | |
735 | |
736 default: | |
737 assert(false, "Unrecognized type"); | |
738 return -1; | |
739 } | |
740 | |
741 // When the threshold is changed, reevaluate if the low memory | |
742 // detection is enabled. | |
743 if (prev != threshold) { | |
744 LowMemoryDetector::recompute_enabled_for_collected_pools(); | |
745 LowMemoryDetector::detect_low_memory(pool); | |
746 } | |
747 return prev; | |
748 JVM_END | |
749 | |
750 // Returns a java/lang/management/MemoryUsage object representing | |
751 // the memory usage for the heap or non-heap memory. | |
752 JVM_ENTRY(jobject, jmm_GetMemoryUsage(JNIEnv* env, jboolean heap)) | |
753 ResourceMark rm(THREAD); | |
754 | |
755 // Calculate the memory usage | |
756 size_t total_init = 0; | |
757 size_t total_used = 0; | |
758 size_t total_committed = 0; | |
759 size_t total_max = 0; | |
760 bool has_undefined_init_size = false; | |
761 bool has_undefined_max_size = false; | |
762 | |
763 for (int i = 0; i < MemoryService::num_memory_pools(); i++) { | |
764 MemoryPool* pool = MemoryService::get_memory_pool(i); | |
765 if ((heap && pool->is_heap()) || (!heap && pool->is_non_heap())) { | |
766 MemoryUsage u = pool->get_memory_usage(); | |
767 total_used += u.used(); | |
768 total_committed += u.committed(); | |
769 | |
770 // if any one of the memory pool has undefined init_size or max_size, | |
771 // set it to -1 | |
772 if (u.init_size() == (size_t)-1) { | |
773 has_undefined_init_size = true; | |
774 } | |
775 if (!has_undefined_init_size) { | |
776 total_init += u.init_size(); | |
777 } | |
778 | |
779 if (u.max_size() == (size_t)-1) { | |
780 has_undefined_max_size = true; | |
781 } | |
782 if (!has_undefined_max_size) { | |
783 total_max += u.max_size(); | |
784 } | |
785 } | |
786 } | |
787 | |
788 // In our current implementation, all pools should have | |
789 // defined init and max size | |
790 assert(!has_undefined_init_size, "Undefined init size"); | |
791 assert(!has_undefined_max_size, "Undefined max size"); | |
792 | |
1064 | 793 MemoryUsage usage((heap ? InitialHeapSize : total_init), |
0 | 794 total_used, |
795 total_committed, | |
796 (heap ? Universe::heap()->max_capacity() : total_max)); | |
797 | |
798 Handle obj = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL); | |
799 return JNIHandles::make_local(env, obj()); | |
800 JVM_END | |
801 | |
802 // Returns the boolean value of a given attribute. | |
803 JVM_LEAF(jboolean, jmm_GetBoolAttribute(JNIEnv *env, jmmBoolAttribute att)) | |
804 switch (att) { | |
805 case JMM_VERBOSE_GC: | |
806 return MemoryService::get_verbose(); | |
807 case JMM_VERBOSE_CLASS: | |
808 return ClassLoadingService::get_verbose(); | |
809 case JMM_THREAD_CONTENTION_MONITORING: | |
810 return ThreadService::is_thread_monitoring_contention(); | |
811 case JMM_THREAD_CPU_TIME: | |
812 return ThreadService::is_thread_cpu_time_enabled(); | |
813 default: | |
814 assert(0, "Unrecognized attribute"); | |
815 return false; | |
816 } | |
817 JVM_END | |
818 | |
819 // Sets the given boolean attribute and returns the previous value. | |
820 JVM_ENTRY(jboolean, jmm_SetBoolAttribute(JNIEnv *env, jmmBoolAttribute att, jboolean flag)) | |
821 switch (att) { | |
822 case JMM_VERBOSE_GC: | |
823 return MemoryService::set_verbose(flag != 0); | |
824 case JMM_VERBOSE_CLASS: | |
825 return ClassLoadingService::set_verbose(flag != 0); | |
826 case JMM_THREAD_CONTENTION_MONITORING: | |
827 return ThreadService::set_thread_monitoring_contention(flag != 0); | |
828 case JMM_THREAD_CPU_TIME: | |
829 return ThreadService::set_thread_cpu_time_enabled(flag != 0); | |
830 default: | |
831 assert(0, "Unrecognized attribute"); | |
832 return false; | |
833 } | |
834 JVM_END | |
835 | |
836 | |
837 static jlong get_gc_attribute(GCMemoryManager* mgr, jmmLongAttribute att) { | |
838 switch (att) { | |
839 case JMM_GC_TIME_MS: | |
840 return mgr->gc_time_ms(); | |
841 | |
842 case JMM_GC_COUNT: | |
843 return mgr->gc_count(); | |
844 | |
845 case JMM_GC_EXT_ATTRIBUTE_INFO_SIZE: | |
846 // current implementation only has 1 ext attribute | |
847 return 1; | |
848 | |
849 default: | |
850 assert(0, "Unrecognized GC attribute"); | |
851 return -1; | |
852 } | |
853 } | |
854 | |
855 class VmThreadCountClosure: public ThreadClosure { | |
856 private: | |
857 int _count; | |
858 public: | |
859 VmThreadCountClosure() : _count(0) {}; | |
860 void do_thread(Thread* thread); | |
861 int count() { return _count; } | |
862 }; | |
863 | |
864 void VmThreadCountClosure::do_thread(Thread* thread) { | |
865 // exclude externally visible JavaThreads | |
866 if (thread->is_Java_thread() && !thread->is_hidden_from_external_view()) { | |
867 return; | |
868 } | |
869 | |
870 _count++; | |
871 } | |
872 | |
873 static jint get_vm_thread_count() { | |
874 VmThreadCountClosure vmtcc; | |
875 { | |
876 MutexLockerEx ml(Threads_lock); | |
877 Threads::threads_do(&vmtcc); | |
878 } | |
879 | |
880 return vmtcc.count(); | |
881 } | |
882 | |
883 static jint get_num_flags() { | |
884 // last flag entry is always NULL, so subtract 1 | |
885 int nFlags = (int) Flag::numFlags - 1; | |
886 int count = 0; | |
887 for (int i = 0; i < nFlags; i++) { | |
888 Flag* flag = &Flag::flags[i]; | |
350 | 889 // Exclude the locked (diagnostic, experimental) flags |
0 | 890 if (flag->is_unlocked() || flag->is_unlocker()) { |
891 count++; | |
892 } | |
893 } | |
894 return count; | |
895 } | |
896 | |
897 static jlong get_long_attribute(jmmLongAttribute att) { | |
898 switch (att) { | |
899 case JMM_CLASS_LOADED_COUNT: | |
900 return ClassLoadingService::loaded_class_count(); | |
901 | |
902 case JMM_CLASS_UNLOADED_COUNT: | |
903 return ClassLoadingService::unloaded_class_count(); | |
904 | |
905 case JMM_THREAD_TOTAL_COUNT: | |
906 return ThreadService::get_total_thread_count(); | |
907 | |
908 case JMM_THREAD_LIVE_COUNT: | |
909 return ThreadService::get_live_thread_count(); | |
910 | |
911 case JMM_THREAD_PEAK_COUNT: | |
912 return ThreadService::get_peak_thread_count(); | |
913 | |
914 case JMM_THREAD_DAEMON_COUNT: | |
915 return ThreadService::get_daemon_thread_count(); | |
916 | |
917 case JMM_JVM_INIT_DONE_TIME_MS: | |
918 return Management::vm_init_done_time(); | |
919 | |
920 case JMM_COMPILE_TOTAL_TIME_MS: | |
921 return Management::ticks_to_ms(CompileBroker::total_compilation_ticks()); | |
922 | |
923 case JMM_OS_PROCESS_ID: | |
924 return os::current_process_id(); | |
925 | |
926 // Hotspot-specific counters | |
927 case JMM_CLASS_LOADED_BYTES: | |
928 return ClassLoadingService::loaded_class_bytes(); | |
929 | |
930 case JMM_CLASS_UNLOADED_BYTES: | |
931 return ClassLoadingService::unloaded_class_bytes(); | |
932 | |
933 case JMM_SHARED_CLASS_LOADED_COUNT: | |
934 return ClassLoadingService::loaded_shared_class_count(); | |
935 | |
936 case JMM_SHARED_CLASS_UNLOADED_COUNT: | |
937 return ClassLoadingService::unloaded_shared_class_count(); | |
938 | |
939 | |
940 case JMM_SHARED_CLASS_LOADED_BYTES: | |
941 return ClassLoadingService::loaded_shared_class_bytes(); | |
942 | |
943 case JMM_SHARED_CLASS_UNLOADED_BYTES: | |
944 return ClassLoadingService::unloaded_shared_class_bytes(); | |
945 | |
946 case JMM_TOTAL_CLASSLOAD_TIME_MS: | |
947 return ClassLoader::classloader_time_ms(); | |
948 | |
949 case JMM_VM_GLOBAL_COUNT: | |
950 return get_num_flags(); | |
951 | |
952 case JMM_SAFEPOINT_COUNT: | |
953 return RuntimeService::safepoint_count(); | |
954 | |
955 case JMM_TOTAL_SAFEPOINTSYNC_TIME_MS: | |
956 return RuntimeService::safepoint_sync_time_ms(); | |
957 | |
958 case JMM_TOTAL_STOPPED_TIME_MS: | |
959 return RuntimeService::safepoint_time_ms(); | |
960 | |
961 case JMM_TOTAL_APP_TIME_MS: | |
962 return RuntimeService::application_time_ms(); | |
963 | |
964 case JMM_VM_THREAD_COUNT: | |
965 return get_vm_thread_count(); | |
966 | |
967 case JMM_CLASS_INIT_TOTAL_COUNT: | |
968 return ClassLoader::class_init_count(); | |
969 | |
970 case JMM_CLASS_INIT_TOTAL_TIME_MS: | |
971 return ClassLoader::class_init_time_ms(); | |
972 | |
973 case JMM_CLASS_VERIFY_TOTAL_TIME_MS: | |
974 return ClassLoader::class_verify_time_ms(); | |
975 | |
976 case JMM_METHOD_DATA_SIZE_BYTES: | |
977 return ClassLoadingService::class_method_data_size(); | |
978 | |
979 case JMM_OS_MEM_TOTAL_PHYSICAL_BYTES: | |
980 return os::physical_memory(); | |
981 | |
982 default: | |
983 return -1; | |
984 } | |
985 } | |
986 | |
987 | |
988 // Returns the long value of a given attribute. | |
989 JVM_ENTRY(jlong, jmm_GetLongAttribute(JNIEnv *env, jobject obj, jmmLongAttribute att)) | |
990 if (obj == NULL) { | |
991 return get_long_attribute(att); | |
992 } else { | |
993 GCMemoryManager* mgr = get_gc_memory_manager_from_jobject(obj, CHECK_(0L)); | |
994 if (mgr != NULL) { | |
995 return get_gc_attribute(mgr, att); | |
996 } | |
997 } | |
998 return -1; | |
999 JVM_END | |
1000 | |
1001 // Gets the value of all attributes specified in the given array | |
1002 // and sets the value in the result array. | |
1003 // Returns the number of attributes found. | |
1004 JVM_ENTRY(jint, jmm_GetLongAttributes(JNIEnv *env, | |
1005 jobject obj, | |
1006 jmmLongAttribute* atts, | |
1007 jint count, | |
1008 jlong* result)) | |
1009 | |
1010 int num_atts = 0; | |
1011 if (obj == NULL) { | |
1012 for (int i = 0; i < count; i++) { | |
1013 result[i] = get_long_attribute(atts[i]); | |
1014 if (result[i] != -1) { | |
1015 num_atts++; | |
1016 } | |
1017 } | |
1018 } else { | |
1019 GCMemoryManager* mgr = get_gc_memory_manager_from_jobject(obj, CHECK_0); | |
1020 for (int i = 0; i < count; i++) { | |
1021 result[i] = get_gc_attribute(mgr, atts[i]); | |
1022 if (result[i] != -1) { | |
1023 num_atts++; | |
1024 } | |
1025 } | |
1026 } | |
1027 return num_atts; | |
1028 JVM_END | |
1029 | |
1030 // Helper function to do thread dump for a specific list of threads | |
1031 static void do_thread_dump(ThreadDumpResult* dump_result, | |
1032 typeArrayHandle ids_ah, // array of thread ID (long[]) | |
1033 int num_threads, | |
1034 int max_depth, | |
1035 bool with_locked_monitors, | |
1036 bool with_locked_synchronizers, | |
1037 TRAPS) { | |
1038 | |
1039 // First get an array of threadObj handles. | |
1040 // A JavaThread may terminate before we get the stack trace. | |
1041 GrowableArray<instanceHandle>* thread_handle_array = new GrowableArray<instanceHandle>(num_threads); | |
1042 { | |
1043 MutexLockerEx ml(Threads_lock); | |
1044 for (int i = 0; i < num_threads; i++) { | |
1045 jlong tid = ids_ah->long_at(i); | |
1046 JavaThread* jt = find_java_thread_from_id(tid); | |
1047 oop thread_obj = (jt != NULL ? jt->threadObj() : (oop)NULL); | |
1048 instanceHandle threadObj_h(THREAD, (instanceOop) thread_obj); | |
1049 thread_handle_array->append(threadObj_h); | |
1050 } | |
1051 } | |
1052 | |
1053 // Obtain thread dumps and thread snapshot information | |
1054 VM_ThreadDump op(dump_result, | |
1055 thread_handle_array, | |
1056 num_threads, | |
1057 max_depth, /* stack depth */ | |
1058 with_locked_monitors, | |
1059 with_locked_synchronizers); | |
1060 VMThread::execute(&op); | |
1061 } | |
1062 | |
1063 // Gets an array of ThreadInfo objects. Each element is the ThreadInfo | |
1064 // for the thread ID specified in the corresponding entry in | |
1065 // the given array of thread IDs; or NULL if the thread does not exist | |
1066 // or has terminated. | |
1067 // | |
1068 // Input parameters: | |
1069 // ids - array of thread IDs | |
1070 // maxDepth - the maximum depth of stack traces to be dumped: | |
1071 // maxDepth == -1 requests to dump entire stack trace. | |
1072 // maxDepth == 0 requests no stack trace. | |
1073 // infoArray - array of ThreadInfo objects | |
1074 // | |
1075 JVM_ENTRY(jint, jmm_GetThreadInfo(JNIEnv *env, jlongArray ids, jint maxDepth, jobjectArray infoArray)) | |
1076 // Check if threads is null | |
1077 if (ids == NULL || infoArray == NULL) { | |
1078 THROW_(vmSymbols::java_lang_NullPointerException(), -1); | |
1079 } | |
1080 | |
1081 if (maxDepth < -1) { | |
1082 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), | |
1083 "Invalid maxDepth", -1); | |
1084 } | |
1085 | |
1086 ResourceMark rm(THREAD); | |
1087 typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids)); | |
1088 typeArrayHandle ids_ah(THREAD, ta); | |
1089 | |
1090 oop infoArray_obj = JNIHandles::resolve_non_null(infoArray); | |
1091 objArrayOop oa = objArrayOop(infoArray_obj); | |
1092 objArrayHandle infoArray_h(THREAD, oa); | |
1093 | |
1094 // validate the thread id array | |
1095 validate_thread_id_array(ids_ah, CHECK_0); | |
1096 | |
1097 // validate the ThreadInfo[] parameters | |
1098 validate_thread_info_array(infoArray_h, CHECK_0); | |
1099 | |
1100 // infoArray must be of the same length as the given array of thread IDs | |
1101 int num_threads = ids_ah->length(); | |
1102 if (num_threads != infoArray_h->length()) { | |
1103 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), | |
1104 "The length of the given ThreadInfo array does not match the length of the given array of thread IDs", -1); | |
1105 } | |
1106 | |
1107 if (JDK_Version::is_gte_jdk16x_version()) { | |
1108 // make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots | |
1109 java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_0); | |
1110 } | |
1111 | |
1112 // Must use ThreadDumpResult to store the ThreadSnapshot. | |
1113 // GC may occur after the thread snapshots are taken but before | |
1114 // this function returns. The threadObj and other oops kept | |
1115 // in the ThreadSnapshot are marked and adjusted during GC. | |
1116 ThreadDumpResult dump_result(num_threads); | |
1117 | |
1118 if (maxDepth == 0) { | |
1119 // no stack trace dumped - do not need to stop the world | |
1120 { | |
1121 MutexLockerEx ml(Threads_lock); | |
1122 for (int i = 0; i < num_threads; i++) { | |
1123 jlong tid = ids_ah->long_at(i); | |
1124 JavaThread* jt = find_java_thread_from_id(tid); | |
1125 ThreadSnapshot* ts; | |
1126 if (jt == NULL) { | |
1127 // if the thread does not exist or now it is terminated, | |
1128 // create dummy snapshot | |
1129 ts = new ThreadSnapshot(); | |
1130 } else { | |
1131 ts = new ThreadSnapshot(jt); | |
1132 } | |
1133 dump_result.add_thread_snapshot(ts); | |
1134 } | |
1135 } | |
1136 } else { | |
1137 // obtain thread dump with the specific list of threads with stack trace | |
1138 | |
1139 do_thread_dump(&dump_result, | |
1140 ids_ah, | |
1141 num_threads, | |
1142 maxDepth, | |
1143 false, /* no locked monitor */ | |
1144 false, /* no locked synchronizers */ | |
1145 CHECK_0); | |
1146 } | |
1147 | |
1148 int num_snapshots = dump_result.num_snapshots(); | |
1149 assert(num_snapshots == num_threads, "Must match the number of thread snapshots"); | |
1150 int index = 0; | |
1151 for (ThreadSnapshot* ts = dump_result.snapshots(); ts != NULL; index++, ts = ts->next()) { | |
1152 // For each thread, create an java/lang/management/ThreadInfo object | |
1153 // and fill with the thread information | |
1154 | |
1155 if (ts->threadObj() == NULL) { | |
1156 // if the thread does not exist or now it is terminated, set threadinfo to NULL | |
1157 infoArray_h->obj_at_put(index, NULL); | |
1158 continue; | |
1159 } | |
1160 | |
1161 // Create java.lang.management.ThreadInfo object | |
1162 instanceOop info_obj = Management::create_thread_info_instance(ts, CHECK_0); | |
1163 infoArray_h->obj_at_put(index, info_obj); | |
1164 } | |
1165 return 0; | |
1166 JVM_END | |
1167 | |
1168 // Dump thread info for the specified threads. | |
1169 // It returns an array of ThreadInfo objects. Each element is the ThreadInfo | |
1170 // for the thread ID specified in the corresponding entry in | |
1171 // the given array of thread IDs; or NULL if the thread does not exist | |
1172 // or has terminated. | |
1173 // | |
1174 // Input parameter: | |
1175 // ids - array of thread IDs; NULL indicates all live threads | |
1176 // locked_monitors - if true, dump locked object monitors | |
1177 // locked_synchronizers - if true, dump locked JSR-166 synchronizers | |
1178 // | |
1179 JVM_ENTRY(jobjectArray, jmm_DumpThreads(JNIEnv *env, jlongArray thread_ids, jboolean locked_monitors, jboolean locked_synchronizers)) | |
1180 ResourceMark rm(THREAD); | |
1181 | |
1182 if (JDK_Version::is_gte_jdk16x_version()) { | |
1183 // make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots | |
1184 java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_NULL); | |
1185 } | |
1186 | |
1187 typeArrayOop ta = typeArrayOop(JNIHandles::resolve(thread_ids)); | |
1188 int num_threads = (ta != NULL ? ta->length() : 0); | |
1189 typeArrayHandle ids_ah(THREAD, ta); | |
1190 | |
1191 ThreadDumpResult dump_result(num_threads); // can safepoint | |
1192 | |
1193 if (ids_ah() != NULL) { | |
1194 | |
1195 // validate the thread id array | |
1196 validate_thread_id_array(ids_ah, CHECK_NULL); | |
1197 | |
1198 // obtain thread dump of a specific list of threads | |
1199 do_thread_dump(&dump_result, | |
1200 ids_ah, | |
1201 num_threads, | |
1202 -1, /* entire stack */ | |
1203 (locked_monitors ? true : false), /* with locked monitors */ | |
1204 (locked_synchronizers ? true : false), /* with locked synchronizers */ | |
1205 CHECK_NULL); | |
1206 } else { | |
1207 // obtain thread dump of all threads | |
1208 VM_ThreadDump op(&dump_result, | |
1209 -1, /* entire stack */ | |
1210 (locked_monitors ? true : false), /* with locked monitors */ | |
1211 (locked_synchronizers ? true : false) /* with locked synchronizers */); | |
1212 VMThread::execute(&op); | |
1213 } | |
1214 | |
1215 int num_snapshots = dump_result.num_snapshots(); | |
1216 | |
1217 // create the result ThreadInfo[] object | |
1218 klassOop k = Management::java_lang_management_ThreadInfo_klass(CHECK_NULL); | |
1219 instanceKlassHandle ik (THREAD, k); | |
1220 objArrayOop r = oopFactory::new_objArray(ik(), num_snapshots, CHECK_NULL); | |
1221 objArrayHandle result_h(THREAD, r); | |
1222 | |
1223 int index = 0; | |
1224 for (ThreadSnapshot* ts = dump_result.snapshots(); ts != NULL; ts = ts->next(), index++) { | |
1225 if (ts->threadObj() == NULL) { | |
1226 // if the thread does not exist or now it is terminated, set threadinfo to NULL | |
1227 result_h->obj_at_put(index, NULL); | |
1228 continue; | |
1229 } | |
1230 | |
1231 | |
1232 | |
1233 ThreadStackTrace* stacktrace = ts->get_stack_trace(); | |
1234 assert(stacktrace != NULL, "Must have a stack trace dumped"); | |
1235 | |
1236 // Create Object[] filled with locked monitors | |
1237 // Create int[] filled with the stack depth where a monitor was locked | |
1238 int num_frames = stacktrace->get_stack_depth(); | |
1239 int num_locked_monitors = stacktrace->num_jni_locked_monitors(); | |
1240 | |
1241 // Count the total number of locked monitors | |
1242 for (int i = 0; i < num_frames; i++) { | |
1243 StackFrameInfo* frame = stacktrace->stack_frame_at(i); | |
1244 num_locked_monitors += frame->num_locked_monitors(); | |
1245 } | |
1246 | |
1247 objArrayHandle monitors_array; | |
1248 typeArrayHandle depths_array; | |
1249 objArrayHandle synchronizers_array; | |
1250 | |
1251 if (locked_monitors) { | |
1252 // Constructs Object[] and int[] to contain the object monitor and the stack depth | |
1253 // where the thread locked it | |
1254 objArrayOop array = oopFactory::new_system_objArray(num_locked_monitors, CHECK_NULL); | |
1255 objArrayHandle mh(THREAD, array); | |
1256 monitors_array = mh; | |
1257 | |
1258 typeArrayOop tarray = oopFactory::new_typeArray(T_INT, num_locked_monitors, CHECK_NULL); | |
1259 typeArrayHandle dh(THREAD, tarray); | |
1260 depths_array = dh; | |
1261 | |
1262 int count = 0; | |
1263 int j = 0; | |
1264 for (int depth = 0; depth < num_frames; depth++) { | |
1265 StackFrameInfo* frame = stacktrace->stack_frame_at(depth); | |
1266 int len = frame->num_locked_monitors(); | |
1267 GrowableArray<oop>* locked_monitors = frame->locked_monitors(); | |
1268 for (j = 0; j < len; j++) { | |
1269 oop monitor = locked_monitors->at(j); | |
1270 assert(monitor != NULL && monitor->is_instance(), "must be a Java object"); | |
1271 monitors_array->obj_at_put(count, monitor); | |
1272 depths_array->int_at_put(count, depth); | |
1273 count++; | |
1274 } | |
1275 } | |
1276 | |
1277 GrowableArray<oop>* jni_locked_monitors = stacktrace->jni_locked_monitors(); | |
1278 for (j = 0; j < jni_locked_monitors->length(); j++) { | |
1279 oop object = jni_locked_monitors->at(j); | |
1280 assert(object != NULL && object->is_instance(), "must be a Java object"); | |
1281 monitors_array->obj_at_put(count, object); | |
1282 // Monitor locked via JNI MonitorEnter call doesn't have stack depth info | |
1283 depths_array->int_at_put(count, -1); | |
1284 count++; | |
1285 } | |
1286 assert(count == num_locked_monitors, "number of locked monitors doesn't match"); | |
1287 } | |
1288 | |
1289 if (locked_synchronizers) { | |
1290 // Create Object[] filled with locked JSR-166 synchronizers | |
1291 assert(ts->threadObj() != NULL, "Must be a valid JavaThread"); | |
1292 ThreadConcurrentLocks* tcl = ts->get_concurrent_locks(); | |
1293 GrowableArray<instanceOop>* locks = (tcl != NULL ? tcl->owned_locks() : NULL); | |
1294 int num_locked_synchronizers = (locks != NULL ? locks->length() : 0); | |
1295 | |
1296 objArrayOop array = oopFactory::new_system_objArray(num_locked_synchronizers, CHECK_NULL); | |
1297 objArrayHandle sh(THREAD, array); | |
1298 synchronizers_array = sh; | |
1299 | |
1300 for (int k = 0; k < num_locked_synchronizers; k++) { | |
1301 synchronizers_array->obj_at_put(k, locks->at(k)); | |
1302 } | |
1303 } | |
1304 | |
1305 // Create java.lang.management.ThreadInfo object | |
1306 instanceOop info_obj = Management::create_thread_info_instance(ts, | |
1307 monitors_array, | |
1308 depths_array, | |
1309 synchronizers_array, | |
1310 CHECK_NULL); | |
1311 result_h->obj_at_put(index, info_obj); | |
1312 } | |
1313 | |
1314 return (jobjectArray) JNIHandles::make_local(env, result_h()); | |
1315 JVM_END | |
1316 | |
1317 // Returns an array of Class objects. | |
1318 JVM_ENTRY(jobjectArray, jmm_GetLoadedClasses(JNIEnv *env)) | |
1319 ResourceMark rm(THREAD); | |
1320 | |
1321 LoadedClassesEnumerator lce(THREAD); // Pass current Thread as parameter | |
1322 | |
1323 int num_classes = lce.num_loaded_classes(); | |
1142 | 1324 objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(), num_classes, CHECK_0); |
0 | 1325 objArrayHandle classes_ah(THREAD, r); |
1326 | |
1327 for (int i = 0; i < num_classes; i++) { | |
1328 KlassHandle kh = lce.get_klass(i); | |
1329 oop mirror = Klass::cast(kh())->java_mirror(); | |
1330 classes_ah->obj_at_put(i, mirror); | |
1331 } | |
1332 | |
1333 return (jobjectArray) JNIHandles::make_local(env, classes_ah()); | |
1334 JVM_END | |
1335 | |
1336 // Reset statistic. Return true if the requested statistic is reset. | |
1337 // Otherwise, return false. | |
1338 // | |
1339 // Input parameters: | |
1340 // obj - specify which instance the statistic associated with to be reset | |
1341 // For PEAK_POOL_USAGE stat, obj is required to be a memory pool object. | |
1342 // For THREAD_CONTENTION_COUNT and TIME stat, obj is required to be a thread ID. | |
1343 // type - the type of statistic to be reset | |
1344 // | |
1345 JVM_ENTRY(jboolean, jmm_ResetStatistic(JNIEnv *env, jvalue obj, jmmStatisticType type)) | |
1346 ResourceMark rm(THREAD); | |
1347 | |
1348 switch (type) { | |
1349 case JMM_STAT_PEAK_THREAD_COUNT: | |
1350 ThreadService::reset_peak_thread_count(); | |
1351 return true; | |
1352 | |
1353 case JMM_STAT_THREAD_CONTENTION_COUNT: | |
1354 case JMM_STAT_THREAD_CONTENTION_TIME: { | |
1355 jlong tid = obj.j; | |
1356 if (tid < 0) { | |
1357 THROW_(vmSymbols::java_lang_IllegalArgumentException(), JNI_FALSE); | |
1358 } | |
1359 | |
1360 // Look for the JavaThread of this given tid | |
1361 MutexLockerEx ml(Threads_lock); | |
1362 if (tid == 0) { | |
1363 // reset contention statistics for all threads if tid == 0 | |
1364 for (JavaThread* java_thread = Threads::first(); java_thread != NULL; java_thread = java_thread->next()) { | |
1365 if (type == JMM_STAT_THREAD_CONTENTION_COUNT) { | |
1366 ThreadService::reset_contention_count_stat(java_thread); | |
1367 } else { | |
1368 ThreadService::reset_contention_time_stat(java_thread); | |
1369 } | |
1370 } | |
1371 } else { | |
1372 // reset contention statistics for a given thread | |
1373 JavaThread* java_thread = find_java_thread_from_id(tid); | |
1374 if (java_thread == NULL) { | |
1375 return false; | |
1376 } | |
1377 | |
1378 if (type == JMM_STAT_THREAD_CONTENTION_COUNT) { | |
1379 ThreadService::reset_contention_count_stat(java_thread); | |
1380 } else { | |
1381 ThreadService::reset_contention_time_stat(java_thread); | |
1382 } | |
1383 } | |
1384 return true; | |
1385 break; | |
1386 } | |
1387 case JMM_STAT_PEAK_POOL_USAGE: { | |
1388 jobject o = obj.l; | |
1389 if (o == NULL) { | |
1390 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE); | |
1391 } | |
1392 | |
1393 oop pool_obj = JNIHandles::resolve(o); | |
1394 assert(pool_obj->is_instance(), "Should be an instanceOop"); | |
1395 instanceHandle ph(THREAD, (instanceOop) pool_obj); | |
1396 | |
1397 MemoryPool* pool = MemoryService::get_memory_pool(ph); | |
1398 if (pool != NULL) { | |
1399 pool->reset_peak_memory_usage(); | |
1400 return true; | |
1401 } | |
1402 break; | |
1403 } | |
1404 case JMM_STAT_GC_STAT: { | |
1405 jobject o = obj.l; | |
1406 if (o == NULL) { | |
1407 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE); | |
1408 } | |
1409 | |
1410 GCMemoryManager* mgr = get_gc_memory_manager_from_jobject(o, CHECK_0); | |
1411 if (mgr != NULL) { | |
1412 mgr->reset_gc_stat(); | |
1413 return true; | |
1414 } | |
1415 break; | |
1416 } | |
1417 default: | |
1418 assert(0, "Unknown Statistic Type"); | |
1419 } | |
1420 return false; | |
1421 JVM_END | |
1422 | |
1423 // Returns the fast estimate of CPU time consumed by | |
1424 // a given thread (in nanoseconds). | |
1425 // If thread_id == 0, return CPU time for the current thread. | |
1426 JVM_ENTRY(jlong, jmm_GetThreadCpuTime(JNIEnv *env, jlong thread_id)) | |
1427 if (!os::is_thread_cpu_time_supported()) { | |
1428 return -1; | |
1429 } | |
1430 | |
1431 if (thread_id < 0) { | |
1432 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), | |
1433 "Invalid thread ID", -1); | |
1434 } | |
1435 | |
1436 JavaThread* java_thread = NULL; | |
1437 if (thread_id == 0) { | |
1438 // current thread | |
1439 return os::current_thread_cpu_time(); | |
1440 } else { | |
1441 MutexLockerEx ml(Threads_lock); | |
1442 java_thread = find_java_thread_from_id(thread_id); | |
1443 if (java_thread != NULL) { | |
1444 return os::thread_cpu_time((Thread*) java_thread); | |
1445 } | |
1446 } | |
1447 return -1; | |
1448 JVM_END | |
1449 | |
1450 // Returns the CPU time consumed by a given thread (in nanoseconds). | |
1451 // If thread_id == 0, CPU time for the current thread is returned. | |
1452 // If user_sys_cpu_time = true, user level and system CPU time of | |
1453 // a given thread is returned; otherwise, only user level CPU time | |
1454 // is returned. | |
1455 JVM_ENTRY(jlong, jmm_GetThreadCpuTimeWithKind(JNIEnv *env, jlong thread_id, jboolean user_sys_cpu_time)) | |
1456 if (!os::is_thread_cpu_time_supported()) { | |
1457 return -1; | |
1458 } | |
1459 | |
1460 if (thread_id < 0) { | |
1461 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), | |
1462 "Invalid thread ID", -1); | |
1463 } | |
1464 | |
1465 JavaThread* java_thread = NULL; | |
1466 if (thread_id == 0) { | |
1467 // current thread | |
1468 return os::current_thread_cpu_time(user_sys_cpu_time != 0); | |
1469 } else { | |
1470 MutexLockerEx ml(Threads_lock); | |
1471 java_thread = find_java_thread_from_id(thread_id); | |
1472 if (java_thread != NULL) { | |
1473 return os::thread_cpu_time((Thread*) java_thread, user_sys_cpu_time != 0); | |
1474 } | |
1475 } | |
1476 return -1; | |
1477 JVM_END | |
1478 | |
1479 // Returns a String array of all VM global flag names | |
1480 JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env)) | |
1481 // last flag entry is always NULL, so subtract 1 | |
1482 int nFlags = (int) Flag::numFlags - 1; | |
1483 // allocate a temp array | |
1142 | 1484 objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(), |
0 | 1485 nFlags, CHECK_0); |
1486 objArrayHandle flags_ah(THREAD, r); | |
1487 int num_entries = 0; | |
1488 for (int i = 0; i < nFlags; i++) { | |
1489 Flag* flag = &Flag::flags[i]; | |
350 | 1490 // Exclude the locked (experimental, diagnostic) flags |
0 | 1491 if (flag->is_unlocked() || flag->is_unlocker()) { |
1492 Handle s = java_lang_String::create_from_str(flag->name, CHECK_0); | |
1493 flags_ah->obj_at_put(num_entries, s()); | |
1494 num_entries++; | |
1495 } | |
1496 } | |
1497 | |
1498 if (num_entries < nFlags) { | |
1499 // Return array of right length | |
1142 | 1500 objArrayOop res = oopFactory::new_objArray(SystemDictionary::String_klass(), num_entries, CHECK_0); |
0 | 1501 for(int i = 0; i < num_entries; i++) { |
1502 res->obj_at_put(i, flags_ah->obj_at(i)); | |
1503 } | |
1504 return (jobjectArray)JNIHandles::make_local(env, res); | |
1505 } | |
1506 | |
1507 return (jobjectArray)JNIHandles::make_local(env, flags_ah()); | |
1508 JVM_END | |
1509 | |
1067
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1510 // Utility function used by jmm_GetVMGlobals. Returns false if flag type |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1511 // can't be determined, true otherwise. If false is returned, then *global |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1512 // will be incomplete and invalid. |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1513 bool add_global_entry(JNIEnv* env, Handle name, jmmVMGlobal *global, Flag *flag, TRAPS) { |
0 | 1514 Handle flag_name; |
1515 if (name() == NULL) { | |
1067
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1516 flag_name = java_lang_String::create_from_str(flag->name, CHECK_false); |
0 | 1517 } else { |
1518 flag_name = name; | |
1519 } | |
1520 global->name = (jstring)JNIHandles::make_local(env, flag_name()); | |
1521 | |
1522 if (flag->is_bool()) { | |
1523 global->value.z = flag->get_bool() ? JNI_TRUE : JNI_FALSE; | |
1524 global->type = JMM_VMGLOBAL_TYPE_JBOOLEAN; | |
1525 } else if (flag->is_intx()) { | |
1526 global->value.j = (jlong)flag->get_intx(); | |
1527 global->type = JMM_VMGLOBAL_TYPE_JLONG; | |
1528 } else if (flag->is_uintx()) { | |
1529 global->value.j = (jlong)flag->get_uintx(); | |
1530 global->type = JMM_VMGLOBAL_TYPE_JLONG; | |
1067
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1531 } else if (flag->is_uint64_t()) { |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1532 global->value.j = (jlong)flag->get_uint64_t(); |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1533 global->type = JMM_VMGLOBAL_TYPE_JLONG; |
0 | 1534 } else if (flag->is_ccstr()) { |
1067
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1535 Handle str = java_lang_String::create_from_str(flag->get_ccstr(), CHECK_false); |
0 | 1536 global->value.l = (jobject)JNIHandles::make_local(env, str()); |
1537 global->type = JMM_VMGLOBAL_TYPE_JSTRING; | |
1067
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1538 } else { |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1539 global->type = JMM_VMGLOBAL_TYPE_UNKNOWN; |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1540 return false; |
0 | 1541 } |
1542 | |
1543 global->writeable = flag->is_writeable(); | |
1544 global->external = flag->is_external(); | |
1545 switch (flag->origin) { | |
1546 case DEFAULT: | |
1547 global->origin = JMM_VMGLOBAL_ORIGIN_DEFAULT; | |
1548 break; | |
1549 case COMMAND_LINE: | |
1550 global->origin = JMM_VMGLOBAL_ORIGIN_COMMAND_LINE; | |
1551 break; | |
1552 case ENVIRON_VAR: | |
1553 global->origin = JMM_VMGLOBAL_ORIGIN_ENVIRON_VAR; | |
1554 break; | |
1555 case CONFIG_FILE: | |
1556 global->origin = JMM_VMGLOBAL_ORIGIN_CONFIG_FILE; | |
1557 break; | |
1558 case MANAGEMENT: | |
1559 global->origin = JMM_VMGLOBAL_ORIGIN_MANAGEMENT; | |
1560 break; | |
1561 case ERGONOMIC: | |
1562 global->origin = JMM_VMGLOBAL_ORIGIN_ERGONOMIC; | |
1563 break; | |
1564 default: | |
1565 global->origin = JMM_VMGLOBAL_ORIGIN_OTHER; | |
1566 } | |
1067
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1567 |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1568 return true; |
0 | 1569 } |
1570 | |
1571 // Fill globals array of count length with jmmVMGlobal entries | |
1572 // specified by names. If names == NULL, fill globals array | |
1573 // with all Flags. Return value is number of entries | |
1574 // created in globals. | |
1575 // If a Flag with a given name in an array element does not | |
1576 // exist, globals[i].name will be set to NULL. | |
1577 JVM_ENTRY(jint, jmm_GetVMGlobals(JNIEnv *env, | |
1578 jobjectArray names, | |
1579 jmmVMGlobal *globals, | |
1580 jint count)) | |
1581 | |
1582 | |
1583 if (globals == NULL) { | |
1584 THROW_(vmSymbols::java_lang_NullPointerException(), 0); | |
1585 } | |
1586 | |
1587 ResourceMark rm(THREAD); | |
1588 | |
1589 if (names != NULL) { | |
1590 // return the requested globals | |
1591 objArrayOop ta = objArrayOop(JNIHandles::resolve_non_null(names)); | |
1592 objArrayHandle names_ah(THREAD, ta); | |
1593 // Make sure we have a String array | |
1594 klassOop element_klass = objArrayKlass::cast(names_ah->klass())->element_klass(); | |
1142 | 1595 if (element_klass != SystemDictionary::String_klass()) { |
0 | 1596 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), |
1597 "Array element type is not String class", 0); | |
1598 } | |
1599 | |
1600 int names_length = names_ah->length(); | |
1601 int num_entries = 0; | |
1602 for (int i = 0; i < names_length && i < count; i++) { | |
1603 oop s = names_ah->obj_at(i); | |
1604 if (s == NULL) { | |
1605 THROW_(vmSymbols::java_lang_NullPointerException(), 0); | |
1606 } | |
1607 | |
1608 Handle sh(THREAD, s); | |
1609 char* str = java_lang_String::as_utf8_string(s); | |
1610 Flag* flag = Flag::find_flag(str, strlen(str)); | |
1067
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1611 if (flag != NULL && |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1612 add_global_entry(env, sh, &globals[i], flag, THREAD)) { |
0 | 1613 num_entries++; |
1614 } else { | |
1615 globals[i].name = NULL; | |
1616 } | |
1617 } | |
1618 return num_entries; | |
1619 } else { | |
1620 // return all globals if names == NULL | |
1621 | |
1622 // last flag entry is always NULL, so subtract 1 | |
1623 int nFlags = (int) Flag::numFlags - 1; | |
1624 Handle null_h; | |
1625 int num_entries = 0; | |
1626 for (int i = 0; i < nFlags && num_entries < count; i++) { | |
1627 Flag* flag = &Flag::flags[i]; | |
350 | 1628 // Exclude the locked (diagnostic, experimental) flags |
1067
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1629 if ((flag->is_unlocked() || flag->is_unlocker()) && |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1630 add_global_entry(env, null_h, &globals[num_entries], flag, THREAD)) { |
0 | 1631 num_entries++; |
1632 } | |
1633 } | |
1634 return num_entries; | |
1635 } | |
1636 JVM_END | |
1637 | |
1638 JVM_ENTRY(void, jmm_SetVMGlobal(JNIEnv *env, jstring flag_name, jvalue new_value)) | |
1639 ResourceMark rm(THREAD); | |
1640 | |
1641 oop fn = JNIHandles::resolve_external_guard(flag_name); | |
1642 if (fn == NULL) { | |
1643 THROW_MSG(vmSymbols::java_lang_NullPointerException(), | |
1644 "The flag name cannot be null."); | |
1645 } | |
1646 char* name = java_lang_String::as_utf8_string(fn); | |
1647 Flag* flag = Flag::find_flag(name, strlen(name)); | |
1648 if (flag == NULL) { | |
1649 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), | |
1650 "Flag does not exist."); | |
1651 } | |
1652 if (!flag->is_writeable()) { | |
1653 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), | |
1654 "This flag is not writeable."); | |
1655 } | |
1656 | |
1657 bool succeed; | |
1658 if (flag->is_bool()) { | |
1659 bool bvalue = (new_value.z == JNI_TRUE ? true : false); | |
1660 succeed = CommandLineFlags::boolAtPut(name, &bvalue, MANAGEMENT); | |
1661 } else if (flag->is_intx()) { | |
1067
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1662 intx ivalue = (intx)new_value.j; |
0 | 1663 succeed = CommandLineFlags::intxAtPut(name, &ivalue, MANAGEMENT); |
1664 } else if (flag->is_uintx()) { | |
1067
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1665 uintx uvalue = (uintx)new_value.j; |
0 | 1666 succeed = CommandLineFlags::uintxAtPut(name, &uvalue, MANAGEMENT); |
1067
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1667 } else if (flag->is_uint64_t()) { |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1668 uint64_t uvalue = (uint64_t)new_value.j; |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
1064
diff
changeset
|
1669 succeed = CommandLineFlags::uint64_tAtPut(name, &uvalue, MANAGEMENT); |
0 | 1670 } else if (flag->is_ccstr()) { |
1671 oop str = JNIHandles::resolve_external_guard(new_value.l); | |
1672 if (str == NULL) { | |
1673 THROW(vmSymbols::java_lang_NullPointerException()); | |
1674 } | |
1675 ccstr svalue = java_lang_String::as_utf8_string(str); | |
1676 succeed = CommandLineFlags::ccstrAtPut(name, &svalue, MANAGEMENT); | |
1677 } | |
1678 assert(succeed, "Setting flag should succeed"); | |
1679 JVM_END | |
1680 | |
1681 class ThreadTimesClosure: public ThreadClosure { | |
1682 private: | |
1683 objArrayOop _names; | |
1684 typeArrayOop _times; | |
1685 int _names_len; | |
1686 int _times_len; | |
1687 int _count; | |
1688 | |
1689 public: | |
1690 ThreadTimesClosure(objArrayOop names, typeArrayOop times); | |
1691 virtual void do_thread(Thread* thread); | |
1692 int count() { return _count; } | |
1693 }; | |
1694 | |
1695 ThreadTimesClosure::ThreadTimesClosure(objArrayOop names, | |
1696 typeArrayOop times) { | |
1697 assert(names != NULL, "names was NULL"); | |
1698 assert(times != NULL, "times was NULL"); | |
1699 _names = names; | |
1700 _names_len = names->length(); | |
1701 _times = times; | |
1702 _times_len = times->length(); | |
1703 _count = 0; | |
1704 } | |
1705 | |
1706 void ThreadTimesClosure::do_thread(Thread* thread) { | |
1707 Handle s; | |
1708 assert(thread != NULL, "thread was NULL"); | |
1709 | |
1710 // exclude externally visible JavaThreads | |
1711 if (thread->is_Java_thread() && !thread->is_hidden_from_external_view()) { | |
1712 return; | |
1713 } | |
1714 | |
1715 if (_count >= _names_len || _count >= _times_len) { | |
1716 // skip if the result array is not big enough | |
1717 return; | |
1718 } | |
1719 | |
1720 EXCEPTION_MARK; | |
1721 | |
1722 assert(thread->name() != NULL, "All threads should have a name"); | |
1723 s = java_lang_String::create_from_str(thread->name(), CHECK); | |
1724 _names->obj_at_put(_count, s()); | |
1725 | |
1726 _times->long_at_put(_count, os::is_thread_cpu_time_supported() ? | |
1727 os::thread_cpu_time(thread) : -1); | |
1728 _count++; | |
1729 } | |
1730 | |
1731 // Fills names with VM internal thread names and times with the corresponding | |
1732 // CPU times. If names or times is NULL, a NullPointerException is thrown. | |
1733 // If the element type of names is not String, an IllegalArgumentException is | |
1734 // thrown. | |
1735 // If an array is not large enough to hold all the entries, only the entries | |
1736 // that fit will be returned. Return value is the number of VM internal | |
1737 // threads entries. | |
1738 JVM_ENTRY(jint, jmm_GetInternalThreadTimes(JNIEnv *env, | |
1739 jobjectArray names, | |
1740 jlongArray times)) | |
1741 if (names == NULL || times == NULL) { | |
1742 THROW_(vmSymbols::java_lang_NullPointerException(), 0); | |
1743 } | |
1744 objArrayOop na = objArrayOop(JNIHandles::resolve_non_null(names)); | |
1745 objArrayHandle names_ah(THREAD, na); | |
1746 | |
1747 // Make sure we have a String array | |
1748 klassOop element_klass = objArrayKlass::cast(names_ah->klass())->element_klass(); | |
1142 | 1749 if (element_klass != SystemDictionary::String_klass()) { |
0 | 1750 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), |
1751 "Array element type is not String class", 0); | |
1752 } | |
1753 | |
1754 typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(times)); | |
1755 typeArrayHandle times_ah(THREAD, ta); | |
1756 | |
1757 ThreadTimesClosure ttc(names_ah(), times_ah()); | |
1758 { | |
1759 MutexLockerEx ml(Threads_lock); | |
1760 Threads::threads_do(&ttc); | |
1761 } | |
1762 | |
1763 return ttc.count(); | |
1764 JVM_END | |
1765 | |
1766 static Handle find_deadlocks(bool object_monitors_only, TRAPS) { | |
1767 ResourceMark rm(THREAD); | |
1768 | |
1769 VM_FindDeadlocks op(!object_monitors_only /* also check concurrent locks? */); | |
1770 VMThread::execute(&op); | |
1771 | |
1772 DeadlockCycle* deadlocks = op.result(); | |
1773 if (deadlocks == NULL) { | |
1774 // no deadlock found and return | |
1775 return Handle(); | |
1776 } | |
1777 | |
1778 int num_threads = 0; | |
1779 DeadlockCycle* cycle; | |
1780 for (cycle = deadlocks; cycle != NULL; cycle = cycle->next()) { | |
1781 num_threads += cycle->num_threads(); | |
1782 } | |
1783 | |
1142 | 1784 objArrayOop r = oopFactory::new_objArray(SystemDictionary::Thread_klass(), num_threads, CHECK_NH); |
0 | 1785 objArrayHandle threads_ah(THREAD, r); |
1786 | |
1787 int index = 0; | |
1788 for (cycle = deadlocks; cycle != NULL; cycle = cycle->next()) { | |
1789 GrowableArray<JavaThread*>* deadlock_threads = cycle->threads(); | |
1790 int len = deadlock_threads->length(); | |
1791 for (int i = 0; i < len; i++) { | |
1792 threads_ah->obj_at_put(index, deadlock_threads->at(i)->threadObj()); | |
1793 index++; | |
1794 } | |
1795 } | |
1796 return threads_ah; | |
1797 } | |
1798 | |
1799 // Finds cycles of threads that are deadlocked involved in object monitors | |
1800 // and JSR-166 synchronizers. | |
1801 // Returns an array of Thread objects which are in deadlock, if any. | |
1802 // Otherwise, returns NULL. | |
1803 // | |
1804 // Input parameter: | |
1805 // object_monitors_only - if true, only check object monitors | |
1806 // | |
1807 JVM_ENTRY(jobjectArray, jmm_FindDeadlockedThreads(JNIEnv *env, jboolean object_monitors_only)) | |
1808 Handle result = find_deadlocks(object_monitors_only != 0, CHECK_0); | |
1809 return (jobjectArray) JNIHandles::make_local(env, result()); | |
1810 JVM_END | |
1811 | |
1812 // Finds cycles of threads that are deadlocked on monitor locks | |
1813 // Returns an array of Thread objects which are in deadlock, if any. | |
1814 // Otherwise, returns NULL. | |
1815 JVM_ENTRY(jobjectArray, jmm_FindMonitorDeadlockedThreads(JNIEnv *env)) | |
1816 Handle result = find_deadlocks(true, CHECK_0); | |
1817 return (jobjectArray) JNIHandles::make_local(env, result()); | |
1818 JVM_END | |
1819 | |
1820 // Gets the information about GC extension attributes including | |
1821 // the name of the attribute, its type, and a short description. | |
1822 // | |
1823 // Input parameters: | |
1824 // mgr - GC memory manager | |
1825 // info - caller allocated array of jmmExtAttributeInfo | |
1826 // count - number of elements of the info array | |
1827 // | |
1828 // Returns the number of GC extension attributes filled in the info array; or | |
1829 // -1 if info is not big enough | |
1830 // | |
1831 JVM_ENTRY(jint, jmm_GetGCExtAttributeInfo(JNIEnv *env, jobject mgr, jmmExtAttributeInfo* info, jint count)) | |
1832 // All GC memory managers have 1 attribute (number of GC threads) | |
1833 if (count == 0) { | |
1834 return 0; | |
1835 } | |
1836 | |
1837 if (info == NULL) { | |
1838 THROW_(vmSymbols::java_lang_NullPointerException(), 0); | |
1839 } | |
1840 | |
1841 info[0].name = "GcThreadCount"; | |
1842 info[0].type = 'I'; | |
1843 info[0].description = "Number of GC threads"; | |
1844 return 1; | |
1845 JVM_END | |
1846 | |
1847 // verify the given array is an array of java/lang/management/MemoryUsage objects | |
1848 // of a given length and return the objArrayOop | |
1849 static objArrayOop get_memory_usage_objArray(jobjectArray array, int length, TRAPS) { | |
1850 if (array == NULL) { | |
1851 THROW_(vmSymbols::java_lang_NullPointerException(), 0); | |
1852 } | |
1853 | |
1854 objArrayOop oa = objArrayOop(JNIHandles::resolve_non_null(array)); | |
1855 objArrayHandle array_h(THREAD, oa); | |
1856 | |
1857 // array must be of the given length | |
1858 if (length != array_h->length()) { | |
1859 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), | |
1860 "The length of the given MemoryUsage array does not match the number of memory pools.", 0); | |
1861 } | |
1862 | |
1863 // check if the element of array is of type MemoryUsage class | |
1864 klassOop usage_klass = Management::java_lang_management_MemoryUsage_klass(CHECK_0); | |
1865 klassOop element_klass = objArrayKlass::cast(array_h->klass())->element_klass(); | |
1866 if (element_klass != usage_klass) { | |
1867 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), | |
1868 "The element type is not MemoryUsage class", 0); | |
1869 } | |
1870 | |
1871 return array_h(); | |
1872 } | |
1873 | |
1874 // Gets the statistics of the last GC of a given GC memory manager. | |
1875 // Input parameters: | |
1876 // obj - GarbageCollectorMXBean object | |
1877 // gc_stat - caller allocated jmmGCStat where: | |
1878 // a. before_gc_usage - array of MemoryUsage objects | |
1879 // b. after_gc_usage - array of MemoryUsage objects | |
1880 // c. gc_ext_attributes_values_size is set to the | |
1881 // gc_ext_attribute_values array allocated | |
1882 // d. gc_ext_attribute_values is a caller allocated array of jvalue. | |
1883 // | |
1884 // On return, | |
1885 // gc_index == 0 indicates no GC statistics available | |
1886 // | |
1887 // before_gc_usage and after_gc_usage - filled with per memory pool | |
1888 // before and after GC usage in the same order as the memory pools | |
1889 // returned by GetMemoryPools for a given GC memory manager. | |
1890 // num_gc_ext_attributes indicates the number of elements in | |
1891 // the gc_ext_attribute_values array is filled; or | |
1892 // -1 if the gc_ext_attributes_values array is not big enough | |
1893 // | |
1894 JVM_ENTRY(void, jmm_GetLastGCStat(JNIEnv *env, jobject obj, jmmGCStat *gc_stat)) | |
1895 ResourceMark rm(THREAD); | |
1896 | |
1897 if (gc_stat->gc_ext_attribute_values_size > 0 && gc_stat->gc_ext_attribute_values == NULL) { | |
1898 THROW(vmSymbols::java_lang_NullPointerException()); | |
1899 } | |
1900 | |
1901 // Get the GCMemoryManager | |
1902 GCMemoryManager* mgr = get_gc_memory_manager_from_jobject(obj, CHECK); | |
1903 | |
1904 // Make a copy of the last GC statistics | |
1905 // GC may occur while constructing the last GC information | |
1906 int num_pools = MemoryService::num_memory_pools(); | |
1907 GCStatInfo* stat = new GCStatInfo(num_pools); | |
1703
f6f3eef8a521
6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents:
1552
diff
changeset
|
1908 if (mgr->get_last_gc_stat(stat) == 0) { |
f6f3eef8a521
6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents:
1552
diff
changeset
|
1909 gc_stat->gc_index = 0; |
f6f3eef8a521
6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents:
1552
diff
changeset
|
1910 return; |
f6f3eef8a521
6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents:
1552
diff
changeset
|
1911 } |
0 | 1912 |
1913 gc_stat->gc_index = stat->gc_index(); | |
1914 gc_stat->start_time = Management::ticks_to_ms(stat->start_time()); | |
1915 gc_stat->end_time = Management::ticks_to_ms(stat->end_time()); | |
1916 | |
1917 // Current implementation does not have GC extension attributes | |
1918 gc_stat->num_gc_ext_attributes = 0; | |
1919 | |
1920 // Fill the arrays of MemoryUsage objects with before and after GC | |
1921 // per pool memory usage | |
1922 objArrayOop bu = get_memory_usage_objArray(gc_stat->usage_before_gc, | |
1923 num_pools, | |
1924 CHECK); | |
1925 objArrayHandle usage_before_gc_ah(THREAD, bu); | |
1926 | |
1927 objArrayOop au = get_memory_usage_objArray(gc_stat->usage_after_gc, | |
1928 num_pools, | |
1929 CHECK); | |
1930 objArrayHandle usage_after_gc_ah(THREAD, au); | |
1931 | |
1932 for (int i = 0; i < num_pools; i++) { | |
1933 Handle before_usage = MemoryService::create_MemoryUsage_obj(stat->before_gc_usage_for_pool(i), CHECK); | |
1934 Handle after_usage; | |
1935 | |
1936 MemoryUsage u = stat->after_gc_usage_for_pool(i); | |
1937 if (u.max_size() == 0 && u.used() > 0) { | |
1938 // If max size == 0, this pool is a survivor space. | |
1939 // Set max size = -1 since the pools will be swapped after GC. | |
1940 MemoryUsage usage(u.init_size(), u.used(), u.committed(), (size_t)-1); | |
1941 after_usage = MemoryService::create_MemoryUsage_obj(usage, CHECK); | |
1942 } else { | |
1943 after_usage = MemoryService::create_MemoryUsage_obj(stat->after_gc_usage_for_pool(i), CHECK); | |
1944 } | |
1945 usage_before_gc_ah->obj_at_put(i, before_usage()); | |
1946 usage_after_gc_ah->obj_at_put(i, after_usage()); | |
1947 } | |
1948 | |
1949 if (gc_stat->gc_ext_attribute_values_size > 0) { | |
1950 // Current implementation only has 1 attribute (number of GC threads) | |
1951 // The type is 'I' | |
1952 gc_stat->gc_ext_attribute_values[0].i = mgr->num_gc_threads(); | |
1953 } | |
1954 JVM_END | |
1955 | |
1956 // Dump heap - Returns 0 if succeeds. | |
1957 JVM_ENTRY(jint, jmm_DumpHeap0(JNIEnv *env, jstring outputfile, jboolean live)) | |
1958 #ifndef SERVICES_KERNEL | |
1959 ResourceMark rm(THREAD); | |
1960 oop on = JNIHandles::resolve_external_guard(outputfile); | |
1961 if (on == NULL) { | |
1962 THROW_MSG_(vmSymbols::java_lang_NullPointerException(), | |
1963 "Output file name cannot be null.", -1); | |
1964 } | |
1965 char* name = java_lang_String::as_utf8_string(on); | |
1966 if (name == NULL) { | |
1967 THROW_MSG_(vmSymbols::java_lang_NullPointerException(), | |
1968 "Output file name cannot be null.", -1); | |
1969 } | |
1970 HeapDumper dumper(live ? true : false); | |
1971 if (dumper.dump(name) != 0) { | |
1972 const char* errmsg = dumper.error_as_C_string(); | |
1973 THROW_MSG_(vmSymbols::java_io_IOException(), errmsg, -1); | |
1974 } | |
1975 return 0; | |
1976 #else // SERVICES_KERNEL | |
1977 return -1; | |
1978 #endif // SERVICES_KERNEL | |
1979 JVM_END | |
1980 | |
1981 jlong Management::ticks_to_ms(jlong ticks) { | |
1982 assert(os::elapsed_frequency() > 0, "Must be non-zero"); | |
1983 return (jlong)(((double)ticks / (double)os::elapsed_frequency()) | |
1984 * (double)1000.0); | |
1985 } | |
1986 | |
1987 const struct jmmInterface_1_ jmm_interface = { | |
1988 NULL, | |
1989 NULL, | |
1990 jmm_GetVersion, | |
1991 jmm_GetOptionalSupport, | |
1992 jmm_GetInputArguments, | |
1993 jmm_GetThreadInfo, | |
1994 jmm_GetInputArgumentArray, | |
1995 jmm_GetMemoryPools, | |
1996 jmm_GetMemoryManagers, | |
1997 jmm_GetMemoryPoolUsage, | |
1998 jmm_GetPeakMemoryPoolUsage, | |
1999 NULL, | |
2000 jmm_GetMemoryUsage, | |
2001 jmm_GetLongAttribute, | |
2002 jmm_GetBoolAttribute, | |
2003 jmm_SetBoolAttribute, | |
2004 jmm_GetLongAttributes, | |
2005 jmm_FindMonitorDeadlockedThreads, | |
2006 jmm_GetThreadCpuTime, | |
2007 jmm_GetVMGlobalNames, | |
2008 jmm_GetVMGlobals, | |
2009 jmm_GetInternalThreadTimes, | |
2010 jmm_ResetStatistic, | |
2011 jmm_SetPoolSensor, | |
2012 jmm_SetPoolThreshold, | |
2013 jmm_GetPoolCollectionUsage, | |
2014 jmm_GetGCExtAttributeInfo, | |
2015 jmm_GetLastGCStat, | |
2016 jmm_GetThreadCpuTimeWithKind, | |
2017 NULL, | |
2018 jmm_DumpHeap0, | |
2019 jmm_FindDeadlockedThreads, | |
2020 jmm_SetVMGlobal, | |
2021 NULL, | |
2022 jmm_DumpThreads | |
2023 }; | |
2024 | |
2025 void* Management::get_jmm_interface(int version) { | |
2026 if (version == JMM_VERSION_1_0) { | |
2027 return (void*) &jmm_interface; | |
2028 } | |
2029 return NULL; | |
2030 } |