1 /*
  2  * Copyright (c) 2003, 2023, 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_SERVICES_THREADSERVICE_HPP
 26 #define SHARE_SERVICES_THREADSERVICE_HPP
 27 
 28 #include "classfile/classLoader.hpp"
 29 #include "classfile/javaClasses.hpp"
 30 #include "classfile/javaThreadStatus.hpp"
 31 #include "runtime/handles.hpp"
 32 #include "runtime/init.hpp"
 33 #include "runtime/javaThread.hpp"
 34 #include "runtime/objectMonitor.hpp"
 35 #include "runtime/perfData.hpp"
 36 #include "runtime/safepoint.hpp"
 37 #include "runtime/threadSMR.hpp"
 38 #include "services/management.hpp"
 39 
 40 class DeadlockCycle;
 41 class ObjectMonitorsHashtable;
 42 class OopClosure;
 43 class StackFrameInfo;
 44 class ThreadConcurrentLocks;
 45 class ThreadDumpResult;
 46 class ThreadSnapshot;
 47 class ThreadStackTrace;
 48 
 49 // VM monitoring and management support for the thread and
 50 // synchronization subsystem
 51 //
 52 // Thread contention monitoring is disabled by default.
 53 // When enabled, the VM will begin measuring the accumulated
 54 // elapsed time a thread blocked on synchronization.
 55 //
 56 class ThreadService : public AllStatic {
 57 private:
 58   // These counters could be moved to Threads class
 59   static PerfCounter*  _total_threads_count;
 60   static PerfVariable* _live_threads_count;
 61   static PerfVariable* _peak_threads_count;
 62   static PerfVariable* _daemon_threads_count;
 63 
 64   // As could this...
 65   // Number of heap bytes allocated by terminated threads.
 66   static volatile jlong _exited_allocated_bytes;
 67 
 68   // These 2 counters are like the above thread counts, but are
 69   // atomically decremented in ThreadService::current_thread_exiting instead of
 70   // ThreadService::remove_thread, so that the thread count is updated before
 71   // Thread.join() returns.
 72   static volatile int  _atomic_threads_count;
 73   static volatile int  _atomic_daemon_threads_count;
 74 
 75   static bool          _thread_monitoring_contention_enabled;
 76   static bool          _thread_cpu_time_enabled;
 77   static bool          _thread_allocated_memory_enabled;
 78 
 79   // Need to keep the list of thread dump result that
 80   // keep references to Method* since thread dump can be
 81   // requested by multiple threads concurrently.
 82   static ThreadDumpResult* _threaddump_list;
 83 
 84   static void decrement_thread_counts(JavaThread* jt, bool daemon);
 85 
 86   // test if the JavaThread is a virtual thread or has a mounted virtual thread
 87   static bool is_virtual_or_carrier_thread(JavaThread* jt);
 88 
 89 public:
 90   static void init();
 91   static void add_thread(JavaThread* thread, bool daemon);
 92   static void remove_thread(JavaThread* thread, bool daemon);
 93   static void current_thread_exiting(JavaThread* jt, bool daemon);
 94 
 95   static bool set_thread_monitoring_contention(bool flag);
 96   static bool is_thread_monitoring_contention() { return _thread_monitoring_contention_enabled; }
 97 
 98   static bool set_thread_cpu_time_enabled(bool flag);
 99   static bool is_thread_cpu_time_enabled()    { return _thread_cpu_time_enabled; }
100 
101   static bool set_thread_allocated_memory_enabled(bool flag);
102   static bool is_thread_allocated_memory_enabled() { return _thread_allocated_memory_enabled; }
103 
104   static jlong get_total_thread_count()       { return _total_threads_count->get_value(); }
105   static jlong get_peak_thread_count()        { return _peak_threads_count->get_value(); }
106   static jlong get_live_thread_count()        { return _atomic_threads_count; }
107   static jlong get_daemon_thread_count()      { return _atomic_daemon_threads_count; }
108 
109   static jlong exited_allocated_bytes()       { return Atomic::load(&_exited_allocated_bytes); }
110   static void incr_exited_allocated_bytes(jlong size) {
111     // No need for an atomic add because called under the Threads_lock,
112     // but because _exited_allocated_bytes is read concurrently, need
113     // atomic store to avoid readers seeing a partial update.
114     Atomic::store(&_exited_allocated_bytes, _exited_allocated_bytes + size);
115   }
116 
117   // Support for thread dump
118   static void   add_thread_dump(ThreadDumpResult* dump);
119   static void   remove_thread_dump(ThreadDumpResult* dump);
120 
121   static Handle get_current_contended_monitor(JavaThread* thread);
122 
123   // This function is called by JVM_DumpThreads.
124   static Handle dump_stack_traces(GrowableArray<instanceHandle>* threads,
125                                   int num_threads, TRAPS);
126 
127   static void   reset_peak_thread_count();
128   static void   reset_contention_count_stat(JavaThread* thread);
129   static void   reset_contention_time_stat(JavaThread* thread);
130 
131   static DeadlockCycle*       find_deadlocks_at_safepoint(ThreadsList * t_list, bool object_monitors_only);
132 
133   static void   metadata_do(void f(Metadata*));
134 };
135 
136 // Per-thread Statistics for synchronization
137 class ThreadStatistics : public CHeapObj<mtInternal> {
138 private:
139   // The following contention statistics are only updated by
140   // the thread owning these statistics when contention occurs.
141 
142   jlong        _contended_enter_count;
143   elapsedTimer _contended_enter_timer;
144   jlong        _monitor_wait_count;
145   elapsedTimer _monitor_wait_timer;
146   jlong        _sleep_count;
147   elapsedTimer _sleep_timer;
148 
149 
150   // These two reset flags are set to true when another thread
151   // requests to reset the statistics.  The actual statistics
152   // are reset when the thread contention occurs and attempts
153   // to update the statistics.
154   bool         _count_pending_reset;
155   bool         _timer_pending_reset;
156 
157   // Keep accurate times for potentially recursive class operations
158   int           _perf_recursion_counts[PerfClassTraceTime::EVENT_TYPE_COUNT];
159   elapsedTimer  _perf_timers[PerfClassTraceTime::EVENT_TYPE_COUNT];
160 
161   // utility functions
162   void  check_and_reset_count()            {
163                                              if (!_count_pending_reset) return;
164                                              _contended_enter_count = 0;
165                                              _monitor_wait_count = 0;
166                                              _sleep_count = 0;
167                                              _count_pending_reset = 0;
168                                            }
169   void  check_and_reset_timer()            {
170                                              if (!_timer_pending_reset) return;
171                                              _contended_enter_timer.reset();
172                                              _monitor_wait_timer.reset();
173                                              _sleep_timer.reset();
174                                              _timer_pending_reset = 0;
175                                            }
176 
177 public:
178   ThreadStatistics();
179 
180   jlong contended_enter_count()            { return (_count_pending_reset ? 0 : _contended_enter_count); }
181   jlong contended_enter_ticks()            { return (_timer_pending_reset ? 0 : _contended_enter_timer.active_ticks()); }
182   jlong monitor_wait_count()               { return (_count_pending_reset ? 0 : _monitor_wait_count); }
183   jlong monitor_wait_ticks()               { return (_timer_pending_reset ? 0 : _monitor_wait_timer.active_ticks()); }
184   jlong sleep_count()                      { return (_count_pending_reset ? 0 : _sleep_count); }
185   jlong sleep_ticks()                      { return (_timer_pending_reset ? 0 : _sleep_timer.active_ticks()); }
186 
187   void monitor_wait()                      { check_and_reset_count(); _monitor_wait_count++; }
188   void monitor_wait_begin()                { check_and_reset_timer(); _monitor_wait_timer.start(); }
189   void monitor_wait_end()                  { _monitor_wait_timer.stop(); check_and_reset_timer(); }
190 
191   void thread_sleep()                      { check_and_reset_count(); _sleep_count++; }
192   void thread_sleep_begin()                { check_and_reset_timer(); _sleep_timer.start(); }
193   void thread_sleep_end()                  { _sleep_timer.stop(); check_and_reset_timer(); }
194 
195   void contended_enter()                   { check_and_reset_count(); _contended_enter_count++; }
196   void contended_enter_begin()             { check_and_reset_timer(); _contended_enter_timer.start(); }
197   void contended_enter_end()               { _contended_enter_timer.stop(); check_and_reset_timer(); }
198 
199   void reset_count_stat()                  { _count_pending_reset = true; }
200   void reset_time_stat()                   { _timer_pending_reset = true; }
201 
202   int* perf_recursion_counts_addr()        { return _perf_recursion_counts; }
203   elapsedTimer* perf_timers_addr()         { return _perf_timers; }
204 };
205 
206 // Thread snapshot to represent the thread state and statistics
207 class ThreadSnapshot : public CHeapObj<mtInternal> {
208 private:
209   // This JavaThread* is protected by being stored in objects that are
210   // protected by a ThreadsListSetter (ThreadDumpResult).
211   JavaThread* _thread;
212   OopHandle   _threadObj;
213   JavaThreadStatus _thread_status;
214 
215   bool    _is_suspended;
216   bool    _is_in_native;
217 
218   jlong   _contended_enter_ticks;
219   jlong   _contended_enter_count;
220   jlong   _monitor_wait_ticks;
221   jlong   _monitor_wait_count;
222   jlong   _sleep_ticks;
223   jlong   _sleep_count;
224 
225   OopHandle     _blocker_object;
226   OopHandle     _blocker_object_owner;
227 
228   ThreadStackTrace*      _stack_trace;
229   ThreadConcurrentLocks* _concurrent_locks;
230   ThreadSnapshot*        _next;
231 
232   // ThreadSnapshot instances should only be created via
233   // ThreadDumpResult::add_thread_snapshot.
234   friend class ThreadDumpResult;
235   ThreadSnapshot() : _thread(nullptr),
236                      _stack_trace(nullptr), _concurrent_locks(nullptr), _next(nullptr) {};
237   void        initialize(ThreadsList * t_list, JavaThread* thread);
238 
239 public:
240   ~ThreadSnapshot();
241 
242   JavaThreadStatus thread_status() { return _thread_status; }
243 
244   oop         threadObj() const;
245 
246   void        set_next(ThreadSnapshot* n) { _next = n; }
247 
248   bool        is_suspended()              { return _is_suspended; }
249   bool        is_in_native()              { return _is_in_native; }
250 
251   jlong       contended_enter_count()     { return _contended_enter_count; }
252   jlong       contended_enter_ticks()     { return _contended_enter_ticks; }
253   jlong       monitor_wait_count()        { return _monitor_wait_count; }
254   jlong       monitor_wait_ticks()        { return _monitor_wait_ticks; }
255   jlong       sleep_count()               { return _sleep_count; }
256   jlong       sleep_ticks()               { return _sleep_ticks; }
257 
258 
259   oop         blocker_object() const;
260   oop         blocker_object_owner() const;
261 
262   ThreadSnapshot*   next() const          { return _next; }
263   ThreadStackTrace* get_stack_trace()     { return _stack_trace; }
264   ThreadConcurrentLocks* get_concurrent_locks()     { return _concurrent_locks; }
265 
266   void        dump_stack_at_safepoint(int max_depth, bool with_locked_monitors,
267                                       ObjectMonitorsHashtable* table, bool full);
268   void        set_concurrent_locks(ThreadConcurrentLocks* l) { _concurrent_locks = l; }
269   void        metadata_do(void f(Metadata*));
270 };
271 
272 class ThreadStackTrace : public CHeapObj<mtInternal> {
273  private:
274   JavaThread*                     _thread;
275   int                             _depth;  // number of stack frames added
276   bool                            _with_locked_monitors;
277   GrowableArray<StackFrameInfo*>* _frames;
278   GrowableArray<OopHandle>*       _jni_locked_monitors;
279 
280  public:
281 
282   ThreadStackTrace(JavaThread* thread, bool with_locked_monitors);
283   ~ThreadStackTrace();
284 
285   JavaThread*     thread()              { return _thread; }
286   StackFrameInfo* stack_frame_at(int i) { return _frames->at(i); }
287   int             get_stack_depth()     { return _depth; }
288 
289   void            add_stack_frame(javaVFrame* jvf);
290   void            dump_stack_at_safepoint(int max_depth, ObjectMonitorsHashtable* table, bool full);
291   Handle          allocate_fill_stack_trace_element_array(TRAPS);
292   void            metadata_do(void f(Metadata*));
293   GrowableArray<OopHandle>* jni_locked_monitors() { return _jni_locked_monitors; }
294   int             num_jni_locked_monitors() { return (_jni_locked_monitors != nullptr ? _jni_locked_monitors->length() : 0); }
295 
296   bool            is_owned_monitor_on_stack(oop object);
297   void            add_jni_locked_monitor(oop object);
298 };
299 
300 // StackFrameInfo for keeping Method* and bci during
301 // stack walking for later construction of StackTraceElement[]
302 // Java instances
303 class StackFrameInfo : public CHeapObj<mtInternal> {
304  private:
305   Method*             _method;
306   int                 _bci;
307   GrowableArray<OopHandle>* _locked_monitors; // list of object monitors locked by this frame
308   // We need to save the mirrors in the backtrace to keep the class
309   // from being unloaded while we still have this stack trace.
310   OopHandle           _class_holder;
311 
312  public:
313 
314   StackFrameInfo(javaVFrame* jvf, bool with_locked_monitors);
315   ~StackFrameInfo();
316   Method*   method() const       { return _method; }
317   int       bci()    const       { return _bci; }
318   void      metadata_do(void f(Metadata*));
319 
320   int       num_locked_monitors()       { return (_locked_monitors != nullptr ? _locked_monitors->length() : 0); }
321   GrowableArray<OopHandle>* locked_monitors() { return _locked_monitors; }
322 
323   void      print_on(outputStream* st) const;
324 };
325 
326 class ThreadConcurrentLocks : public CHeapObj<mtInternal> {
327 private:
328   GrowableArray<OopHandle>*   _owned_locks;
329   ThreadConcurrentLocks*      _next;
330   // This JavaThread* is protected in one of two different ways
331   // depending on the usage of the ThreadConcurrentLocks object:
332   // 1) by being stored in objects that are only allocated and used at a
333   // safepoint (ConcurrentLocksDump), or 2) by being stored in objects
334   // that are protected by a ThreadsListSetter (ThreadSnapshot inside
335   // ThreadDumpResult).
336   JavaThread*                 _thread;
337  public:
338   ThreadConcurrentLocks(JavaThread* thread);
339   ~ThreadConcurrentLocks();
340 
341   void                        add_lock(instanceOop o);
342   void                        set_next(ThreadConcurrentLocks* n) { _next = n; }
343   ThreadConcurrentLocks*      next() { return _next; }
344   JavaThread*                 java_thread()                      { return _thread; }
345   GrowableArray<OopHandle>*   owned_locks()                      { return _owned_locks; }
346 };
347 
348 class ConcurrentLocksDump : public StackObj {
349  private:
350   ThreadConcurrentLocks* _map;
351   ThreadConcurrentLocks* _last;   // Last ThreadConcurrentLocks in the map
352   bool                   _retain_map_on_free;
353 
354   void build_map(GrowableArray<oop>* aos_objects);
355   void add_lock(JavaThread* thread, instanceOop o);
356 
357  public:
358   ConcurrentLocksDump(bool retain_map_on_free) : _map(nullptr), _last(nullptr), _retain_map_on_free(retain_map_on_free) {
359     assert(SafepointSynchronize::is_at_safepoint(), "Must be constructed at a safepoint.");
360   };
361   ConcurrentLocksDump() : _map(nullptr), _last(nullptr), _retain_map_on_free(false) {
362     assert(SafepointSynchronize::is_at_safepoint(), "Must be constructed at a safepoint.");
363   };
364   ~ConcurrentLocksDump();
365 
366   void                        dump_at_safepoint();
367   ThreadConcurrentLocks*      thread_concurrent_locks(JavaThread* thread);
368   void                        print_locks_on(JavaThread* t, outputStream* st);
369 };
370 
371 class ThreadDumpResult : public StackObj {
372  private:
373   int                  _num_threads;
374   int                  _num_snapshots;
375   ThreadSnapshot*      _snapshots;
376   ThreadSnapshot*      _last;
377   ThreadDumpResult*    _next;
378   ThreadsListSetter    _setter;  // Helper to set hazard ptr in the originating thread
379                                  // which protects the JavaThreads in _snapshots.
380 
381   void                 link_thread_snapshot(ThreadSnapshot* ts);
382 
383  public:
384   ThreadDumpResult();
385   ThreadDumpResult(int num_threads);
386   ~ThreadDumpResult();
387 
388   ThreadSnapshot*      add_thread_snapshot();
389   ThreadSnapshot*      add_thread_snapshot(JavaThread* thread);
390 
391   void                 set_next(ThreadDumpResult* next) { _next = next; }
392   ThreadDumpResult*    next()                           { return _next; }
393   int                  num_threads()                    { return _num_threads; }
394   int                  num_snapshots()                  { return _num_snapshots; }
395   ThreadSnapshot*      snapshots()                      { return _snapshots; }
396   void                 set_t_list()                     { _setter.set(); }
397   ThreadsList*         t_list();
398   bool                 t_list_has_been_set()            { return _setter.is_set(); }
399   void                 metadata_do(void f(Metadata*));
400 };
401 
402 class DeadlockCycle : public CHeapObj<mtInternal> {
403  private:
404   GrowableArray<JavaThread*>* _threads;
405   DeadlockCycle*              _next;
406  public:
407   DeadlockCycle();
408   ~DeadlockCycle();
409 
410   DeadlockCycle* next()                     { return _next; }
411   void           set_next(DeadlockCycle* d) { _next = d; }
412   void           add_thread(JavaThread* t)  { _threads->append(t); }
413   void           reset()                    { _threads->clear(); }
414   int            num_threads()              { return _threads->length(); }
415   GrowableArray<JavaThread*>* threads()     { return _threads; }
416   void           print_on_with(ThreadsList * t_list, outputStream* st) const;
417 };
418 
419 // Utility class to get list of java threads.
420 class ThreadsListEnumerator : public StackObj {
421 private:
422   GrowableArray<instanceHandle>* _threads_array;
423 public:
424   ThreadsListEnumerator(Thread* cur_thread,
425                         bool include_jvmti_agent_threads = false,
426                         bool include_jni_attaching_threads = true,
427                         bool include_bound_virtual_threads = false);
428   int            num_threads()            { return _threads_array->length(); }
429   instanceHandle get_threadObj(int index) { return _threads_array->at(index); }
430 };
431 
432 
433 // abstract utility class to set new thread states, and restore previous after the block exits
434 class JavaThreadStatusChanger : public StackObj {
435  private:
436   JavaThreadStatus _old_state;
437   JavaThread*  _java_thread;
438   bool _is_alive;
439 
440   void save_old_state(JavaThread* java_thread) {
441     _java_thread  = java_thread;
442     _is_alive = is_alive(java_thread);
443     if (is_alive()) {
444       _old_state = java_lang_Thread::get_thread_status(_java_thread->threadObj());
445     }
446   }
447 
448  public:
449   static void set_thread_status(JavaThread* java_thread,
450                                 JavaThreadStatus state) {
451     java_lang_Thread::set_thread_status(java_thread->threadObj(), state);
452   }
453 
454   void set_thread_status(JavaThreadStatus state) {
455     if (is_alive()) {
456       set_thread_status(_java_thread, state);
457     }
458   }
459 
460   JavaThreadStatusChanger(JavaThread* java_thread,
461                           JavaThreadStatus state) : _old_state(JavaThreadStatus::NEW) {
462     save_old_state(java_thread);
463     set_thread_status(state);
464   }
465 
466   JavaThreadStatusChanger(JavaThread* java_thread) : _old_state(JavaThreadStatus::NEW) {
467     save_old_state(java_thread);
468   }
469 
470   ~JavaThreadStatusChanger() {
471     set_thread_status(_old_state);
472   }
473 
474   static bool is_alive(JavaThread* java_thread) {
475     return java_thread != nullptr && java_thread->threadObj() != nullptr;
476   }
477 
478   bool is_alive() {
479     return _is_alive;
480   }
481 };
482 
483 // Change status to waiting on an object  (timed or indefinite)
484 class JavaThreadInObjectWaitState : public JavaThreadStatusChanger {
485  private:
486   ThreadStatistics* _stat;
487   bool _active;
488 
489  public:
490   JavaThreadInObjectWaitState(JavaThread *java_thread, bool timed) :
491     JavaThreadStatusChanger(java_thread,
492                             timed ? JavaThreadStatus::IN_OBJECT_WAIT_TIMED : JavaThreadStatus::IN_OBJECT_WAIT) {
493     if (is_alive()) {
494       _stat = java_thread->get_thread_stat();
495       _active = ThreadService::is_thread_monitoring_contention();
496       _stat->monitor_wait();
497       if (_active) {
498         _stat->monitor_wait_begin();
499       }
500     } else {
501       _active = false;
502     }
503   }
504 
505   ~JavaThreadInObjectWaitState() {
506     if (_active) {
507       _stat->monitor_wait_end();
508     }
509   }
510 };
511 
512 // Change status to parked (timed or indefinite)
513 class JavaThreadParkedState : public JavaThreadStatusChanger {
514  private:
515   ThreadStatistics* _stat;
516   bool _active;
517 
518  public:
519   JavaThreadParkedState(JavaThread *java_thread, bool timed) :
520     JavaThreadStatusChanger(java_thread,
521                             timed ? JavaThreadStatus::PARKED_TIMED : JavaThreadStatus::PARKED) {
522     if (is_alive()) {
523       _stat = java_thread->get_thread_stat();
524       _active = ThreadService::is_thread_monitoring_contention();
525       _stat->monitor_wait();
526       if (_active) {
527         _stat->monitor_wait_begin();
528       }
529     } else {
530       _active = false;
531     }
532   }
533 
534   ~JavaThreadParkedState() {
535     if (_active) {
536       _stat->monitor_wait_end();
537     }
538   }
539 };
540 
541 // Change status to blocked on (re-)entering a synchronization block
542 class JavaThreadBlockedOnMonitorEnterState : public JavaThreadStatusChanger {
543  private:
544   ThreadStatistics* _stat;
545   bool _active;
546 
547   static bool contended_enter_begin(JavaThread *java_thread) {
548     set_thread_status(java_thread, JavaThreadStatus::BLOCKED_ON_MONITOR_ENTER);
549     ThreadStatistics* stat = java_thread->get_thread_stat();
550     stat->contended_enter();
551     bool active = ThreadService::is_thread_monitoring_contention();
552     if (active) {
553       stat->contended_enter_begin();
554     }
555     return active;
556   }
557 
558  public:
559   // java_thread is waiting thread being blocked on monitor reenter.
560   // Current thread is the notifying thread which holds the monitor.
561   static bool wait_reenter_begin(JavaThread *java_thread, ObjectMonitor *obj_m) {
562     assert((java_thread != nullptr), "Java thread should not be null here");
563     bool active = false;
564     if (is_alive(java_thread)) {
565       active = contended_enter_begin(java_thread);
566     }
567     return active;
568   }
569 
570   static void wait_reenter_end(JavaThread *java_thread, bool active) {
571     if (active) {
572       java_thread->get_thread_stat()->contended_enter_end();
573     }
574     set_thread_status(java_thread, JavaThreadStatus::RUNNABLE);
575   }
576 
577   JavaThreadBlockedOnMonitorEnterState(JavaThread *java_thread, ObjectMonitor *obj_m) :
578     JavaThreadStatusChanger(java_thread), _stat(nullptr), _active(false) {
579     assert((java_thread != nullptr), "Java thread should not be null here");
580     // Change thread status and collect contended enter stats for monitor contended
581     // enter done for external java world objects and it is contended. All other cases
582     // like for vm internal objects and for external objects which are not contended
583     // thread status is not changed and contended enter stat is not collected.
584     _active = false;
585     if (is_alive() && obj_m->contentions() > 0) {
586       _stat = java_thread->get_thread_stat();
587       _active = contended_enter_begin(java_thread);
588     }
589   }
590 
591   ~JavaThreadBlockedOnMonitorEnterState() {
592     if (_active) {
593       _stat->contended_enter_end();
594     }
595   }
596 };
597 
598 // Change status to sleeping
599 class JavaThreadSleepState : public JavaThreadStatusChanger {
600  private:
601   ThreadStatistics* _stat;
602   bool _active;
603  public:
604   JavaThreadSleepState(JavaThread *java_thread) :
605     JavaThreadStatusChanger(java_thread, JavaThreadStatus::SLEEPING) {
606     if (is_alive()) {
607       _stat = java_thread->get_thread_stat();
608       _active = ThreadService::is_thread_monitoring_contention();
609       _stat->thread_sleep();
610       if (_active) {
611         _stat->thread_sleep_begin();
612       }
613     } else {
614       _active = false;
615     }
616   }
617 
618   ~JavaThreadSleepState() {
619     if (_active) {
620       _stat->thread_sleep_end();
621     }
622   }
623 };
624 
625 #endif // SHARE_SERVICES_THREADSERVICE_HPP