aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2011-11-20 17:56:47 +0100
committerMike Pall <mike>2011-11-20 17:56:47 +0100
commitf8a4769fb2bd398d526dfe0bdd6814875a2fa39e (patch)
tree23153ce6405908dd4c6d40d38749254e7ca0cc6e
parentdc2a39e46d9498c475eaf9ad7c4a8ae61a73094a (diff)
downloadluajit-f8a4769fb2bd398d526dfe0bdd6814875a2fa39e.tar.gz
luajit-f8a4769fb2bd398d526dfe0bdd6814875a2fa39e.tar.bz2
luajit-f8a4769fb2bd398d526dfe0bdd6814875a2fa39e.zip
Keep maximum frame extent in snap->topslot.
-rw-r--r--src/lj_asm.c47
-rw-r--r--src/lj_jit.h2
-rw-r--r--src/lj_opt_loop.c1
-rw-r--r--src/lj_snap.c40
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. */
907static 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. */
931static int32_t asm_stack_adjust(ASMState *as) 907static 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. */
1395static 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. */
1419static void asm_tail_link(ASMState *as) 1410static 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. */
84static void snapshot_framelinks(jit_State *J, SnapEntry *map) 85static 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);