mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-12 17:24:09 +00:00
Keep maximum frame extent in snap->topslot.
This commit is contained in:
parent
dc2a39e46d
commit
f8a4769fb2
47
src/lj_asm.c
47
src/lj_asm.c
@ -903,30 +903,6 @@ static uint32_t asm_callx_flags(ASMState *as, IRIns *ir)
|
|||||||
return (nargs | (ir->t.irt << CCI_OTSHIFT));
|
return (nargs | (ir->t.irt << CCI_OTSHIFT));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get extent of the stack for a snapshot. */
|
|
||||||
static BCReg asm_stack_extent(ASMState *as, SnapShot *snap, BCReg *ptopslot)
|
|
||||||
{
|
|
||||||
SnapEntry *map = &as->T->snapmap[snap->mapofs];
|
|
||||||
MSize n, nent = snap->nent;
|
|
||||||
BCReg baseslot = 0, topslot = 0;
|
|
||||||
/* Must check all frames to find topslot (outer can be larger than inner). */
|
|
||||||
for (n = 0; n < nent; n++) {
|
|
||||||
SnapEntry sn = map[n];
|
|
||||||
if ((sn & SNAP_FRAME)) {
|
|
||||||
IRIns *ir = IR(snap_ref(sn));
|
|
||||||
GCfunc *fn = ir_kfunc(ir);
|
|
||||||
if (isluafunc(fn)) {
|
|
||||||
BCReg s = snap_slot(sn);
|
|
||||||
BCReg fs = s + funcproto(fn)->framesize;
|
|
||||||
if (fs > topslot) topslot = fs;
|
|
||||||
baseslot = s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*ptopslot = topslot;
|
|
||||||
return baseslot;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate stack adjustment. */
|
/* Calculate stack adjustment. */
|
||||||
static int32_t asm_stack_adjust(ASMState *as)
|
static int32_t asm_stack_adjust(ASMState *as)
|
||||||
{
|
{
|
||||||
@ -1415,13 +1391,30 @@ static void asm_head_side(ASMState *as)
|
|||||||
|
|
||||||
/* -- Tail of trace ------------------------------------------------------- */
|
/* -- Tail of trace ------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Get base slot for a snapshot. */
|
||||||
|
static BCReg asm_baseslot(ASMState *as, SnapShot *snap, int *gotframe)
|
||||||
|
{
|
||||||
|
SnapEntry *map = &as->T->snapmap[snap->mapofs];
|
||||||
|
MSize n;
|
||||||
|
for (n = snap->nent; n > 0; n--) {
|
||||||
|
SnapEntry sn = map[n-1];
|
||||||
|
if ((sn & SNAP_FRAME)) {
|
||||||
|
*gotframe = 1;
|
||||||
|
return snap_slot(sn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Link to another trace. */
|
/* Link to another trace. */
|
||||||
static void asm_tail_link(ASMState *as)
|
static void asm_tail_link(ASMState *as)
|
||||||
{
|
{
|
||||||
SnapNo snapno = as->T->nsnap-1; /* Last snapshot. */
|
SnapNo snapno = as->T->nsnap-1; /* Last snapshot. */
|
||||||
SnapShot *snap = &as->T->snap[snapno];
|
SnapShot *snap = &as->T->snap[snapno];
|
||||||
BCReg baseslot = asm_stack_extent(as, snap, &as->topslot);
|
int gotframe = 0;
|
||||||
|
BCReg baseslot = asm_baseslot(as, snap, &gotframe);
|
||||||
|
|
||||||
|
as->topslot = snap->topslot;
|
||||||
checkmclim(as);
|
checkmclim(as);
|
||||||
ra_allocref(as, REF_BASE, RID2RSET(RID_BASE));
|
ra_allocref(as, REF_BASE, RID2RSET(RID_BASE));
|
||||||
|
|
||||||
@ -1454,8 +1447,8 @@ static void asm_tail_link(ASMState *as)
|
|||||||
/* Sync the interpreter state with the on-trace state. */
|
/* Sync the interpreter state with the on-trace state. */
|
||||||
asm_stack_restore(as, snap);
|
asm_stack_restore(as, snap);
|
||||||
|
|
||||||
/* Root traces that grow the stack need to check the stack at the end. */
|
/* Root traces that add frames need to check the stack at the end. */
|
||||||
if (!as->parent && as->topslot)
|
if (!as->parent && gotframe)
|
||||||
asm_stack_check(as, as->topslot, NULL, as->freeset & RSET_GPR, snapno);
|
asm_stack_check(as, as->topslot, NULL, as->freeset & RSET_GPR, snapno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,9 +138,9 @@ typedef struct SnapShot {
|
|||||||
uint16_t mapofs; /* Offset into snapshot map. */
|
uint16_t mapofs; /* Offset into snapshot map. */
|
||||||
IRRef1 ref; /* First IR ref for this snapshot. */
|
IRRef1 ref; /* First IR ref for this snapshot. */
|
||||||
uint8_t nslots; /* Number of valid slots. */
|
uint8_t nslots; /* Number of valid slots. */
|
||||||
|
uint8_t topslot; /* Maximum frame extent. */
|
||||||
uint8_t nent; /* Number of compressed entries. */
|
uint8_t nent; /* Number of compressed entries. */
|
||||||
uint8_t count; /* Count of taken exits for this snapshot. */
|
uint8_t count; /* Count of taken exits for this snapshot. */
|
||||||
uint8_t unused;
|
|
||||||
} SnapShot;
|
} SnapShot;
|
||||||
|
|
||||||
#define SNAPCOUNT_DONE 255 /* Already compiled and linked a side trace. */
|
#define SNAPCOUNT_DONE 255 /* Already compiled and linked a side trace. */
|
||||||
|
@ -199,6 +199,7 @@ static void loop_subst_snap(jit_State *J, SnapShot *osnap,
|
|||||||
snap->mapofs = (uint16_t)nmapofs;
|
snap->mapofs = (uint16_t)nmapofs;
|
||||||
snap->ref = (IRRef1)J->cur.nins;
|
snap->ref = (IRRef1)J->cur.nins;
|
||||||
snap->nslots = nslots;
|
snap->nslots = nslots;
|
||||||
|
snap->topslot = osnap->topslot;
|
||||||
snap->count = 0;
|
snap->count = 0;
|
||||||
nmap = &J->cur.snapmap[nmapofs];
|
nmap = &J->cur.snapmap[nmapofs];
|
||||||
/* Substitute snapshot slots. */
|
/* Substitute snapshot slots. */
|
||||||
|
@ -63,7 +63,8 @@ static MSize snapshot_slots(jit_State *J, SnapEntry *map, BCReg nslots)
|
|||||||
if (ref) {
|
if (ref) {
|
||||||
SnapEntry sn = SNAP_TR(s, tr);
|
SnapEntry sn = SNAP_TR(s, tr);
|
||||||
IRIns *ir = IR(ref);
|
IRIns *ir = IR(ref);
|
||||||
if (ir->o == IR_SLOAD && ir->op1 == s && ref > retf) {
|
if (!(sn & (SNAP_CONT|SNAP_FRAME)) &&
|
||||||
|
ir->o == IR_SLOAD && ir->op1 == s && ref > retf) {
|
||||||
/* No need to snapshot unmodified non-inherited slots. */
|
/* No need to snapshot unmodified non-inherited slots. */
|
||||||
if (!(ir->op2 & IRSLOAD_INHERIT))
|
if (!(ir->op2 & IRSLOAD_INHERIT))
|
||||||
continue;
|
continue;
|
||||||
@ -81,16 +82,19 @@ static MSize snapshot_slots(jit_State *J, SnapEntry *map, BCReg nslots)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add frame links at the end of the snapshot. */
|
/* Add frame links at the end of the snapshot. */
|
||||||
static void snapshot_framelinks(jit_State *J, SnapEntry *map)
|
static BCReg snapshot_framelinks(jit_State *J, SnapEntry *map)
|
||||||
{
|
{
|
||||||
cTValue *frame = J->L->base - 1;
|
cTValue *frame = J->L->base - 1;
|
||||||
cTValue *lim = J->L->base - J->baseslot;
|
cTValue *lim = J->L->base - J->baseslot;
|
||||||
|
cTValue *ftop = frame + funcproto(frame_func(frame))->framesize;
|
||||||
MSize f = 0;
|
MSize f = 0;
|
||||||
map[f++] = SNAP_MKPC(J->pc); /* The current PC is always the first entry. */
|
map[f++] = SNAP_MKPC(J->pc); /* The current PC is always the first entry. */
|
||||||
while (frame > lim) { /* Backwards traversal of all frames above base. */
|
while (frame > lim) { /* Backwards traversal of all frames above base. */
|
||||||
if (frame_islua(frame)) {
|
if (frame_islua(frame)) {
|
||||||
map[f++] = SNAP_MKPC(frame_pc(frame));
|
map[f++] = SNAP_MKPC(frame_pc(frame));
|
||||||
frame = frame_prevl(frame);
|
frame = frame_prevl(frame);
|
||||||
|
if (frame + funcproto(frame_func(frame))->framesize > ftop)
|
||||||
|
ftop = frame + funcproto(frame_func(frame))->framesize;
|
||||||
} else if (frame_iscont(frame)) {
|
} else if (frame_iscont(frame)) {
|
||||||
map[f++] = SNAP_MKFTSZ(frame_ftsz(frame));
|
map[f++] = SNAP_MKFTSZ(frame_ftsz(frame));
|
||||||
map[f++] = SNAP_MKPC(frame_contpc(frame));
|
map[f++] = SNAP_MKPC(frame_contpc(frame));
|
||||||
@ -102,6 +106,7 @@ static void snapshot_framelinks(jit_State *J, SnapEntry *map)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
lua_assert(f == (MSize)(1 + J->framedepth));
|
lua_assert(f == (MSize)(1 + J->framedepth));
|
||||||
|
return (BCReg)(ftop - lim);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Take a snapshot of the current stack. */
|
/* Take a snapshot of the current stack. */
|
||||||
@ -114,7 +119,7 @@ static void snapshot_stack(jit_State *J, SnapShot *snap, MSize nsnapmap)
|
|||||||
lj_snap_grow_map(J, nsnapmap + nslots + (MSize)J->framedepth+1);
|
lj_snap_grow_map(J, nsnapmap + nslots + (MSize)J->framedepth+1);
|
||||||
p = &J->cur.snapmap[nsnapmap];
|
p = &J->cur.snapmap[nsnapmap];
|
||||||
nent = snapshot_slots(J, p, nslots);
|
nent = snapshot_slots(J, p, nslots);
|
||||||
snapshot_framelinks(J, p + nent);
|
snap->topslot = (uint8_t)snapshot_framelinks(J, p + nent);
|
||||||
snap->mapofs = (uint16_t)nsnapmap;
|
snap->mapofs = (uint16_t)nsnapmap;
|
||||||
snap->ref = (IRRef1)J->cur.nins;
|
snap->ref = (IRRef1)J->cur.nins;
|
||||||
snap->nent = (uint8_t)nent;
|
snap->nent = (uint8_t)nent;
|
||||||
@ -338,7 +343,6 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr)
|
|||||||
SnapEntry *map = &T->snapmap[snap->mapofs];
|
SnapEntry *map = &T->snapmap[snap->mapofs];
|
||||||
SnapEntry *flinks = &T->snapmap[snap_nextofs(T, snap)-1];
|
SnapEntry *flinks = &T->snapmap[snap_nextofs(T, snap)-1];
|
||||||
int32_t ftsz0;
|
int32_t ftsz0;
|
||||||
BCReg nslots = snap->nslots;
|
|
||||||
TValue *frame;
|
TValue *frame;
|
||||||
BloomFilter rfilt = snap_renamefilter(T, snapno);
|
BloomFilter rfilt = snap_renamefilter(T, snapno);
|
||||||
const BCIns *pc = snap_pc(map[nent]);
|
const BCIns *pc = snap_pc(map[nent]);
|
||||||
@ -348,9 +352,9 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr)
|
|||||||
setcframe_pc(cframe_raw(L->cframe), pc+1);
|
setcframe_pc(cframe_raw(L->cframe), pc+1);
|
||||||
|
|
||||||
/* Make sure the stack is big enough for the slots from the snapshot. */
|
/* Make sure the stack is big enough for the slots from the snapshot. */
|
||||||
if (LJ_UNLIKELY(L->base + nslots > tvref(L->maxstack))) {
|
if (LJ_UNLIKELY(L->base + snap->topslot > tvref(L->maxstack))) {
|
||||||
L->top = curr_topL(L);
|
L->top = curr_topL(L);
|
||||||
lj_state_growstack(L, nslots - curr_proto(L)->framesize);
|
lj_state_growstack(L, snap->topslot - curr_proto(L)->framesize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill stack slots with data from the registers and spill slots. */
|
/* Fill stack slots with data from the registers and spill slots. */
|
||||||
@ -364,27 +368,9 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr)
|
|||||||
IRIns *ir = &T->ir[ref];
|
IRIns *ir = &T->ir[ref];
|
||||||
if (irref_isk(ref)) { /* Restore constant slot. */
|
if (irref_isk(ref)) { /* Restore constant slot. */
|
||||||
lj_ir_kvalue(L, o, ir);
|
lj_ir_kvalue(L, o, ir);
|
||||||
if ((sn & (SNAP_CONT|SNAP_FRAME))) {
|
|
||||||
/* Overwrite tag with frame link. */
|
|
||||||
o->fr.tp.ftsz = s != 0 ? (int32_t)*flinks-- : ftsz0;
|
|
||||||
if ((sn & SNAP_FRAME)) {
|
|
||||||
GCfunc *fn = ir_kfunc(ir);
|
|
||||||
if (isluafunc(fn)) {
|
|
||||||
MSize framesize = funcproto(fn)->framesize;
|
|
||||||
L->base = ++o;
|
|
||||||
if (LJ_UNLIKELY(o + framesize > tvref(L->maxstack))) {
|
|
||||||
ptrdiff_t fsave = savestack(L, frame);
|
|
||||||
L->top = o;
|
|
||||||
lj_state_growstack(L, framesize); /* Grow again. */
|
|
||||||
frame = restorestack(L, fsave);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (!(sn & SNAP_NORESTORE)) {
|
} else if (!(sn & SNAP_NORESTORE)) {
|
||||||
IRType1 t = ir->t;
|
IRType1 t = ir->t;
|
||||||
RegSP rs = ir->prev;
|
RegSP rs = ir->prev;
|
||||||
lua_assert(!(sn & (SNAP_CONT|SNAP_FRAME)));
|
|
||||||
if (LJ_UNLIKELY(bloomtest(rfilt, ref)))
|
if (LJ_UNLIKELY(bloomtest(rfilt, ref)))
|
||||||
rs = snap_renameref(T, snapno, ref, rs);
|
rs = snap_renameref(T, snapno, ref, rs);
|
||||||
if (ra_hasspill(regsp_spill(rs))) { /* Restore from spill slot. */
|
if (ra_hasspill(regsp_spill(rs))) { /* Restore from spill slot. */
|
||||||
@ -438,10 +424,14 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr)
|
|||||||
(uint32_t)ex->gpr[regsp_reg(rs)-RID_MIN_GPR];
|
(uint32_t)ex->gpr[regsp_reg(rs)-RID_MIN_GPR];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((sn & (SNAP_CONT|SNAP_FRAME))) { /* Overwrite tag with frame link. */
|
||||||
|
o->fr.tp.ftsz = s != 0 ? (int32_t)*flinks-- : ftsz0;
|
||||||
|
L->base = o+1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
switch (bc_op(*pc)) {
|
switch (bc_op(*pc)) {
|
||||||
case BC_CALLM: case BC_CALLMT: case BC_RETM: case BC_TSETM:
|
case BC_CALLM: case BC_CALLMT: case BC_RETM: case BC_TSETM:
|
||||||
L->top = frame + nslots;
|
L->top = frame + snap->nslots;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
L->top = curr_topL(L);
|
L->top = curr_topL(L);
|
||||||
|
Loading…
Reference in New Issue
Block a user