diff options
| author | Mike Pall <mike> | 2011-11-20 17:56:47 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2011-11-20 17:56:47 +0100 |
| commit | f8a4769fb2bd398d526dfe0bdd6814875a2fa39e (patch) | |
| tree | 23153ce6405908dd4c6d40d38749254e7ca0cc6e /src | |
| parent | dc2a39e46d9498c475eaf9ad7c4a8ae61a73094a (diff) | |
| download | luajit-f8a4769fb2bd398d526dfe0bdd6814875a2fa39e.tar.gz luajit-f8a4769fb2bd398d526dfe0bdd6814875a2fa39e.tar.bz2 luajit-f8a4769fb2bd398d526dfe0bdd6814875a2fa39e.zip | |
Keep maximum frame extent in snap->topslot.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_asm.c | 47 | ||||
| -rw-r--r-- | src/lj_jit.h | 2 | ||||
| -rw-r--r-- | src/lj_opt_loop.c | 1 | ||||
| -rw-r--r-- | src/lj_snap.c | 40 |
4 files changed, 37 insertions, 53 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 | ||
diff --git a/src/lj_jit.h b/src/lj_jit.h index e80547ab..11dc9737 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h | |||
| @@ -138,9 +138,9 @@ typedef struct SnapShot { | |||
| 138 | uint16_t mapofs; /* Offset into snapshot map. */ | 138 | uint16_t mapofs; /* Offset into snapshot map. */ |
| 139 | IRRef1 ref; /* First IR ref for this snapshot. */ | 139 | IRRef1 ref; /* First IR ref for this snapshot. */ |
| 140 | uint8_t nslots; /* Number of valid slots. */ | 140 | uint8_t nslots; /* Number of valid slots. */ |
| 141 | uint8_t topslot; /* Maximum frame extent. */ | ||
| 141 | uint8_t nent; /* Number of compressed entries. */ | 142 | uint8_t nent; /* Number of compressed entries. */ |
| 142 | uint8_t count; /* Count of taken exits for this snapshot. */ | 143 | uint8_t count; /* Count of taken exits for this snapshot. */ |
| 143 | uint8_t unused; | ||
| 144 | } SnapShot; | 144 | } SnapShot; |
| 145 | 145 | ||
| 146 | #define SNAPCOUNT_DONE 255 /* Already compiled and linked a side trace. */ | 146 | #define SNAPCOUNT_DONE 255 /* Already compiled and linked a side trace. */ |
diff --git a/src/lj_opt_loop.c b/src/lj_opt_loop.c index 8d2935f6..c3d115b2 100644 --- a/src/lj_opt_loop.c +++ b/src/lj_opt_loop.c | |||
| @@ -199,6 +199,7 @@ static void loop_subst_snap(jit_State *J, SnapShot *osnap, | |||
| 199 | snap->mapofs = (uint16_t)nmapofs; | 199 | snap->mapofs = (uint16_t)nmapofs; |
| 200 | snap->ref = (IRRef1)J->cur.nins; | 200 | snap->ref = (IRRef1)J->cur.nins; |
| 201 | snap->nslots = nslots; | 201 | snap->nslots = nslots; |
| 202 | snap->topslot = osnap->topslot; | ||
| 202 | snap->count = 0; | 203 | snap->count = 0; |
| 203 | nmap = &J->cur.snapmap[nmapofs]; | 204 | nmap = &J->cur.snapmap[nmapofs]; |
| 204 | /* Substitute snapshot slots. */ | 205 | /* Substitute snapshot slots. */ |
diff --git a/src/lj_snap.c b/src/lj_snap.c index a2025d88..89f73982 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c | |||
| @@ -63,7 +63,8 @@ static MSize snapshot_slots(jit_State *J, SnapEntry *map, BCReg nslots) | |||
| 63 | if (ref) { | 63 | if (ref) { |
| 64 | SnapEntry sn = SNAP_TR(s, tr); | 64 | SnapEntry sn = SNAP_TR(s, tr); |
| 65 | IRIns *ir = IR(ref); | 65 | IRIns *ir = IR(ref); |
| 66 | if (ir->o == IR_SLOAD && ir->op1 == s && ref > retf) { | 66 | if (!(sn & (SNAP_CONT|SNAP_FRAME)) && |
| 67 | ir->o == IR_SLOAD && ir->op1 == s && ref > retf) { | ||
| 67 | /* No need to snapshot unmodified non-inherited slots. */ | 68 | /* No need to snapshot unmodified non-inherited slots. */ |
| 68 | if (!(ir->op2 & IRSLOAD_INHERIT)) | 69 | if (!(ir->op2 & IRSLOAD_INHERIT)) |
| 69 | continue; | 70 | continue; |
| @@ -81,16 +82,19 @@ static MSize snapshot_slots(jit_State *J, SnapEntry *map, BCReg nslots) | |||
| 81 | } | 82 | } |
| 82 | 83 | ||
| 83 | /* Add frame links at the end of the snapshot. */ | 84 | /* Add frame links at the end of the snapshot. */ |
| 84 | static void snapshot_framelinks(jit_State *J, SnapEntry *map) | 85 | static BCReg snapshot_framelinks(jit_State *J, SnapEntry *map) |
| 85 | { | 86 | { |
| 86 | cTValue *frame = J->L->base - 1; | 87 | cTValue *frame = J->L->base - 1; |
| 87 | cTValue *lim = J->L->base - J->baseslot; | 88 | cTValue *lim = J->L->base - J->baseslot; |
| 89 | cTValue *ftop = frame + funcproto(frame_func(frame))->framesize; | ||
| 88 | MSize f = 0; | 90 | MSize f = 0; |
| 89 | map[f++] = SNAP_MKPC(J->pc); /* The current PC is always the first entry. */ | 91 | map[f++] = SNAP_MKPC(J->pc); /* The current PC is always the first entry. */ |
| 90 | while (frame > lim) { /* Backwards traversal of all frames above base. */ | 92 | while (frame > lim) { /* Backwards traversal of all frames above base. */ |
| 91 | if (frame_islua(frame)) { | 93 | if (frame_islua(frame)) { |
| 92 | map[f++] = SNAP_MKPC(frame_pc(frame)); | 94 | map[f++] = SNAP_MKPC(frame_pc(frame)); |
| 93 | frame = frame_prevl(frame); | 95 | frame = frame_prevl(frame); |
| 96 | if (frame + funcproto(frame_func(frame))->framesize > ftop) | ||
| 97 | ftop = frame + funcproto(frame_func(frame))->framesize; | ||
| 94 | } else if (frame_iscont(frame)) { | 98 | } else if (frame_iscont(frame)) { |
| 95 | map[f++] = SNAP_MKFTSZ(frame_ftsz(frame)); | 99 | map[f++] = SNAP_MKFTSZ(frame_ftsz(frame)); |
| 96 | map[f++] = SNAP_MKPC(frame_contpc(frame)); | 100 | map[f++] = SNAP_MKPC(frame_contpc(frame)); |
| @@ -102,6 +106,7 @@ static void snapshot_framelinks(jit_State *J, SnapEntry *map) | |||
| 102 | } | 106 | } |
| 103 | } | 107 | } |
| 104 | lua_assert(f == (MSize)(1 + J->framedepth)); | 108 | lua_assert(f == (MSize)(1 + J->framedepth)); |
| 109 | return (BCReg)(ftop - lim); | ||
| 105 | } | 110 | } |
| 106 | 111 | ||
| 107 | /* Take a snapshot of the current stack. */ | 112 | /* Take a snapshot of the current stack. */ |
| @@ -114,7 +119,7 @@ static void snapshot_stack(jit_State *J, SnapShot *snap, MSize nsnapmap) | |||
| 114 | lj_snap_grow_map(J, nsnapmap + nslots + (MSize)J->framedepth+1); | 119 | lj_snap_grow_map(J, nsnapmap + nslots + (MSize)J->framedepth+1); |
| 115 | p = &J->cur.snapmap[nsnapmap]; | 120 | p = &J->cur.snapmap[nsnapmap]; |
| 116 | nent = snapshot_slots(J, p, nslots); | 121 | nent = snapshot_slots(J, p, nslots); |
| 117 | snapshot_framelinks(J, p + nent); | 122 | snap->topslot = (uint8_t)snapshot_framelinks(J, p + nent); |
| 118 | snap->mapofs = (uint16_t)nsnapmap; | 123 | snap->mapofs = (uint16_t)nsnapmap; |
| 119 | snap->ref = (IRRef1)J->cur.nins; | 124 | snap->ref = (IRRef1)J->cur.nins; |
| 120 | snap->nent = (uint8_t)nent; | 125 | snap->nent = (uint8_t)nent; |
| @@ -338,7 +343,6 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) | |||
| 338 | SnapEntry *map = &T->snapmap[snap->mapofs]; | 343 | SnapEntry *map = &T->snapmap[snap->mapofs]; |
| 339 | SnapEntry *flinks = &T->snapmap[snap_nextofs(T, snap)-1]; | 344 | SnapEntry *flinks = &T->snapmap[snap_nextofs(T, snap)-1]; |
| 340 | int32_t ftsz0; | 345 | int32_t ftsz0; |
| 341 | BCReg nslots = snap->nslots; | ||
| 342 | TValue *frame; | 346 | TValue *frame; |
| 343 | BloomFilter rfilt = snap_renamefilter(T, snapno); | 347 | BloomFilter rfilt = snap_renamefilter(T, snapno); |
| 344 | const BCIns *pc = snap_pc(map[nent]); | 348 | const BCIns *pc = snap_pc(map[nent]); |
| @@ -348,9 +352,9 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) | |||
| 348 | setcframe_pc(cframe_raw(L->cframe), pc+1); | 352 | setcframe_pc(cframe_raw(L->cframe), pc+1); |
| 349 | 353 | ||
| 350 | /* Make sure the stack is big enough for the slots from the snapshot. */ | 354 | /* Make sure the stack is big enough for the slots from the snapshot. */ |
| 351 | if (LJ_UNLIKELY(L->base + nslots > tvref(L->maxstack))) { | 355 | if (LJ_UNLIKELY(L->base + snap->topslot > tvref(L->maxstack))) { |
| 352 | L->top = curr_topL(L); | 356 | L->top = curr_topL(L); |
| 353 | lj_state_growstack(L, nslots - curr_proto(L)->framesize); | 357 | lj_state_growstack(L, snap->topslot - curr_proto(L)->framesize); |
| 354 | } | 358 | } |
| 355 | 359 | ||
| 356 | /* Fill stack slots with data from the registers and spill slots. */ | 360 | /* 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) | |||
| 364 | IRIns *ir = &T->ir[ref]; | 368 | IRIns *ir = &T->ir[ref]; |
| 365 | if (irref_isk(ref)) { /* Restore constant slot. */ | 369 | if (irref_isk(ref)) { /* Restore constant slot. */ |
| 366 | lj_ir_kvalue(L, o, ir); | 370 | lj_ir_kvalue(L, o, ir); |
| 367 | if ((sn & (SNAP_CONT|SNAP_FRAME))) { | ||
| 368 | /* Overwrite tag with frame link. */ | ||
| 369 | o->fr.tp.ftsz = s != 0 ? (int32_t)*flinks-- : ftsz0; | ||
| 370 | if ((sn & SNAP_FRAME)) { | ||
| 371 | GCfunc *fn = ir_kfunc(ir); | ||
| 372 | if (isluafunc(fn)) { | ||
| 373 | MSize framesize = funcproto(fn)->framesize; | ||
| 374 | L->base = ++o; | ||
| 375 | if (LJ_UNLIKELY(o + framesize > tvref(L->maxstack))) { | ||
| 376 | ptrdiff_t fsave = savestack(L, frame); | ||
| 377 | L->top = o; | ||
| 378 | lj_state_growstack(L, framesize); /* Grow again. */ | ||
| 379 | frame = restorestack(L, fsave); | ||
| 380 | } | ||
| 381 | } | ||
| 382 | } | ||
| 383 | } | ||
| 384 | } else if (!(sn & SNAP_NORESTORE)) { | 371 | } else if (!(sn & SNAP_NORESTORE)) { |
| 385 | IRType1 t = ir->t; | 372 | IRType1 t = ir->t; |
| 386 | RegSP rs = ir->prev; | 373 | RegSP rs = ir->prev; |
| 387 | lua_assert(!(sn & (SNAP_CONT|SNAP_FRAME))); | ||
| 388 | if (LJ_UNLIKELY(bloomtest(rfilt, ref))) | 374 | if (LJ_UNLIKELY(bloomtest(rfilt, ref))) |
| 389 | rs = snap_renameref(T, snapno, ref, rs); | 375 | rs = snap_renameref(T, snapno, ref, rs); |
| 390 | if (ra_hasspill(regsp_spill(rs))) { /* Restore from spill slot. */ | 376 | if (ra_hasspill(regsp_spill(rs))) { /* Restore from spill slot. */ |
| @@ -438,10 +424,14 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) | |||
| 438 | (uint32_t)ex->gpr[regsp_reg(rs)-RID_MIN_GPR]; | 424 | (uint32_t)ex->gpr[regsp_reg(rs)-RID_MIN_GPR]; |
| 439 | } | 425 | } |
| 440 | } | 426 | } |
| 427 | if ((sn & (SNAP_CONT|SNAP_FRAME))) { /* Overwrite tag with frame link. */ | ||
| 428 | o->fr.tp.ftsz = s != 0 ? (int32_t)*flinks-- : ftsz0; | ||
| 429 | L->base = o+1; | ||
| 430 | } | ||
| 441 | } | 431 | } |
| 442 | switch (bc_op(*pc)) { | 432 | switch (bc_op(*pc)) { |
| 443 | case BC_CALLM: case BC_CALLMT: case BC_RETM: case BC_TSETM: | 433 | case BC_CALLM: case BC_CALLMT: case BC_RETM: case BC_TSETM: |
| 444 | L->top = frame + nslots; | 434 | L->top = frame + snap->nslots; |
| 445 | break; | 435 | break; |
| 446 | default: | 436 | default: |
| 447 | L->top = curr_topL(L); | 437 | L->top = curr_topL(L); |
