src/hotspot/share/runtime/synchronizer.hpp
changeset 57906 e17f768b3b71
parent 57893 49fea19f0726
child 58679 9c3209ff7550
child 59156 14fa9e70ae71
equal deleted inserted replaced
57905:55723932d06e 57906:e17f768b3b71
    32 #include "runtime/perfData.hpp"
    32 #include "runtime/perfData.hpp"
    33 
    33 
    34 class ObjectMonitor;
    34 class ObjectMonitor;
    35 class ThreadsList;
    35 class ThreadsList;
    36 
    36 
       
    37 typedef PaddedEnd<ObjectMonitor, DEFAULT_CACHE_LINE_SIZE> PaddedObjectMonitor;
       
    38 
    37 struct DeflateMonitorCounters {
    39 struct DeflateMonitorCounters {
    38   int nInuse;              // currently associated with objects
    40   int n_in_use;              // currently associated with objects
    39   int nInCirculation;      // extant
    41   int n_in_circulation;      // extant
    40   int nScavenged;          // reclaimed (global and per-thread)
    42   int n_scavenged;           // reclaimed (global and per-thread)
    41   int perThreadScavenged;  // per-thread scavenge total
    43   int per_thread_scavenged;  // per-thread scavenge total
    42   double perThreadTimes;   // per-thread scavenge times
    44   double per_thread_times;   // per-thread scavenge times
    43 };
    45 };
    44 
    46 
    45 class ObjectSynchronizer : AllStatic {
    47 class ObjectSynchronizer : AllStatic {
    46   friend class VMStructs;
    48   friend class VMStructs;
    47  public:
    49  public:
    77   // Handle all interpreter, compiler and jni cases
    79   // Handle all interpreter, compiler and jni cases
    78   static int  wait(Handle obj, jlong millis, TRAPS);
    80   static int  wait(Handle obj, jlong millis, TRAPS);
    79   static void notify(Handle obj, TRAPS);
    81   static void notify(Handle obj, TRAPS);
    80   static void notifyall(Handle obj, TRAPS);
    82   static void notifyall(Handle obj, TRAPS);
    81 
    83 
    82   static bool quick_notify(oopDesc* obj, Thread* Self, bool All);
    84   static bool quick_notify(oopDesc* obj, Thread* self, bool All);
    83   static bool quick_enter(oop obj, Thread* Self, BasicLock* Lock);
    85   static bool quick_enter(oop obj, Thread* self, BasicLock* Lock);
    84 
    86 
    85   // Special internal-use-only method for use by JVM infrastructure
    87   // Special internal-use-only method for use by JVM infrastructure
    86   // that needs to wait() on a java-level object but that can't risk
    88   // that needs to wait() on a java-level object but that can't risk
    87   // throwing unexpected InterruptedExecutionExceptions.
    89   // throwing unexpected InterruptedExecutionExceptions.
    88   static void waitUninterruptibly(Handle obj, jlong Millis, Thread * THREAD);
    90   static void wait_uninterruptibly(Handle obj, jlong Millis, Thread* THREAD);
    89 
    91 
    90   // used by classloading to free classloader object lock,
    92   // used by classloading to free classloader object lock,
    91   // wait on an internal lock, and reclaim original lock
    93   // wait on an internal lock, and reclaim original lock
    92   // with original recursion count
    94   // with original recursion count
    93   static intptr_t complete_exit(Handle obj, TRAPS);
    95   static intptr_t complete_exit(Handle obj, TRAPS);
    94   static void reenter (Handle obj, intptr_t recursion, TRAPS);
    96   static void reenter (Handle obj, intptr_t recursion, TRAPS);
    95 
    97 
    96   // thread-specific and global objectMonitor free list accessors
    98   // thread-specific and global ObjectMonitor free list accessors
    97   static ObjectMonitor * omAlloc(Thread * Self);
    99   static ObjectMonitor* om_alloc(Thread* self);
    98   static void omRelease(Thread * Self, ObjectMonitor * m,
   100   static void om_release(Thread* self, ObjectMonitor* m,
    99                         bool FromPerThreadAlloc);
   101                          bool FromPerThreadAlloc);
   100   static void omFlush(Thread * Self);
   102   static void om_flush(Thread* self);
   101 
   103 
   102   // Inflate light weight monitor to heavy weight monitor
   104   // Inflate light weight monitor to heavy weight monitor
   103   static ObjectMonitor* inflate(Thread * Self, oop obj, const InflateCause cause);
   105   static ObjectMonitor* inflate(Thread* self, oop obj, const InflateCause cause);
   104   // This version is only for internal use
   106   // This version is only for internal use
   105   static void inflate_helper(oop obj);
   107   static void inflate_helper(oop obj);
   106   static const char* inflate_cause_name(const InflateCause cause);
   108   static const char* inflate_cause_name(const InflateCause cause);
   107 
   109 
   108   // Returns the identity hash value for an oop
   110   // Returns the identity hash value for an oop
   109   // NOTE: It may cause monitor inflation
   111   // NOTE: It may cause monitor inflation
   110   static intptr_t identity_hash_value_for(Handle obj);
   112   static intptr_t identity_hash_value_for(Handle obj);
   111   static intptr_t FastHashCode(Thread * Self, oop obj);
   113   static intptr_t FastHashCode(Thread* self, oop obj);
   112 
   114 
   113   // java.lang.Thread support
   115   // java.lang.Thread support
   114   static bool current_thread_holds_lock(JavaThread* thread, Handle h_obj);
   116   static bool current_thread_holds_lock(JavaThread* thread, Handle h_obj);
   115   static LockOwnership query_lock_ownership(JavaThread * self, Handle h_obj);
   117   static LockOwnership query_lock_ownership(JavaThread* self, Handle h_obj);
   116 
   118 
   117   static JavaThread* get_lock_owner(ThreadsList * t_list, Handle h_obj);
   119   static JavaThread* get_lock_owner(ThreadsList * t_list, Handle h_obj);
   118 
   120 
   119   // JNI detach support
   121   // JNI detach support
   120   static void release_monitors_owned_by_thread(TRAPS);
   122   static void release_monitors_owned_by_thread(TRAPS);
   127   static void deflate_thread_local_monitors(Thread* thread, DeflateMonitorCounters* counters);
   129   static void deflate_thread_local_monitors(Thread* thread, DeflateMonitorCounters* counters);
   128   static void prepare_deflate_idle_monitors(DeflateMonitorCounters* counters);
   130   static void prepare_deflate_idle_monitors(DeflateMonitorCounters* counters);
   129   static void finish_deflate_idle_monitors(DeflateMonitorCounters* counters);
   131   static void finish_deflate_idle_monitors(DeflateMonitorCounters* counters);
   130 
   132 
   131   // For a given monitor list: global or per-thread, deflate idle monitors
   133   // For a given monitor list: global or per-thread, deflate idle monitors
   132   static int deflate_monitor_list(ObjectMonitor** listheadp,
   134   static int deflate_monitor_list(ObjectMonitor** list_p,
   133                                   ObjectMonitor** freeHeadp,
   135                                   ObjectMonitor** free_head_p,
   134                                   ObjectMonitor** freeTailp);
   136                                   ObjectMonitor** free_tail_p);
   135   static bool deflate_monitor(ObjectMonitor* mid, oop obj,
   137   static bool deflate_monitor(ObjectMonitor* mid, oop obj,
   136                               ObjectMonitor** freeHeadp,
   138                               ObjectMonitor** free_head_p,
   137                               ObjectMonitor** freeTailp);
   139                               ObjectMonitor** free_tail_p);
   138   static bool is_cleanup_needed();
   140   static bool is_cleanup_needed();
   139   static void oops_do(OopClosure* f);
   141   static void oops_do(OopClosure* f);
   140   // Process oops in thread local used monitors
   142   // Process oops in thread local used monitors
   141   static void thread_local_used_oops_do(Thread* thread, OopClosure* f);
   143   static void thread_local_used_oops_do(Thread* thread, OopClosure* f);
   142 
   144 
   143   // debugging
   145   // debugging
   144   static void audit_and_print_stats(bool on_exit);
   146   static void audit_and_print_stats(bool on_exit);
   145   static void chk_free_entry(JavaThread * jt, ObjectMonitor * n,
   147   static void chk_free_entry(JavaThread* jt, ObjectMonitor* n,
   146                              outputStream * out, int *error_cnt_p);
   148                              outputStream * out, int *error_cnt_p);
   147   static void chk_global_free_list_and_count(outputStream * out,
   149   static void chk_global_free_list_and_count(outputStream * out,
   148                                              int *error_cnt_p);
   150                                              int *error_cnt_p);
   149   static void chk_global_in_use_list_and_count(outputStream * out,
   151   static void chk_global_in_use_list_and_count(outputStream * out,
   150                                                int *error_cnt_p);
   152                                                int *error_cnt_p);
   151   static void chk_in_use_entry(JavaThread * jt, ObjectMonitor * n,
   153   static void chk_in_use_entry(JavaThread* jt, ObjectMonitor* n,
   152                                outputStream * out, int *error_cnt_p);
   154                                outputStream * out, int *error_cnt_p);
   153   static void chk_per_thread_in_use_list_and_count(JavaThread *jt,
   155   static void chk_per_thread_in_use_list_and_count(JavaThread *jt,
   154                                                    outputStream * out,
   156                                                    outputStream * out,
   155                                                    int *error_cnt_p);
   157                                                    int *error_cnt_p);
   156   static void chk_per_thread_free_list_and_count(JavaThread *jt,
   158   static void chk_per_thread_free_list_and_count(JavaThread *jt,
   163  private:
   165  private:
   164   friend class SynchronizerTest;
   166   friend class SynchronizerTest;
   165 
   167 
   166   enum { _BLOCKSIZE = 128 };
   168   enum { _BLOCKSIZE = 128 };
   167   // global list of blocks of monitors
   169   // global list of blocks of monitors
   168   static PaddedEnd<ObjectMonitor> * volatile gBlockList;
   170   static PaddedObjectMonitor* volatile g_block_list;
   169   // global monitor free list
   171   // global monitor free list
   170   static ObjectMonitor * volatile gFreeList;
   172   static ObjectMonitor* volatile g_free_list;
   171   // global monitor in-use list, for moribund threads,
   173   // global monitor in-use list, for moribund threads,
   172   // monitors they inflated need to be scanned for deflation
   174   // monitors they inflated need to be scanned for deflation
   173   static ObjectMonitor * volatile gOmInUseList;
   175   static ObjectMonitor* volatile g_om_in_use_list;
   174   // count of entries in gOmInUseList
   176   // count of entries in g_om_in_use_list
   175   static int gOmInUseCount;
   177   static int g_om_in_use_count;
   176 
   178 
   177   // Process oops in all global used monitors (i.e. moribund thread's monitors)
   179   // Process oops in all global used monitors (i.e. moribund thread's monitors)
   178   static void global_used_oops_do(OopClosure* f);
   180   static void global_used_oops_do(OopClosure* f);
   179   // Process oops in monitors on the given list
   181   // Process oops in monitors on the given list
   180   static void list_oops_do(ObjectMonitor* list, OopClosure* f);
   182   static void list_oops_do(ObjectMonitor* list, OopClosure* f);
   181 
   183 
   182   // Support for SynchronizerTest access to GVars fields:
   184   // Support for SynchronizerTest access to GVars fields:
   183   static u_char* get_gvars_addr();
   185   static u_char* get_gvars_addr();
   184   static u_char* get_gvars_hcSequence_addr();
   186   static u_char* get_gvars_hc_sequence_addr();
   185   static size_t get_gvars_size();
   187   static size_t get_gvars_size();
   186   static u_char* get_gvars_stwRandom_addr();
   188   static u_char* get_gvars_stw_random_addr();
   187 };
   189 };
   188 
   190 
   189 // ObjectLocker enforces balanced locking and can never throw an
   191 // ObjectLocker enforces balanced locking and can never throw an
   190 // IllegalMonitorStateException. However, a pending exception may
   192 // IllegalMonitorStateException. However, a pending exception may
   191 // have to pass through, and we must also be able to deal with
   193 // have to pass through, and we must also be able to deal with
   196   Thread*   _thread;
   198   Thread*   _thread;
   197   Handle    _obj;
   199   Handle    _obj;
   198   BasicLock _lock;
   200   BasicLock _lock;
   199   bool      _dolock;   // default true
   201   bool      _dolock;   // default true
   200  public:
   202  public:
   201   ObjectLocker(Handle obj, Thread* thread, bool doLock = true);
   203   ObjectLocker(Handle obj, Thread* thread, bool do_lock = true);
   202   ~ObjectLocker();
   204   ~ObjectLocker();
   203 
   205 
   204   // Monitor behavior
   206   // Monitor behavior
   205   void wait(TRAPS)  { ObjectSynchronizer::wait(_obj, 0, CHECK); } // wait forever
   207   void wait(TRAPS)  { ObjectSynchronizer::wait(_obj, 0, CHECK); } // wait forever
   206   void notify_all(TRAPS)  { ObjectSynchronizer::notifyall(_obj, CHECK); }
   208   void notify_all(TRAPS)  { ObjectSynchronizer::notifyall(_obj, CHECK); }
   207   void waitUninterruptibly(TRAPS) { ObjectSynchronizer::waitUninterruptibly(_obj, 0, CHECK); }
   209   void wait_uninterruptibly(TRAPS) { ObjectSynchronizer::wait_uninterruptibly(_obj, 0, CHECK); }
   208   // complete_exit gives up lock completely, returning recursion count
   210   // complete_exit gives up lock completely, returning recursion count
   209   // reenter reclaims lock with original recursion count
   211   // reenter reclaims lock with original recursion count
   210   intptr_t complete_exit(TRAPS)  { return ObjectSynchronizer::complete_exit(_obj, THREAD); }
   212   intptr_t complete_exit(TRAPS)  { return ObjectSynchronizer::complete_exit(_obj, THREAD); }
   211   void reenter(intptr_t recursion, TRAPS)  { ObjectSynchronizer::reenter(_obj, recursion, CHECK); }
   213   void reenter(intptr_t recursion, TRAPS)  { ObjectSynchronizer::reenter(_obj, recursion, CHECK); }
   212 };
   214 };