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);