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;