aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2011-06-29 01:53:39 +0200
committerMike Pall <mike>2011-06-29 01:53:39 +0200
commit64dbe7d929cb5c368176ccb967b8909a4af8ede3 (patch)
treee0dcc6fef7ccca7d9b77e4f6c2364779956f499b /src
parent82eca898db87bde10fbbb14a0f35ef75b6c3dcc6 (diff)
downloadluajit-64dbe7d929cb5c368176ccb967b8909a4af8ede3.tar.gz
luajit-64dbe7d929cb5c368176ccb967b8909a4af8ede3.tar.bz2
luajit-64dbe7d929cb5c368176ccb967b8909a4af8ede3.zip
Return to lower frame via interpreter for unhandled cases.
E.g. spontaneous upcalls from C are now compiled.
Diffstat (limited to 'src')
-rw-r--r--src/lj_record.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/src/lj_record.c b/src/lj_record.c
index 49d743a2..e4c59bf4 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -661,6 +661,17 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults)
661 J->base[--rbase] = TREF_TRUE; /* Prepend true to results. */ 661 J->base[--rbase] = TREF_TRUE; /* Prepend true to results. */
662 frame = frame_prevd(frame); 662 frame = frame_prevd(frame);
663 } 663 }
664 /* Return to lower frame via interpreter for unhandled cases. */
665 if (J->framedepth == 0 && J->pt && bc_isret(bc_op(*J->pc)) &&
666 (!frame_islua(frame) ||
667 (J->parent == 0 && !bc_isret(bc_op(J->cur.startins))))) {
668 /* NYI: specialize to frame type and return directly, not via RET*. */
669 for (i = -1; i < (ptrdiff_t)rbase; i++)
670 J->base[i] = 0; /* Purge dead slots. */
671 J->maxslot = rbase + (BCReg)gotresults;
672 rec_stop(J, LJ_TRLINK_RETURN, 0); /* Return to interpreter. */
673 return;
674 }
664 if (frame_isvarg(frame)) { 675 if (frame_isvarg(frame)) {
665 BCReg cbase = (BCReg)frame_delta(frame); 676 BCReg cbase = (BCReg)frame_delta(frame);
666 if (--J->framedepth < 0) /* NYI: return of vararg func to lower frame. */ 677 if (--J->framedepth < 0) /* NYI: return of vararg func to lower frame. */
@@ -1283,7 +1294,7 @@ static TRef rec_upvalue(jit_State *J, uint32_t uv, TRef val)
1283/* -- Record calls to Lua functions --------------------------------------- */ 1294/* -- Record calls to Lua functions --------------------------------------- */
1284 1295
1285/* Check unroll limits for calls. */ 1296/* Check unroll limits for calls. */
1286static void check_call_unroll(jit_State *J) 1297static void check_call_unroll(jit_State *J, TraceNo lnk)
1287{ 1298{
1288 IRRef fref = tref_ref(J->base[-1]); 1299 IRRef fref = tref_ref(J->base[-1]);
1289 int32_t count = 0; 1300 int32_t count = 0;
@@ -1300,8 +1311,14 @@ static void check_call_unroll(jit_State *J)
1300 rec_stop(J, LJ_TRLINK_UPREC, J->cur.traceno); /* Up-recursion. */ 1311 rec_stop(J, LJ_TRLINK_UPREC, J->cur.traceno); /* Up-recursion. */
1301 } 1312 }
1302 } else { 1313 } else {
1303 if (count > J->param[JIT_P_callunroll]) 1314 if (count > J->param[JIT_P_callunroll]) {
1315 if (lnk) { /* Possible tail- or up-recursion. */
1316 lj_trace_flush(J, lnk); /* Flush trace that only returns. */
1317 /* Set a small, pseudo-random hotcount for a quick retry of JFUNC*. */
1318 hotcount_set(J2GG(J), J->pc+1, LJ_PRNG_BITS(J, 4));
1319 }
1304 lj_trace_err(J, LJ_TRERR_CUNROLL); 1320 lj_trace_err(J, LJ_TRERR_CUNROLL);
1321 }
1305 } 1322 }
1306} 1323}
1307 1324
@@ -1346,13 +1363,23 @@ static void rec_func_vararg(jit_State *J)
1346static void rec_func_lua(jit_State *J) 1363static void rec_func_lua(jit_State *J)
1347{ 1364{
1348 rec_func_setup(J); 1365 rec_func_setup(J);
1349 check_call_unroll(J); 1366 check_call_unroll(J, 0);
1350} 1367}
1351 1368
1352/* Record entry to an already compiled function. */ 1369/* Record entry to an already compiled function. */
1353static void rec_func_jit(jit_State *J, TraceNo lnk) 1370static void rec_func_jit(jit_State *J, TraceNo lnk)
1354{ 1371{
1372 GCtrace *T;
1355 rec_func_setup(J); 1373 rec_func_setup(J);
1374 T = traceref(J, lnk);
1375 if (T->linktype == LJ_TRLINK_RETURN) { /* Trace returns to interpreter? */
1376 check_call_unroll(J, lnk);
1377 /* Temporarily unpatch JFUNC* to continue recording across function. */
1378 J->patchins = *J->pc;
1379 J->patchpc = (BCIns *)J->pc;
1380 *J->patchpc = T->startins;
1381 return;
1382 }
1356 J->instunroll = 0; /* Cannot continue across a compiled function. */ 1383 J->instunroll = 0; /* Cannot continue across a compiled function. */
1357 if (J->pc == J->startpc && J->framedepth + J->retdepth == 0) 1384 if (J->pc == J->startpc && J->framedepth + J->retdepth == 0)
1358 rec_stop(J, LJ_TRLINK_TAILREC, J->cur.traceno); /* Extra tail-recursion. */ 1385 rec_stop(J, LJ_TRLINK_TAILREC, J->cur.traceno); /* Extra tail-recursion. */