summaryrefslogtreecommitdiff
path: root/src/jit/target.h
diff options
context:
space:
mode:
authorBruce Forstall <brucefo@microsoft.com>2018-01-10 16:24:31 -0800
committerBruce Forstall <brucefo@microsoft.com>2018-01-10 18:22:46 -0800
commitd84eba26320c2400be64bc4ff5dd9157f64a640e (patch)
treec8e96cdbfa8750fbf9a0bc1a54242ad59e56e0d6 /src/jit/target.h
parente275d2dfe18ad1f7db9c35220283001a81a7c669 (diff)
downloadcoreclr-d84eba26320c2400be64bc4ff5dd9157f64a640e.tar.gz
coreclr-d84eba26320c2400be64bc4ff5dd9157f64a640e.tar.bz2
coreclr-d84eba26320c2400be64bc4ff5dd9157f64a640e.zip
Fix ARM GCStress hole with byref write barrier helper
When unrolling a STOREOBJ, we can generate multiple consecutive byref helper calls. This helper has a unique calling convention where the dst and src addresses are modified by adding pointer size to their original value (thus allowing consecutive helper calls without reloading the dst/src addresses). So, for liveness purposes, the helper call kills the dst/src values. However, for GC purposes, it does not, as the registers still contain byref pointers. We were, in the ARM case, reporting the r0/r1 registers dead after the first call, so a GC didn't update them, and a second call updated garbage. In fixing this, I cleaned up the helper call kill handling a bit. I also fixed and improved RyuJIT/x86 write barrier kill modeling.
Diffstat (limited to 'src/jit/target.h')
-rw-r--r--src/jit/target.h18
1 files changed, 12 insertions, 6 deletions
diff --git a/src/jit/target.h b/src/jit/target.h
index 1753f440e9..453f8f9e6c 100644
--- a/src/jit/target.h
+++ b/src/jit/target.h
@@ -986,6 +986,7 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
// For e.g return value could be preserved in rcx so that it is available for
// profiler.
#define REG_DEFAULT_HELPER_CALL_TARGET REG_RAX
+ #define RBM_DEFAULT_HELPER_CALL_TARGET RBM_RAX
// GenericPInvokeCalliHelper VASigCookie Parameter
#define REG_PINVOKE_COOKIE_PARAM REG_R11
@@ -1242,12 +1243,12 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define RBM_CALLEE_SAVED (RBM_INT_CALLEE_SAVED | RBM_FLT_CALLEE_SAVED)
#define RBM_CALLEE_TRASH (RBM_INT_CALLEE_TRASH | RBM_FLT_CALLEE_TRASH)
-#ifdef LEGACY_BACKEND
- #define RBM_CALLEE_TRASH_NOGC (RBM_R2|RBM_R3|RBM_LR)
-#else
- #define RBM_CALLEE_TRASH_NOGC RBM_CALLEE_TRASH
-#endif
+
#define REG_DEFAULT_HELPER_CALL_TARGET REG_R12
+ #define RBM_DEFAULT_HELPER_CALL_TARGET RBM_R12
+
+ #define RBM_CALLEE_TRASH_NOGC (RBM_R2|RBM_R3|RBM_LR|RBM_DEFAULT_HELPER_CALL_TARGET)
+
#define REG_FASTTAILCALL_TARGET REG_R12 // Target register for fast tail call
#define RBM_FASTTAILCALL_TARGET RBM_R12
@@ -1598,8 +1599,13 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define RBM_CALLEE_SAVED (RBM_INT_CALLEE_SAVED | RBM_FLT_CALLEE_SAVED)
#define RBM_CALLEE_TRASH (RBM_INT_CALLEE_TRASH | RBM_FLT_CALLEE_TRASH)
- #define RBM_CALLEE_TRASH_NOGC (RBM_R12|RBM_R13|RBM_R14|RBM_R15|RBM_IP1)
+
#define REG_DEFAULT_HELPER_CALL_TARGET REG_R12
+ #define RBM_DEFAULT_HELPER_CALL_TARGET RBM_R12
+
+ // REVIEW: why does arm64 RBM_CALLEE_TRASH_NOGC include IP1? The JIT_ByRefWriteBarrier only trashes r12 and r15.
+ #define RBM_CALLEE_TRASH_NOGC (RBM_R12|RBM_R15|RBM_IP1|RBM_DEFAULT_HELPER_CALL_TARGET)
+
#define REG_FASTTAILCALL_TARGET REG_IP0 // Target register for fast tail call
#define RBM_FASTTAILCALL_TARGET RBM_IP0