aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2011-06-28 23:23:34 +0200
committerMike Pall <mike>2011-06-28 23:23:34 +0200
commitdeeb8196c4d4085f3cc5a3389b568de7da739190 (patch)
tree6b5e9840f785f3fff3348ef1c9aee494cdf06431
parent3dbae4ffc2ba8f6ebf8adf86742521bce6dbf8f8 (diff)
downloadluajit-deeb8196c4d4085f3cc5a3389b568de7da739190.tar.gz
luajit-deeb8196c4d4085f3cc5a3389b568de7da739190.tar.bz2
luajit-deeb8196c4d4085f3cc5a3389b568de7da739190.zip
Reorganize trace linking and track link types.
-rw-r--r--lib/dump.lua14
-rw-r--r--lib/v.lua17
-rw-r--r--src/lib_jit.c10
-rw-r--r--src/lj_asm.c2
-rw-r--r--src/lj_asm_arm.h3
-rw-r--r--src/lj_asm_x86.h3
-rw-r--r--src/lj_jit.h14
-rw-r--r--src/lj_record.c29
-rw-r--r--src/lj_trace.c2
9 files changed, 63 insertions, 31 deletions
diff --git a/lib/dump.lua b/lib/dump.lua
index 5f32eb80..6ada21bc 100644
--- a/lib/dump.lua
+++ b/lib/dump.lua
@@ -504,13 +504,15 @@ local function dump_trace(what, tr, func, pc, otr, oex)
504 if what == "abort" then 504 if what == "abort" then
505 out:write(" ", fmtfunc(func, pc), " -- ", fmterr(otr, oex), "\n") 505 out:write(" ", fmtfunc(func, pc), " -- ", fmterr(otr, oex), "\n")
506 else 506 else
507 local link = traceinfo(tr).link 507 local info = traceinfo(tr)
508 if link == tr then 508 local link, ltype = info.link, info.linktype
509 link = "loop" 509 if link == tr or link == 0 then
510 elseif link == 0 then 510 out:write(" -> ", ltype, "\n")
511 link = "interpreter" 511 elseif ltype == "root" then
512 out:write(" -> ", link, "\n")
513 else
514 out:write(" -> ", link, " ", ltype, "\n")
512 end 515 end
513 out:write(" -> ", link, "\n")
514 end 516 end
515 if dumpmode.H then out:write("</pre>\n\n") else out:write("\n") end 517 if dumpmode.H then out:write("</pre>\n\n") else out:write("\n") end
516 else 518 else
diff --git a/lib/v.lua b/lib/v.lua
index bf61f125..d2a0c235 100644
--- a/lib/v.lua
+++ b/lib/v.lua
@@ -22,7 +22,7 @@
22-- 22--
23-- The output from the first example should look like this: 23-- The output from the first example should look like this:
24-- 24--
25-- [TRACE 1 (command line):1] 25-- [TRACE 1 (command line):1 loop]
26-- [TRACE 2 (1/3) (command line):1 -> 1] 26-- [TRACE 2 (1/3) (command line):1 -> 1]
27-- 27--
28-- The first number in each line is the internal trace number. Next are 28-- The first number in each line is the internal trace number. Next are
@@ -111,15 +111,20 @@ local function dump_trace(what, tr, func, pc, otr, oex)
111 startex, startloc, fmterr(otr, oex))) 111 startex, startloc, fmterr(otr, oex)))
112 end 112 end
113 elseif what == "stop" then 113 elseif what == "stop" then
114 local link = traceinfo(tr).link 114 local info = traceinfo(tr)
115 if link == 0 then 115 local link, ltype = info.link, info.linktype
116 if ltype == "interpreter" then
116 out:write(format("[TRACE %3s %s%s -- fallback to interpreter]\n", 117 out:write(format("[TRACE %3s %s%s -- fallback to interpreter]\n",
117 tr, startex, startloc)) 118 tr, startex, startloc))
118 elseif link == tr then 119 elseif link == tr or link == 0 then
119 out:write(format("[TRACE %3s %s%s]\n", tr, startex, startloc)) 120 out:write(format("[TRACE %3s %s%s %s]\n",
120 else 121 tr, startex, startloc, ltype))
122 elseif ltype == "root" then
121 out:write(format("[TRACE %3s %s%s -> %d]\n", 123 out:write(format("[TRACE %3s %s%s -> %d]\n",
122 tr, startex, startloc, link)) 124 tr, startex, startloc, link))
125 else
126 out:write(format("[TRACE %3s %s%s -> %d %s]\n",
127 tr, startex, startloc, link, ltype))
123 end 128 end
124 else 129 else
125 out:write(format("[TRACE %s]\n", what)) 130 out:write(format("[TRACE %s]\n", what))
diff --git a/src/lib_jit.c b/src/lib_jit.c
index 66b3856a..d1f24f52 100644
--- a/src/lib_jit.c
+++ b/src/lib_jit.c
@@ -276,18 +276,26 @@ static GCtrace *jit_checktrace(lua_State *L)
276 return NULL; 276 return NULL;
277} 277}
278 278
279/* Names of link types. ORDER LJ_TRLINK */
280static const char *const jit_trlinkname[] = {
281 "none", "root", "loop", "tail-recursion", "up-recursion", "down-recursion",
282 "interpreter", "return"
283};
284
279/* local info = jit.util.traceinfo(tr) */ 285/* local info = jit.util.traceinfo(tr) */
280LJLIB_CF(jit_util_traceinfo) 286LJLIB_CF(jit_util_traceinfo)
281{ 287{
282 GCtrace *T = jit_checktrace(L); 288 GCtrace *T = jit_checktrace(L);
283 if (T) { 289 if (T) {
284 GCtab *t; 290 GCtab *t;
285 lua_createtable(L, 0, 4); /* Increment hash size if fields are added. */ 291 lua_createtable(L, 0, 8); /* Increment hash size if fields are added. */
286 t = tabV(L->top-1); 292 t = tabV(L->top-1);
287 setintfield(L, t, "nins", (int32_t)T->nins - REF_BIAS - 1); 293 setintfield(L, t, "nins", (int32_t)T->nins - REF_BIAS - 1);
288 setintfield(L, t, "nk", REF_BIAS - (int32_t)T->nk); 294 setintfield(L, t, "nk", REF_BIAS - (int32_t)T->nk);
289 setintfield(L, t, "link", T->link); 295 setintfield(L, t, "link", T->link);
290 setintfield(L, t, "nexit", T->nsnap); 296 setintfield(L, t, "nexit", T->nsnap);
297 setstrV(L, L->top++, lj_str_newz(L, jit_trlinkname[T->linktype]));
298 lua_setfield(L, -2, "linktype");
291 /* There are many more fields. Add them only when needed. */ 299 /* There are many more fields. Add them only when needed. */
292 return 1; 300 return 1;
293 } 301 }
diff --git a/src/lj_asm.c b/src/lj_asm.c
index adb5a9ce..932ff8ea 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -1305,7 +1305,7 @@ static void asm_tail_link(ASMState *as)
1305 checkmclim(as); 1305 checkmclim(as);
1306 ra_allocref(as, REF_BASE, RID2RSET(RID_BASE)); 1306 ra_allocref(as, REF_BASE, RID2RSET(RID_BASE));
1307 1307
1308 if (as->T->link == TRACE_INTERP) { 1308 if (as->T->link == 0) {
1309 /* Setup fixed registers for exit to interpreter. */ 1309 /* Setup fixed registers for exit to interpreter. */
1310 const BCIns *pc = snap_pc(as->T->snapmap[snap->mapofs + snap->nent]); 1310 const BCIns *pc = snap_pc(as->T->snapmap[snap->mapofs + snap->nent]);
1311 int32_t mres; 1311 int32_t mres;
diff --git a/src/lj_asm_arm.h b/src/lj_asm_arm.h
index 31b300bf..99f3055f 100644
--- a/src/lj_asm_arm.h
+++ b/src/lj_asm_arm.h
@@ -1681,8 +1681,7 @@ static void asm_tail_fixup(ASMState *as, TraceNo lnk)
1681 p[-2] = (ARMI_ADD^k) | ARMF_D(RID_SP) | ARMF_N(RID_SP); 1681 p[-2] = (ARMI_ADD^k) | ARMF_D(RID_SP) | ARMF_N(RID_SP);
1682 } 1682 }
1683 /* Patch exit branch. */ 1683 /* Patch exit branch. */
1684 target = lnk == TRACE_INTERP ? (MCode *)lj_vm_exit_interp : 1684 target = lnk ? traceref(as->J, lnk)->mcode : (MCode *)lj_vm_exit_interp;
1685 traceref(as->J, lnk)->mcode;
1686 p[-1] = ARMI_B|(((target-p)-1)&0x00ffffffu); 1685 p[-1] = ARMI_B|(((target-p)-1)&0x00ffffffu);
1687} 1686}
1688 1687
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h
index 141957c7..0803ecef 100644
--- a/src/lj_asm_x86.h
+++ b/src/lj_asm_x86.h
@@ -2418,8 +2418,7 @@ static void asm_tail_fixup(ASMState *as, TraceNo lnk)
2418 } 2418 }
2419 } 2419 }
2420 /* Patch exit branch. */ 2420 /* Patch exit branch. */
2421 target = lnk == TRACE_INTERP ? (MCode *)lj_vm_exit_interp : 2421 target = lnk ? traceref(as->J, lnk)->mcode : (MCode *)lj_vm_exit_interp;
2422 traceref(as->J, lnk)->mcode;
2423 *(int32_t *)(p-4) = jmprel(p, target); 2422 *(int32_t *)(p-4) = jmprel(p, target);
2424 p[-5] = XI_JMP; 2423 p[-5] = XI_JMP;
2425 /* Drop unused mcode tail. Fill with NOPs to make the prefetcher happy. */ 2424 /* Drop unused mcode tail. Fill with NOPs to make the prefetcher happy. */
diff --git a/src/lj_jit.h b/src/lj_jit.h
index ea2dd4ad..7e26aadc 100644
--- a/src/lj_jit.h
+++ b/src/lj_jit.h
@@ -174,13 +174,23 @@ typedef uint32_t ExitNo;
174typedef uint32_t TraceNo; /* Used to pass around trace numbers. */ 174typedef uint32_t TraceNo; /* Used to pass around trace numbers. */
175typedef uint16_t TraceNo1; /* Stored trace number. */ 175typedef uint16_t TraceNo1; /* Stored trace number. */
176 176
177#define TRACE_INTERP 0 /* Fallback to interpreter. */ 177/* Type of link. ORDER LJ_TRLINK */
178typedef enum {
179 LJ_TRLINK_NONE, /* Incomplete trace. No link, yet. */
180 LJ_TRLINK_ROOT, /* Link to other root trace. */
181 LJ_TRLINK_LOOP, /* Loop to same trace. */
182 LJ_TRLINK_TAILREC, /* Tail-recursion. */
183 LJ_TRLINK_UPREC, /* Up-recursion. */
184 LJ_TRLINK_DOWNREC, /* Down-recursion. */
185 LJ_TRLINK_INTERP, /* Fallback to interpreter. */
186 LJ_TRLINK_RETURN /* Return to interpreter. */
187} TraceLink;
178 188
179/* Trace object. */ 189/* Trace object. */
180typedef struct GCtrace { 190typedef struct GCtrace {
181 GCHeader; 191 GCHeader;
182 uint8_t topslot; /* Top stack slot already checked to be allocated. */ 192 uint8_t topslot; /* Top stack slot already checked to be allocated. */
183 uint8_t unused1; 193 uint8_t linktype; /* Type of link. */
184 IRRef nins; /* Next IR instruction. Biased with REF_BIAS. */ 194 IRRef nins; /* Next IR instruction. Biased with REF_BIAS. */
185 GCRef gclist; 195 GCRef gclist;
186 IRIns *ir; /* IR instructions/constants. Biased with REF_BIAS. */ 196 IRIns *ir; /* IR instructions/constants. Biased with REF_BIAS. */
diff --git a/src/lj_record.c b/src/lj_record.c
index 63d5e4c1..49d743a2 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -212,9 +212,10 @@ static void canonicalize_slots(jit_State *J)
212} 212}
213 213
214/* Stop recording. */ 214/* Stop recording. */
215static void rec_stop(jit_State *J, TraceNo lnk) 215static void rec_stop(jit_State *J, TraceLink linktype, TraceNo lnk)
216{ 216{
217 lj_trace_end(J); 217 lj_trace_end(J);
218 J->cur.linktype = (uint8_t)linktype;
218 J->cur.link = (uint16_t)lnk; 219 J->cur.link = (uint16_t)lnk;
219 /* Looping back at the same stack level? */ 220 /* Looping back at the same stack level? */
220 if (lnk == J->cur.traceno && J->framedepth + J->retdepth == 0) { 221 if (lnk == J->cur.traceno && J->framedepth + J->retdepth == 0) {
@@ -522,7 +523,7 @@ static void rec_loop_interp(jit_State *J, const BCIns *pc, LoopEvent ev)
522 /* Same loop? */ 523 /* Same loop? */
523 if (ev == LOOPEV_LEAVE) /* Must loop back to form a root trace. */ 524 if (ev == LOOPEV_LEAVE) /* Must loop back to form a root trace. */
524 lj_trace_err(J, LJ_TRERR_LLEAVE); 525 lj_trace_err(J, LJ_TRERR_LLEAVE);
525 rec_stop(J, J->cur.traceno); /* Root trace forms a loop. */ 526 rec_stop(J, LJ_TRLINK_LOOP, J->cur.traceno); /* Looping root trace. */
526 } else if (ev != LOOPEV_LEAVE) { /* Entering inner loop? */ 527 } else if (ev != LOOPEV_LEAVE) { /* Entering inner loop? */
527 /* It's usually better to abort here and wait until the inner loop 528 /* It's usually better to abort here and wait until the inner loop
528 ** is traced. But if the inner loop repeatedly didn't loop back, 529 ** is traced. But if the inner loop repeatedly didn't loop back,
@@ -553,8 +554,9 @@ static void rec_loop_jit(jit_State *J, TraceNo lnk, LoopEvent ev)
553 } else if (ev != LOOPEV_LEAVE) { /* Side trace enters a compiled loop. */ 554 } else if (ev != LOOPEV_LEAVE) { /* Side trace enters a compiled loop. */
554 J->instunroll = 0; /* Cannot continue across a compiled loop op. */ 555 J->instunroll = 0; /* Cannot continue across a compiled loop op. */
555 if (J->pc == J->startpc && J->framedepth + J->retdepth == 0) 556 if (J->pc == J->startpc && J->framedepth + J->retdepth == 0)
556 lnk = J->cur.traceno; /* Can form an extra loop. */ 557 rec_stop(J, LJ_TRLINK_LOOP, J->cur.traceno); /* Form an extra loop. */
557 rec_stop(J, lnk); /* Link to the loop. */ 558 else
559 rec_stop(J, LJ_TRLINK_ROOT, lnk); /* Link to the loop. */
558 } /* Side trace continues across a loop that's left or not entered. */ 560 } /* Side trace continues across a loop that's left or not entered. */
559} 561}
560 562
@@ -678,7 +680,7 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults)
678 if (check_downrec_unroll(J, pt)) { 680 if (check_downrec_unroll(J, pt)) {
679 J->maxslot = (BCReg)(rbase + gotresults); 681 J->maxslot = (BCReg)(rbase + gotresults);
680 lj_snap_purge(J); 682 lj_snap_purge(J);
681 rec_stop(J, J->cur.traceno); /* Down-recursion. */ 683 rec_stop(J, LJ_TRLINK_DOWNREC, J->cur.traceno); /* Down-recursion. */
682 return; 684 return;
683 } 685 }
684 lj_snap_add(J); 686 lj_snap_add(J);
@@ -1292,7 +1294,10 @@ static void check_call_unroll(jit_State *J)
1292 if (J->pc == J->startpc) { 1294 if (J->pc == J->startpc) {
1293 if (count + J->tailcalled > J->param[JIT_P_recunroll]) { 1295 if (count + J->tailcalled > J->param[JIT_P_recunroll]) {
1294 J->pc++; 1296 J->pc++;
1295 rec_stop(J, J->cur.traceno); /* Up-recursion or tail-recursion. */ 1297 if (J->framedepth + J->retdepth == 0)
1298 rec_stop(J, LJ_TRLINK_TAILREC, J->cur.traceno); /* Tail-recursion. */
1299 else
1300 rec_stop(J, LJ_TRLINK_UPREC, J->cur.traceno); /* Up-recursion. */
1296 } 1301 }
1297 } else { 1302 } else {
1298 if (count > J->param[JIT_P_callunroll]) 1303 if (count > J->param[JIT_P_callunroll])
@@ -1350,8 +1355,9 @@ static void rec_func_jit(jit_State *J, TraceNo lnk)
1350 rec_func_setup(J); 1355 rec_func_setup(J);
1351 J->instunroll = 0; /* Cannot continue across a compiled function. */ 1356 J->instunroll = 0; /* Cannot continue across a compiled function. */
1352 if (J->pc == J->startpc && J->framedepth + J->retdepth == 0) 1357 if (J->pc == J->startpc && J->framedepth + J->retdepth == 0)
1353 lnk = J->cur.traceno; /* Can form an extra tail-recursive loop. */ 1358 rec_stop(J, LJ_TRLINK_TAILREC, J->cur.traceno); /* Extra tail-recursion. */
1354 rec_stop(J, lnk); /* Link to the function. */ 1359 else
1360 rec_stop(J, LJ_TRLINK_ROOT, lnk); /* Link to the function. */
1355} 1361}
1356 1362
1357/* -- Vararg handling ----------------------------------------------------- */ 1363/* -- Vararg handling ----------------------------------------------------- */
@@ -1863,7 +1869,7 @@ void lj_record_ins(jit_State *J)
1863 case BC_JFORI: 1869 case BC_JFORI:
1864 lua_assert(bc_op(pc[(ptrdiff_t)rc-BCBIAS_J]) == BC_JFORL); 1870 lua_assert(bc_op(pc[(ptrdiff_t)rc-BCBIAS_J]) == BC_JFORL);
1865 if (rec_for(J, pc, 0) != LOOPEV_LEAVE) /* Link to existing loop. */ 1871 if (rec_for(J, pc, 0) != LOOPEV_LEAVE) /* Link to existing loop. */
1866 rec_stop(J, bc_d(pc[(ptrdiff_t)rc-BCBIAS_J])); 1872 rec_stop(J, LJ_TRLINK_ROOT, bc_d(pc[(ptrdiff_t)rc-BCBIAS_J]));
1867 /* Continue tracing if the loop is not entered. */ 1873 /* Continue tracing if the loop is not entered. */
1868 break; 1874 break;
1869 1875
@@ -2121,8 +2127,9 @@ void lj_record_setup(jit_State *J)
2121 sidecheck: 2127 sidecheck:
2122 if (traceref(J, J->cur.root)->nchild >= J->param[JIT_P_maxside] || 2128 if (traceref(J, J->cur.root)->nchild >= J->param[JIT_P_maxside] ||
2123 T->snap[J->exitno].count >= J->param[JIT_P_hotexit] + 2129 T->snap[J->exitno].count >= J->param[JIT_P_hotexit] +
2124 J->param[JIT_P_tryside]) 2130 J->param[JIT_P_tryside]) {
2125 rec_stop(J, TRACE_INTERP); 2131 rec_stop(J, LJ_TRLINK_INTERP, 0);
2132 }
2126 } else { /* Root trace. */ 2133 } else { /* Root trace. */
2127 J->cur.root = 0; 2134 J->cur.root = 0;
2128 J->cur.startins = *J->pc; 2135 J->cur.startins = *J->pc;
diff --git a/src/lj_trace.c b/src/lj_trace.c
index 0542ea1f..c65ca9cd 100644
--- a/src/lj_trace.c
+++ b/src/lj_trace.c
@@ -509,6 +509,7 @@ static int trace_abort(jit_State *J)
509 if (traceno) { 509 if (traceno) {
510 ptrdiff_t errobj = savestack(L, L->top-1); /* Stack may be resized. */ 510 ptrdiff_t errobj = savestack(L, L->top-1); /* Stack may be resized. */
511 J->cur.link = 0; 511 J->cur.link = 0;
512 J->cur.linktype = LJ_TRLINK_NONE;
512 lj_vmevent_send(L, TRACE, 513 lj_vmevent_send(L, TRACE,
513 TValue *frame; 514 TValue *frame;
514 const BCIns *pc; 515 const BCIns *pc;
@@ -590,6 +591,7 @@ static TValue *trace_state(lua_State *L, lua_CFunction dummy, void *ud)
590 lj_opt_dce(J); 591 lj_opt_dce(J);
591 if (lj_opt_loop(J)) { /* Loop optimization failed? */ 592 if (lj_opt_loop(J)) { /* Loop optimization failed? */
592 J->cur.link = 0; 593 J->cur.link = 0;
594 J->cur.linktype = LJ_TRLINK_NONE;
593 J->loopref = J->cur.nins; 595 J->loopref = J->cur.nins;
594 J->state = LJ_TRACE_RECORD; /* Try to continue recording. */ 596 J->state = LJ_TRACE_RECORD; /* Try to continue recording. */
595 break; 597 break;