diff options
author | Mike Pall <mike> | 2010-02-18 19:32:13 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2010-02-18 19:32:13 +0100 |
commit | b11eeab906b4c5f26f257d8c75987769abd68507 (patch) | |
tree | c042c276844809be6c75b716fafa443c9af00e79 /src/lj_record.c | |
parent | 65586ca4dcbcffe08f96aee69ac22374c32c6e8a (diff) | |
download | luajit-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.c | 29 |
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. */ |
477 | static void rec_call(jit_State *J, BCReg func, ptrdiff_t nargs) | 477 | static 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. */ | ||
503 | static 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. */ |
508 | static void rec_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs) | 514 | static 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. */ |
1697 | static void rec_func_ff(jit_State *J) | 1704 | static 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 ------------------------------------------------ */ |