24 |
24 |
25 #ifndef SHARE_RUNTIME_SYNCHRONIZER_HPP |
25 #ifndef SHARE_RUNTIME_SYNCHRONIZER_HPP |
26 #define SHARE_RUNTIME_SYNCHRONIZER_HPP |
26 #define SHARE_RUNTIME_SYNCHRONIZER_HPP |
27 |
27 |
28 #include "memory/padded.hpp" |
28 #include "memory/padded.hpp" |
29 #include "oops/markOop.hpp" |
29 #include "oops/markWord.hpp" |
30 #include "runtime/basicLock.hpp" |
30 #include "runtime/basicLock.hpp" |
31 #include "runtime/handles.hpp" |
31 #include "runtime/handles.hpp" |
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: |
63 } InflateCause; |
65 } InflateCause; |
64 |
66 |
65 // exit must be implemented non-blocking, since the compiler cannot easily handle |
67 // exit must be implemented non-blocking, since the compiler cannot easily handle |
66 // deoptimization at monitor exit. Hence, it does not take a Handle argument. |
68 // deoptimization at monitor exit. Hence, it does not take a Handle argument. |
67 |
69 |
68 // This is full version of monitor enter and exit. I choose not |
70 // This is the "slow path" version of monitor enter and exit. |
69 // to use enter() and exit() in order to make sure user be ware |
71 static void enter(Handle obj, BasicLock* lock, TRAPS); |
70 // of the performance and semantics difference. They are normally |
72 static void exit(oop obj, BasicLock* lock, Thread* THREAD); |
71 // used by ObjectLocker etc. The interpreter and compiler use |
|
72 // assembly copies of these routines. Please keep them synchronized. |
|
73 // |
|
74 // attempt_rebias flag is used by UseBiasedLocking implementation |
|
75 static void fast_enter(Handle obj, BasicLock* lock, bool attempt_rebias, |
|
76 TRAPS); |
|
77 static void fast_exit(oop obj, BasicLock* lock, Thread* THREAD); |
|
78 |
|
79 // WARNING: They are ONLY used to handle the slow cases. They should |
|
80 // only be used when the fast cases failed. Use of these functions |
|
81 // without previous fast case check may cause fatal error. |
|
82 static void slow_enter(Handle obj, BasicLock* lock, TRAPS); |
|
83 static void slow_exit(oop obj, BasicLock* lock, Thread* THREAD); |
|
84 |
73 |
85 // Used only to handle jni locks or other unmatched monitor enter/exit |
74 // Used only to handle jni locks or other unmatched monitor enter/exit |
86 // Internally they will use heavy weight monitor. |
75 // Internally they will use heavy weight monitor. |
87 static void jni_enter(Handle obj, TRAPS); |
76 static void jni_enter(Handle obj, TRAPS); |
88 static void jni_exit(oop obj, Thread* THREAD); |
77 static void jni_exit(oop obj, Thread* THREAD); |
90 // Handle all interpreter, compiler and jni cases |
79 // Handle all interpreter, compiler and jni cases |
91 static int wait(Handle obj, jlong millis, TRAPS); |
80 static int wait(Handle obj, jlong millis, TRAPS); |
92 static void notify(Handle obj, TRAPS); |
81 static void notify(Handle obj, TRAPS); |
93 static void notifyall(Handle obj, TRAPS); |
82 static void notifyall(Handle obj, TRAPS); |
94 |
83 |
95 static bool quick_notify(oopDesc* obj, Thread* Self, bool All); |
84 static bool quick_notify(oopDesc* obj, Thread* self, bool All); |
96 static bool quick_enter(oop obj, Thread* Self, BasicLock* Lock); |
85 static bool quick_enter(oop obj, Thread* self, BasicLock* Lock); |
97 |
86 |
98 // Special internal-use-only method for use by JVM infrastructure |
87 // Special internal-use-only method for use by JVM infrastructure |
99 // 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 |
100 // throwing unexpected InterruptedExecutionExceptions. |
89 // throwing unexpected InterruptedExecutionExceptions. |
101 static void waitUninterruptibly(Handle obj, jlong Millis, Thread * THREAD); |
90 static void wait_uninterruptibly(Handle obj, jlong Millis, Thread* THREAD); |
102 |
91 |
103 // used by classloading to free classloader object lock, |
92 // used by classloading to free classloader object lock, |
104 // wait on an internal lock, and reclaim original lock |
93 // wait on an internal lock, and reclaim original lock |
105 // with original recursion count |
94 // with original recursion count |
106 static intptr_t complete_exit(Handle obj, TRAPS); |
95 static intptr_t complete_exit(Handle obj, TRAPS); |
107 static void reenter (Handle obj, intptr_t recursion, TRAPS); |
96 static void reenter (Handle obj, intptr_t recursion, TRAPS); |
108 |
97 |
109 // thread-specific and global objectMonitor free list accessors |
98 // thread-specific and global ObjectMonitor free list accessors |
110 static ObjectMonitor * omAlloc(Thread * Self); |
99 static ObjectMonitor* om_alloc(Thread* self); |
111 static void omRelease(Thread * Self, ObjectMonitor * m, |
100 static void om_release(Thread* self, ObjectMonitor* m, |
112 bool FromPerThreadAlloc); |
101 bool FromPerThreadAlloc); |
113 static void omFlush(Thread * Self); |
102 static void om_flush(Thread* self); |
114 |
103 |
115 // Inflate light weight monitor to heavy weight monitor |
104 // Inflate light weight monitor to heavy weight monitor |
116 static ObjectMonitor* inflate(Thread * Self, oop obj, const InflateCause cause); |
105 static ObjectMonitor* inflate(Thread* self, oop obj, const InflateCause cause); |
117 // This version is only for internal use |
106 // This version is only for internal use |
118 static void inflate_helper(oop obj); |
107 static void inflate_helper(oop obj); |
119 static const char* inflate_cause_name(const InflateCause cause); |
108 static const char* inflate_cause_name(const InflateCause cause); |
120 |
109 |
121 // Returns the identity hash value for an oop |
110 // Returns the identity hash value for an oop |
122 // NOTE: It may cause monitor inflation |
111 // NOTE: It may cause monitor inflation |
123 static intptr_t identity_hash_value_for(Handle obj); |
112 static intptr_t identity_hash_value_for(Handle obj); |
124 static intptr_t FastHashCode(Thread * Self, oop obj); |
113 static intptr_t FastHashCode(Thread* self, oop obj); |
125 |
114 |
126 // java.lang.Thread support |
115 // java.lang.Thread support |
127 static bool current_thread_holds_lock(JavaThread* thread, Handle h_obj); |
116 static bool current_thread_holds_lock(JavaThread* thread, Handle h_obj); |
128 static LockOwnership query_lock_ownership(JavaThread * self, Handle h_obj); |
117 static LockOwnership query_lock_ownership(JavaThread* self, Handle h_obj); |
129 |
118 |
130 static JavaThread* get_lock_owner(ThreadsList * t_list, Handle h_obj); |
119 static JavaThread* get_lock_owner(ThreadsList * t_list, Handle h_obj); |
131 |
120 |
132 // JNI detach support |
121 // JNI detach support |
133 static void release_monitors_owned_by_thread(TRAPS); |
122 static void release_monitors_owned_by_thread(TRAPS); |
140 static void deflate_thread_local_monitors(Thread* thread, DeflateMonitorCounters* counters); |
129 static void deflate_thread_local_monitors(Thread* thread, DeflateMonitorCounters* counters); |
141 static void prepare_deflate_idle_monitors(DeflateMonitorCounters* counters); |
130 static void prepare_deflate_idle_monitors(DeflateMonitorCounters* counters); |
142 static void finish_deflate_idle_monitors(DeflateMonitorCounters* counters); |
131 static void finish_deflate_idle_monitors(DeflateMonitorCounters* counters); |
143 |
132 |
144 // 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 |
145 static int deflate_monitor_list(ObjectMonitor** listheadp, |
134 static int deflate_monitor_list(ObjectMonitor** list_p, |
146 ObjectMonitor** freeHeadp, |
135 ObjectMonitor** free_head_p, |
147 ObjectMonitor** freeTailp); |
136 ObjectMonitor** free_tail_p); |
148 static bool deflate_monitor(ObjectMonitor* mid, oop obj, |
137 static bool deflate_monitor(ObjectMonitor* mid, oop obj, |
149 ObjectMonitor** freeHeadp, |
138 ObjectMonitor** free_head_p, |
150 ObjectMonitor** freeTailp); |
139 ObjectMonitor** free_tail_p); |
151 static bool is_cleanup_needed(); |
140 static bool is_cleanup_needed(); |
152 static void oops_do(OopClosure* f); |
141 static void oops_do(OopClosure* f); |
153 // Process oops in thread local used monitors |
142 // Process oops in thread local used monitors |
154 static void thread_local_used_oops_do(Thread* thread, OopClosure* f); |
143 static void thread_local_used_oops_do(Thread* thread, OopClosure* f); |
155 |
144 |
156 // debugging |
145 // debugging |
157 static void audit_and_print_stats(bool on_exit); |
146 static void audit_and_print_stats(bool on_exit); |
158 static void chk_free_entry(JavaThread * jt, ObjectMonitor * n, |
147 static void chk_free_entry(JavaThread* jt, ObjectMonitor* n, |
159 outputStream * out, int *error_cnt_p); |
148 outputStream * out, int *error_cnt_p); |
160 static void chk_global_free_list_and_count(outputStream * out, |
149 static void chk_global_free_list_and_count(outputStream * out, |
161 int *error_cnt_p); |
150 int *error_cnt_p); |
162 static void chk_global_in_use_list_and_count(outputStream * out, |
151 static void chk_global_in_use_list_and_count(outputStream * out, |
163 int *error_cnt_p); |
152 int *error_cnt_p); |
164 static void chk_in_use_entry(JavaThread * jt, ObjectMonitor * n, |
153 static void chk_in_use_entry(JavaThread* jt, ObjectMonitor* n, |
165 outputStream * out, int *error_cnt_p); |
154 outputStream * out, int *error_cnt_p); |
166 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, |
167 outputStream * out, |
156 outputStream * out, |
168 int *error_cnt_p); |
157 int *error_cnt_p); |
169 static void chk_per_thread_free_list_and_count(JavaThread *jt, |
158 static void chk_per_thread_free_list_and_count(JavaThread *jt, |
176 private: |
165 private: |
177 friend class SynchronizerTest; |
166 friend class SynchronizerTest; |
178 |
167 |
179 enum { _BLOCKSIZE = 128 }; |
168 enum { _BLOCKSIZE = 128 }; |
180 // global list of blocks of monitors |
169 // global list of blocks of monitors |
181 static PaddedEnd<ObjectMonitor> * volatile gBlockList; |
170 static PaddedObjectMonitor* volatile g_block_list; |
182 // global monitor free list |
171 // global monitor free list |
183 static ObjectMonitor * volatile gFreeList; |
172 static ObjectMonitor* volatile g_free_list; |
184 // global monitor in-use list, for moribund threads, |
173 // global monitor in-use list, for moribund threads, |
185 // monitors they inflated need to be scanned for deflation |
174 // monitors they inflated need to be scanned for deflation |
186 static ObjectMonitor * volatile gOmInUseList; |
175 static ObjectMonitor* volatile g_om_in_use_list; |
187 // count of entries in gOmInUseList |
176 // count of entries in g_om_in_use_list |
188 static int gOmInUseCount; |
177 static int g_om_in_use_count; |
189 |
178 |
190 // 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) |
191 static void global_used_oops_do(OopClosure* f); |
180 static void global_used_oops_do(OopClosure* f); |
192 // Process oops in monitors on the given list |
181 // Process oops in monitors on the given list |
193 static void list_oops_do(ObjectMonitor* list, OopClosure* f); |
182 static void list_oops_do(ObjectMonitor* list, OopClosure* f); |
194 |
183 |
195 // Support for SynchronizerTest access to GVars fields: |
184 // Support for SynchronizerTest access to GVars fields: |
196 static u_char* get_gvars_addr(); |
185 static u_char* get_gvars_addr(); |
197 static u_char* get_gvars_hcSequence_addr(); |
186 static u_char* get_gvars_hc_sequence_addr(); |
198 static size_t get_gvars_size(); |
187 static size_t get_gvars_size(); |
199 static u_char* get_gvars_stwRandom_addr(); |
188 static u_char* get_gvars_stw_random_addr(); |
200 }; |
189 }; |
201 |
190 |
202 // ObjectLocker enforces balanced locking and can never throw an |
191 // ObjectLocker enforces balanced locking and can never throw an |
203 // IllegalMonitorStateException. However, a pending exception may |
192 // IllegalMonitorStateException. However, a pending exception may |
204 // 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 |
209 Thread* _thread; |
198 Thread* _thread; |
210 Handle _obj; |
199 Handle _obj; |
211 BasicLock _lock; |
200 BasicLock _lock; |
212 bool _dolock; // default true |
201 bool _dolock; // default true |
213 public: |
202 public: |
214 ObjectLocker(Handle obj, Thread* thread, bool doLock = true); |
203 ObjectLocker(Handle obj, Thread* thread, bool do_lock = true); |
215 ~ObjectLocker(); |
204 ~ObjectLocker(); |
216 |
205 |
217 // Monitor behavior |
206 // Monitor behavior |
218 void wait(TRAPS) { ObjectSynchronizer::wait(_obj, 0, CHECK); } // wait forever |
207 void wait(TRAPS) { ObjectSynchronizer::wait(_obj, 0, CHECK); } // wait forever |
219 void notify_all(TRAPS) { ObjectSynchronizer::notifyall(_obj, CHECK); } |
208 void notify_all(TRAPS) { ObjectSynchronizer::notifyall(_obj, CHECK); } |
220 void waitUninterruptibly(TRAPS) { ObjectSynchronizer::waitUninterruptibly(_obj, 0, CHECK); } |
209 void wait_uninterruptibly(TRAPS) { ObjectSynchronizer::wait_uninterruptibly(_obj, 0, CHECK); } |
221 // complete_exit gives up lock completely, returning recursion count |
210 // complete_exit gives up lock completely, returning recursion count |
222 // reenter reclaims lock with original recursion count |
211 // reenter reclaims lock with original recursion count |
223 intptr_t complete_exit(TRAPS) { return ObjectSynchronizer::complete_exit(_obj, THREAD); } |
212 intptr_t complete_exit(TRAPS) { return ObjectSynchronizer::complete_exit(_obj, THREAD); } |
224 void reenter(intptr_t recursion, TRAPS) { ObjectSynchronizer::reenter(_obj, recursion, CHECK); } |
213 void reenter(intptr_t recursion, TRAPS) { ObjectSynchronizer::reenter(_obj, recursion, CHECK); } |
225 }; |
214 }; |