diff options
Diffstat (limited to 'src/lj_asm.c')
-rw-r--r-- | src/lj_asm.c | 47 |
1 files changed, 20 insertions, 27 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index be6a11ff..16671a8a 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
@@ -903,30 +903,6 @@ static uint32_t asm_callx_flags(ASMState *as, IRIns *ir) | |||
903 | return (nargs | (ir->t.irt << CCI_OTSHIFT)); | 903 | return (nargs | (ir->t.irt << CCI_OTSHIFT)); |
904 | } | 904 | } |
905 | 905 | ||
906 | /* Get extent of the stack for a snapshot. */ | ||
907 | static BCReg asm_stack_extent(ASMState *as, SnapShot *snap, BCReg *ptopslot) | ||
908 | { | ||
909 | SnapEntry *map = &as->T->snapmap[snap->mapofs]; | ||
910 | MSize n, nent = snap->nent; | ||
911 | BCReg baseslot = 0, topslot = 0; | ||
912 | /* Must check all frames to find topslot (outer can be larger than inner). */ | ||
913 | for (n = 0; n < nent; n++) { | ||
914 | SnapEntry sn = map[n]; | ||
915 | if ((sn & SNAP_FRAME)) { | ||
916 | IRIns *ir = IR(snap_ref(sn)); | ||
917 | GCfunc *fn = ir_kfunc(ir); | ||
918 | if (isluafunc(fn)) { | ||
919 | BCReg s = snap_slot(sn); | ||
920 | BCReg fs = s + funcproto(fn)->framesize; | ||
921 | if (fs > topslot) topslot = fs; | ||
922 | baseslot = s; | ||
923 | } | ||
924 | } | ||
925 | } | ||
926 | *ptopslot = topslot; | ||
927 | return baseslot; | ||
928 | } | ||
929 | |||
930 | /* Calculate stack adjustment. */ | 906 | /* Calculate stack adjustment. */ |
931 | static int32_t asm_stack_adjust(ASMState *as) | 907 | static int32_t asm_stack_adjust(ASMState *as) |
932 | { | 908 | { |
@@ -1415,13 +1391,30 @@ static void asm_head_side(ASMState *as) | |||
1415 | 1391 | ||
1416 | /* -- Tail of trace ------------------------------------------------------- */ | 1392 | /* -- Tail of trace ------------------------------------------------------- */ |
1417 | 1393 | ||
1394 | /* Get base slot for a snapshot. */ | ||
1395 | static BCReg asm_baseslot(ASMState *as, SnapShot *snap, int *gotframe) | ||
1396 | { | ||
1397 | SnapEntry *map = &as->T->snapmap[snap->mapofs]; | ||
1398 | MSize n; | ||
1399 | for (n = snap->nent; n > 0; n--) { | ||
1400 | SnapEntry sn = map[n-1]; | ||
1401 | if ((sn & SNAP_FRAME)) { | ||
1402 | *gotframe = 1; | ||
1403 | return snap_slot(sn); | ||
1404 | } | ||
1405 | } | ||
1406 | return 0; | ||
1407 | } | ||
1408 | |||
1418 | /* Link to another trace. */ | 1409 | /* Link to another trace. */ |
1419 | static void asm_tail_link(ASMState *as) | 1410 | static void asm_tail_link(ASMState *as) |
1420 | { | 1411 | { |
1421 | SnapNo snapno = as->T->nsnap-1; /* Last snapshot. */ | 1412 | SnapNo snapno = as->T->nsnap-1; /* Last snapshot. */ |
1422 | SnapShot *snap = &as->T->snap[snapno]; | 1413 | SnapShot *snap = &as->T->snap[snapno]; |
1423 | BCReg baseslot = asm_stack_extent(as, snap, &as->topslot); | 1414 | int gotframe = 0; |
1415 | BCReg baseslot = asm_baseslot(as, snap, &gotframe); | ||
1424 | 1416 | ||
1417 | as->topslot = snap->topslot; | ||
1425 | checkmclim(as); | 1418 | checkmclim(as); |
1426 | ra_allocref(as, REF_BASE, RID2RSET(RID_BASE)); | 1419 | ra_allocref(as, REF_BASE, RID2RSET(RID_BASE)); |
1427 | 1420 | ||
@@ -1454,8 +1447,8 @@ static void asm_tail_link(ASMState *as) | |||
1454 | /* Sync the interpreter state with the on-trace state. */ | 1447 | /* Sync the interpreter state with the on-trace state. */ |
1455 | asm_stack_restore(as, snap); | 1448 | asm_stack_restore(as, snap); |
1456 | 1449 | ||
1457 | /* Root traces that grow the stack need to check the stack at the end. */ | 1450 | /* Root traces that add frames need to check the stack at the end. */ |
1458 | if (!as->parent && as->topslot) | 1451 | if (!as->parent && gotframe) |
1459 | asm_stack_check(as, as->topslot, NULL, as->freeset & RSET_GPR, snapno); | 1452 | asm_stack_check(as, as->topslot, NULL, as->freeset & RSET_GPR, snapno); |
1460 | } | 1453 | } |
1461 | 1454 | ||