aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-02-21 16:47:43 +0100
committerMike Pall <mike>2010-02-21 16:47:43 +0100
commitc1658ddcf1a2e6b6713419451cfe4ed96424e6e6 (patch)
tree92c66c46178dbc22122c722f334eef17902db600 /src
parentc52da1f2da4963762e7743419d58e372e1c9ac06 (diff)
downloadluajit-c1658ddcf1a2e6b6713419451cfe4ed96424e6e6.tar.gz
luajit-c1658ddcf1a2e6b6713419451cfe4ed96424e6e6.tar.bz2
luajit-c1658ddcf1a2e6b6713419451cfe4ed96424e6e6.zip
Eliminate redundant stack checks. Add checks for growing root traces.
Diffstat (limited to 'src')
-rw-r--r--src/lj_asm.c28
-rw-r--r--src/lj_jit.h6
2 files changed, 26 insertions, 8 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c
index aed12043..8d852ac0 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -2840,19 +2840,24 @@ static void asm_head_root(ASMState *as)
2840 spadj = sps_adjust(as->evenspill); 2840 spadj = sps_adjust(as->evenspill);
2841 as->T->spadjust = (uint16_t)spadj; 2841 as->T->spadjust = (uint16_t)spadj;
2842 emit_addptr(as, RID_ESP, -spadj); 2842 emit_addptr(as, RID_ESP, -spadj);
2843 /* Root traces assume a checked stack for the starting proto. */
2844 as->T->topslot = gcref(as->T->startpt)->pt.framesize;
2843} 2845}
2844 2846
2845/* Check Lua stack size for overflow at the start of a side trace. 2847/* Check Lua stack size for overflow at the start of a side trace.
2846** Stack overflow is rare, so let the regular exit handling fix this up. 2848** Stack overflow is rare, so let the regular exit handling fix this up.
2847** This is done in the context of the *parent* trace and parent exitno! 2849** This is done in the context of the *parent* trace and parent exitno!
2848*/ 2850*/
2849static void asm_checkstack(ASMState *as, BCReg topslot, Reg pbase, RegSet allow) 2851static void asm_checkstack(ASMState *as, BCReg topslot,
2852 Reg pbase, RegSet allow, ExitNo exitno)
2850{ 2853{
2851 /* Try to get an unused temp. register, otherwise spill/restore eax. */ 2854 /* Try to get an unused temp. register, otherwise spill/restore eax. */
2852 Reg r = allow ? rset_pickbot(allow) : RID_EAX; 2855 Reg r = allow ? rset_pickbot(allow) : RID_EAX;
2853 emit_jcc(as, CC_B, exitstub_addr(as->J, as->J->exitno)); 2856 emit_jcc(as, CC_B, exitstub_addr(as->J, exitno));
2854 if (allow == RSET_EMPTY) /* Restore temp. register. */ 2857 if (allow == RSET_EMPTY) /* Restore temp. register. */
2855 emit_rmro(as, XO_MOV, r, RID_ESP, sps_scale(SPS_TEMP1)); 2858 emit_rmro(as, XO_MOV, r, RID_ESP, sps_scale(SPS_TEMP1));
2859 else
2860 ra_modified(as, r);
2856 emit_gri(as, XG_ARITHi(XOg_CMP), r, (int32_t)(8*topslot)); 2861 emit_gri(as, XG_ARITHi(XOg_CMP), r, (int32_t)(8*topslot));
2857 if (ra_hasreg(pbase) && pbase != r) 2862 if (ra_hasreg(pbase) && pbase != r)
2858 emit_rr(as, XO_ARITH(XOg_SUB), r, pbase); 2863 emit_rr(as, XO_ARITH(XOg_SUB), r, pbase);
@@ -3029,9 +3034,13 @@ static void asm_head_side(ASMState *as)
3029 /* Continue with coalescing to fix up the broken cycle(s). */ 3034 /* Continue with coalescing to fix up the broken cycle(s). */
3030 } 3035 }
3031 3036
3032 /* Check Lua stack size if frames have been added. */ 3037 /* Inherit top stack slot already checked by parent trace. */
3033 if (as->topslot) 3038 as->T->topslot = as->parent->topslot;
3034 asm_checkstack(as, as->topslot, pbase, allow & RSET_GPR); 3039 if (as->topslot > as->T->topslot) { /* Need to check for higher slot? */
3040 as->T->topslot = (uint8_t)as->topslot; /* Remember for child traces. */
3041 /* Reuse the parent exit in the context of the parent trace. */
3042 asm_checkstack(as, as->topslot, pbase, allow & RSET_GPR, as->J->exitno);
3043 }
3035} 3044}
3036 3045
3037/* -- Tail of trace ------------------------------------------------------- */ 3046/* -- Tail of trace ------------------------------------------------------- */
@@ -3041,7 +3050,8 @@ static void asm_head_side(ASMState *as)
3041*/ 3050*/
3042static void asm_tail_sync(ASMState *as) 3051static void asm_tail_sync(ASMState *as)
3043{ 3052{
3044 SnapShot *snap = &as->T->snap[as->T->nsnap-1]; /* Last snapshot. */ 3053 SnapNo snapno = as->T->nsnap-1; /* Last snapshot. */
3054 SnapShot *snap = &as->T->snap[snapno];
3045 MSize n, nent = snap->nent; 3055 MSize n, nent = snap->nent;
3046 SnapEntry *map = &as->T->snapmap[snap->mapofs]; 3056 SnapEntry *map = &as->T->snapmap[snap->mapofs];
3047 SnapEntry *flinks = map + nent + snap->depth; 3057 SnapEntry *flinks = map + nent + snap->depth;
@@ -3107,6 +3117,10 @@ static void asm_tail_sync(ASMState *as)
3107 checkmclim(as); 3117 checkmclim(as);
3108 } 3118 }
3109 lua_assert(map + nent == flinks); 3119 lua_assert(map + nent == flinks);
3120
3121 /* Root traces that grow the stack need to check the stack at the end. */
3122 if (!as->parent && topslot)
3123 asm_checkstack(as, topslot, RID_BASE, as->freeset & RSET_GPR, snapno);
3110} 3124}
3111 3125
3112/* Fixup the tail code. */ 3126/* Fixup the tail code. */
@@ -3479,7 +3493,7 @@ void lj_asm_trace(jit_State *J, Trace *T)
3479 if (as->gcsteps) 3493 if (as->gcsteps)
3480 asm_gc_check(as, &as->T->snap[0]); 3494 asm_gc_check(as, &as->T->snap[0]);
3481 asm_const_remat(as); 3495 asm_const_remat(as);
3482 if (J->parent) 3496 if (as->parent)
3483 asm_head_side(as); 3497 asm_head_side(as);
3484 else 3498 else
3485 asm_head_root(as); 3499 asm_head_root(as);
diff --git a/src/lj_jit.h b/src/lj_jit.h
index a43611de..41a3fe9a 100644
--- a/src/lj_jit.h
+++ b/src/lj_jit.h
@@ -169,6 +169,10 @@ typedef struct Trace {
169 TraceNo1 nextside; /* Next side trace of same root trace. */ 169 TraceNo1 nextside; /* Next side trace of same root trace. */
170 uint16_t nchild; /* Number of child traces (root trace only). */ 170 uint16_t nchild; /* Number of child traces (root trace only). */
171 uint16_t spadjust; /* Stack pointer adjustment (offset in bytes). */ 171 uint16_t spadjust; /* Stack pointer adjustment (offset in bytes). */
172 uint8_t topslot; /* Top stack slot already checked to be allocated. */
173 uint8_t unused1;
174 uint8_t unused2;
175 uint8_t unused3;
172#ifdef LUAJIT_USE_GDBJIT 176#ifdef LUAJIT_USE_GDBJIT
173 void *gdbjit_entry; /* GDB JIT entry. */ 177 void *gdbjit_entry; /* GDB JIT entry. */
174#endif 178#endif
@@ -227,9 +231,9 @@ typedef struct jit_State {
227 231
228 TraceState state; /* Trace compiler state. */ 232 TraceState state; /* Trace compiler state. */
229 233
234 uint64_t tailcalled; /* History of the number of successive tailcalls. */
230 int32_t instunroll; /* Unroll counter for instable loops. */ 235 int32_t instunroll; /* Unroll counter for instable loops. */
231 int32_t loopunroll; /* Unroll counter for loop ops in side traces. */ 236 int32_t loopunroll; /* Unroll counter for loop ops in side traces. */
232 uint64_t tailcalled; /* History of the number of successive tailcalls. */
233 int32_t framedepth; /* Current frame depth. */ 237 int32_t framedepth; /* Current frame depth. */
234 int32_t retdepth; /* Return frame depth (count of RETF). */ 238 int32_t retdepth; /* Return frame depth (count of RETF). */
235 239