Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 8d584f2

Browse files
committed
Fix a long standing bug for AMD64 with bad assert.
When having a really large frame the code for generating funclet prolog expects to have RAX being used as initReg. For AMD64 the RBP is being pushed and then used as scratch (and passed as initReg.) This was causing the assert to trigger. Added code to handle properly use of RBP on AMD64 and also modified the assert to properly allow RAX and RBP as initReg.
1 parent 6ccf4e2 commit 8d584f2

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

src/jit/codegencommon.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4840,7 +4840,6 @@ void CodeGen::genCheckUseBlockInit()
48404840
// so reserve two extra callee saved
48414841
// This is better than pushing eax, ecx, because we in the later
48424842
// we will mess up already computed offsets on the stack (for ESP frames)
4843-
48444843
regSet.rsSetRegsModified(RBM_EDI);
48454844

48464845
// For register arguments we may have to save ECX (and RDI on Amd64 System V OSes.)
@@ -5411,23 +5410,43 @@ void CodeGen::genAllocLclFrame(unsigned frameSize,
54115410

54125411
#else // !CPU_LOAD_STORE_ARCH
54135412

5413+
// Code size for each instruction. We need this because the
5414+
// backward branch is hard-coded with the number of bytes to branch.
5415+
54145416
// loop:
5417+
// For x86
54155418
// test [esp + eax], eax 3
54165419
// sub eax, 0x1000 5
54175420
// cmp EAX, -frameSize 5
54185421
// jge loop 2
5422+
//
5423+
// For AMD64 using RAX
5424+
// test [rsp + rax], rax 4
5425+
// sub rax, 0x1000 6
5426+
// cmp rax, -frameSize 6
5427+
// jge loop 2
5428+
//
5429+
// For AMD64 using RBP
5430+
// test [rsp + rbp], rbp 4
5431+
// sub rbp, 0x1000 7
5432+
// cmp rbp, -frameSize 7
5433+
// jge loop 2
54195434
getEmitter()->emitIns_R_ARR(INS_TEST, EA_PTRSIZE, initReg, REG_SPBASE, initReg, 0);
54205435
inst_RV_IV(INS_sub, initReg, CORINFO_PAGE_SIZE, EA_PTRSIZE);
54215436
inst_RV_IV(INS_cmp, initReg, -((ssize_t)frameSize), EA_PTRSIZE);
5422-
inst_IV (INS_jge, -15 AMD64_ONLY(-3)); // Branch backwards to Start of Loop
5437+
int extraBytesForBackJump = 0;
5438+
#ifdef _TARGET_AMD64_
5439+
extraBytesForBackJump = ((initReg == REG_EAX) ? 3 : 5);
5440+
#endif // _TARGET_AMD64_
5441+
inst_IV(INS_jge, -15 - extraBytesForBackJump); // Branch backwards to Start of Loop
54235442

54245443
#endif // !CPU_LOAD_STORE_ARCH
54255444

54265445
*pInitRegZeroed = false; // The initReg does not contain zero
54275446

54285447
#ifdef _TARGET_XARCH_
5429-
// The backward branch above depends upon using EAX
5430-
assert(initReg == REG_EAX);
5448+
// The backward branch above depends upon using EAX (and for Amd64 funclets EBP)
5449+
assert((initReg == REG_EAX) AMD64_ONLY(|| (initReg == REG_EBP)));
54315450

54325451
if (pushedStubParam)
54335452
{

0 commit comments

Comments
 (0)