comparison src/share/vm/runtime/mutex.cpp @ 4740:eccc4b1f8945

7050298: ARM: SIGSEGV in JNIHandleBlock::allocate_handle Summary: missing release barrier in Monitor::IUnlock Reviewed-by: dholmes, dice
author vladidan
date Wed, 07 Dec 2011 16:47:08 -0500
parents f08d439fab8c
children aa3d708d67c4
comparison
equal deleted inserted replaced
4739:52b5d32fbfaf 4740:eccc4b1f8945
525 goto Exeunt ; 525 goto Exeunt ;
526 } 526 }
527 527
528 void Monitor::IUnlock (bool RelaxAssert) { 528 void Monitor::IUnlock (bool RelaxAssert) {
529 assert (ILocked(), "invariant") ; 529 assert (ILocked(), "invariant") ;
530 _LockWord.Bytes[_LSBINDEX] = 0 ; // drop outer lock 530 // Conceptually we need a MEMBAR #storestore|#loadstore barrier or fence immediately
531 // before the store that releases the lock. Crucially, all the stores and loads in the
532 // critical section must be globally visible before the store of 0 into the lock-word
533 // that releases the lock becomes globally visible. That is, memory accesses in the
534 // critical section should not be allowed to bypass or overtake the following ST that
535 // releases the lock. As such, to prevent accesses within the critical section
536 // from "leaking" out, we need a release fence between the critical section and the
537 // store that releases the lock. In practice that release barrier is elided on
538 // platforms with strong memory models such as TSO.
539 //
540 // Note that the OrderAccess::storeload() fence that appears after unlock store
541 // provides for progress conditions and succession and is _not related to exclusion
542 // safety or lock release consistency.
543 OrderAccess::release_store(&_LockWord.Bytes[_LSBINDEX], 0); // drop outer lock
544
531 OrderAccess::storeload (); 545 OrderAccess::storeload ();
532 ParkEvent * const w = _OnDeck ; 546 ParkEvent * const w = _OnDeck ;
533 assert (RelaxAssert || w != Thread::current()->_MutexEvent, "invariant") ; 547 assert (RelaxAssert || w != Thread::current()->_MutexEvent, "invariant") ;
534 if (w != NULL) { 548 if (w != NULL) {
535 // Either we have a valid ondeck thread or ondeck is transiently "locked" 549 // Either we have a valid ondeck thread or ondeck is transiently "locked"