Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 3516aae

Browse files
author
Rahul Kumar
authored
Merge pull request #6418 from rahku/crossgen
Do not insert gcstress interrupt instruction at call to JIT_RareDisab…
2 parents 35e1d3b + b881558 commit 3516aae

File tree

1 file changed

+61
-3
lines changed

1 file changed

+61
-3
lines changed

src/vm/gccover.cpp

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737

3838
MethodDesc* AsMethodDesc(size_t addr);
3939
static SLOT getTargetOfCall(SLOT instrPtr, PCONTEXT regs, SLOT*nextInstr);
40+
bool isCallToStopForGCJitHelper(SLOT instrPtr);
4041
#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
4142
static void replaceSafePointInstructionWithGcStressInstr(UINT32 safePointOffset, LPVOID codeStart);
4243
static bool replaceInterruptibleRangesWithGcStressInstr (UINT32 startOffset, UINT32 stopOffset, LPVOID codeStart);
@@ -911,7 +912,11 @@ bool replaceInterruptibleRangesWithGcStressInstr (UINT32 startOffset, UINT32 sto
911912
if (instrLen == 2)
912913
*((WORD*)instrPtr) = INTERRUPT_INSTR;
913914
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+
}
915920

916921
instrPtr += instrLen;
917922
#elif defined(_TARGET_ARM64_)
@@ -920,8 +925,10 @@ bool replaceInterruptibleRangesWithGcStressInstr (UINT32 startOffset, UINT32 sto
920925
*((DWORD*)instrPtr) != INTERRUPT_INSTR_CALL &&
921926
*((DWORD*)instrPtr) != INTERRUPT_INSTR_PROTECT_RET);
922927
}
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;
925932
instrPtr += 4;
926933
#endif
927934

@@ -940,6 +947,57 @@ bool replaceInterruptibleRangesWithGcStressInstr (UINT32 startOffset, UINT32 sto
940947
}
941948
#endif
942949

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+
9431001
static size_t getRegVal(unsigned regNum, PCONTEXT regs)
9441002
{
9451003
return *getRegAddr(regNum, regs);

0 commit comments

Comments
 (0)