Introduce a Marking Register in ARM code generation.
When generating code for ARM, maintain the status of
Thread::Current()->GetIsGcMarking() in register R8,
dubbed MR (Marking Register), and check the value of that
register (instead of loading and checking a read barrier
marking entrypoint) in read barriers.
Test: m test-art-target
Test: m test-art-target with tree built with ART_USE_READ_BARRIER=false
Test: m test-art-host-gtest
Test: ARM device boot test
Bug: 37707231
Change-Id: I30b44254460d0bbb9f1b2adc65eca52ca3de3f53
diff --git a/compiler/utils/arm/assembler_arm_vixl.cc b/compiler/utils/arm/assembler_arm_vixl.cc
index eb3f870..af3b447 100644
--- a/compiler/utils/arm/assembler_arm_vixl.cc
+++ b/compiler/utils/arm/assembler_arm_vixl.cc
@@ -37,7 +37,10 @@
#define ___ vixl_masm_.
#endif
+// Thread register definition.
extern const vixl32::Register tr(TR);
+// Marking register definition.
+extern const vixl32::Register mr(MR);
void ArmVIXLAssembler::FinalizeCode() {
vixl_masm_.FinalizeCode();
diff --git a/compiler/utils/arm/assembler_arm_vixl.h b/compiler/utils/arm/assembler_arm_vixl.h
index e81e767..66b22ea 100644
--- a/compiler/utils/arm/assembler_arm_vixl.h
+++ b/compiler/utils/arm/assembler_arm_vixl.h
@@ -241,6 +241,8 @@
// Thread register declaration.
extern const vixl32::Register tr;
+// Marking register declaration.
+extern const vixl32::Register mr;
} // namespace arm
} // namespace art
diff --git a/compiler/utils/arm/jni_macro_assembler_arm_vixl.cc b/compiler/utils/arm/jni_macro_assembler_arm_vixl.cc
index d07c047..bebe64c 100644
--- a/compiler/utils/arm/jni_macro_assembler_arm_vixl.cc
+++ b/compiler/utils/arm/jni_macro_assembler_arm_vixl.cc
@@ -120,8 +120,8 @@
CHECK_ALIGNED(frame_size, kStackAlignment);
cfi().RememberState();
- // Compute callee saves to pop and PC.
- RegList core_spill_mask = 1 << PC;
+ // Compute callee saves to pop and LR.
+ RegList core_spill_mask = 1 << LR;
uint32_t fp_spill_mask = 0;
for (const ManagedRegister& reg : callee_save_regs) {
if (reg.AsArm().IsCoreRegister()) {
@@ -136,6 +136,7 @@
CHECK_GT(frame_size, pop_values * kFramePointerSize);
DecreaseFrameSize(frame_size - (pop_values * kFramePointerSize)); // handles CFI as well.
+ // Pop FP callee saves.
if (fp_spill_mask != 0) {
uint32_t first = CTZ(fp_spill_mask);
// Check that list is contiguous.
@@ -146,9 +147,18 @@
cfi().RestoreMany(DWARFReg(s0), fp_spill_mask);
}
- // Pop callee saves and PC.
+ // Pop core callee saves and LR.
___ Pop(RegisterList(core_spill_mask));
+ if (kEmitCompilerReadBarrier && kUseBakerReadBarrier) {
+ // Refresh Mark Register.
+ // TODO: Refresh MR only if suspend is taken.
+ ___ Ldr(mr, MemOperand(tr, Thread::IsGcMarkingOffset<kArmPointerSize>().Int32Value()));
+ }
+
+ // Return to LR.
+ ___ Bx(vixl32::lr);
+
// The CFI should be restored for any code that follows the exit block.
cfi().RestoreState();
cfi().DefCFAOffset(frame_size);
diff --git a/compiler/utils/arm64/jni_macro_assembler_arm64.cc b/compiler/utils/arm64/jni_macro_assembler_arm64.cc
index c436fd9..bab84be 100644
--- a/compiler/utils/arm64/jni_macro_assembler_arm64.cc
+++ b/compiler/utils/arm64/jni_macro_assembler_arm64.cc
@@ -782,7 +782,7 @@
// Decrease frame size to start of callee saved regs.
DecreaseFrameSize(frame_size);
- // Pop callee saved and return to LR.
+ // Return to LR.
___ Ret();
// The CFI should be restored for any code that follows the exit block.
diff --git a/compiler/utils/assembler_thumb_test.cc b/compiler/utils/assembler_thumb_test.cc
index 4e9b619..759ed38 100644
--- a/compiler/utils/assembler_thumb_test.cc
+++ b/compiler/utils/assembler_thumb_test.cc
@@ -1643,6 +1643,10 @@
#define __ assembler.
TEST_F(ArmVIXLAssemblerTest, VixlJniHelpers) {
+ // Run the test only with Baker read barriers, as the expected
+ // generated code contains a Marking Register refresh instruction.
+ TEST_DISABLED_WITHOUT_BAKER_READ_BARRIERS();
+
const bool is_static = true;
const bool is_synchronized = false;
const bool is_critical_native = false;
diff --git a/compiler/utils/assembler_thumb_test_expected.cc.inc b/compiler/utils/assembler_thumb_test_expected.cc.inc
index eaaf815..563d135 100644
--- a/compiler/utils/assembler_thumb_test_expected.cc.inc
+++ b/compiler/utils/assembler_thumb_test_expected.cc.inc
@@ -5595,7 +5595,7 @@
" 1dc: f8cd c7ff str.w ip, [sp, #2047] ; 0x7ff\n",
" 1e0: f8cd c7ff str.w ip, [sp, #2047] ; 0x7ff\n",
" 1e4: f000 b802 b.w 1ec <VixlJniHelpers+0x1ec>\n",
- " 1e8: f000 b818 b.w 21c <VixlJniHelpers+0x21c>\n",
+ " 1e8: f000 b81b b.w 222 <VixlJniHelpers+0x222>\n",
" 1ec: f8cd c7ff str.w ip, [sp, #2047] ; 0x7ff\n",
" 1f0: f8cd c7ff str.w ip, [sp, #2047] ; 0x7ff\n",
" 1f4: f8cd c7ff str.w ip, [sp, #2047] ; 0x7ff\n",
@@ -5608,10 +5608,12 @@
" 210: b008 add sp, #32\n",
" 212: b009 add sp, #36 ; 0x24\n",
" 214: ecbd 8a10 vpop {s16-s31}\n",
- " 218: e8bd 8de0 ldmia.w sp!, {r5, r6, r7, r8, sl, fp, pc}\n",
- " 21c: 4660 mov r0, ip\n",
- " 21e: f8d9 c2c0 ldr.w ip, [r9, #704] ; 0x2c0\n",
- " 222: 47e0 blx ip\n",
+ " 218: e8bd 4de0 ldmia.w sp!, {r5, r6, r7, r8, sl, fp, lr}\n",
+ " 21c: f8d9 8034 ldr.w r8, [r9, #52] ; 0x34\n",
+ " 220: 4770 bx lr\n",
+ " 222: 4660 mov r0, ip\n",
+ " 224: f8d9 c2c0 ldr.w ip, [r9, #704] ; 0x2c0\n",
+ " 228: 47e0 blx ip\n",
nullptr
};