Introduce more compact ReadBarrierMark slow-paths.
Replace entry point ReadBarrierMark with 32
ReadBarrierMarkRegX entry points, using register
number X as input and output (instead of the standard
runtime calling convention) to save two moves in Baker's
read barrier mark slow-path code.
Test: ART host and target (ARM, ARM64) tests.
Bug: 29506760
Bug: 12687968
Change-Id: I73cfb82831cf040b8b018e984163c865cc44ed87
diff --git a/runtime/arch/arm/entrypoints_init_arm.cc b/runtime/arch/arm/entrypoints_init_arm.cc
index 4c68862..8f18ff3 100644
--- a/runtime/arch/arm/entrypoints_init_arm.cc
+++ b/runtime/arch/arm/entrypoints_init_arm.cc
@@ -30,6 +30,22 @@
extern "C" uint32_t artIsAssignableFromCode(const mirror::Class* klass,
const mirror::Class* ref_class);
+// Read barrier entrypoints.
+// art_quick_read_barrier_mark_regX uses an non-standard calling
+// convention: it expects its input in register X and returns its
+// result in that same register.
+extern "C" mirror::Object* art_quick_read_barrier_mark_reg01(mirror::Object*);
+extern "C" mirror::Object* art_quick_read_barrier_mark_reg02(mirror::Object*);
+extern "C" mirror::Object* art_quick_read_barrier_mark_reg03(mirror::Object*);
+extern "C" mirror::Object* art_quick_read_barrier_mark_reg04(mirror::Object*);
+extern "C" mirror::Object* art_quick_read_barrier_mark_reg05(mirror::Object*);
+extern "C" mirror::Object* art_quick_read_barrier_mark_reg06(mirror::Object*);
+extern "C" mirror::Object* art_quick_read_barrier_mark_reg07(mirror::Object*);
+extern "C" mirror::Object* art_quick_read_barrier_mark_reg08(mirror::Object*);
+extern "C" mirror::Object* art_quick_read_barrier_mark_reg09(mirror::Object*);
+extern "C" mirror::Object* art_quick_read_barrier_mark_reg10(mirror::Object*);
+extern "C" mirror::Object* art_quick_read_barrier_mark_reg11(mirror::Object*);
+extern "C" mirror::Object* art_quick_read_barrier_mark_reg12(mirror::Object*);
// Used by soft float.
// Single-precision FP arithmetics.
@@ -103,7 +119,39 @@
// Read barrier.
qpoints->pReadBarrierJni = ReadBarrierJni;
- qpoints->pReadBarrierMark = artReadBarrierMark;
+ qpoints->pReadBarrierMarkReg00 = artReadBarrierMark;
+ qpoints->pReadBarrierMarkReg01 = art_quick_read_barrier_mark_reg01;
+ qpoints->pReadBarrierMarkReg02 = art_quick_read_barrier_mark_reg02;
+ qpoints->pReadBarrierMarkReg03 = art_quick_read_barrier_mark_reg03;
+ qpoints->pReadBarrierMarkReg04 = art_quick_read_barrier_mark_reg04;
+ qpoints->pReadBarrierMarkReg05 = art_quick_read_barrier_mark_reg05;
+ qpoints->pReadBarrierMarkReg06 = art_quick_read_barrier_mark_reg06;
+ qpoints->pReadBarrierMarkReg07 = art_quick_read_barrier_mark_reg07;
+ qpoints->pReadBarrierMarkReg08 = art_quick_read_barrier_mark_reg08;
+ qpoints->pReadBarrierMarkReg09 = art_quick_read_barrier_mark_reg09;
+ qpoints->pReadBarrierMarkReg10 = art_quick_read_barrier_mark_reg10;
+ qpoints->pReadBarrierMarkReg11 = art_quick_read_barrier_mark_reg11;
+ qpoints->pReadBarrierMarkReg12 = art_quick_read_barrier_mark_reg12;
+ qpoints->pReadBarrierMarkReg13 = nullptr; // Cannot use register 13 (SP) to pass arguments.
+ qpoints->pReadBarrierMarkReg14 = nullptr; // Cannot use register 14 (LR) to pass arguments.
+ qpoints->pReadBarrierMarkReg15 = nullptr; // Cannot use register 15 (PC) to pass arguments.
+ // ARM has only 16 core registers.
+ qpoints->pReadBarrierMarkReg16 = nullptr;
+ qpoints->pReadBarrierMarkReg17 = nullptr;
+ qpoints->pReadBarrierMarkReg18 = nullptr;
+ qpoints->pReadBarrierMarkReg19 = nullptr;
+ qpoints->pReadBarrierMarkReg20 = nullptr;
+ qpoints->pReadBarrierMarkReg21 = nullptr;
+ qpoints->pReadBarrierMarkReg22 = nullptr;
+ qpoints->pReadBarrierMarkReg23 = nullptr;
+ qpoints->pReadBarrierMarkReg24 = nullptr;
+ qpoints->pReadBarrierMarkReg25 = nullptr;
+ qpoints->pReadBarrierMarkReg26 = nullptr;
+ qpoints->pReadBarrierMarkReg27 = nullptr;
+ qpoints->pReadBarrierMarkReg28 = nullptr;
+ qpoints->pReadBarrierMarkReg29 = nullptr;
+ qpoints->pReadBarrierMarkReg30 = nullptr;
+ qpoints->pReadBarrierMarkReg31 = nullptr;
qpoints->pReadBarrierSlow = artReadBarrierSlow;
qpoints->pReadBarrierForRootSlow = artReadBarrierForRootSlow;
}
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S
index d940164..82d64b9 100644
--- a/runtime/arch/arm/quick_entrypoints_arm.S
+++ b/runtime/arch/arm/quick_entrypoints_arm.S
@@ -1743,3 +1743,43 @@
.cfi_adjust_cfa_offset -4
pop {pc}
END art_quick_l2f
+
+ /*
+ * Create a function `name` calling the ReadBarrier::Mark routine,
+ * getting its argument and returning its result through register
+ * `reg`, thus following a non-standard runtime calling convention:
+ * - `reg` is used to pass the (sole) argument of this function
+ * (instead of R0);
+ * - `reg` is used to return the result of this function (instead of R0);
+ * - R0 is treated like a normal (non-argument) caller-save register;
+ * - everything else is the same as in the standard runtime calling
+ * convention (e.g. same callee-save registers).
+ */
+.macro READ_BARRIER_MARK_REG name, reg
+ENTRY \name
+ push {lr} @ save return address
+ .cfi_adjust_cfa_offset 4
+ .cfi_rel_offset lr, 0
+ sub sp, #4 @ push padding (native calling convention 8-byte alignment)
+ .cfi_adjust_cfa_offset 4
+ mov r0, \reg @ pass arg1 - obj from `reg`
+ bl artReadBarrierMark @ artReadBarrierMark(obj)
+ mov \reg, r0 @ return result into `reg`
+ add sp, #4 @ pop padding
+ .cfi_adjust_cfa_offset -4
+ pop {pc} @ return
+END \name
+.endm
+
+READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg01, r1
+READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg02, r2
+READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg03, r3
+READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg04, r4
+READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg05, r5
+READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg06, r6
+READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg07, r7
+READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg08, r8
+READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg09, r9
+READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg10, r10
+READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg11, r11
+READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg12, r12