Refactor SystemArrayCopy intrinsics.

Test: m test-art-host
Test: m test-art-target
Change-Id: I2f9ccdbb831030e670996b97e0c422f505b3abf6
diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc
index 807d6cf..b012608 100644
--- a/compiler/optimizing/intrinsics_arm64.cc
+++ b/compiler/optimizing/intrinsics_arm64.cc
@@ -198,6 +198,8 @@
     DCHECK_NE(LocationFrom(src_stop_addr).reg(), IP0);
     DCHECK_NE(tmp_.reg(), IP0);
     DCHECK(0 <= tmp_.reg() && tmp_.reg() < kNumberOfWRegisters) << tmp_.reg();
+    // TODO: Load the entrypoint once before the loop, instead of
+    // loading it at every iteration.
     int32_t entry_point_offset =
         CodeGenerator::GetReadBarrierMarkEntryPointsOffset<kArm64PointerSize>(tmp_.reg());
     // This runtime call does not require a stack map.
@@ -2191,8 +2193,9 @@
   }
 }
 
-// Compute base source address, base destination address, and end source address
-// for System.arraycopy* intrinsics.
+// Compute base source address, base destination address, and end
+// source address for System.arraycopy* intrinsics in `src_base`,
+// `dst_base` and `src_end` respectively.
 static void GenSystemArrayCopyAddresses(MacroAssembler* masm,
                                         Primitive::Type type,
                                         const Register& src,
@@ -2203,12 +2206,13 @@
                                         const Register& src_base,
                                         const Register& dst_base,
                                         const Register& src_end) {
+  // This routine is used by the SystemArrayCopy and the SystemArrayCopyChar intrinsics.
   DCHECK(type == Primitive::kPrimNot || type == Primitive::kPrimChar)
       << "Unexpected element type: " << type;
   const int32_t element_size = Primitive::ComponentSize(type);
   const int32_t element_size_shift = Primitive::ComponentSizeShift(type);
+  const uint32_t data_offset = mirror::Array::DataOffset(element_size).Uint32Value();
 
-  uint32_t data_offset = mirror::Array::DataOffset(element_size).Uint32Value();
   if (src_pos.IsConstant()) {
     int32_t constant = src_pos.GetConstant()->AsIntConstant()->GetValue();
     __ Add(src_base, src, element_size * constant + data_offset);
@@ -2712,12 +2716,18 @@
       __ Cbnz(temp2, intrinsic_slow_path->GetEntryLabel());
     }
 
+    const Primitive::Type type = Primitive::kPrimNot;
+    const int32_t element_size = Primitive::ComponentSize(Primitive::kPrimNot);
+
     Register src_curr_addr = temp1.X();
     Register dst_curr_addr = temp2.X();
     Register src_stop_addr = temp3.X();
 
+    // Compute base source address, base destination address, and end
+    // source address in `src_curr_addr`, `dst_curr_addr` and
+    // `src_stop_addr` respectively.
     GenSystemArrayCopyAddresses(masm,
-                                Primitive::kPrimNot,
+                                type,
                                 src,
                                 src_pos,
                                 dest,
@@ -2727,8 +2737,6 @@
                                 dst_curr_addr,
                                 src_stop_addr);
 
-    const int32_t element_size = Primitive::ComponentSize(Primitive::kPrimNot);
-
     if (kEmitCompilerReadBarrier && kUseBakerReadBarrier) {
       // TODO: Also convert this intrinsic to the IsGcMarking strategy?
 
@@ -2801,7 +2809,6 @@
       __ Bind(&done);
     } else {
       // Non read barrier code.
-
       // Iterate over the arrays and do a raw copy of the objects. We don't need to
       // poison/unpoison.
       vixl::aarch64::Label loop, done;
@@ -2817,6 +2824,7 @@
       __ Bind(&done);
     }
   }
+
   // We only need one card marking on the destination array.
   codegen_->MarkGCCard(dest.W(), Register(), /* value_can_be_null */ false);