133 // after the safepoint. Since after a safepoint, each of the |
137 // after the safepoint. Since after a safepoint, each of the |
134 // following two methods is either entered from the method entry and |
138 // following two methods is either entered from the method entry and |
135 // falls into the slow path, or is resumed from the safepoints in |
139 // falls into the slow path, or is resumed from the safepoints in |
136 // the method, which only exist in the slow path. So when _needs_gc |
140 // the method, which only exist in the slow path. So when _needs_gc |
137 // is set, the slow path is always taken, till _needs_gc is cleared. |
141 // is set, the slow path is always taken, till _needs_gc is cleared. |
138 static void lock_critical(JavaThread* thread); |
142 inline static void lock_critical(JavaThread* thread); |
139 static void unlock_critical(JavaThread* thread); |
143 inline static void unlock_critical(JavaThread* thread); |
140 |
144 |
141 static address needs_gc_address() { return (address) &_needs_gc; } |
145 static address needs_gc_address() { return (address) &_needs_gc; } |
142 }; |
146 }; |
143 |
147 |
144 |
|
145 // A NoGCVerifier object can be placed in methods where one assumes that |
|
146 // no garbage collection will occur. The destructor will verify this property |
|
147 // unless the constructor is called with argument false (not verifygc). |
|
148 // |
|
149 // The check will only be done in debug mode and if verifygc true. |
|
150 |
|
151 class NoGCVerifier: public StackObj { |
|
152 friend class PauseNoGCVerifier; |
|
153 |
|
154 protected: |
|
155 bool _verifygc; |
|
156 unsigned int _old_invocations; |
|
157 |
|
158 public: |
|
159 #ifdef ASSERT |
|
160 NoGCVerifier(bool verifygc = true); |
|
161 ~NoGCVerifier(); |
|
162 #else |
|
163 NoGCVerifier(bool verifygc = true) {} |
|
164 ~NoGCVerifier() {} |
|
165 #endif |
|
166 }; |
|
167 |
|
168 // A PauseNoGCVerifier is used to temporarily pause the behavior |
|
169 // of a NoGCVerifier object. If we are not in debug mode or if the |
|
170 // NoGCVerifier object has a _verifygc value of false, then there |
|
171 // is nothing to do. |
|
172 |
|
173 class PauseNoGCVerifier: public StackObj { |
|
174 private: |
|
175 NoGCVerifier * _ngcv; |
|
176 |
|
177 public: |
|
178 #ifdef ASSERT |
|
179 PauseNoGCVerifier(NoGCVerifier * ngcv); |
|
180 ~PauseNoGCVerifier(); |
|
181 #else |
|
182 PauseNoGCVerifier(NoGCVerifier * ngcv) {} |
|
183 ~PauseNoGCVerifier() {} |
|
184 #endif |
|
185 }; |
|
186 |
|
187 |
|
188 // A NoSafepointVerifier object will throw an assertion failure if |
|
189 // the current thread passes a possible safepoint while this object is |
|
190 // instantiated. A safepoint, will either be: an oop allocation, blocking |
|
191 // on a Mutex or JavaLock, or executing a VM operation. |
|
192 // |
|
193 // If StrictSafepointChecks is turned off, it degrades into a NoGCVerifier |
|
194 // |
|
195 class NoSafepointVerifier : public NoGCVerifier { |
|
196 friend class PauseNoSafepointVerifier; |
|
197 |
|
198 private: |
|
199 bool _activated; |
|
200 Thread *_thread; |
|
201 public: |
|
202 #ifdef ASSERT |
|
203 NoSafepointVerifier(bool activated = true, bool verifygc = true ) : |
|
204 NoGCVerifier(verifygc), |
|
205 _activated(activated) { |
|
206 _thread = Thread::current(); |
|
207 if (_activated) { |
|
208 _thread->_allow_allocation_count++; |
|
209 _thread->_allow_safepoint_count++; |
|
210 } |
|
211 } |
|
212 |
|
213 ~NoSafepointVerifier() { |
|
214 if (_activated) { |
|
215 _thread->_allow_allocation_count--; |
|
216 _thread->_allow_safepoint_count--; |
|
217 } |
|
218 } |
|
219 #else |
|
220 NoSafepointVerifier(bool activated = true, bool verifygc = true) : NoGCVerifier(verifygc){} |
|
221 ~NoSafepointVerifier() {} |
|
222 #endif |
|
223 }; |
|
224 |
|
225 // A PauseNoSafepointVerifier is used to temporarily pause the |
|
226 // behavior of a NoSafepointVerifier object. If we are not in debug |
|
227 // mode then there is nothing to do. If the NoSafepointVerifier |
|
228 // object has an _activated value of false, then there is nothing to |
|
229 // do for safepoint and allocation checking, but there may still be |
|
230 // something to do for the underlying NoGCVerifier object. |
|
231 |
|
232 class PauseNoSafepointVerifier : public PauseNoGCVerifier { |
|
233 private: |
|
234 NoSafepointVerifier * _nsv; |
|
235 |
|
236 public: |
|
237 #ifdef ASSERT |
|
238 PauseNoSafepointVerifier(NoSafepointVerifier * nsv) |
|
239 : PauseNoGCVerifier(nsv) { |
|
240 |
|
241 _nsv = nsv; |
|
242 if (_nsv->_activated) { |
|
243 _nsv->_thread->_allow_allocation_count--; |
|
244 _nsv->_thread->_allow_safepoint_count--; |
|
245 } |
|
246 } |
|
247 |
|
248 ~PauseNoSafepointVerifier() { |
|
249 if (_nsv->_activated) { |
|
250 _nsv->_thread->_allow_allocation_count++; |
|
251 _nsv->_thread->_allow_safepoint_count++; |
|
252 } |
|
253 } |
|
254 #else |
|
255 PauseNoSafepointVerifier(NoSafepointVerifier * nsv) |
|
256 : PauseNoGCVerifier(nsv) {} |
|
257 ~PauseNoSafepointVerifier() {} |
|
258 #endif |
|
259 }; |
|
260 |
|
261 // A SkipGCALot object is used to elide the usual effect of gc-a-lot |
|
262 // over a section of execution by a thread. Currently, it's used only to |
|
263 // prevent re-entrant calls to GC. |
|
264 class SkipGCALot : public StackObj { |
|
265 private: |
|
266 bool _saved; |
|
267 Thread* _t; |
|
268 |
|
269 public: |
|
270 #ifdef ASSERT |
|
271 SkipGCALot(Thread* t) : _t(t) { |
|
272 _saved = _t->skip_gcalot(); |
|
273 _t->set_skip_gcalot(true); |
|
274 } |
|
275 |
|
276 ~SkipGCALot() { |
|
277 assert(_t->skip_gcalot(), "Save-restore protocol invariant"); |
|
278 _t->set_skip_gcalot(_saved); |
|
279 } |
|
280 #else |
|
281 SkipGCALot(Thread* t) { } |
|
282 ~SkipGCALot() { } |
|
283 #endif |
|
284 }; |
|
285 |
|
286 // JRT_LEAF currently can be called from either _thread_in_Java or |
|
287 // _thread_in_native mode. In _thread_in_native, it is ok |
|
288 // for another thread to trigger GC. The rest of the JRT_LEAF |
|
289 // rules apply. |
|
290 class JRTLeafVerifier : public NoSafepointVerifier { |
|
291 static bool should_verify_GC(); |
|
292 public: |
|
293 #ifdef ASSERT |
|
294 JRTLeafVerifier(); |
|
295 ~JRTLeafVerifier(); |
|
296 #else |
|
297 JRTLeafVerifier() {} |
|
298 ~JRTLeafVerifier() {} |
|
299 #endif |
|
300 }; |
|
301 |
|
302 // A NoAllocVerifier object can be placed in methods where one assumes that |
|
303 // no allocation will occur. The destructor will verify this property |
|
304 // unless the constructor is called with argument false (not activated). |
|
305 // |
|
306 // The check will only be done in debug mode and if activated. |
|
307 // Note: this only makes sense at safepoints (otherwise, other threads may |
|
308 // allocate concurrently.) |
|
309 |
|
310 class NoAllocVerifier : public StackObj { |
|
311 private: |
|
312 bool _activated; |
|
313 |
|
314 public: |
|
315 #ifdef ASSERT |
|
316 NoAllocVerifier(bool activated = true) { |
|
317 _activated = activated; |
|
318 if (_activated) Thread::current()->_allow_allocation_count++; |
|
319 } |
|
320 |
|
321 ~NoAllocVerifier() { |
|
322 if (_activated) Thread::current()->_allow_allocation_count--; |
|
323 } |
|
324 #else |
|
325 NoAllocVerifier(bool activated = true) {} |
|
326 ~NoAllocVerifier() {} |
|
327 #endif |
|
328 }; |
|
329 |
|
330 #endif // SHARE_VM_GC_SHARED_GCLOCKER_HPP |
148 #endif // SHARE_VM_GC_SHARED_GCLOCKER_HPP |