diff --git a/src/coreclr/src/jit/codegenxarch.cpp b/src/coreclr/src/jit/codegenxarch.cpp index 259f331470237..4600b38878736 100644 --- a/src/coreclr/src/jit/codegenxarch.cpp +++ b/src/coreclr/src/jit/codegenxarch.cpp @@ -1970,43 +1970,32 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pIni return; } - const target_size_t pageSize = compiler->eeGetPageSize(); - target_size_t lastTouchDelta = 0; // What offset from the final SP was the last probe? + const target_size_t pageSize = compiler->eeGetPageSize(); if (frameSize == REGSIZE_BYTES) { // Frame size is the same as register size. - inst_RV(INS_push, REG_EAX, TYP_I_IMPL); + GetEmitter()->emitIns_R(INS_push, EA_PTRSIZE, REG_EAX); + compiler->unwindAllocStack(frameSize); } else if (frameSize < pageSize) { - // Frame size is (0x0008..0x1000) - inst_RV_IV(INS_sub, REG_SPBASE, frameSize, EA_PTRSIZE); - lastTouchDelta = frameSize; - } - else if (frameSize < compiler->getVeryLargeFrameSize()) - { - lastTouchDelta = frameSize; - - // Frame size is (0x1000..0x3000) + GetEmitter()->emitIns_R_I(INS_sub, EA_PTRSIZE, REG_SPBASE, frameSize); + compiler->unwindAllocStack(frameSize); - GetEmitter()->emitIns_AR_R(INS_test, EA_PTRSIZE, REG_EAX, REG_SPBASE, -(int)pageSize); - lastTouchDelta -= pageSize; + const unsigned lastProbedLocToFinalSp = frameSize; - if (frameSize >= 0x2000) + if (lastProbedLocToFinalSp + STACK_PROBE_BOUNDARY_THRESHOLD_BYTES > pageSize) { - GetEmitter()->emitIns_AR_R(INS_test, EA_PTRSIZE, REG_EAX, REG_SPBASE, -2 * (int)pageSize); - lastTouchDelta -= pageSize; + // We haven't probed almost a complete page. If the next action on the stack might subtract from SP + // first, before touching the current SP, then we need to probe at the very bottom. This can + // happen on x86, for example, when we copy an argument to the stack using a "SUB ESP; REP MOV" + // strategy. + GetEmitter()->emitIns_R_AR(INS_test, EA_4BYTE, REG_EAX, REG_SPBASE, 0); } - - inst_RV_IV(INS_sub, REG_SPBASE, frameSize, EA_PTRSIZE); - assert(lastTouchDelta == frameSize % pageSize); } else { - // Frame size >= 0x3000 - assert(frameSize >= compiler->getVeryLargeFrameSize()); - #ifdef TARGET_X86 int spOffset = -(int)frameSize; @@ -2053,24 +2042,14 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pIni GetEmitter()->emitIns_R_R(INS_mov, EA_PTRSIZE, REG_SPBASE, REG_STACK_PROBE_HELPER_ARG); #endif // !TARGET_X86 + compiler->unwindAllocStack(frameSize); + if (initReg == REG_STACK_PROBE_HELPER_ARG) { *pInitRegZeroed = false; } } - if (lastTouchDelta + STACK_PROBE_BOUNDARY_THRESHOLD_BYTES > pageSize) - { - // We haven't probed almost a complete page. If the next action on the stack might subtract from SP - // first, before touching the current SP, then we do one more probe at the very bottom. This can - // happen on x86, for example, when we copy an argument to the stack using a "SUB ESP; REP MOV" - // strategy. - - GetEmitter()->emitIns_AR_R(INS_test, EA_PTRSIZE, REG_EAX, REG_SPBASE, 0); - } - - compiler->unwindAllocStack(frameSize); - #ifdef USING_SCOPE_INFO if (!doubleAlignOrFramePointerUsed()) {