281 |
281 |
282 slow_enter(obj, lock, THREAD); |
282 slow_enter(obj, lock, THREAD); |
283 } |
283 } |
284 |
284 |
285 void ObjectSynchronizer::fast_exit(oop object, BasicLock* lock, TRAPS) { |
285 void ObjectSynchronizer::fast_exit(oop object, BasicLock* lock, TRAPS) { |
286 assert(!object->mark()->has_bias_pattern(), "should not see bias pattern here"); |
286 markOop mark = object->mark(); |
287 // if displaced header is null, the previous enter is recursive enter, no-op |
287 // We cannot check for Biased Locking if we are racing an inflation. |
|
288 assert(mark == markOopDesc::INFLATING() || |
|
289 !mark->has_bias_pattern(), "should not see bias pattern here"); |
|
290 |
288 markOop dhw = lock->displaced_header(); |
291 markOop dhw = lock->displaced_header(); |
289 markOop mark; |
|
290 if (dhw == NULL) { |
292 if (dhw == NULL) { |
291 // Recursive stack-lock. |
293 // If the displaced header is NULL, then this exit matches up with |
292 // Diagnostics -- Could be: stack-locked, inflating, inflated. |
294 // a recursive enter. No real work to do here except for diagnostics. |
293 mark = object->mark(); |
295 #ifndef PRODUCT |
294 assert(!mark->is_neutral(), "invariant"); |
296 if (mark != markOopDesc::INFLATING()) { |
295 if (mark->has_locker() && mark != markOopDesc::INFLATING()) { |
297 // Only do diagnostics if we are not racing an inflation. Simply |
296 assert(THREAD->is_lock_owned((address)mark->locker()), "invariant"); |
298 // exiting a recursive enter of a Java Monitor that is being |
297 } |
299 // inflated is safe; see the has_monitor() comment below. |
298 if (mark->has_monitor()) { |
300 assert(!mark->is_neutral(), "invariant"); |
299 ObjectMonitor * m = mark->monitor(); |
301 assert(!mark->has_locker() || |
300 assert(((oop)(m->object()))->mark() == mark, "invariant"); |
302 THREAD->is_lock_owned((address)mark->locker()), "invariant"); |
301 assert(m->is_entered(THREAD), "invariant"); |
303 if (mark->has_monitor()) { |
302 } |
304 // The BasicLock's displaced_header is marked as a recursive |
|
305 // enter and we have an inflated Java Monitor (ObjectMonitor). |
|
306 // This is a special case where the Java Monitor was inflated |
|
307 // after this thread entered the stack-lock recursively. When a |
|
308 // Java Monitor is inflated, we cannot safely walk the Java |
|
309 // Monitor owner's stack and update the BasicLocks because a |
|
310 // Java Monitor can be asynchronously inflated by a thread that |
|
311 // does not own the Java Monitor. |
|
312 ObjectMonitor * m = mark->monitor(); |
|
313 assert(((oop)(m->object()))->mark() == mark, "invariant"); |
|
314 assert(m->is_entered(THREAD), "invariant"); |
|
315 } |
|
316 } |
|
317 #endif |
303 return; |
318 return; |
304 } |
319 } |
305 |
320 |
306 mark = object->mark(); |
|
307 |
|
308 // If the object is stack-locked by the current thread, try to |
|
309 // swing the displaced header from the box back to the mark. |
|
310 if (mark == (markOop) lock) { |
321 if (mark == (markOop) lock) { |
|
322 // If the object is stack-locked by the current thread, try to |
|
323 // swing the displaced header from the BasicLock back to the mark. |
311 assert(dhw->is_neutral(), "invariant"); |
324 assert(dhw->is_neutral(), "invariant"); |
312 if ((markOop) Atomic::cmpxchg_ptr (dhw, object->mark_addr(), mark) == mark) { |
325 if ((markOop) Atomic::cmpxchg_ptr(dhw, object->mark_addr(), mark) == mark) { |
313 TEVENT(fast_exit: release stacklock); |
326 TEVENT(fast_exit: release stack-lock); |
314 return; |
327 return; |
315 } |
328 } |
316 } |
329 } |
317 |
330 |
|
331 // We have to take the slow-path of possible inflation and then exit. |
318 ObjectSynchronizer::inflate(THREAD, |
332 ObjectSynchronizer::inflate(THREAD, |
319 object, |
333 object, |
320 inflate_cause_vm_internal)->exit(true, THREAD); |
334 inflate_cause_vm_internal)->exit(true, THREAD); |
321 } |
335 } |
322 |
336 |
1745 public: |
1759 public: |
1746 ReleaseJavaMonitorsClosure(Thread* thread) : THREAD(thread) {} |
1760 ReleaseJavaMonitorsClosure(Thread* thread) : THREAD(thread) {} |
1747 void do_monitor(ObjectMonitor* mid) { |
1761 void do_monitor(ObjectMonitor* mid) { |
1748 if (mid->owner() == THREAD) { |
1762 if (mid->owner() == THREAD) { |
1749 if (ObjectMonitor::Knob_VerifyMatch != 0) { |
1763 if (ObjectMonitor::Knob_VerifyMatch != 0) { |
|
1764 ResourceMark rm; |
1750 Handle obj((oop) mid->object()); |
1765 Handle obj((oop) mid->object()); |
1751 tty->print("INFO: unexpected locked object:"); |
1766 tty->print("INFO: unexpected locked object:"); |
1752 javaVFrame::print_locked_object_class_name(tty, obj, "locked"); |
1767 javaVFrame::print_locked_object_class_name(tty, obj, "locked"); |
1753 fatal("exiting JavaThread=" INTPTR_FORMAT |
1768 fatal("exiting JavaThread=" INTPTR_FORMAT |
1754 " unexpectedly owns ObjectMonitor=" INTPTR_FORMAT, |
1769 " unexpectedly owns ObjectMonitor=" INTPTR_FORMAT, |