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 }; |