Allow mcode allocations outside of the jump range to the support code.

Thank you for your patience. #285
This commit is contained in:
Mike Pall
2025-11-06 00:42:02 +01:00
parent 3c7b158b79
commit 68354f4447
19 changed files with 479 additions and 230 deletions

View File

@@ -48,23 +48,38 @@ static Reg ra_alloc2(ASMState *as, IRIns *ir, RegSet allow)
static void asm_exitstub_setup(ASMState *as, ExitNo nexits)
{
ExitNo i;
int ind;
uintptr_t target = (uintptr_t)(void *)lj_vm_exit_handler;
MCode *mxp = as->mctop;
if (mxp - (nexits + 3 + MCLIM_REDZONE) < as->mclim)
if (mxp - (nexits + 4 + MCLIM_REDZONE) < as->mclim)
asm_mclimit(as);
/* 1: mflr r0; bl ->vm_exit_handler; li r0, traceno; bl <1; bl <1; ... */
ind = ((target - (uintptr_t)(mxp - nexits - 2) + 0x02000000u) >> 26) ? 2 : 0;
/* !ind: 1: mflr r0; bl ->vm_exit_handler; li r0, traceno;
** ind: 1: lwz r0, K32_VXH(jgl); mtctr r0; mflr r0; bctrl; li r0, traceno;
** bl <1; bl <1; ...
*/
for (i = nexits-1; (int32_t)i >= 0; i--)
*--mxp = PPCI_BL|(((-3-i)&0x00ffffffu)<<2);
*--mxp = PPCI_BL | (((-3-ind-i) & 0x00ffffffu) << 2);
as->mcexit = mxp;
*--mxp = PPCI_LI|PPCF_T(RID_TMP)|as->T->traceno; /* Read by exit handler. */
mxp--;
*mxp = PPCI_BL|((((MCode *)(void *)lj_vm_exit_handler-mxp)&0x00ffffffu)<<2);
*--mxp = PPCI_MFLR|PPCF_T(RID_TMP);
if (ind) {
*--mxp = PPCI_BCTRL;
*--mxp = PPCI_MFLR | PPCF_T(RID_TMP);
*--mxp = PPCI_MTCTR | PPCF_T(RID_TMP);
*--mxp = PPCI_LWZ | PPCF_T(RID_TMP) | PPCF_A(RID_JGL) |
jglofs(as, &as->J->k32[LJ_K32_VM_EXIT_HANDLER]);
} else {
mxp--;
*mxp = PPCI_BL | ((target - (uintptr_t)mxp) & 0x03fffffcu);
*--mxp = PPCI_MFLR | PPCF_T(RID_TMP);
}
as->mctop = mxp;
}
static MCode *asm_exitstub_addr(ASMState *as, ExitNo exitno)
{
/* Keep this in-sync with exitstub_trace_addr(). */
return as->mctop + exitno + 3;
return as->mcexit + exitno;
}
/* Emit conditional branch to exit for guard. */
@@ -2218,34 +2233,43 @@ static Reg asm_head_side_base(ASMState *as, IRIns *irp)
/* Fixup the tail code. */
static void asm_tail_fixup(ASMState *as, TraceNo lnk)
{
MCode *p = as->mctop;
MCode *target;
uintptr_t target = lnk ? (uintptr_t)traceref(as->J, lnk)->mcode : (uintptr_t)(void *)lj_vm_exit_interp;
MCode *mcp = as->mctail;
int32_t spadj = as->T->spadjust;
if (spadj == 0) {
*--p = PPCI_NOP;
*--p = PPCI_NOP;
as->mctop = p;
} else {
/* Patch stack adjustment. */
if (spadj) { /* Emit stack adjustment. */
lj_assertA(checki16(CFRAME_SIZE+spadj), "stack adjustment out of range");
p[-3] = PPCI_ADDI | PPCF_T(RID_TMP) | PPCF_A(RID_SP) | (CFRAME_SIZE+spadj);
p[-2] = PPCI_STWU | PPCF_T(RID_TMP) | PPCF_A(RID_SP) | spadj;
*mcp++ = PPCI_ADDI | PPCF_T(RID_TMP) | PPCF_A(RID_SP) | (CFRAME_SIZE+spadj);
*mcp++ = PPCI_STWU | PPCF_T(RID_TMP) | PPCF_A(RID_SP) | spadj;
}
/* Patch exit branch. */
target = lnk ? traceref(as->J, lnk)->mcode : (MCode *)lj_vm_exit_interp;
p[-1] = PPCI_B|(((target-p+1)&0x00ffffffu)<<2);
/* Emit exit branch. */
if ((((target - (uintptr_t)mcp) + 0x02000000u) >> 26) == 0) {
*mcp = PPCI_B | ((target - (uintptr_t)mcp) & 0x03fffffcu); mcp++;
} else {
*mcp++ = PPCI_LWZ | PPCF_T(RID_TMP) | PPCF_A(RID_JGL) |
jglofs(as, &as->J->k32[LJ_K32_VM_EXIT_INTERP]);
*mcp++ = PPCI_MTCTR | PPCF_T(RID_TMP);
*mcp++ = PPCI_BCTR;
}
while (as->mctop > mcp) *--as->mctop = PPCI_NOP;
}
/* Prepare tail of code. */
static void asm_tail_prep(ASMState *as)
static void asm_tail_prep(ASMState *as, TraceNo lnk)
{
MCode *p = as->mctop - 1; /* Leave room for exit branch. */
if (as->loopref) {
as->invmcp = as->mcp = p;
} else {
as->mcp = p-2; /* Leave room for stack pointer adjustment. */
if (!lnk) {
uintptr_t target = (uintptr_t)(void *)lj_vm_exit_interp;
if ((((target - (uintptr_t)p) + 0x02000000u) >> 26) ||
(((target - (uintptr_t)(p-2)) + 0x02000000u) >> 26)) p -= 2;
}
p -= 2; /* Leave room for stack pointer adjustment. */
as->mcp = p;
as->invmcp = NULL;
}
as->mctail = p;
}
/* -- Trace setup --------------------------------------------------------- */