diff options
| author | 2018-06-19 01:09:01 +0000 | |
|---|---|---|
| committer | 2018-06-19 01:09:01 +0000 | |
| commit | 2c12bb624e91d8f1282d868fd2f2e33ba3746d6c (patch) | |
| tree | b378c9a7051ce84c3c22847be179845a04d76376 | |
| parent | e3435cb810a5c48626a1564dbed0ae4dda89d57b (diff) | |
| parent | 8bb3c68422ce06f444d7c4e49c7af7b1c5cbeb7c (diff) | |
Merge "Use strong CAS for identity hash code"
| -rw-r--r-- | runtime/mirror/object-readbarrier-inl.h | 34 | ||||
| -rw-r--r-- | runtime/mirror/object.cc | 4 | ||||
| -rw-r--r-- | runtime/mirror/object.h | 10 | ||||
| -rw-r--r-- | runtime/monitor.cc | 12 |
4 files changed, 51 insertions, 9 deletions
diff --git a/runtime/mirror/object-readbarrier-inl.h b/runtime/mirror/object-readbarrier-inl.h index aeaa850abe..2988d06d96 100644 --- a/runtime/mirror/object-readbarrier-inl.h +++ b/runtime/mirror/object-readbarrier-inl.h @@ -39,7 +39,8 @@ inline LockWord Object::GetLockWord(bool as_volatile) { template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> inline bool Object::CasFieldWeakRelaxed32(MemberOffset field_offset, - int32_t old_value, int32_t new_value) { + int32_t old_value, + int32_t new_value) { if (kCheckTransaction) { DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); } @@ -55,10 +56,37 @@ inline bool Object::CasFieldWeakRelaxed32(MemberOffset field_offset, return atomic_addr->CompareAndSetWeakRelaxed(old_value, new_value); } +template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> +inline bool Object::CasFieldStrongRelaxed32(MemberOffset field_offset, + int32_t old_value, + int32_t new_value) { + if (kCheckTransaction) { + DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); + } + if (kTransactionActive) { + Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true); + } + if (kVerifyFlags & kVerifyThis) { + VerifyObject(this); + } + uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); + AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr); + + return atomic_addr->CompareAndSetStrongRelaxed(old_value, new_value); +} + inline bool Object::CasLockWordWeakRelaxed(LockWord old_val, LockWord new_val) { // Force use of non-transactional mode and do not check. - return CasFieldWeakRelaxed32<false, false>( - OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue()); + return CasFieldWeakRelaxed32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), + old_val.GetValue(), + new_val.GetValue()); +} + +inline bool Object::CasLockWordStrongRelaxed(LockWord old_val, LockWord new_val) { + // Force use of non-transactional mode and do not check. + return CasFieldStrongRelaxed32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), + old_val.GetValue(), + new_val.GetValue()); } inline bool Object::CasLockWordWeakRelease(LockWord old_val, LockWord new_val) { diff --git a/runtime/mirror/object.cc b/runtime/mirror/object.cc index 4240e702b5..200bc471b8 100644 --- a/runtime/mirror/object.cc +++ b/runtime/mirror/object.cc @@ -197,7 +197,9 @@ int32_t Object::IdentityHashCode() { // loop iteration. LockWord hash_word = LockWord::FromHashCode(GenerateIdentityHashCode(), lw.GCState()); DCHECK_EQ(hash_word.GetState(), LockWord::kHashCode); - if (current_this->CasLockWordWeakRelaxed(lw, hash_word)) { + // Use a strong CAS to prevent spurious failures since these can make the boot image + // non-deterministic. + if (current_this->CasLockWordStrongRelaxed(lw, hash_word)) { return hash_word.GetHashCode(); } break; diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h index a89d6323a5..f92ff1e2af 100644 --- a/runtime/mirror/object.h +++ b/runtime/mirror/object.h @@ -159,6 +159,8 @@ class MANAGED LOCKABLE Object { REQUIRES_SHARED(Locks::mutator_lock_); bool CasLockWordWeakRelease(LockWord old_val, LockWord new_val) REQUIRES_SHARED(Locks::mutator_lock_); + bool CasLockWordStrongRelaxed(LockWord old_val, LockWord new_val) + REQUIRES_SHARED(Locks::mutator_lock_); uint32_t GetLockOwnerThreadId(); // Try to enter the monitor, returns non null if we succeeded. @@ -539,6 +541,14 @@ class MANAGED LOCKABLE Object { template<bool kTransactionActive, bool kCheckTransaction = true, VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> + ALWAYS_INLINE bool CasFieldStrongRelaxed32(MemberOffset field_offset, + int32_t old_value, + int32_t new_value) + REQUIRES_SHARED(Locks::mutator_lock_); + + template<bool kTransactionActive, + bool kCheckTransaction = true, + VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> ALWAYS_INLINE bool CasFieldWeakAcquire32(MemberOffset field_offset, int32_t old_value, int32_t new_value) diff --git a/runtime/monitor.cc b/runtime/monitor.cc index 2c38de5dae..e723169ac2 100644 --- a/runtime/monitor.cc +++ b/runtime/monitor.cc @@ -134,13 +134,15 @@ Monitor::Monitor(Thread* self, Thread* owner, mirror::Object* obj, int32_t hash_ } int32_t Monitor::GetHashCode() { - while (!HasHashCode()) { - if (hash_code_.CompareAndSetWeakRelaxed(0, mirror::Object::GenerateIdentityHashCode())) { - break; - } + int32_t hc = hash_code_.load(std::memory_order_relaxed); + if (!HasHashCode()) { + // Use a strong CAS to prevent spurious failures since these can make the boot image + // non-deterministic. + hash_code_.CompareAndSetStrongRelaxed(0, mirror::Object::GenerateIdentityHashCode()); + hc = hash_code_.load(std::memory_order_relaxed); } DCHECK(HasHashCode()); - return hash_code_.load(std::memory_order_relaxed); + return hc; } bool Monitor::Install(Thread* self) { |