diff options
author | Ian Rogers <irogers@google.com> | 2014-07-10 17:35:57 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-07-10 16:05:36 +0000 |
commit | adce33da293b0eeaaf52673338770f22be71ca5d (patch) | |
tree | b2d65f4668793fab5652dfe41dcf13c913fee3a8 /runtime | |
parent | cba6b1fc88fd54c35211fd49a7a7501cfcdaa170 (diff) | |
parent | 228602f562f1d130d06e60a98752d99c2d467d6a (diff) | |
download | art-adce33da293b0eeaaf52673338770f22be71ca5d.zip art-adce33da293b0eeaaf52673338770f22be71ca5d.tar.gz art-adce33da293b0eeaaf52673338770f22be71ca5d.tar.bz2 |
Merge "Make CAS operations in Object use art::Atomic."
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/interpreter/interpreter.cc | 6 | ||||
-rw-r--r-- | runtime/mirror/object-inl.h | 47 | ||||
-rw-r--r-- | runtime/mirror/object.cc | 2 | ||||
-rw-r--r-- | runtime/mirror/object.h | 12 | ||||
-rw-r--r-- | runtime/monitor.cc | 4 | ||||
-rw-r--r-- | runtime/native/sun_misc_Unsafe.cc | 9 |
6 files changed, 45 insertions, 35 deletions
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc index cb4d444..729444e 100644 --- a/runtime/interpreter/interpreter.cc +++ b/runtime/interpreter/interpreter.cc @@ -95,9 +95,11 @@ static void UnstartedRuntimeJni(Thread* self, ArtMethod* method, jint newValue = args[4]; bool success; if (Runtime::Current()->IsActiveTransaction()) { - success = obj->CasField32<true>(MemberOffset(offset), expectedValue, newValue); + success = obj->CasFieldWeakSequentiallyConsistent32<true>(MemberOffset(offset), + expectedValue, newValue); } else { - success = obj->CasField32<false>(MemberOffset(offset), expectedValue, newValue); + success = obj->CasFieldWeakSequentiallyConsistent32<false>(MemberOffset(offset), + expectedValue, newValue); } result->SetZ(success ? JNI_TRUE : JNI_FALSE); } else if (name == "void sun.misc.Unsafe.putObject(java.lang.Object, long, java.lang.Object)") { diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h index 62c1162..089ef57 100644 --- a/runtime/mirror/object-inl.h +++ b/runtime/mirror/object-inl.h @@ -69,10 +69,10 @@ inline void Object::SetLockWord(LockWord new_val, bool as_volatile) { } } -inline bool Object::CasLockWord(LockWord old_val, LockWord new_val) { +inline bool Object::CasLockWordWeakSequentiallyConsistent(LockWord old_val, LockWord new_val) { // Force use of non-transactional mode and do not check. - return CasField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), - new_val.GetValue()); + return CasFieldWeakSequentiallyConsistent32<false, false>( + OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue()); } inline uint32_t Object::GetLockOwnerThreadId() { @@ -131,21 +131,17 @@ inline bool Object::AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object* DCHECK(kUseBakerOrBrooksReadBarrier); MemberOffset offset = OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_); byte* raw_addr = reinterpret_cast<byte*>(this) + offset.SizeValue(); - HeapReference<Object>* ref = reinterpret_cast<HeapReference<Object>*>(raw_addr); + Atomic<uint32_t>* atomic_rb_ptr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr); HeapReference<Object> expected_ref(HeapReference<Object>::FromMirrorPtr(expected_rb_ptr)); HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(rb_ptr)); - uint32_t expected_val = expected_ref.reference_; - uint32_t new_val; do { - uint32_t old_val = ref->reference_; - if (old_val != expected_val) { + if (UNLIKELY(atomic_rb_ptr->LoadRelaxed() != expected_ref.reference_)) { // Lost the race. return false; } - new_val = new_ref.reference_; - } while (!__sync_bool_compare_and_swap( - reinterpret_cast<uint32_t*>(raw_addr), expected_val, new_val)); - DCHECK_EQ(new_val, ref->reference_); + } while (!atomic_rb_ptr->CompareExchangeWeakSequentiallyConsistent(expected_ref.reference_, + new_ref.reference_)); + DCHECK_EQ(new_ref.reference_, atomic_rb_ptr->LoadRelaxed()); return true; #else LOG(FATAL) << "Unreachable"; @@ -448,7 +444,8 @@ inline void Object::SetField32Volatile(MemberOffset field_offset, int32_t new_va } template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> -inline bool Object::CasField32(MemberOffset field_offset, int32_t old_value, int32_t new_value) { +inline bool Object::CasFieldWeakSequentiallyConsistent32(MemberOffset field_offset, + int32_t old_value, int32_t new_value) { if (kCheckTransaction) { DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); } @@ -459,9 +456,9 @@ inline bool Object::CasField32(MemberOffset field_offset, int32_t old_value, int VerifyObject(this); } byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value(); - volatile int32_t* addr = reinterpret_cast<volatile int32_t*>(raw_addr); + AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr); - return __sync_bool_compare_and_swap(addr, old_value, new_value); + return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value); } template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> @@ -513,7 +510,8 @@ inline void Object::SetField64Volatile(MemberOffset field_offset, int64_t new_va } template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> -inline bool Object::CasField64(MemberOffset field_offset, int64_t old_value, int64_t new_value) { +inline bool Object::CasFieldWeakSequentiallyConsistent64(MemberOffset field_offset, + int64_t old_value, int64_t new_value) { if (kCheckTransaction) { DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); } @@ -524,8 +522,8 @@ inline bool Object::CasField64(MemberOffset field_offset, int64_t old_value, int VerifyObject(this); } byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value(); - volatile int64_t* addr = reinterpret_cast<volatile int64_t*>(raw_addr); - return QuasiAtomic::Cas64(old_value, new_value, addr); + Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr); + return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value); } template<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, @@ -615,8 +613,8 @@ inline HeapReference<Object>* Object::GetFieldObjectReferenceAddr(MemberOffset f } template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> -inline bool Object::CasFieldObject(MemberOffset field_offset, Object* old_value, - Object* new_value) { +inline bool Object::CasFieldWeakSequentiallyConsistentObject(MemberOffset field_offset, + Object* old_value, Object* new_value) { if (kCheckTransaction) { DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); } @@ -632,11 +630,14 @@ inline bool Object::CasFieldObject(MemberOffset field_offset, Object* old_value, if (kTransactionActive) { Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true); } - byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value(); - volatile int32_t* addr = reinterpret_cast<volatile int32_t*>(raw_addr); HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value)); HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value)); - bool success = __sync_bool_compare_and_swap(addr, old_ref.reference_, new_ref.reference_); + byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value(); + Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr); + + bool success = atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_ref.reference_, + new_ref.reference_); + if (success) { Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value); } diff --git a/runtime/mirror/object.cc b/runtime/mirror/object.cc index 422a88b..e58091f 100644 --- a/runtime/mirror/object.cc +++ b/runtime/mirror/object.cc @@ -156,7 +156,7 @@ int32_t Object::IdentityHashCode() const { // loop iteration. LockWord hash_word(LockWord::FromHashCode(GenerateIdentityHashCode())); DCHECK_EQ(hash_word.GetState(), LockWord::kHashCode); - if (const_cast<Object*>(this)->CasLockWord(lw, hash_word)) { + if (const_cast<Object*>(this)->CasLockWordWeakSequentiallyConsistent(lw, hash_word)) { return hash_word.GetHashCode(); } break; diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h index c082443..d29011a 100644 --- a/runtime/mirror/object.h +++ b/runtime/mirror/object.h @@ -110,7 +110,8 @@ class MANAGED LOCKABLE Object { // have C++11 "strong" semantics. // TODO: In most, possibly all, cases, these assumptions are too strong. // Confirm and weaken the implementation. - bool CasLockWord(LockWord old_val, LockWord new_val) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + bool CasLockWordWeakSequentiallyConsistent(LockWord old_val, LockWord new_val) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); uint32_t GetLockOwnerThreadId(); mirror::Object* MonitorEnter(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) @@ -226,7 +227,8 @@ class MANAGED LOCKABLE Object { template<bool kTransactionActive, bool kCheckTransaction = true, VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> - bool CasFieldObject(MemberOffset field_offset, Object* old_value, Object* new_value) + bool CasFieldWeakSequentiallyConsistentObject(MemberOffset field_offset, Object* old_value, + Object* new_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> @@ -252,7 +254,8 @@ class MANAGED LOCKABLE Object { template<bool kTransactionActive, bool kCheckTransaction = true, VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> - bool CasField32(MemberOffset field_offset, int32_t old_value, int32_t new_value) ALWAYS_INLINE + bool CasFieldWeakSequentiallyConsistent32(MemberOffset field_offset, int32_t old_value, + int32_t new_value) ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kIsVolatile = false> @@ -275,7 +278,8 @@ class MANAGED LOCKABLE Object { template<bool kTransactionActive, bool kCheckTransaction = true, VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> - bool CasField64(MemberOffset field_offset, int64_t old_value, int64_t new_value) + bool CasFieldWeakSequentiallyConsistent64(MemberOffset field_offset, int64_t old_value, + int64_t new_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); template<bool kTransactionActive, bool kCheckTransaction = true, diff --git a/runtime/monitor.cc b/runtime/monitor.cc index c3ec38d..5633a77 100644 --- a/runtime/monitor.cc +++ b/runtime/monitor.cc @@ -163,7 +163,7 @@ bool Monitor::Install(Thread* self) { } LockWord fat(this); // Publish the updated lock word, which may race with other threads. - bool success = GetObject()->CasLockWord(lw, fat); + bool success = GetObject()->CasLockWordWeakSequentiallyConsistent(lw, fat); // Lock profiling. if (success && owner_ != nullptr && lock_profiling_threshold_ != 0) { locking_method_ = owner_->GetCurrentMethod(&locking_dex_pc_); @@ -722,7 +722,7 @@ mirror::Object* Monitor::MonitorEnter(Thread* self, mirror::Object* obj) { switch (lock_word.GetState()) { case LockWord::kUnlocked: { LockWord thin_locked(LockWord::FromThinLockId(thread_id, 0)); - if (h_obj->CasLockWord(lock_word, thin_locked)) { + if (h_obj->CasLockWordWeakSequentiallyConsistent(lock_word, thin_locked)) { // CasLockWord enforces more than the acquire ordering we need here. return h_obj.Get(); // Success! } diff --git a/runtime/native/sun_misc_Unsafe.cc b/runtime/native/sun_misc_Unsafe.cc index d23cfff..7cc4cac 100644 --- a/runtime/native/sun_misc_Unsafe.cc +++ b/runtime/native/sun_misc_Unsafe.cc @@ -28,7 +28,8 @@ static jboolean Unsafe_compareAndSwapInt(JNIEnv* env, jobject, jobject javaObj, ScopedFastNativeObjectAccess soa(env); mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); // JNI must use non transactional mode. - bool success = obj->CasField32<false>(MemberOffset(offset), expectedValue, newValue); + bool success = obj->CasFieldWeakSequentiallyConsistent32<false>(MemberOffset(offset), + expectedValue, newValue); return success ? JNI_TRUE : JNI_FALSE; } @@ -37,7 +38,8 @@ static jboolean Unsafe_compareAndSwapLong(JNIEnv* env, jobject, jobject javaObj, ScopedFastNativeObjectAccess soa(env); mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); // JNI must use non transactional mode. - bool success = obj->CasField64<false>(MemberOffset(offset), expectedValue, newValue); + bool success = obj->CasFieldWeakSequentiallyConsistent64<false>(MemberOffset(offset), + expectedValue, newValue); return success ? JNI_TRUE : JNI_FALSE; } @@ -48,7 +50,8 @@ static jboolean Unsafe_compareAndSwapObject(JNIEnv* env, jobject, jobject javaOb mirror::Object* expectedValue = soa.Decode<mirror::Object*>(javaExpectedValue); mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue); // JNI must use non transactional mode. - bool success = obj->CasFieldObject<false>(MemberOffset(offset), expectedValue, newValue); + bool success = obj->CasFieldWeakSequentiallyConsistentObject<false>(MemberOffset(offset), + expectedValue, newValue); return success ? JNI_TRUE : JNI_FALSE; } |