diff options
| author | Mike Pall <mike> | 2011-06-28 23:23:34 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2011-06-28 23:23:34 +0200 |
| commit | deeb8196c4d4085f3cc5a3389b568de7da739190 (patch) | |
| tree | 6b5e9840f785f3fff3348ef1c9aee494cdf06431 | |
| parent | 3dbae4ffc2ba8f6ebf8adf86742521bce6dbf8f8 (diff) | |
| download | luajit-deeb8196c4d4085f3cc5a3389b568de7da739190.tar.gz luajit-deeb8196c4d4085f3cc5a3389b568de7da739190.tar.bz2 luajit-deeb8196c4d4085f3cc5a3389b568de7da739190.zip | |
Reorganize trace linking and track link types.
| -rw-r--r-- | lib/dump.lua | 14 | ||||
| -rw-r--r-- | lib/v.lua | 17 | ||||
| -rw-r--r-- | src/lib_jit.c | 10 | ||||
| -rw-r--r-- | src/lj_asm.c | 2 | ||||
| -rw-r--r-- | src/lj_asm_arm.h | 3 | ||||
| -rw-r--r-- | src/lj_asm_x86.h | 3 | ||||
| -rw-r--r-- | src/lj_jit.h | 14 | ||||
| -rw-r--r-- | src/lj_record.c | 29 | ||||
| -rw-r--r-- | src/lj_trace.c | 2 |
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 |
| @@ -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 */ | ||
| 280 | static 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) */ |
| 280 | LJLIB_CF(jit_util_traceinfo) | 286 | LJLIB_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; | |||
| 174 | typedef uint32_t TraceNo; /* Used to pass around trace numbers. */ | 174 | typedef uint32_t TraceNo; /* Used to pass around trace numbers. */ |
| 175 | typedef uint16_t TraceNo1; /* Stored trace number. */ | 175 | typedef uint16_t TraceNo1; /* Stored trace number. */ |
| 176 | 176 | ||
| 177 | #define TRACE_INTERP 0 /* Fallback to interpreter. */ | 177 | /* Type of link. ORDER LJ_TRLINK */ |
| 178 | typedef 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. */ |
| 180 | typedef struct GCtrace { | 190 | typedef 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. */ |
| 215 | static void rec_stop(jit_State *J, TraceNo lnk) | 215 | static 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; |
