From bf9f899a998eba28f84c77e0c4996d1c22d94b0f Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Mon, 8 Feb 2021 19:03:56 -0800 Subject: [PATCH] Allow larger than 0x1000 bytes allocation in genStackPointerConstantAdjustment() (#47862) * In AOT scenarios the VM reports to the JIT the minimal supported page size in src/coreclr/vm/jitinterface.cpp * Have genStackPointerConstantAdjustment accept regTmp argument on Arm32 and Arm64 The temporary register is going to be used when sub sp,sp,#spDelta can not be encoded. For example, this happens when spDelta corresponds to OsPageSize and the OsPageSize is larger than 0x1000 bytes. The following code needs to be generated in such cases mov regTmp,#spDelta sub sp,sp,regTmp * Use genInstrWithConstant(INS_sub) and rsGetRsvdReg() as temporary register to encode amount of sp adjustment in src/coreclr/jit/codegenarm64.cpp * Update comment to reflect that REG_NA can be passed for regTmp in genStackPointerConstantAdjustment in src/coreclr/jit/codegenarmarch.cpp --- src/coreclr/jit/codegen.h | 5 ----- src/coreclr/jit/codegenarm.cpp | 2 +- src/coreclr/jit/codegenarm64.cpp | 10 ++++++---- src/coreclr/jit/codegenarmarch.cpp | 14 +++++++++++--- src/coreclr/vm/jitinterface.cpp | 11 ++++++++++- 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/coreclr/jit/codegen.h b/src/coreclr/jit/codegen.h index 9deffd0..7f40326 100644 --- a/src/coreclr/jit/codegen.h +++ b/src/coreclr/jit/codegen.h @@ -1301,12 +1301,7 @@ protected: void genReturn(GenTree* treeNode); -#ifdef TARGET_ARMARCH - void genStackPointerConstantAdjustment(ssize_t spDelta); -#else // !TARGET_ARMARCH void genStackPointerConstantAdjustment(ssize_t spDelta, regNumber regTmp); -#endif // !TARGET_ARMARCH - void genStackPointerConstantAdjustmentWithProbe(ssize_t spDelta, regNumber regTmp); target_ssize_t genStackPointerConstantAdjustmentLoopWithProbe(ssize_t spDelta, regNumber regTmp); diff --git a/src/coreclr/jit/codegenarm.cpp b/src/coreclr/jit/codegenarm.cpp index 6cc322a..4eae6d63 100644 --- a/src/coreclr/jit/codegenarm.cpp +++ b/src/coreclr/jit/codegenarm.cpp @@ -581,7 +581,7 @@ ALLOC_DONE: } else { - genStackPointerConstantAdjustment(-(ssize_t)stackAdjustment); + genStackPointerConstantAdjustment(-(ssize_t)stackAdjustment, regTmp); } // Return the stackalloc'ed address in result register. diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index 7bff146..0406fb2 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -2234,7 +2234,7 @@ void CodeGen::genLclHeap(GenTree* tree) // ldr wz, [SP, #0] GetEmitter()->emitIns_R_R_I(INS_ldr, EA_4BYTE, REG_ZR, REG_SP, 0); - inst_RV_IV(INS_sub, REG_SP, amount, EA_PTRSIZE); + genInstrWithConstant(INS_sub, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, amount, rsGetRsvdReg()); lastTouchDelta = amount; @@ -2363,21 +2363,23 @@ ALLOC_DONE: assert((stackAdjustment % STACK_ALIGN) == 0); // This must be true for the stack to remain aligned assert((lastTouchDelta == ILLEGAL_LAST_TOUCH_DELTA) || (lastTouchDelta >= 0)); + const regNumber tmpReg = rsGetRsvdReg(); + if ((lastTouchDelta == ILLEGAL_LAST_TOUCH_DELTA) || (stackAdjustment + (unsigned)lastTouchDelta + STACK_PROBE_BOUNDARY_THRESHOLD_BYTES > compiler->eeGetPageSize())) { - genStackPointerConstantAdjustmentLoopWithProbe(-(ssize_t)stackAdjustment, REG_ZR); + genStackPointerConstantAdjustmentLoopWithProbe(-(ssize_t)stackAdjustment, tmpReg); } else { - genStackPointerConstantAdjustment(-(ssize_t)stackAdjustment); + genStackPointerConstantAdjustment(-(ssize_t)stackAdjustment, tmpReg); } // Return the stackalloc'ed address in result register. // TargetReg = SP + stackAdjustment. // - genInstrWithConstant(INS_add, EA_PTRSIZE, targetReg, REG_SPBASE, (ssize_t)stackAdjustment, rsGetRsvdReg()); + genInstrWithConstant(INS_add, EA_PTRSIZE, targetReg, REG_SPBASE, (ssize_t)stackAdjustment, tmpReg); } else // stackAdjustment == 0 { diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index b653017..ed7277e 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -27,11 +27,15 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // // Arguments: // spDelta - the value to add to SP. Must be negative or zero. +// regTmp - an available temporary register that is used if 'spDelta' cannot be encoded by +// 'sub sp, sp, #spDelta' instruction. +// Can be REG_NA if the caller knows for certain that 'spDelta' fits into the immediate +// value range. // // Return Value: // None. // -void CodeGen::genStackPointerConstantAdjustment(ssize_t spDelta) +void CodeGen::genStackPointerConstantAdjustment(ssize_t spDelta, regNumber regTmp) { assert(spDelta < 0); @@ -39,7 +43,11 @@ void CodeGen::genStackPointerConstantAdjustment(ssize_t spDelta) // function that does a probe, which will in turn call this function. assert((target_size_t)(-spDelta) <= compiler->eeGetPageSize()); - inst_RV_IV(INS_sub, REG_SPBASE, (target_ssize_t)-spDelta, EA_PTRSIZE); +#ifdef TARGET_ARM64 + genInstrWithConstant(INS_sub, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, -spDelta, regTmp); +#else + genInstrWithConstant(INS_sub, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, -spDelta, INS_FLAGS_DONT_CARE, regTmp); +#endif } //------------------------------------------------------------------------ @@ -58,7 +66,7 @@ void CodeGen::genStackPointerConstantAdjustment(ssize_t spDelta) void CodeGen::genStackPointerConstantAdjustmentWithProbe(ssize_t spDelta, regNumber regTmp) { GetEmitter()->emitIns_R_R_I(INS_ldr, EA_4BYTE, regTmp, REG_SP, 0); - genStackPointerConstantAdjustment(spDelta); + genStackPointerConstantAdjustment(spDelta, regTmp); } //------------------------------------------------------------------------ diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 6fabfae..b48fbbe 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -10228,7 +10228,16 @@ void CEEInfo::getEEInfo(CORINFO_EE_INFO *pEEInfoOut) _ASSERTE(sizeof(ReversePInvokeFrame) <= pEEInfoOut->sizeOfReversePInvokeFrame); #endif - pEEInfoOut->osPageSize = GetOsPageSize(); + if (!IsReadyToRunCompilation()) + { + pEEInfoOut->osPageSize = GetOsPageSize(); + } + else + { + // In AOT scenarios the VM reports to the JIT the minimal supported page size. + pEEInfoOut->osPageSize = 0x1000; + } + pEEInfoOut->maxUncheckedOffsetForNullObject = MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT; pEEInfoOut->targetAbi = CORINFO_CORECLR_ABI; -- 2.7.4