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

Commit 667a12e

Browse files
committed
Merge pull request #484 from LLITCHEV/work2
Fix a long standing bug for AMD64 with very large frames and using a scratch register.
2 parents 19a27e2 + 8d584f2 commit 667a12e

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
@@ -4849,7 +4849,6 @@ void CodeGen::genCheckUseBlockInit()
48494849
// so reserve two extra callee saved
48504850
// This is better than pushing eax, ecx, because we in the later
48514851
// we will mess up already computed offsets on the stack (for ESP frames)
4852-
48534852
regSet.rsSetRegsModified(RBM_EDI);
48544853

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

54215420
#else // !CPU_LOAD_STORE_ARCH
54225421

5422+
// Code size for each instruction. We need this because the
5423+
// backward branch is hard-coded with the number of bytes to branch.
5424+
54235425
// loop:
5426+
// For x86
54245427
// test [esp + eax], eax 3
54255428
// sub eax, 0x1000 5
54265429
// cmp EAX, -frameSize 5
54275430
// jge loop 2
5431+
//
5432+
// For AMD64 using RAX
5433+
// test [rsp + rax], rax 4
5434+
// sub rax, 0x1000 6
5435+
// cmp rax, -frameSize 6
5436+
// jge loop 2
5437+
//
5438+
// For AMD64 using RBP
5439+
// test [rsp + rbp], rbp 4
5440+
// sub rbp, 0x1000 7
5441+
// cmp rbp, -frameSize 7
5442+
// jge loop 2
54285443
getEmitter()->emitIns_R_ARR(INS_TEST, EA_PTRSIZE, initReg, REG_SPBASE, initReg, 0);
54295444
inst_RV_IV(INS_sub, initReg, CORINFO_PAGE_SIZE, EA_PTRSIZE);
54305445
inst_RV_IV(INS_cmp, initReg, -((ssize_t)frameSize), EA_PTRSIZE);
5431-
inst_IV (INS_jge, -15 AMD64_ONLY(-3)); // Branch backwards to Start of Loop
5446+
int extraBytesForBackJump = 0;
5447+
#ifdef _TARGET_AMD64_
5448+
extraBytesForBackJump = ((initReg == REG_EAX) ? 3 : 5);
5449+
#endif // _TARGET_AMD64_
5450+
inst_IV(INS_jge, -15 - extraBytesForBackJump); // Branch backwards to Start of Loop
54325451

54335452
#endif // !CPU_LOAD_STORE_ARCH
54345453

54355454
*pInitRegZeroed = false; // The initReg does not contain zero
54365455

54375456
#ifdef _TARGET_XARCH_
5438-
// The backward branch above depends upon using EAX
5439-
assert(initReg == REG_EAX);
5457+
// The backward branch above depends upon using EAX (and for Amd64 funclets EBP)
5458+
assert((initReg == REG_EAX) AMD64_ONLY(|| (initReg == REG_EBP)));
54405459

54415460
if (pushedStubParam)
54425461
{

0 commit comments

Comments
 (0)