Skip to content

Commit 130f8c0

Browse files
authored
[clr-interp] Add safepoints at method entry and backwards branch (#115567)
* [clr-interp] Add safepoints at method entry and backwards branch Interpreter runs in GC unsafe mode, so without these safepoints for cooperative suspend, the GC could fail to suspend threads executing in the interpreter. * [clr-interp] Add some starting contracts to interp exec method
1 parent 7c25dd9 commit 130f8c0

File tree

3 files changed

+22
-0
lines changed

3 files changed

+22
-0
lines changed

src/coreclr/interpreter/compiler.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,6 +1418,10 @@ void InterpCompiler::EmitBranch(InterpOpcode opcode, int32_t ilOffset)
14181418
if (target < 0 || target >= m_ILCodeSize)
14191419
assert(0);
14201420

1421+
// Backwards branch, emit safepoint
1422+
if (ilOffset < 0)
1423+
AddIns(INTOP_SAFEPOINT);
1424+
14211425
InterpBasicBlock *pTargetBB = m_ppOffsetToBB[target];
14221426
assert(pTargetBB != NULL);
14231427

@@ -2123,6 +2127,10 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
21232127

21242128
codeEnd = m_ip + m_ILCodeSize;
21252129

2130+
// Safepoint at each method entry. This could be done as part of a call, rather than
2131+
// adding an opcode.
2132+
AddIns(INTOP_SAFEPOINT);
2133+
21262134
linkBBlocks = true;
21272135
needsRetryEmit = false;
21282136
retry_emit:

src/coreclr/interpreter/intops.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ OPDEF(INTOP_LDLOCA, "ldloca", 3, 1, 0, InterpOpInt)
3535

3636
OPDEF(INTOP_SWITCH, "switch", 0, 0, 1, InterpOpSwitch)
3737

38+
OPDEF(INTOP_SAFEPOINT, "safepoint", 1, 0, 0, InterpOpNoArgs)
3839
OPDEF(INTOP_BR, "br", 2, 0, 0, InterpOpBranch)
3940

4041
OPDEF(INTOP_BRFALSE_I4, "brfalse.i4", 3, 0, 1, InterpOpBranch)

src/coreclr/vm/interpexec.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ static void InterpBreakpoint()
3636

3737
void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFrame *pFrame, InterpThreadContext *pThreadContext)
3838
{
39+
CONTRACTL
40+
{
41+
GC_TRIGGERS;
42+
MODE_COOPERATIVE;
43+
}
44+
CONTRACTL_END;
45+
3946
#if defined(HOST_AMD64) && defined(HOST_WINDOWS)
4047
pInterpreterFrame->SetInterpExecMethodSSP((TADDR)_rdsspq());
4148
#endif // HOST_AMD64 && HOST_WINDOWS
@@ -293,6 +300,12 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr
293300
break;
294301
}
295302

303+
case INTOP_SAFEPOINT:
304+
if (g_TrapReturningThreads)
305+
JIT_PollGC();
306+
ip++;
307+
break;
308+
296309
case INTOP_BR:
297310
ip += ip[1];
298311
break;

0 commit comments

Comments
 (0)