diff options
author | Bruce Forstall <brucefo@microsoft.com> | 2018-01-10 16:24:31 -0800 |
---|---|---|
committer | Bruce Forstall <brucefo@microsoft.com> | 2018-01-10 18:22:46 -0800 |
commit | d84eba26320c2400be64bc4ff5dd9157f64a640e (patch) | |
tree | c8e96cdbfa8750fbf9a0bc1a54242ad59e56e0d6 /src/jit/target.h | |
parent | e275d2dfe18ad1f7db9c35220283001a81a7c669 (diff) | |
download | coreclr-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.h | 18 |
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 |