1 /*
2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
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 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_VM_SERVICES_THREADSERVICE_HPP
26 #define SHARE_VM_SERVICES_THREADSERVICE_HPP
27
28 #include "classfile/javaClasses.hpp"
29 #include "runtime/handles.hpp"
30 #include "runtime/init.hpp"
31 #include "runtime/jniHandles.hpp"
32 #include "runtime/objectMonitor.hpp"
33 #include "runtime/objectMonitor.inline.hpp"
34 #include "runtime/perfData.hpp"
35 #include "services/management.hpp"
36 #include "services/serviceUtil.hpp"
37
38 class OopClosure;
39 class ThreadDumpResult;
40 class ThreadStackTrace;
41 class ThreadSnapshot;
42 class StackFrameInfo;
43 class ThreadConcurrentLocks;
44 class DeadlockCycle;
45
46 // VM monitoring and management support for the thread and
47 // synchronization subsystem
48 //
49 // Thread contention monitoring is disabled by default.
50 // When enabled, the VM will begin measuring the accumulated
51 // elapsed time a thread blocked on synchronization.
52 //
53 class ThreadService : public AllStatic {
54 private:
92 static jlong get_live_thread_count() { return _live_threads_count->get_value() - _exiting_threads_count; }
93 static jlong get_daemon_thread_count() { return _daemon_threads_count->get_value() - _exiting_daemon_threads_count; }
94
95 static int exiting_threads_count() { return _exiting_threads_count; }
96 static int exiting_daemon_threads_count() { return _exiting_daemon_threads_count; }
97
98 // Support for thread dump
99 static void add_thread_dump(ThreadDumpResult* dump);
100 static void remove_thread_dump(ThreadDumpResult* dump);
101
102 static Handle get_current_contended_monitor(JavaThread* thread);
103
104 // This function is called by JVM_DumpThreads.
105 static Handle dump_stack_traces(GrowableArray<instanceHandle>* threads,
106 int num_threads, TRAPS);
107
108 static void reset_peak_thread_count();
109 static void reset_contention_count_stat(JavaThread* thread);
110 static void reset_contention_time_stat(JavaThread* thread);
111
112 static DeadlockCycle* find_deadlocks_at_safepoint(bool object_monitors_only);
113
114 // GC support
115 static void oops_do(OopClosure* f);
116 static void metadata_do(void f(Metadata*));
117 };
118
119 // Per-thread Statistics for synchronization
120 class ThreadStatistics : public CHeapObj<mtInternal> {
121 private:
122 // The following contention statistics are only updated by
123 // the thread owning these statistics when contention occurs.
124
125 jlong _contended_enter_count;
126 elapsedTimer _contended_enter_timer;
127 jlong _monitor_wait_count;
128 elapsedTimer _monitor_wait_timer;
129 jlong _sleep_count;
130 elapsedTimer _sleep_timer;
131
132
172 void monitor_wait_end() { _monitor_wait_timer.stop(); check_and_reset_timer(); }
173
174 void thread_sleep() { check_and_reset_count(); _sleep_count++; }
175 void thread_sleep_begin() { check_and_reset_timer(); _sleep_timer.start(); }
176 void thread_sleep_end() { _sleep_timer.stop(); check_and_reset_timer(); }
177
178 void contended_enter() { check_and_reset_count(); _contended_enter_count++; }
179 void contended_enter_begin() { check_and_reset_timer(); _contended_enter_timer.start(); }
180 void contended_enter_end() { _contended_enter_timer.stop(); check_and_reset_timer(); }
181
182 void reset_count_stat() { _count_pending_reset = true; }
183 void reset_time_stat() { _timer_pending_reset = true; }
184
185 int* perf_recursion_counts_addr() { return _perf_recursion_counts; }
186 elapsedTimer* perf_timers_addr() { return _perf_timers; }
187 };
188
189 // Thread snapshot to represent the thread state and statistics
190 class ThreadSnapshot : public CHeapObj<mtInternal> {
191 private:
192 JavaThread* _thread;
193 oop _threadObj;
194 java_lang_Thread::ThreadStatus _thread_status;
195
196 bool _is_ext_suspended;
197 bool _is_in_native;
198
199 jlong _contended_enter_ticks;
200 jlong _contended_enter_count;
201 jlong _monitor_wait_ticks;
202 jlong _monitor_wait_count;
203 jlong _sleep_ticks;
204 jlong _sleep_count;
205 oop _blocker_object;
206 oop _blocker_object_owner;
207
208 ThreadStackTrace* _stack_trace;
209 ThreadConcurrentLocks* _concurrent_locks;
210 ThreadSnapshot* _next;
211
212 public:
213 // Dummy snapshot
214 ThreadSnapshot() : _thread(NULL), _threadObj(NULL), _stack_trace(NULL), _concurrent_locks(NULL), _next(NULL),
215 _blocker_object(NULL), _blocker_object_owner(NULL) {};
216 ThreadSnapshot(JavaThread* thread);
217 ~ThreadSnapshot();
218
219 java_lang_Thread::ThreadStatus thread_status() { return _thread_status; }
220
221 oop threadObj() const { return _threadObj; }
222
223 void set_next(ThreadSnapshot* n) { _next = n; }
224
225 bool is_ext_suspended() { return _is_ext_suspended; }
226 bool is_in_native() { return _is_in_native; }
227
228 jlong contended_enter_count() { return _contended_enter_count; }
229 jlong contended_enter_ticks() { return _contended_enter_ticks; }
230 jlong monitor_wait_count() { return _monitor_wait_count; }
231 jlong monitor_wait_ticks() { return _monitor_wait_ticks; }
232 jlong sleep_count() { return _sleep_count; }
233 jlong sleep_ticks() { return _sleep_ticks; }
234
235
236 oop blocker_object() { return _blocker_object; }
293 ~StackFrameInfo() {
294 if (_locked_monitors != NULL) {
295 delete _locked_monitors;
296 }
297 };
298 Method* method() const { return _method; }
299 int bci() const { return _bci; }
300 void oops_do(OopClosure* f);
301 void metadata_do(void f(Metadata*));
302
303 int num_locked_monitors() { return (_locked_monitors != NULL ? _locked_monitors->length() : 0); }
304 GrowableArray<oop>* locked_monitors() { return _locked_monitors; }
305
306 void print_on(outputStream* st) const;
307 };
308
309 class ThreadConcurrentLocks : public CHeapObj<mtInternal> {
310 private:
311 GrowableArray<instanceOop>* _owned_locks;
312 ThreadConcurrentLocks* _next;
313 JavaThread* _thread;
314 public:
315 ThreadConcurrentLocks(JavaThread* thread);
316 ~ThreadConcurrentLocks();
317
318 void add_lock(instanceOop o);
319 void set_next(ThreadConcurrentLocks* n) { _next = n; }
320 ThreadConcurrentLocks* next() { return _next; }
321 JavaThread* java_thread() { return _thread; }
322 GrowableArray<instanceOop>* owned_locks() { return _owned_locks; }
323 void oops_do(OopClosure* f);
324 };
325
326 class ConcurrentLocksDump : public StackObj {
327 private:
328 ThreadConcurrentLocks* _map;
329 ThreadConcurrentLocks* _last; // Last ThreadConcurrentLocks in the map
330 bool _retain_map_on_free;
331
332 void build_map(GrowableArray<oop>* aos_objects);
333 void add_lock(JavaThread* thread, instanceOop o);
334
335 public:
336 ConcurrentLocksDump(bool retain_map_on_free) : _map(NULL), _last(NULL), _retain_map_on_free(retain_map_on_free) {};
337 ConcurrentLocksDump() : _map(NULL), _last(NULL), _retain_map_on_free(false) {};
338 ~ConcurrentLocksDump();
339
340 void dump_at_safepoint();
341 ThreadConcurrentLocks* thread_concurrent_locks(JavaThread* thread);
342 void print_locks_on(JavaThread* t, outputStream* st);
343 };
344
345 class ThreadDumpResult : public StackObj {
346 private:
347 int _num_threads;
348 int _num_snapshots;
349 ThreadSnapshot* _snapshots;
350 ThreadSnapshot* _last;
351 ThreadDumpResult* _next;
352 public:
353 ThreadDumpResult();
354 ThreadDumpResult(int num_threads);
355 ~ThreadDumpResult();
356
357 void add_thread_snapshot(ThreadSnapshot* ts);
358 void set_next(ThreadDumpResult* next) { _next = next; }
359 ThreadDumpResult* next() { return _next; }
360 int num_threads() { return _num_threads; }
361 int num_snapshots() { return _num_snapshots; }
362 ThreadSnapshot* snapshots() { return _snapshots; }
363 void oops_do(OopClosure* f);
364 void metadata_do(void f(Metadata*));
365 };
366
367 class DeadlockCycle : public CHeapObj<mtInternal> {
368 private:
369 bool _is_deadlock;
370 GrowableArray<JavaThread*>* _threads;
371 DeadlockCycle* _next;
372 public:
373 DeadlockCycle();
374 ~DeadlockCycle();
375
376 DeadlockCycle* next() { return _next; }
377 void set_next(DeadlockCycle* d) { _next = d; }
378 void add_thread(JavaThread* t) { _threads->append(t); }
379 void reset() { _is_deadlock = false; _threads->clear(); }
380 void set_deadlock(bool value) { _is_deadlock = value; }
381 bool is_deadlock() { return _is_deadlock; }
382 int num_threads() { return _threads->length(); }
383 GrowableArray<JavaThread*>* threads() { return _threads; }
384 void print_on(outputStream* st) const;
385 };
386
387 // Utility class to get list of java threads.
388 class ThreadsListEnumerator : public StackObj {
389 private:
390 GrowableArray<instanceHandle>* _threads_array;
391 public:
392 ThreadsListEnumerator(Thread* cur_thread,
393 bool include_jvmti_agent_threads = false,
394 bool include_jni_attaching_threads = true);
395 int num_threads() { return _threads_array->length(); }
396 instanceHandle get_threadObj(int index) { return _threads_array->at(index); }
397 };
398
399
400 // abstract utility class to set new thread states, and restore previous after the block exits
401 class JavaThreadStatusChanger : public StackObj {
402 private:
403 java_lang_Thread::ThreadStatus _old_state;
404 JavaThread* _java_thread;
|
1 /*
2 * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
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 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_VM_SERVICES_THREADSERVICE_HPP
26 #define SHARE_VM_SERVICES_THREADSERVICE_HPP
27
28 #include "classfile/javaClasses.hpp"
29 #include "runtime/handles.hpp"
30 #include "runtime/init.hpp"
31 #include "runtime/jniHandles.hpp"
32 #include "runtime/objectMonitor.hpp"
33 #include "runtime/objectMonitor.inline.hpp"
34 #include "runtime/perfData.hpp"
35 #include "runtime/thread.hpp"
36 #include "services/management.hpp"
37 #include "services/serviceUtil.hpp"
38
39 class OopClosure;
40 class ThreadDumpResult;
41 class ThreadStackTrace;
42 class ThreadSnapshot;
43 class StackFrameInfo;
44 class ThreadConcurrentLocks;
45 class DeadlockCycle;
46
47 // VM monitoring and management support for the thread and
48 // synchronization subsystem
49 //
50 // Thread contention monitoring is disabled by default.
51 // When enabled, the VM will begin measuring the accumulated
52 // elapsed time a thread blocked on synchronization.
53 //
54 class ThreadService : public AllStatic {
55 private:
93 static jlong get_live_thread_count() { return _live_threads_count->get_value() - _exiting_threads_count; }
94 static jlong get_daemon_thread_count() { return _daemon_threads_count->get_value() - _exiting_daemon_threads_count; }
95
96 static int exiting_threads_count() { return _exiting_threads_count; }
97 static int exiting_daemon_threads_count() { return _exiting_daemon_threads_count; }
98
99 // Support for thread dump
100 static void add_thread_dump(ThreadDumpResult* dump);
101 static void remove_thread_dump(ThreadDumpResult* dump);
102
103 static Handle get_current_contended_monitor(JavaThread* thread);
104
105 // This function is called by JVM_DumpThreads.
106 static Handle dump_stack_traces(GrowableArray<instanceHandle>* threads,
107 int num_threads, TRAPS);
108
109 static void reset_peak_thread_count();
110 static void reset_contention_count_stat(JavaThread* thread);
111 static void reset_contention_time_stat(JavaThread* thread);
112
113 static DeadlockCycle* find_deadlocks_at_safepoint(ThreadsList * t_list, bool object_monitors_only);
114
115 // GC support
116 static void oops_do(OopClosure* f);
117 static void metadata_do(void f(Metadata*));
118 };
119
120 // Per-thread Statistics for synchronization
121 class ThreadStatistics : public CHeapObj<mtInternal> {
122 private:
123 // The following contention statistics are only updated by
124 // the thread owning these statistics when contention occurs.
125
126 jlong _contended_enter_count;
127 elapsedTimer _contended_enter_timer;
128 jlong _monitor_wait_count;
129 elapsedTimer _monitor_wait_timer;
130 jlong _sleep_count;
131 elapsedTimer _sleep_timer;
132
133
173 void monitor_wait_end() { _monitor_wait_timer.stop(); check_and_reset_timer(); }
174
175 void thread_sleep() { check_and_reset_count(); _sleep_count++; }
176 void thread_sleep_begin() { check_and_reset_timer(); _sleep_timer.start(); }
177 void thread_sleep_end() { _sleep_timer.stop(); check_and_reset_timer(); }
178
179 void contended_enter() { check_and_reset_count(); _contended_enter_count++; }
180 void contended_enter_begin() { check_and_reset_timer(); _contended_enter_timer.start(); }
181 void contended_enter_end() { _contended_enter_timer.stop(); check_and_reset_timer(); }
182
183 void reset_count_stat() { _count_pending_reset = true; }
184 void reset_time_stat() { _timer_pending_reset = true; }
185
186 int* perf_recursion_counts_addr() { return _perf_recursion_counts; }
187 elapsedTimer* perf_timers_addr() { return _perf_timers; }
188 };
189
190 // Thread snapshot to represent the thread state and statistics
191 class ThreadSnapshot : public CHeapObj<mtInternal> {
192 private:
193 // This JavaThread* is protected by being stored in objects that are
194 // protected by a ThreadsListSetter (ThreadDumpResult).
195 JavaThread* _thread;
196 oop _threadObj;
197 java_lang_Thread::ThreadStatus _thread_status;
198
199 bool _is_ext_suspended;
200 bool _is_in_native;
201
202 jlong _contended_enter_ticks;
203 jlong _contended_enter_count;
204 jlong _monitor_wait_ticks;
205 jlong _monitor_wait_count;
206 jlong _sleep_ticks;
207 jlong _sleep_count;
208 oop _blocker_object;
209 oop _blocker_object_owner;
210
211 ThreadStackTrace* _stack_trace;
212 ThreadConcurrentLocks* _concurrent_locks;
213 ThreadSnapshot* _next;
214
215 public:
216 // Dummy snapshot
217 ThreadSnapshot() : _thread(NULL), _threadObj(NULL), _stack_trace(NULL), _concurrent_locks(NULL), _next(NULL),
218 _blocker_object(NULL), _blocker_object_owner(NULL) {};
219 ThreadSnapshot(ThreadsList * t_list, JavaThread* thread);
220 ~ThreadSnapshot();
221
222 java_lang_Thread::ThreadStatus thread_status() { return _thread_status; }
223
224 oop threadObj() const { return _threadObj; }
225
226 void set_next(ThreadSnapshot* n) { _next = n; }
227
228 bool is_ext_suspended() { return _is_ext_suspended; }
229 bool is_in_native() { return _is_in_native; }
230
231 jlong contended_enter_count() { return _contended_enter_count; }
232 jlong contended_enter_ticks() { return _contended_enter_ticks; }
233 jlong monitor_wait_count() { return _monitor_wait_count; }
234 jlong monitor_wait_ticks() { return _monitor_wait_ticks; }
235 jlong sleep_count() { return _sleep_count; }
236 jlong sleep_ticks() { return _sleep_ticks; }
237
238
239 oop blocker_object() { return _blocker_object; }
296 ~StackFrameInfo() {
297 if (_locked_monitors != NULL) {
298 delete _locked_monitors;
299 }
300 };
301 Method* method() const { return _method; }
302 int bci() const { return _bci; }
303 void oops_do(OopClosure* f);
304 void metadata_do(void f(Metadata*));
305
306 int num_locked_monitors() { return (_locked_monitors != NULL ? _locked_monitors->length() : 0); }
307 GrowableArray<oop>* locked_monitors() { return _locked_monitors; }
308
309 void print_on(outputStream* st) const;
310 };
311
312 class ThreadConcurrentLocks : public CHeapObj<mtInternal> {
313 private:
314 GrowableArray<instanceOop>* _owned_locks;
315 ThreadConcurrentLocks* _next;
316 // This JavaThread* is protected in one of two different ways
317 // depending on the usage of the ThreadConcurrentLocks object:
318 // 1) by being stored in objects that are only allocated and used at a
319 // safepoint (ConcurrentLocksDump), or 2) by being stored in objects
320 // that are protected by a ThreadsListSetter (ThreadSnapshot inside
321 // ThreadDumpResult).
322 JavaThread* _thread;
323 public:
324 ThreadConcurrentLocks(JavaThread* thread);
325 ~ThreadConcurrentLocks();
326
327 void add_lock(instanceOop o);
328 void set_next(ThreadConcurrentLocks* n) { _next = n; }
329 ThreadConcurrentLocks* next() { return _next; }
330 JavaThread* java_thread() { return _thread; }
331 GrowableArray<instanceOop>* owned_locks() { return _owned_locks; }
332 void oops_do(OopClosure* f);
333 };
334
335 class ConcurrentLocksDump : public StackObj {
336 private:
337 ThreadConcurrentLocks* _map;
338 ThreadConcurrentLocks* _last; // Last ThreadConcurrentLocks in the map
339 bool _retain_map_on_free;
340
341 void build_map(GrowableArray<oop>* aos_objects);
342 void add_lock(JavaThread* thread, instanceOop o);
343
344 public:
345 ConcurrentLocksDump(bool retain_map_on_free) : _map(NULL), _last(NULL), _retain_map_on_free(retain_map_on_free) {
346 assert(SafepointSynchronize::is_at_safepoint(), "Must be constructed at a safepoint.");
347 };
348 ConcurrentLocksDump() : _map(NULL), _last(NULL), _retain_map_on_free(false) {
349 assert(SafepointSynchronize::is_at_safepoint(), "Must be constructed at a safepoint.");
350 };
351 ~ConcurrentLocksDump();
352
353 void dump_at_safepoint();
354 ThreadConcurrentLocks* thread_concurrent_locks(JavaThread* thread);
355 void print_locks_on(JavaThread* t, outputStream* st);
356 };
357
358 class ThreadDumpResult : public StackObj {
359 private:
360 int _num_threads;
361 int _num_snapshots;
362 ThreadSnapshot* _snapshots;
363 ThreadSnapshot* _last;
364 ThreadDumpResult* _next;
365 ThreadsListSetter _setter; // Helper to set hazard ptr in the originating thread
366 // which protects the JavaThreads in _snapshots.
367
368 public:
369 ThreadDumpResult();
370 ThreadDumpResult(int num_threads);
371 ~ThreadDumpResult();
372
373 void add_thread_snapshot(ThreadSnapshot* ts);
374 void set_next(ThreadDumpResult* next) { _next = next; }
375 ThreadDumpResult* next() { return _next; }
376 int num_threads() { return _num_threads; }
377 int num_snapshots() { return _num_snapshots; }
378 ThreadSnapshot* snapshots() { return _snapshots; }
379 void set_t_list() { _setter.set(); }
380 ThreadsList* t_list();
381 bool t_list_has_been_set() { return _setter.target_needs_release(); }
382 void oops_do(OopClosure* f);
383 void metadata_do(void f(Metadata*));
384 };
385
386 class DeadlockCycle : public CHeapObj<mtInternal> {
387 private:
388 bool _is_deadlock;
389 GrowableArray<JavaThread*>* _threads;
390 DeadlockCycle* _next;
391 public:
392 DeadlockCycle();
393 ~DeadlockCycle();
394
395 DeadlockCycle* next() { return _next; }
396 void set_next(DeadlockCycle* d) { _next = d; }
397 void add_thread(JavaThread* t) { _threads->append(t); }
398 void reset() { _is_deadlock = false; _threads->clear(); }
399 void set_deadlock(bool value) { _is_deadlock = value; }
400 bool is_deadlock() { return _is_deadlock; }
401 int num_threads() { return _threads->length(); }
402 GrowableArray<JavaThread*>* threads() { return _threads; }
403 void print_on_with(ThreadsList * t_list, outputStream* st) const;
404 };
405
406 // Utility class to get list of java threads.
407 class ThreadsListEnumerator : public StackObj {
408 private:
409 GrowableArray<instanceHandle>* _threads_array;
410 public:
411 ThreadsListEnumerator(Thread* cur_thread,
412 bool include_jvmti_agent_threads = false,
413 bool include_jni_attaching_threads = true);
414 int num_threads() { return _threads_array->length(); }
415 instanceHandle get_threadObj(int index) { return _threads_array->at(index); }
416 };
417
418
419 // abstract utility class to set new thread states, and restore previous after the block exits
420 class JavaThreadStatusChanger : public StackObj {
421 private:
422 java_lang_Thread::ThreadStatus _old_state;
423 JavaThread* _java_thread;
|