From 21f9b736b7a915c80f8c4df74fac4905bb9bf2fd Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Mon, 15 Nov 2021 16:28:07 +0100 Subject: [PATCH] Disable poisoning for large structs (#61589) For very large structs (> 64K in size) poisoning could end up generating instructions requiring larger local var offsets than we can handle. This hits IMPL_LIMIT that throws InvalidProgramException. Turn off poisoning for larger structs that require more than 16 movs to also avoid the significant code bloat by the singular movs. This is a less risky version of #61521 for backporting to .NET 6. Fix #60852 --- src/coreclr/jit/codegencommon.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index a33b4b9..8585bab 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -12461,6 +12461,17 @@ void CodeGen::genPoisonFrame(regMaskTP regLiveIn) assert(varDsc->lvOnFrame); + int size = (int)compiler->lvaLclSize(varNum); + + if (size / TARGET_POINTER_SIZE > 16) + { + // For very large structs the offsets in the movs we emit below can + // grow too large to be handled properly by JIT. Furthermore, while + // this is only debug code, for very large structs this can bloat + // the code too much due to the singular movs used. + continue; + } + if (!hasPoisonImm) { #ifdef TARGET_64BIT @@ -12478,8 +12489,7 @@ void CodeGen::genPoisonFrame(regMaskTP regLiveIn) #else int addr = 0; #endif - int size = (int)compiler->lvaLclSize(varNum); - int end = addr + size; + int end = addr + size; for (int offs = addr; offs < end;) { #ifdef TARGET_64BIT -- 2.7.4