Refactor Object CAS with and without write barrier
Removes duplicated logic.
Test: test-art-host
Change-Id: I1f5df417c59312f224e0a448c7bd6358912bba07
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 44b0c2b..26dba02 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -114,13 +114,17 @@
bool set;
// Set the ext_data_ field using CAS semantics.
if (Runtime::Current()->IsActiveTransaction()) {
- set = h_this->CasFieldStrongSequentiallyConsistentObject<true>(ext_offset,
- ObjPtr<ClassExt>(nullptr),
- new_ext.Get());
+ set = h_this->CasFieldObject<true>(ext_offset,
+ nullptr,
+ new_ext.Get(),
+ CASMode::kStrong,
+ std::memory_order_seq_cst);
} else {
- set = h_this->CasFieldStrongSequentiallyConsistentObject<false>(ext_offset,
- ObjPtr<ClassExt>(nullptr),
- new_ext.Get());
+ set = h_this->CasFieldObject<false>(ext_offset,
+ nullptr,
+ new_ext.Get(),
+ CASMode::kStrong,
+ std::memory_order_seq_cst);
}
ObjPtr<ClassExt> ret(set ? new_ext.Get() : h_this->GetExtData());
DCHECK(!set || h_this->GetExtData() == new_ext.Get());
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index d94ded0..47f0a29 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -665,11 +665,35 @@
}
template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
-inline bool Object::CasFieldWeakSequentiallyConsistentObject(MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value) {
- bool success = CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier<
- kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset, old_value, new_value);
+inline bool Object::CasFieldObjectWithoutWriteBarrier(MemberOffset field_offset,
+ ObjPtr<Object> old_value,
+ ObjPtr<Object> new_value,
+ CASMode mode,
+ std::memory_order memory_order) {
+ VerifyTransaction<kTransactionActive, kCheckTransaction>();
+ VerifyCAS<kVerifyFlags>(new_value, old_value);
+ if (kTransactionActive) {
+ Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
+ }
+ uint32_t old_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(old_value));
+ uint32_t new_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(new_value));
+ uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
+ Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
+ return atomic_addr->CompareAndSet(old_ref, new_ref, mode, memory_order);
+}
+
+template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
+inline bool Object::CasFieldObject(MemberOffset field_offset,
+ ObjPtr<Object> old_value,
+ ObjPtr<Object> new_value,
+ CASMode mode,
+ std::memory_order memory_order) {
+ bool success = CasFieldObjectWithoutWriteBarrier<
+ kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset,
+ old_value,
+ new_value,
+ mode,
+ memory_order);
if (success) {
WriteBarrier::ForFieldWrite(this, field_offset, new_value);
}
@@ -677,94 +701,6 @@
}
template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
-inline bool Object::CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier(
- MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value) {
- VerifyTransaction<kTransactionActive, kCheckTransaction>();
- VerifyCAS<kVerifyFlags>(new_value, old_value);
- if (kTransactionActive) {
- Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
- }
- uint32_t old_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(old_value));
- uint32_t new_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(new_value));
- uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
- Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
-
- bool success = atomic_addr->CompareAndSetWeakSequentiallyConsistent(old_ref, new_ref);
- return success;
-}
-
-template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
-inline bool Object::CasFieldStrongSequentiallyConsistentObject(MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value) {
- bool success = CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier<
- kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset, old_value, new_value);
- if (success) {
- WriteBarrier::ForFieldWrite(this, field_offset, new_value);
- }
- return success;
-}
-
-template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
-inline bool Object::CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier(
- MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value) {
- VerifyTransaction<kTransactionActive, kCheckTransaction>();
- VerifyCAS<kVerifyFlags>(new_value, old_value);
- if (kTransactionActive) {
- Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
- }
- uint32_t old_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(old_value));
- uint32_t new_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(new_value));
- uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
- Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
-
- bool success = atomic_addr->CompareAndSetStrongSequentiallyConsistent(old_ref, new_ref);
- return success;
-}
-
-template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
-inline bool Object::CasFieldWeakRelaxedObjectWithoutWriteBarrier(
- MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value) {
- VerifyTransaction<kTransactionActive, kCheckTransaction>();
- VerifyCAS<kVerifyFlags>(new_value, old_value);
- if (kTransactionActive) {
- Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
- }
- uint32_t old_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(old_value));
- uint32_t new_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(new_value));
- uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
- Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
-
- bool success = atomic_addr->CompareAndSetWeakRelaxed(old_ref, new_ref);
- return success;
-}
-
-template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
-inline bool Object::CasFieldWeakReleaseObjectWithoutWriteBarrier(
- MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value) {
- VerifyTransaction<kTransactionActive, kCheckTransaction>();
- VerifyCAS<kVerifyFlags>(new_value, old_value);
- if (kTransactionActive) {
- Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
- }
- uint32_t old_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(old_value));
- uint32_t new_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(new_value));
- uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
- Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
-
- bool success = atomic_addr->CompareAndSetWeakRelease(old_ref, new_ref);
- return success;
-}
-
-template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
inline ObjPtr<Object> Object::CompareAndExchangeFieldObject(MemberOffset field_offset,
ObjPtr<Object> old_value,
ObjPtr<Object> new_value) {
diff --git a/runtime/mirror/object-readbarrier-inl.h b/runtime/mirror/object-readbarrier-inl.h
index 634a83a..df50d06 100644
--- a/runtime/mirror/object-readbarrier-inl.h
+++ b/runtime/mirror/object-readbarrier-inl.h
@@ -193,64 +193,6 @@
return true;
}
-template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
-inline bool Object::CasFieldStrongRelaxedObjectWithoutWriteBarrier(
- MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value) {
- if (kCheckTransaction) {
- DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
- }
- if (kVerifyFlags & kVerifyThis) {
- VerifyObject(this);
- }
- if (kVerifyFlags & kVerifyWrites) {
- VerifyObject(new_value);
- }
- if (kVerifyFlags & kVerifyReads) {
- VerifyObject(old_value);
- }
- if (kTransactionActive) {
- Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
- }
- uint32_t old_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(old_value));
- uint32_t new_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(new_value));
- uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
- Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
-
- bool success = atomic_addr->CompareAndSetStrongRelaxed(old_ref, new_ref);
- return success;
-}
-
-template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
-inline bool Object::CasFieldStrongReleaseObjectWithoutWriteBarrier(
- MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value) {
- if (kCheckTransaction) {
- DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
- }
- if (kVerifyFlags & kVerifyThis) {
- VerifyObject(this);
- }
- if (kVerifyFlags & kVerifyWrites) {
- VerifyObject(new_value);
- }
- if (kVerifyFlags & kVerifyReads) {
- VerifyObject(old_value);
- }
- if (kTransactionActive) {
- Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
- }
- uint32_t old_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(old_value));
- uint32_t new_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(new_value));
- uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
- Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
-
- bool success = atomic_addr->CompareAndSetStrongRelease(old_ref, new_ref);
- return success;
-}
-
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h
index e19b524..c7cffed 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -315,30 +315,20 @@
template<bool kTransactionActive,
bool kCheckTransaction = true,
VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- bool CasFieldWeakSequentiallyConsistentObject(MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value)
+ ALWAYS_INLINE bool CasFieldObject(MemberOffset field_offset,
+ ObjPtr<Object> old_value,
+ ObjPtr<Object> new_value,
+ CASMode mode,
+ std::memory_order memory_order)
REQUIRES_SHARED(Locks::mutator_lock_);
template<bool kTransactionActive,
bool kCheckTransaction = true,
VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- bool CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier(MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value)
- REQUIRES_SHARED(Locks::mutator_lock_);
- template<bool kTransactionActive,
- bool kCheckTransaction = true,
- VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- bool CasFieldStrongSequentiallyConsistentObject(MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value)
- REQUIRES_SHARED(Locks::mutator_lock_);
- template<bool kTransactionActive,
- bool kCheckTransaction = true,
- VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- bool CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier(MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value)
+ ALWAYS_INLINE bool CasFieldObjectWithoutWriteBarrier(MemberOffset field_offset,
+ ObjPtr<Object> old_value,
+ ObjPtr<Object> new_value,
+ CASMode mode,
+ std::memory_order memory_order)
REQUIRES_SHARED(Locks::mutator_lock_);
template<bool kTransactionActive,
@@ -355,36 +345,6 @@
ObjPtr<Object> ExchangeFieldObject(MemberOffset field_offset, ObjPtr<Object> new_value)
REQUIRES_SHARED(Locks::mutator_lock_);
- template<bool kTransactionActive,
- bool kCheckTransaction = true,
- VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- bool CasFieldWeakRelaxedObjectWithoutWriteBarrier(MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value)
- REQUIRES_SHARED(Locks::mutator_lock_);
- template<bool kTransactionActive,
- bool kCheckTransaction = true,
- VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- bool CasFieldWeakReleaseObjectWithoutWriteBarrier(MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- template<bool kTransactionActive,
- bool kCheckTransaction = true,
- VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- bool CasFieldStrongRelaxedObjectWithoutWriteBarrier(MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value)
- REQUIRES_SHARED(Locks::mutator_lock_);
- template<bool kTransactionActive,
- bool kCheckTransaction = true,
- VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- bool CasFieldStrongReleaseObjectWithoutWriteBarrier(MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
HeapReference<Object>* GetFieldObjectReferenceAddr(MemberOffset field_offset)
REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/mirror/var_handle.cc b/runtime/mirror/var_handle.cc
index 4319c5d..56c953b 100644
--- a/runtime/mirror/var_handle.cc
+++ b/runtime/mirror/var_handle.cc
@@ -1021,15 +1021,17 @@
ObjPtr<Object> desired_value = ValueGetter<ObjPtr<Object>>::Get(getter);
bool cas_result;
if (Runtime::Current()->IsActiveTransaction()) {
- cas_result = obj->CasFieldStrongSequentiallyConsistentObject<kTransactionActive>(
- field_offset,
- expected_value,
- desired_value);
+ cas_result = obj->CasFieldObject<kTransactionActive>(field_offset,
+ expected_value,
+ desired_value,
+ CASMode::kStrong,
+ std::memory_order_seq_cst);
} else {
- cas_result = obj->CasFieldStrongSequentiallyConsistentObject<kTransactionInactive>(
- field_offset,
- expected_value,
- desired_value);
+ cas_result = obj->CasFieldObject<kTransactionInactive>(field_offset,
+ expected_value,
+ desired_value,
+ CASMode::kStrong,
+ std::memory_order_seq_cst);
}
StoreResult(cas_result, result);
break;
@@ -1043,15 +1045,18 @@
ObjPtr<Object> desired_value = ValueGetter<ObjPtr<Object>>::Get(getter);
bool cas_result;
if (Runtime::Current()->IsActiveTransaction()) {
- cas_result = obj->CasFieldWeakSequentiallyConsistentObject<kTransactionActive>(
- field_offset,
- expected_value,
- desired_value);
+ cas_result = obj->CasFieldObject<kTransactionActive>(field_offset,
+ expected_value,
+ desired_value,
+ CASMode::kWeak,
+ std::memory_order_seq_cst);
} else {
- cas_result = obj->CasFieldWeakSequentiallyConsistentObject<kTransactionInactive>(
+ cas_result = obj->CasFieldObject<kTransactionInactive>(
field_offset,
expected_value,
- desired_value);
+ desired_value,
+ CASMode::kWeak,
+ std::memory_order_seq_cst);
}
StoreResult(cas_result, result);
break;
@@ -1064,15 +1069,13 @@
ObjPtr<Object> desired_value = ValueGetter<ObjPtr<Object>>::Get(getter);
ObjPtr<Object> witness_value;
if (Runtime::Current()->IsActiveTransaction()) {
- witness_value = obj->CompareAndExchangeFieldObject<kTransactionActive>(
- field_offset,
- expected_value,
- desired_value);
+ witness_value = obj->CompareAndExchangeFieldObject<kTransactionActive>(field_offset,
+ expected_value,
+ desired_value);
} else {
- witness_value = obj->CompareAndExchangeFieldObject<kTransactionInactive>(
- field_offset,
- expected_value,
- desired_value);
+ witness_value = obj->CompareAndExchangeFieldObject<kTransactionInactive>(field_offset,
+ expected_value,
+ desired_value);
}
StoreResult(witness_value, result);
break;