Skip to content

Commit 21f9b73

Browse files
authored
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
1 parent bb3bdf8 commit 21f9b73

File tree

1 file changed

+12
-2
lines changed

1 file changed

+12
-2
lines changed

src/coreclr/jit/codegencommon.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12461,6 +12461,17 @@ void CodeGen::genPoisonFrame(regMaskTP regLiveIn)
1246112461

1246212462
assert(varDsc->lvOnFrame);
1246312463

12464+
int size = (int)compiler->lvaLclSize(varNum);
12465+
12466+
if (size / TARGET_POINTER_SIZE > 16)
12467+
{
12468+
// For very large structs the offsets in the movs we emit below can
12469+
// grow too large to be handled properly by JIT. Furthermore, while
12470+
// this is only debug code, for very large structs this can bloat
12471+
// the code too much due to the singular movs used.
12472+
continue;
12473+
}
12474+
1246412475
if (!hasPoisonImm)
1246512476
{
1246612477
#ifdef TARGET_64BIT
@@ -12478,8 +12489,7 @@ void CodeGen::genPoisonFrame(regMaskTP regLiveIn)
1247812489
#else
1247912490
int addr = 0;
1248012491
#endif
12481-
int size = (int)compiler->lvaLclSize(varNum);
12482-
int end = addr + size;
12492+
int end = addr + size;
1248312493
for (int offs = addr; offs < end;)
1248412494
{
1248512495
#ifdef TARGET_64BIT

0 commit comments

Comments
 (0)