37
37
38
38
MethodDesc* AsMethodDesc (size_t addr);
39
39
static SLOT getTargetOfCall (SLOT instrPtr, PCONTEXT regs, SLOT*nextInstr);
40
+ bool isCallToStopForGCJitHelper (SLOT instrPtr);
40
41
#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
41
42
static void replaceSafePointInstructionWithGcStressInstr (UINT32 safePointOffset, LPVOID codeStart);
42
43
static bool replaceInterruptibleRangesWithGcStressInstr (UINT32 startOffset, UINT32 stopOffset, LPVOID codeStart);
@@ -911,7 +912,11 @@ bool replaceInterruptibleRangesWithGcStressInstr (UINT32 startOffset, UINT32 sto
911
912
if (instrLen == 2 )
912
913
*((WORD*)instrPtr) = INTERRUPT_INSTR;
913
914
else
914
- *((DWORD*)instrPtr) = INTERRUPT_INSTR_32;
915
+ {
916
+ // Do not replace with gcstress interrupt instruction at call to JIT_RareDisableHelper
917
+ if (!isCallToStopForGCJitHelper (instrPtr))
918
+ *((DWORD*)instrPtr) = INTERRUPT_INSTR_32;
919
+ }
915
920
916
921
instrPtr += instrLen;
917
922
#elif defined(_TARGET_ARM64_)
@@ -920,8 +925,10 @@ bool replaceInterruptibleRangesWithGcStressInstr (UINT32 startOffset, UINT32 sto
920
925
*((DWORD*)instrPtr) != INTERRUPT_INSTR_CALL &&
921
926
*((DWORD*)instrPtr) != INTERRUPT_INSTR_PROTECT_RET);
922
927
}
923
-
924
- *((DWORD*)instrPtr) = INTERRUPT_INSTR;
928
+
929
+ // Do not replace with gcstress interrupt instruction at call to JIT_RareDisableHelper
930
+ if (!isCallToStopForGCJitHelper (instrPtr))
931
+ *((DWORD*)instrPtr) = INTERRUPT_INSTR;
925
932
instrPtr += 4 ;
926
933
#endif
927
934
@@ -940,6 +947,57 @@ bool replaceInterruptibleRangesWithGcStressInstr (UINT32 startOffset, UINT32 sto
940
947
}
941
948
#endif
942
949
950
+ // Is this a call instruction to JIT_RareDisableHelper()
951
+ // We cannot insert GCStress instruction at this call
952
+ // For arm64 & arm (R2R) call to jithelpers happens via a stub.
953
+ // For other architectures call does not happen via stub.
954
+ // For other architecures we can get the target directly by calling getTargetOfCall().
955
+ // This is not the case for arm64/arm so need to decode the stub
956
+ // instruction to find the actual jithelper target.
957
+ // For other architecture we detect call to JIT_RareDisableHelper
958
+ // in function OnGcCoverageInterrupt() since getTargetOfCall() can
959
+ // get the actual jithelper target.
960
+ bool isCallToStopForGCJitHelper (SLOT instrPtr)
961
+ {
962
+ #if defined(_TARGET_ARM64_)
963
+ if (((*reinterpret_cast <DWORD*>(instrPtr)) & 0xFC000000 ) == 0x94000000 ) // Do we have a BL instruction?
964
+ {
965
+ // call through immediate
966
+ int imm26 = ((*((DWORD*)instrPtr)) & 0x03FFFFFF )<<2 ;
967
+ // SignExtend the immediate value.
968
+ imm26 = (imm26 << 4 ) >> 4 ;
969
+ DWORD* target = (DWORD*) (instrPtr + imm26);
970
+ // Call to jithelpers happens via jumpstub
971
+ if (*target == 0x58000050 /* ldr xip0, PC+8*/ && *(target+1 ) == 0xd61f0200 /* br xip0 */ )
972
+ {
973
+ // get the actual jithelper target
974
+ target = *(((DWORD**)target) + 1 );
975
+ if ((TADDR)target == GetEEFuncEntryPoint (JIT_RareDisableHelper))
976
+ {
977
+ return true ;
978
+ }
979
+ }
980
+ }
981
+ #elif defined(_TARGET_ARM_)
982
+ if ((instrPtr[1 ] & 0xf8 ) == 0xf0 && (instrPtr[3 ] & 0xc0 ) == 0xc0 ) // call using imm
983
+ {
984
+ int imm32 = GetThumb2BlRel24 ((UINT16 *)instrPtr);
985
+ WORD* target = (WORD*) (instrPtr + 4 + imm32);
986
+ // Is target a stub
987
+ if (*target == 0xf8df && *(target+1 ) == 0xf000 ) // ldr pc, [pc+4]
988
+ {
989
+ // get actual target
990
+ target = *((WORD**)target + 1 );
991
+ if ((TADDR)target == GetEEFuncEntryPoint (JIT_RareDisableHelper))
992
+ {
993
+ return true ;
994
+ }
995
+ }
996
+ }
997
+ #endif
998
+ return false ;
999
+ }
1000
+
943
1001
static size_t getRegVal (unsigned regNum, PCONTEXT regs)
944
1002
{
945
1003
return *getRegAddr (regNum, regs);
0 commit comments