diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index dad1ba0b929b89..b2bdd295adf54a 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -1517,29 +1517,6 @@ void CodeGen::genExitCode(BasicBlock* block) if (compiler->getNeedsGSSecurityCookie()) { genEmitGSCookieCheck(jmpEpilog); - - if (jmpEpilog) - { - // Dev10 642944 - - // The GS cookie check created a temp label that has no live - // incoming GC registers, we need to fix that - - unsigned varNum; - LclVarDsc* varDsc; - - /* Figure out which register parameters hold pointers */ - - for (varNum = 0, varDsc = compiler->lvaTable; varNum < compiler->lvaCount && varDsc->lvIsRegArg; - varNum++, varDsc++) - { - noway_assert(varDsc->lvIsParam); - - gcInfo.gcMarkRegPtrVal(varDsc->GetArgReg(), varDsc->TypeGet()); - } - - GetEmitter()->emitThisGCrefRegs = GetEmitter()->emitInitGCrefRegs = gcInfo.gcRegGCrefSetCur; - GetEmitter()->emitThisByrefRegs = GetEmitter()->emitInitByrefRegs = gcInfo.gcRegByrefSetCur; - } } genReserveEpilog(block); diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index d91b822afa11a9..c82d2df22b9e12 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -10427,9 +10427,9 @@ regMaskTP emitter::emitGetGCRegsKilledByNoGCCall(CorInfoHelpFunc helper) // of the last instruction in the region makes GC safe again. // In particular - once the IP is on the first instruction, but not executed it yet, // it is still safe to do GC. -// The only special case is when NoGC region is used for prologs/epilogs. -// In such case the GC info could be incorrect until the prolog completes and epilogs -// may have unwindability restrictions, so the first instruction cannot have GC. +// The only special case is when NoGC region is used for prologs. +// In such case the GC info could be incorrect until the prolog completes, so the first +// instruction cannot have GC. void emitter::emitDisableGC() { diff --git a/src/coreclr/jit/emitinl.h b/src/coreclr/jit/emitinl.h index 022064073d908d..a586193dd5b714 100644 --- a/src/coreclr/jit/emitinl.h +++ b/src/coreclr/jit/emitinl.h @@ -594,8 +594,7 @@ bool emitter::emitGenNoGCLst(Callback& cb) emitter::instrDesc* id = emitFirstInstrDesc(ig->igData); assert(id != nullptr); assert(id->idCodeSize() > 0); - if (!cb(ig->igFuncIdx, ig->igOffs, ig->igSize, id->idCodeSize(), - ig->igFlags & (IGF_FUNCLET_PROLOG | IGF_FUNCLET_EPILOG | IGF_EPILOG))) + if (!cb(ig->igFuncIdx, ig->igOffs, ig->igSize, id->idCodeSize(), ig->igFlags & (IGF_FUNCLET_PROLOG))) { return false; } diff --git a/src/coreclr/jit/gcencode.cpp b/src/coreclr/jit/gcencode.cpp index 4863c95a7f59dd..ae05bf797f86ab 100644 --- a/src/coreclr/jit/gcencode.cpp +++ b/src/coreclr/jit/gcencode.cpp @@ -4027,8 +4027,7 @@ class InterruptibleRangeReporter // Report everything between the previous region and the current // region as interruptible. - bool operator()( - unsigned igFuncIdx, unsigned igOffs, unsigned igSize, unsigned firstInstrSize, bool isInPrologOrEpilog) + bool operator()(unsigned igFuncIdx, unsigned igOffs, unsigned igSize, unsigned firstInstrSize, bool isInProlog) { if (igOffs < m_uninterruptibleEnd) { @@ -4042,9 +4041,9 @@ class InterruptibleRangeReporter if (igOffs > m_uninterruptibleEnd) { // Once the first instruction in IG executes, we cannot have GC. - // But it is ok to have GC while the IP is on the first instruction, unless we are in prolog/epilog. + // But it is ok to have GC while the IP is on the first instruction, unless we are in prolog. unsigned interruptibleEnd = igOffs; - if (!isInPrologOrEpilog) + if (!isInProlog) { interruptibleEnd += firstInstrSize; } diff --git a/src/coreclr/nativeaot/Runtime/thread.cpp b/src/coreclr/nativeaot/Runtime/thread.cpp index b796b052182260..c2e94a1dc8f383 100644 --- a/src/coreclr/nativeaot/Runtime/thread.cpp +++ b/src/coreclr/nativeaot/Runtime/thread.cpp @@ -675,10 +675,16 @@ void Thread::HijackCallback(NATIVE_CONTEXT* pThreadContext, void* pThreadToHijac if (runtime->IsConservativeStackReportingEnabled() || codeManager->IsSafePoint(pvAddress)) { + // IsUnwindable is precise on arm64, but can give false negatives on other architectures. + // (when IP is on the first instruction of an epilog, we still can unwind, + // but we can tell if the instruction is the first only if we can navigate instructions backwards and check) + // The preciseness of IsUnwindable is tracked in https://github.com/dotnet/runtime/issues/101932 +#if defined(TARGET_ARM64) // we may not be able to unwind in some locations, such as epilogs. // such locations should not contain safe points. // when scanning conservatively we do not need to unwind ASSERT(codeManager->IsUnwindable(pvAddress) || runtime->IsConservativeStackReportingEnabled()); +#endif // if we are not given a thread to hijack // perform in-line wait on the current thread