summaryrefslogtreecommitdiff
path: root/src/lj_record.c
diff options
context:
space:
mode:
authorMike Pall <mike>2010-02-18 19:32:13 +0100
committerMike Pall <mike>2010-02-18 19:32:13 +0100
commitb11eeab906b4c5f26f257d8c75987769abd68507 (patch)
treec042c276844809be6c75b716fafa443c9af00e79 /src/lj_record.c
parent65586ca4dcbcffe08f96aee69ac22374c32c6e8a (diff)
downloadluajit-b11eeab906b4c5f26f257d8c75987769abd68507.tar.gz
luajit-b11eeab906b4c5f26f257d8c75987769abd68507.tar.bz2
luajit-b11eeab906b4c5f26f257d8c75987769abd68507.zip
Use a limited history buffer for tailcall counts while recording.
Diffstat (limited to 'src/lj_record.c')
-rw-r--r--src/lj_record.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/src/lj_record.c b/src/lj_record.c
index f4bfd5f7..3f7c2bde 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -473,8 +473,8 @@ static void rec_loop_jit(jit_State *J, TraceNo lnk, LoopEvent ev)
473 473
474/* -- Record calls and returns -------------------------------------------- */ 474/* -- Record calls and returns -------------------------------------------- */
475 475
476/* Record call. */ 476/* Record call setup. */
477static void rec_call(jit_State *J, BCReg func, ptrdiff_t nargs) 477static void rec_call_setup(jit_State *J, BCReg func, ptrdiff_t nargs)
478{ 478{
479 RecordIndex ix; 479 RecordIndex ix;
480 TValue *functv = &J->L->base[func]; 480 TValue *functv = &J->L->base[func];
@@ -496,24 +496,30 @@ static void rec_call(jit_State *J, BCReg func, ptrdiff_t nargs)
496 trfunc = lj_ir_kfunc(J, funcV(functv)); 496 trfunc = lj_ir_kfunc(J, funcV(functv));
497 emitir(IRTG(IR_EQ, IRT_FUNC), fbase[0], trfunc); 497 emitir(IRTG(IR_EQ, IRT_FUNC), fbase[0], trfunc);
498 fbase[0] = trfunc | TREF_FRAME; 498 fbase[0] = trfunc | TREF_FRAME;
499 J->maxslot = nargs;
500}
499 501
502/* Record call. */
503static void rec_call(jit_State *J, BCReg func, ptrdiff_t nargs)
504{
505 rec_call_setup(J, func, nargs);
500 /* Bump frame. */ 506 /* Bump frame. */
501 J->framedepth++; 507 J->framedepth++;
508 J->tailcalled <<= 8; /* NYI: tail call history overflow is ignored. */
502 J->base += func+1; 509 J->base += func+1;
503 J->baseslot += func+1; 510 J->baseslot += func+1;
504 J->maxslot = nargs;
505} 511}
506 512
507/* Record tail call. */ 513/* Record tail call. */
508static void rec_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs) 514static void rec_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs)
509{ 515{
510 rec_call(J, func, nargs); 516 rec_call_setup(J, func, nargs);
511 /* Move func + args down. */ 517 /* Move func + args down. */
512 J->framedepth--;
513 J->base -= func+1;
514 J->baseslot -= func+1;
515 memmove(&J->base[-1], &J->base[func], sizeof(TRef)*(J->maxslot+1)); 518 memmove(&J->base[-1], &J->base[func], sizeof(TRef)*(J->maxslot+1));
516 /* Note: the new TREF_FRAME is now at J->base[-1] (even for slot #0). */ 519 /* Note: the new TREF_FRAME is now at J->base[-1] (even for slot #0). */
520 /* Tailcalls can form a loop, so count towards the loop unroll limit. */
521 if ((int32_t)(++J->tailcalled & 0xff) > J->loopunroll)
522 lj_trace_err(J, LJ_TRERR_LUNROLL);
517} 523}
518 524
519/* Record return. */ 525/* Record return. */
@@ -521,6 +527,7 @@ static void rec_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults)
521{ 527{
522 TValue *frame = J->L->base - 1; 528 TValue *frame = J->L->base - 1;
523 ptrdiff_t i; 529 ptrdiff_t i;
530 J->tailcalled >>= 8;
524 for (i = 0; i < gotresults; i++) 531 for (i = 0; i < gotresults; i++)
525 getslot(J, rbase+i); /* Ensure all results have a reference. */ 532 getslot(J, rbase+i); /* Ensure all results have a reference. */
526 while (frame_ispcall(frame)) { /* Immediately resolve pcall() returns. */ 533 while (frame_ispcall(frame)) { /* Immediately resolve pcall() returns. */
@@ -1693,7 +1700,7 @@ static uint32_t recdef_lookup(GCfunc *fn)
1693 return 0; 1700 return 0;
1694} 1701}
1695 1702
1696/* Record call to fast function or C function. */ 1703/* Record entry to a fast function or C function. */
1697static void rec_func_ff(jit_State *J) 1704static void rec_func_ff(jit_State *J)
1698{ 1705{
1699 RecordFFData rd; 1706 RecordFFData rd;
@@ -1719,7 +1726,7 @@ static void check_call_unroll(jit_State *J)
1719 if ((J->slot[s] & TREF_FRAME) && tref_ref(J->slot[s]) == fref) 1726 if ((J->slot[s] & TREF_FRAME) && tref_ref(J->slot[s]) == fref)
1720 count++; 1727 count++;
1721 if (J->pc == J->startpc) { 1728 if (J->pc == J->startpc) {
1722 if (count + J->tailcalled > J->param[JIT_P_recunroll]) 1729 if (count + (int32_t)(J->tailcalled & 0xff) > J->param[JIT_P_recunroll])
1723 lj_trace_err(J, LJ_TRERR_NYIRECU); 1730 lj_trace_err(J, LJ_TRERR_NYIRECU);
1724 } else { 1731 } else {
1725 if (count > J->param[JIT_P_callunroll]) 1732 if (count > J->param[JIT_P_callunroll])
@@ -2057,9 +2064,6 @@ void lj_record_ins(jit_State *J)
2057 /* fallthrough */ 2064 /* fallthrough */
2058 case BC_CALLT: 2065 case BC_CALLT:
2059 rec_tailcall(J, ra, (ptrdiff_t)rc-1); 2066 rec_tailcall(J, ra, (ptrdiff_t)rc-1);
2060 /* Tailcalls can form a loop, so count towards the loop unroll limit. */
2061 if (++J->tailcalled > J->loopunroll)
2062 lj_trace_err(J, LJ_TRERR_LUNROLL);
2063 break; 2067 break;
2064 2068
2065 /* -- Returns ----------------------------------------------------------- */ 2069 /* -- Returns ----------------------------------------------------------- */
@@ -2070,7 +2074,6 @@ void lj_record_ins(jit_State *J)
2070 /* fallthrough */ 2074 /* fallthrough */
2071 case BC_RET: case BC_RET0: case BC_RET1: 2075 case BC_RET: case BC_RET0: case BC_RET1:
2072 rec_ret(J, ra, (ptrdiff_t)rc-1); 2076 rec_ret(J, ra, (ptrdiff_t)rc-1);
2073 J->tailcalled = 0; /* NYI: logic is broken, need a better check. */
2074 break; 2077 break;
2075 2078
2076 /* -- Loops and branches ------------------------------------------------ */ 2079 /* -- Loops and branches ------------------------------------------------ */