Mercurial > hg > truffle
annotate src/share/vm/services/threadService.hpp @ 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 | c18cbe5936b8 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
948
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:
948
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
948
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:
948
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 class OopClosure; | |
26 class ThreadDumpResult; | |
27 class ThreadStackTrace; | |
28 class ThreadSnapshot; | |
29 class StackFrameInfo; | |
30 class ThreadConcurrentLocks; | |
31 class DeadlockCycle; | |
32 | |
33 // VM monitoring and management support for the thread and | |
34 // synchronization subsystem | |
35 // | |
36 // Thread contention monitoring is disabled by default. | |
37 // When enabled, the VM will begin measuring the accumulated | |
38 // elapsed time a thread blocked on synchronization. | |
39 // | |
40 class ThreadService : public AllStatic { | |
41 private: | |
42 // These counters could be moved to Threads class | |
43 static PerfCounter* _total_threads_count; | |
44 static PerfVariable* _live_threads_count; | |
45 static PerfVariable* _peak_threads_count; | |
46 static PerfVariable* _daemon_threads_count; | |
47 | |
48 // These 2 counters are atomically incremented once the thread is exiting. | |
49 // They will be atomically decremented when ThreadService::remove_thread is called. | |
50 static volatile int _exiting_threads_count; | |
51 static volatile int _exiting_daemon_threads_count; | |
52 | |
53 static bool _thread_monitoring_contention_enabled; | |
54 static bool _thread_cpu_time_enabled; | |
55 | |
56 // Need to keep the list of thread dump result that | |
57 // keep references to methodOop since thread dump can be | |
58 // requested by multiple threads concurrently. | |
59 static ThreadDumpResult* _threaddump_list; | |
60 | |
61 public: | |
62 static void init(); | |
63 static void add_thread(JavaThread* thread, bool daemon); | |
64 static void remove_thread(JavaThread* thread, bool daemon); | |
65 static void current_thread_exiting(JavaThread* jt); | |
66 | |
67 static bool set_thread_monitoring_contention(bool flag); | |
68 static bool is_thread_monitoring_contention() { return _thread_monitoring_contention_enabled; } | |
69 | |
70 static bool set_thread_cpu_time_enabled(bool flag); | |
71 static bool is_thread_cpu_time_enabled() { return _thread_cpu_time_enabled; } | |
72 | |
73 static jlong get_total_thread_count() { return _total_threads_count->get_value(); } | |
74 static jlong get_peak_thread_count() { return _peak_threads_count->get_value(); } | |
75 static jlong get_live_thread_count() { return _live_threads_count->get_value() - _exiting_threads_count; } | |
76 static jlong get_daemon_thread_count() { return _daemon_threads_count->get_value() - _exiting_daemon_threads_count; } | |
77 | |
78 static int exiting_threads_count() { return _exiting_threads_count; } | |
79 static int exiting_daemon_threads_count() { return _exiting_daemon_threads_count; } | |
80 | |
81 // Support for thread dump | |
82 static void add_thread_dump(ThreadDumpResult* dump); | |
83 static void remove_thread_dump(ThreadDumpResult* dump); | |
84 | |
85 static Handle get_current_contended_monitor(JavaThread* thread); | |
86 | |
87 // This function is called by JVM_DumpThreads. | |
88 static Handle dump_stack_traces(GrowableArray<instanceHandle>* threads, | |
89 int num_threads, TRAPS); | |
90 | |
91 static void reset_peak_thread_count(); | |
92 static void reset_contention_count_stat(JavaThread* thread); | |
93 static void reset_contention_time_stat(JavaThread* thread); | |
94 | |
95 static DeadlockCycle* find_deadlocks_at_safepoint(bool object_monitors_only); | |
96 | |
97 // GC support | |
98 static void oops_do(OopClosure* f); | |
99 }; | |
100 | |
101 // Per-thread Statistics for synchronization | |
102 class ThreadStatistics : public CHeapObj { | |
103 private: | |
104 // The following contention statistics are only updated by | |
105 // the thread owning these statistics when contention occurs. | |
106 | |
107 jlong _contended_enter_count; | |
108 elapsedTimer _contended_enter_timer; | |
109 jlong _monitor_wait_count; | |
110 elapsedTimer _monitor_wait_timer; | |
111 jlong _sleep_count; | |
112 elapsedTimer _sleep_timer; | |
113 | |
114 | |
115 // These two reset flags are set to true when another thread | |
116 // requests to reset the statistics. The actual statistics | |
117 // are reset when the thread contention occurs and attempts | |
118 // to update the statistics. | |
119 bool _count_pending_reset; | |
120 bool _timer_pending_reset; | |
121 | |
122 // Keep accurate times for potentially recursive class operations | |
875
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
470
diff
changeset
|
123 int _perf_recursion_counts[6]; |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
470
diff
changeset
|
124 elapsedTimer _perf_timers[6]; |
0 | 125 |
126 // utility functions | |
127 void check_and_reset_count() { | |
128 if (!_count_pending_reset) return; | |
129 _contended_enter_count = 0; | |
130 _monitor_wait_count = 0; | |
131 _sleep_count = 0; | |
132 _count_pending_reset = 0; | |
133 } | |
134 void check_and_reset_timer() { | |
135 if (!_timer_pending_reset) return; | |
136 _contended_enter_timer.reset(); | |
137 _monitor_wait_timer.reset(); | |
138 _sleep_timer.reset(); | |
139 _timer_pending_reset = 0; | |
140 } | |
141 | |
142 public: | |
143 ThreadStatistics(); | |
144 | |
145 jlong contended_enter_count() { return (_count_pending_reset ? 0 : _contended_enter_count); } | |
146 jlong contended_enter_ticks() { return (_timer_pending_reset ? 0 : _contended_enter_timer.active_ticks()); } | |
147 jlong monitor_wait_count() { return (_count_pending_reset ? 0 : _monitor_wait_count); } | |
148 jlong monitor_wait_ticks() { return (_timer_pending_reset ? 0 : _monitor_wait_timer.active_ticks()); } | |
149 jlong sleep_count() { return (_count_pending_reset ? 0 : _sleep_count); } | |
150 jlong sleep_ticks() { return (_timer_pending_reset ? 0 : _sleep_timer.active_ticks()); } | |
151 | |
152 void monitor_wait() { check_and_reset_count(); _monitor_wait_count++; } | |
153 void monitor_wait_begin() { check_and_reset_timer(); _monitor_wait_timer.start(); } | |
154 void monitor_wait_end() { _monitor_wait_timer.stop(); check_and_reset_timer(); } | |
155 | |
156 void thread_sleep() { check_and_reset_count(); _sleep_count++; } | |
157 void thread_sleep_begin() { check_and_reset_timer(); _sleep_timer.start(); } | |
158 void thread_sleep_end() { _sleep_timer.stop(); check_and_reset_timer(); } | |
159 | |
160 void contended_enter() { check_and_reset_count(); _contended_enter_count++; } | |
161 void contended_enter_begin() { check_and_reset_timer(); _contended_enter_timer.start(); } | |
162 void contended_enter_end() { _contended_enter_timer.stop(); check_and_reset_timer(); } | |
163 | |
164 void reset_count_stat() { _count_pending_reset = true; } | |
165 void reset_time_stat() { _timer_pending_reset = true; } | |
166 | |
875
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
470
diff
changeset
|
167 int* perf_recursion_counts_addr() { return _perf_recursion_counts; } |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
470
diff
changeset
|
168 elapsedTimer* perf_timers_addr() { return _perf_timers; } |
0 | 169 }; |
170 | |
171 // Thread snapshot to represent the thread state and statistics | |
172 class ThreadSnapshot : public CHeapObj { | |
173 private: | |
174 JavaThread* _thread; | |
175 oop _threadObj; | |
176 java_lang_Thread::ThreadStatus _thread_status; | |
177 | |
178 bool _is_ext_suspended; | |
179 bool _is_in_native; | |
180 | |
181 jlong _contended_enter_ticks; | |
182 jlong _contended_enter_count; | |
183 jlong _monitor_wait_ticks; | |
184 jlong _monitor_wait_count; | |
185 jlong _sleep_ticks; | |
186 jlong _sleep_count; | |
187 oop _blocker_object; | |
188 oop _blocker_object_owner; | |
189 | |
190 ThreadStackTrace* _stack_trace; | |
191 ThreadConcurrentLocks* _concurrent_locks; | |
192 ThreadSnapshot* _next; | |
193 | |
194 public: | |
195 // Dummy snapshot | |
196 ThreadSnapshot() : _thread(NULL), _threadObj(NULL), _stack_trace(NULL), _concurrent_locks(NULL), _next(NULL), | |
197 _blocker_object(NULL), _blocker_object_owner(NULL) {}; | |
198 ThreadSnapshot(JavaThread* thread); | |
199 ~ThreadSnapshot(); | |
200 | |
201 java_lang_Thread::ThreadStatus thread_status() { return _thread_status; } | |
202 | |
203 oop threadObj() const { return _threadObj; } | |
204 | |
205 void set_next(ThreadSnapshot* n) { _next = n; } | |
206 | |
207 bool is_ext_suspended() { return _is_ext_suspended; } | |
208 bool is_in_native() { return _is_in_native; } | |
209 | |
210 jlong contended_enter_count() { return _contended_enter_count; } | |
211 jlong contended_enter_ticks() { return _contended_enter_ticks; } | |
212 jlong monitor_wait_count() { return _monitor_wait_count; } | |
213 jlong monitor_wait_ticks() { return _monitor_wait_ticks; } | |
214 jlong sleep_count() { return _sleep_count; } | |
215 jlong sleep_ticks() { return _sleep_ticks; } | |
216 | |
217 | |
218 oop blocker_object() { return _blocker_object; } | |
219 oop blocker_object_owner() { return _blocker_object_owner; } | |
220 | |
221 ThreadSnapshot* next() const { return _next; } | |
222 ThreadStackTrace* get_stack_trace() { return _stack_trace; } | |
223 ThreadConcurrentLocks* get_concurrent_locks() { return _concurrent_locks; } | |
224 | |
225 void dump_stack_at_safepoint(int max_depth, bool with_locked_monitors); | |
226 void set_concurrent_locks(ThreadConcurrentLocks* l) { _concurrent_locks = l; } | |
227 void oops_do(OopClosure* f); | |
228 }; | |
229 | |
230 class ThreadStackTrace : public CHeapObj { | |
231 private: | |
232 JavaThread* _thread; | |
233 int _depth; // number of stack frames added | |
234 bool _with_locked_monitors; | |
235 GrowableArray<StackFrameInfo*>* _frames; | |
236 GrowableArray<oop>* _jni_locked_monitors; | |
237 | |
238 public: | |
239 | |
240 ThreadStackTrace(JavaThread* thread, bool with_locked_monitors); | |
241 ~ThreadStackTrace(); | |
242 | |
396
4d05b7cb7842
6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents:
0
diff
changeset
|
243 JavaThread* thread() { return _thread; } |
0 | 244 StackFrameInfo* stack_frame_at(int i) { return _frames->at(i); } |
245 int get_stack_depth() { return _depth; } | |
246 | |
247 void add_stack_frame(javaVFrame* jvf); | |
248 void dump_stack_at_safepoint(int max_depth); | |
249 Handle allocate_fill_stack_trace_element_array(TRAPS); | |
250 void oops_do(OopClosure* f); | |
251 GrowableArray<oop>* jni_locked_monitors() { return _jni_locked_monitors; } | |
252 int num_jni_locked_monitors() { return (_jni_locked_monitors != NULL ? _jni_locked_monitors->length() : 0); } | |
253 | |
254 bool is_owned_monitor_on_stack(oop object); | |
255 void add_jni_locked_monitor(oop object) { _jni_locked_monitors->append(object); } | |
256 }; | |
257 | |
258 // StackFrameInfo for keeping methodOop and bci during | |
259 // stack walking for later construction of StackTraceElement[] | |
260 // Java instances | |
261 class StackFrameInfo : public CHeapObj { | |
262 private: | |
263 methodOop _method; | |
264 int _bci; | |
265 GrowableArray<oop>* _locked_monitors; // list of object monitors locked by this frame | |
266 | |
267 public: | |
268 | |
269 StackFrameInfo(javaVFrame* jvf, bool with_locked_monitors); | |
270 ~StackFrameInfo() { | |
271 if (_locked_monitors != NULL) { | |
272 delete _locked_monitors; | |
273 } | |
274 }; | |
275 methodOop method() const { return _method; } | |
276 int bci() const { return _bci; } | |
277 void oops_do(OopClosure* f); | |
278 | |
279 int num_locked_monitors() { return (_locked_monitors != NULL ? _locked_monitors->length() : 0); } | |
280 GrowableArray<oop>* locked_monitors() { return _locked_monitors; } | |
281 | |
282 void print_on(outputStream* st) const; | |
283 }; | |
284 | |
285 class ThreadConcurrentLocks : public CHeapObj { | |
286 private: | |
287 GrowableArray<instanceOop>* _owned_locks; | |
288 ThreadConcurrentLocks* _next; | |
289 JavaThread* _thread; | |
290 public: | |
291 ThreadConcurrentLocks(JavaThread* thread); | |
292 ~ThreadConcurrentLocks(); | |
293 | |
294 void add_lock(instanceOop o); | |
295 void set_next(ThreadConcurrentLocks* n) { _next = n; } | |
296 ThreadConcurrentLocks* next() { return _next; } | |
297 JavaThread* java_thread() { return _thread; } | |
298 GrowableArray<instanceOop>* owned_locks() { return _owned_locks; } | |
299 void oops_do(OopClosure* f); | |
300 }; | |
301 | |
302 class ConcurrentLocksDump : public StackObj { | |
303 private: | |
304 ThreadConcurrentLocks* _map; | |
305 ThreadConcurrentLocks* _last; // Last ThreadConcurrentLocks in the map | |
306 bool _retain_map_on_free; | |
307 | |
308 void build_map(GrowableArray<oop>* aos_objects); | |
309 void add_lock(JavaThread* thread, instanceOop o); | |
310 | |
311 public: | |
312 ConcurrentLocksDump(bool retain_map_on_free) : _map(NULL), _last(NULL), _retain_map_on_free(retain_map_on_free) {}; | |
313 ConcurrentLocksDump() : _map(NULL), _last(NULL), _retain_map_on_free(false) {}; | |
314 ~ConcurrentLocksDump(); | |
315 | |
316 void dump_at_safepoint(); | |
317 ThreadConcurrentLocks* thread_concurrent_locks(JavaThread* thread); | |
318 void print_locks_on(JavaThread* t, outputStream* st); | |
319 }; | |
320 | |
321 class ThreadDumpResult : public StackObj { | |
322 private: | |
323 int _num_threads; | |
324 int _num_snapshots; | |
325 ThreadSnapshot* _snapshots; | |
326 ThreadSnapshot* _last; | |
327 ThreadDumpResult* _next; | |
328 public: | |
329 ThreadDumpResult(); | |
330 ThreadDumpResult(int num_threads); | |
331 ~ThreadDumpResult(); | |
332 | |
333 void add_thread_snapshot(ThreadSnapshot* ts); | |
334 void set_next(ThreadDumpResult* next) { _next = next; } | |
335 ThreadDumpResult* next() { return _next; } | |
336 int num_threads() { return _num_threads; } | |
337 int num_snapshots() { return _num_snapshots; } | |
338 ThreadSnapshot* snapshots() { return _snapshots; } | |
339 void oops_do(OopClosure* f); | |
340 }; | |
341 | |
342 class DeadlockCycle : public CHeapObj { | |
343 private: | |
344 bool _is_deadlock; | |
345 GrowableArray<JavaThread*>* _threads; | |
346 DeadlockCycle* _next; | |
347 public: | |
348 DeadlockCycle(); | |
349 ~DeadlockCycle(); | |
350 | |
351 DeadlockCycle* next() { return _next; } | |
352 void set_next(DeadlockCycle* d) { _next = d; } | |
353 void add_thread(JavaThread* t) { _threads->append(t); } | |
354 void reset() { _is_deadlock = false; _threads->clear(); } | |
355 void set_deadlock(bool value) { _is_deadlock = value; } | |
356 bool is_deadlock() { return _is_deadlock; } | |
357 int num_threads() { return _threads->length(); } | |
358 GrowableArray<JavaThread*>* threads() { return _threads; } | |
359 void print_on(outputStream* st) const; | |
360 }; | |
361 | |
362 // Utility class to get list of java threads. | |
363 class ThreadsListEnumerator : public StackObj { | |
364 private: | |
365 GrowableArray<instanceHandle>* _threads_array; | |
366 public: | |
367 ThreadsListEnumerator(Thread* cur_thread, | |
368 bool include_jvmti_agent_threads = false, | |
369 bool include_jni_attaching_threads = true); | |
370 int num_threads() { return _threads_array->length(); } | |
371 instanceHandle get_threadObj(int index) { return _threads_array->at(index); } | |
372 }; | |
373 | |
374 | |
375 // abstract utility class to set new thread states, and restore previous after the block exits | |
376 class JavaThreadStatusChanger : public StackObj { | |
377 private: | |
378 java_lang_Thread::ThreadStatus _old_state; | |
379 JavaThread* _java_thread; | |
380 bool _is_alive; | |
381 | |
382 void save_old_state(JavaThread* java_thread) { | |
383 _java_thread = java_thread; | |
384 _is_alive = is_alive(java_thread); | |
385 if (is_alive()) { | |
386 _old_state = java_lang_Thread::get_thread_status(_java_thread->threadObj()); | |
387 } | |
388 } | |
389 | |
390 public: | |
391 static void set_thread_status(JavaThread* java_thread, | |
392 java_lang_Thread::ThreadStatus state) { | |
393 java_lang_Thread::set_thread_status(java_thread->threadObj(), state); | |
394 } | |
395 | |
396 void set_thread_status(java_lang_Thread::ThreadStatus state) { | |
397 if (is_alive()) { | |
398 set_thread_status(_java_thread, state); | |
399 } | |
400 } | |
401 | |
402 JavaThreadStatusChanger(JavaThread* java_thread, | |
403 java_lang_Thread::ThreadStatus state) { | |
404 save_old_state(java_thread); | |
405 set_thread_status(state); | |
406 } | |
407 | |
408 JavaThreadStatusChanger(JavaThread* java_thread) { | |
409 save_old_state(java_thread); | |
410 } | |
411 | |
412 ~JavaThreadStatusChanger() { | |
413 set_thread_status(_old_state); | |
414 } | |
415 | |
416 static bool is_alive(JavaThread* java_thread) { | |
417 return java_thread != NULL && java_thread->threadObj() != NULL; | |
418 } | |
419 | |
420 bool is_alive() { | |
421 return _is_alive; | |
422 } | |
423 }; | |
424 | |
425 // Change status to waiting on an object (timed or indefinite) | |
426 class JavaThreadInObjectWaitState : public JavaThreadStatusChanger { | |
427 private: | |
428 ThreadStatistics* _stat; | |
429 bool _active; | |
430 | |
431 public: | |
432 JavaThreadInObjectWaitState(JavaThread *java_thread, bool timed) : | |
433 JavaThreadStatusChanger(java_thread, | |
434 timed ? java_lang_Thread::IN_OBJECT_WAIT_TIMED : java_lang_Thread::IN_OBJECT_WAIT) { | |
435 if (is_alive()) { | |
436 _stat = java_thread->get_thread_stat(); | |
437 _active = ThreadService::is_thread_monitoring_contention(); | |
438 _stat->monitor_wait(); | |
439 if (_active) { | |
440 _stat->monitor_wait_begin(); | |
441 } | |
442 } else { | |
443 _active = false; | |
444 } | |
445 } | |
446 | |
447 ~JavaThreadInObjectWaitState() { | |
448 if (_active) { | |
449 _stat->monitor_wait_end(); | |
450 } | |
451 } | |
452 }; | |
453 | |
454 // Change status to parked (timed or indefinite) | |
455 class JavaThreadParkedState : public JavaThreadStatusChanger { | |
456 private: | |
457 ThreadStatistics* _stat; | |
458 bool _active; | |
459 | |
460 public: | |
461 JavaThreadParkedState(JavaThread *java_thread, bool timed) : | |
462 JavaThreadStatusChanger(java_thread, | |
463 timed ? java_lang_Thread::PARKED_TIMED : java_lang_Thread::PARKED) { | |
464 if (is_alive()) { | |
465 _stat = java_thread->get_thread_stat(); | |
466 _active = ThreadService::is_thread_monitoring_contention(); | |
467 _stat->monitor_wait(); | |
468 if (_active) { | |
469 _stat->monitor_wait_begin(); | |
470 } | |
471 } else { | |
472 _active = false; | |
473 } | |
474 } | |
475 | |
476 ~JavaThreadParkedState() { | |
477 if (_active) { | |
478 _stat->monitor_wait_end(); | |
479 } | |
480 } | |
481 }; | |
482 | |
483 // Change status to blocked on (re-)entering a synchronization block | |
484 class JavaThreadBlockedOnMonitorEnterState : public JavaThreadStatusChanger { | |
485 private: | |
486 ThreadStatistics* _stat; | |
487 bool _active; | |
488 | |
489 static bool contended_enter_begin(JavaThread *java_thread) { | |
490 set_thread_status(java_thread, java_lang_Thread::BLOCKED_ON_MONITOR_ENTER); | |
491 ThreadStatistics* stat = java_thread->get_thread_stat(); | |
492 stat->contended_enter(); | |
493 bool active = ThreadService::is_thread_monitoring_contention(); | |
494 if (active) { | |
495 stat->contended_enter_begin(); | |
496 } | |
497 return active; | |
498 } | |
499 | |
500 public: | |
501 // java_thread is waiting thread being blocked on monitor reenter. | |
502 // Current thread is the notifying thread which holds the monitor. | |
503 static bool wait_reenter_begin(JavaThread *java_thread, ObjectMonitor *obj_m) { | |
504 assert((java_thread != NULL), "Java thread should not be null here"); | |
505 bool active = false; | |
506 if (is_alive(java_thread) && ServiceUtil::visible_oop((oop)obj_m->object())) { | |
507 active = contended_enter_begin(java_thread); | |
508 } | |
509 return active; | |
510 } | |
511 | |
512 static void wait_reenter_end(JavaThread *java_thread, bool active) { | |
513 if (active) { | |
514 java_thread->get_thread_stat()->contended_enter_end(); | |
515 } | |
516 set_thread_status(java_thread, java_lang_Thread::RUNNABLE); | |
517 } | |
518 | |
519 JavaThreadBlockedOnMonitorEnterState(JavaThread *java_thread, ObjectMonitor *obj_m) : | |
520 JavaThreadStatusChanger(java_thread) { | |
521 assert((java_thread != NULL), "Java thread should not be null here"); | |
522 // Change thread status and collect contended enter stats for monitor contended | |
523 // enter done for external java world objects and it is contended. All other cases | |
524 // like for vm internal objects and for external objects which are not contended | |
525 // thread status is not changed and contended enter stat is not collected. | |
526 _active = false; | |
527 if (is_alive() && ServiceUtil::visible_oop((oop)obj_m->object()) && obj_m->contentions() > 0) { | |
528 _stat = java_thread->get_thread_stat(); | |
529 _active = contended_enter_begin(java_thread); | |
530 } | |
531 } | |
532 | |
533 ~JavaThreadBlockedOnMonitorEnterState() { | |
534 if (_active) { | |
535 _stat->contended_enter_end(); | |
536 } | |
537 } | |
538 }; | |
539 | |
540 // Change status to sleeping | |
541 class JavaThreadSleepState : public JavaThreadStatusChanger { | |
542 private: | |
543 ThreadStatistics* _stat; | |
544 bool _active; | |
545 public: | |
546 JavaThreadSleepState(JavaThread *java_thread) : | |
547 JavaThreadStatusChanger(java_thread, java_lang_Thread::SLEEPING) { | |
548 if (is_alive()) { | |
549 _stat = java_thread->get_thread_stat(); | |
550 _active = ThreadService::is_thread_monitoring_contention(); | |
551 _stat->thread_sleep(); | |
552 if (_active) { | |
553 _stat->thread_sleep_begin(); | |
554 } | |
555 } else { | |
556 _active = false; | |
557 } | |
558 } | |
559 | |
560 ~JavaThreadSleepState() { | |
561 if (_active) { | |
562 _stat->thread_sleep_end(); | |
563 } | |
564 } | |
565 }; |