Use art::Atomic for CopyObject

Just to be sure it doesn't get turned into memcpy.

Also avoid casting ObjectArray to IntArray. This is a strict aliasing
violation.

Bug: 32012820

Test: test-art-host

Change-Id: Icc5d4a758cb4f4e1686389bb0cb74ac08e554f04
diff --git a/runtime/mirror/object.cc b/runtime/mirror/object.cc
index 8e49743..9d3c26e 100644
--- a/runtime/mirror/object.cc
+++ b/runtime/mirror/object.cc
@@ -86,14 +86,16 @@
     DCHECK_ALIGNED(dst_bytes, sizeof(uintptr_t));
     // Use word sized copies to begin.
     while (num_bytes >= sizeof(uintptr_t)) {
-      *reinterpret_cast<uintptr_t*>(dst_bytes) = *reinterpret_cast<uintptr_t*>(src_bytes);
+      reinterpret_cast<Atomic<uintptr_t>*>(dst_bytes)->StoreRelaxed(
+          reinterpret_cast<Atomic<uintptr_t>*>(src_bytes)->LoadRelaxed());
       src_bytes += sizeof(uintptr_t);
       dst_bytes += sizeof(uintptr_t);
       num_bytes -= sizeof(uintptr_t);
     }
     // Copy possible 32 bit word.
     if (sizeof(uintptr_t) != sizeof(uint32_t) && num_bytes >= sizeof(uint32_t)) {
-      *reinterpret_cast<uint32_t*>(dst_bytes) = *reinterpret_cast<uint32_t*>(src_bytes);
+      reinterpret_cast<Atomic<uint32_t>*>(dst_bytes)->StoreRelaxed(
+          reinterpret_cast<Atomic<uint32_t>*>(src_bytes)->LoadRelaxed());
       src_bytes += sizeof(uint32_t);
       dst_bytes += sizeof(uint32_t);
       num_bytes -= sizeof(uint32_t);
@@ -101,7 +103,8 @@
     // Copy remaining bytes, avoid going past the end of num_bytes since there may be a redzone
     // there.
     while (num_bytes > 0) {
-      *reinterpret_cast<uint8_t*>(dst_bytes) = *reinterpret_cast<uint8_t*>(src_bytes);
+      reinterpret_cast<Atomic<uint8_t>*>(dst_bytes)->StoreRelaxed(
+          reinterpret_cast<Atomic<uint8_t>*>(src_bytes)->LoadRelaxed());
       src_bytes += sizeof(uint8_t);
       dst_bytes += sizeof(uint8_t);
       num_bytes -= sizeof(uint8_t);
diff --git a/runtime/mirror/object_array-inl.h b/runtime/mirror/object_array-inl.h
index c3c5231..d5bc256 100644
--- a/runtime/mirror/object_array-inl.h
+++ b/runtime/mirror/object_array-inl.h
@@ -131,28 +131,24 @@
   // Perform the memmove using int memmove then perform the write barrier.
   static_assert(sizeof(HeapReference<T>) == sizeof(uint32_t),
                 "art::mirror::HeapReference<T> and uint32_t have different sizes.");
-  IntArray* dstAsIntArray = reinterpret_cast<IntArray*>(this);
-  IntArray* srcAsIntArray = reinterpret_cast<IntArray*>(src);
-  if (kUseReadBarrier) {
-    // TODO: Optimize this later?
-    const bool copy_forward = (src != this) || (dst_pos < src_pos) || (dst_pos - src_pos >= count);
-    if (copy_forward) {
-      // Forward copy.
-      for (int i = 0; i < count; ++i) {
-        // We need a RB here. ObjectArray::GetWithoutChecks() contains a RB.
-        Object* obj = src->GetWithoutChecks(src_pos + i);
-        SetWithoutChecks<false>(dst_pos + i, obj);
-      }
-    } else {
-      // Backward copy.
-      for (int i = count - 1; i >= 0; --i) {
-        // We need a RB here. ObjectArray::GetWithoutChecks() contains a RB.
-        Object* obj = src->GetWithoutChecks(src_pos + i);
-        SetWithoutChecks<false>(dst_pos + i, obj);
-      }
+  // TODO: Optimize this later?
+  // We can't use memmove since it does not handle read barriers and may do by per byte copying.
+  // See b/32012820.
+  const bool copy_forward = (src != this) || (dst_pos < src_pos) || (dst_pos - src_pos >= count);
+  if (copy_forward) {
+    // Forward copy.
+    for (int i = 0; i < count; ++i) {
+      // We need a RB here. ObjectArray::GetWithoutChecks() contains a RB.
+      Object* obj = src->GetWithoutChecks(src_pos + i);
+      SetWithoutChecksAndWriteBarrier<false>(dst_pos + i, obj);
     }
   } else {
-    dstAsIntArray->Memmove(dst_pos, srcAsIntArray, src_pos, count);
+    // Backward copy.
+    for (int i = count - 1; i >= 0; --i) {
+      // We need a RB here. ObjectArray::GetWithoutChecks() contains a RB.
+      Object* obj = src->GetWithoutChecks(src_pos + i);
+      SetWithoutChecksAndWriteBarrier<false>(dst_pos + i, obj);
+    }
   }
   Runtime::Current()->GetHeap()->WriteBarrierArray(this, dst_pos, count);
   if (kIsDebugBuild) {
@@ -175,17 +171,13 @@
   // Perform the memmove using int memcpy then perform the write barrier.
   static_assert(sizeof(HeapReference<T>) == sizeof(uint32_t),
                 "art::mirror::HeapReference<T> and uint32_t have different sizes.");
-  IntArray* dstAsIntArray = reinterpret_cast<IntArray*>(this);
-  IntArray* srcAsIntArray = reinterpret_cast<IntArray*>(src);
-  if (kUseReadBarrier) {
-    // TODO: Optimize this later?
-    for (int i = 0; i < count; ++i) {
-      // We need a RB here. ObjectArray::GetWithoutChecks() contains a RB.
-      T* obj = src->GetWithoutChecks(src_pos + i);
-      SetWithoutChecks<false>(dst_pos + i, obj);
-    }
-  } else {
-    dstAsIntArray->Memcpy(dst_pos, srcAsIntArray, src_pos, count);
+  // TODO: Optimize this later?
+  // We can't use memmove since it does not handle read barriers and may do by per byte copying.
+  // See b/32012820.
+  for (int i = 0; i < count; ++i) {
+    // We need a RB here. ObjectArray::GetWithoutChecks() contains a RB.
+    T* obj = src->GetWithoutChecks(src_pos + i);
+    SetWithoutChecksAndWriteBarrier<false>(dst_pos + i, obj);
   }
   Runtime::Current()->GetHeap()->WriteBarrierArray(this, dst_pos, count);
   if (kIsDebugBuild) {