diff options
| author | Mike Pall <mike> | 2015-08-29 23:22:29 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2015-08-29 23:24:26 +0200 |
| commit | a3a6866d4c2cc096b478c8f81b73a3b818034b89 (patch) | |
| tree | 763f1e2db63fdbc46671e2f44e33ce71a4db2746 /src | |
| parent | ad29314c2c5b205d591e3a6af0a18dc0f69a7f48 (diff) | |
| download | luajit-a3a6866d4c2cc096b478c8f81b73a3b818034b89.tar.gz luajit-a3a6866d4c2cc096b478c8f81b73a3b818034b89.tar.bz2 luajit-a3a6866d4c2cc096b478c8f81b73a3b818034b89.zip | |
Re-enable trace stitching.
Thanks to Vyacheslav Egorov.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_ffrecord.c | 39 | ||||
| -rw-r--r-- | src/lj_gc.c | 2 | ||||
| -rw-r--r-- | src/lj_ir.c | 44 | ||||
| -rw-r--r-- | src/lj_iropt.h | 1 | ||||
| -rw-r--r-- | src/lj_jit.h | 1 | ||||
| -rw-r--r-- | src/lj_snap.c | 4 | ||||
| -rw-r--r-- | src/lj_trace.c | 7 | ||||
| -rw-r--r-- | src/lj_traceerr.h | 2 | ||||
| -rw-r--r-- | src/vm_arm.dasc | 13 | ||||
| -rw-r--r-- | src/vm_mips.dasc | 10 | ||||
| -rw-r--r-- | src/vm_ppc.dasc | 8 | ||||
| -rw-r--r-- | src/vm_x86.dasc | 11 |
12 files changed, 59 insertions, 83 deletions
diff --git a/src/lj_ffrecord.c b/src/lj_ffrecord.c index a08113ca..6cc05a24 100644 --- a/src/lj_ffrecord.c +++ b/src/lj_ffrecord.c | |||
| @@ -96,18 +96,10 @@ static ptrdiff_t results_wanted(jit_State *J) | |||
| 96 | return -1; | 96 | return -1; |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | #ifdef LUAJIT_TRACE_STITCHING | ||
| 100 | /* This feature is disabled for now due to a design mistake. Sorry. | ||
| 101 | ** | ||
| 102 | ** It causes unpredictable behavior and crashes when a full trace flush | ||
| 103 | ** happens with a stitching continuation still in the stack somewhere. | ||
| 104 | */ | ||
| 105 | |||
| 106 | /* Trace stitching: add continuation below frame to start a new trace. */ | 99 | /* Trace stitching: add continuation below frame to start a new trace. */ |
| 107 | static void recff_stitch(jit_State *J) | 100 | static void recff_stitch(jit_State *J) |
| 108 | { | 101 | { |
| 109 | ASMFunction cont = lj_cont_stitch; | 102 | ASMFunction cont = lj_cont_stitch; |
| 110 | TraceNo traceno = J->cur.traceno; | ||
| 111 | lua_State *L = J->L; | 103 | lua_State *L = J->L; |
| 112 | TValue *base = L->base; | 104 | TValue *base = L->base; |
| 113 | const BCIns *pc = frame_pc(base-1); | 105 | const BCIns *pc = frame_pc(base-1); |
| @@ -120,7 +112,7 @@ static void recff_stitch(jit_State *J) | |||
| 120 | setframe_ftsz(base+1, ((char *)(base+1) - (char *)pframe) + FRAME_CONT); | 112 | setframe_ftsz(base+1, ((char *)(base+1) - (char *)pframe) + FRAME_CONT); |
| 121 | setcont(base, cont); | 113 | setcont(base, cont); |
| 122 | setframe_pc(base, pc); | 114 | setframe_pc(base, pc); |
| 123 | if (LJ_DUALNUM) setintV(base-1, traceno); else base[-1].u64 = traceno; | 115 | setnilV(base-1); /* Incorrect, but rec_check_slots() won't run anymore. */ |
| 124 | L->base += 2; | 116 | L->base += 2; |
| 125 | L->top += 2; | 117 | L->top += 2; |
| 126 | 118 | ||
| @@ -132,7 +124,9 @@ static void recff_stitch(jit_State *J) | |||
| 132 | trcont = lj_ir_kptr(J, (void *)cont); | 124 | trcont = lj_ir_kptr(J, (void *)cont); |
| 133 | #endif | 125 | #endif |
| 134 | J->base[0] = trcont | TREF_CONT; | 126 | J->base[0] = trcont | TREF_CONT; |
| 135 | J->base[-1] = LJ_DUALNUM ? lj_ir_kint(J,traceno) : lj_ir_knum_u64(J,traceno); | 127 | J->ktracep = lj_ir_k64_reserve(J); |
| 128 | lua_assert(irt_toitype_(IRT_P64) == LJ_TTRACE); | ||
| 129 | J->base[-1] = emitir(IRT(IR_XLOAD, IRT_P64), lj_ir_kptr(J, &J->ktracep->gcr), 0); | ||
| 136 | J->base += 2; | 130 | J->base += 2; |
| 137 | J->baseslot += 2; | 131 | J->baseslot += 2; |
| 138 | J->framedepth++; | 132 | J->framedepth++; |
| @@ -181,31 +175,6 @@ static void LJ_FASTCALL recff_nyi(jit_State *J, RecordFFData *rd) | |||
| 181 | 175 | ||
| 182 | /* Must stop the trace for classic C functions with arbitrary side-effects. */ | 176 | /* Must stop the trace for classic C functions with arbitrary side-effects. */ |
| 183 | #define recff_c recff_nyi | 177 | #define recff_c recff_nyi |
| 184 | #else | ||
| 185 | /* Fallback handler for fast functions that are not recorded (yet). */ | ||
| 186 | static void LJ_FASTCALL recff_nyi(jit_State *J, RecordFFData *rd) | ||
| 187 | { | ||
| 188 | setfuncV(J->L, &J->errinfo, J->fn); | ||
| 189 | lj_trace_err_info(J, LJ_TRERR_NYIFF); | ||
| 190 | UNUSED(rd); | ||
| 191 | } | ||
| 192 | |||
| 193 | /* Throw error for unsupported variant of fast function. */ | ||
| 194 | LJ_NORET static void recff_nyiu(jit_State *J, RecordFFData *rd) | ||
| 195 | { | ||
| 196 | setfuncV(J->L, &J->errinfo, J->fn); | ||
| 197 | lj_trace_err_info(J, LJ_TRERR_NYIFFU); | ||
| 198 | UNUSED(rd); | ||
| 199 | } | ||
| 200 | |||
| 201 | /* Must abort the trace for classic C functions with arbitrary side-effects. */ | ||
| 202 | static void LJ_FASTCALL recff_c(jit_State *J, RecordFFData *rd) | ||
| 203 | { | ||
| 204 | setfuncV(J->L, &J->errinfo, J->fn); | ||
| 205 | lj_trace_err_info(J, LJ_TRERR_NYICF); | ||
| 206 | UNUSED(rd); | ||
| 207 | } | ||
| 208 | #endif | ||
| 209 | 178 | ||
| 210 | /* Emit BUFHDR for the global temporary buffer. */ | 179 | /* Emit BUFHDR for the global temporary buffer. */ |
| 211 | static TRef recff_bufhdr(jit_State *J) | 180 | static TRef recff_bufhdr(jit_State *J) |
diff --git a/src/lj_gc.c b/src/lj_gc.c index 99d664aa..afd39972 100644 --- a/src/lj_gc.c +++ b/src/lj_gc.c | |||
| @@ -69,7 +69,7 @@ static void gc_mark(global_State *g, GCobj *o) | |||
| 69 | gray2black(o); /* Closed upvalues are never gray. */ | 69 | gray2black(o); /* Closed upvalues are never gray. */ |
| 70 | } else if (gct != ~LJ_TSTR && gct != ~LJ_TCDATA) { | 70 | } else if (gct != ~LJ_TSTR && gct != ~LJ_TCDATA) { |
| 71 | lua_assert(gct == ~LJ_TFUNC || gct == ~LJ_TTAB || | 71 | lua_assert(gct == ~LJ_TFUNC || gct == ~LJ_TTAB || |
| 72 | gct == ~LJ_TTHREAD || gct == ~LJ_TPROTO); | 72 | gct == ~LJ_TTHREAD || gct == ~LJ_TPROTO || gct == ~LJ_TTRACE); |
| 73 | setgcrefr(o->gch.gclist, g->gc.gray); | 73 | setgcrefr(o->gch.gclist, g->gc.gray); |
| 74 | setgcref(g->gc.gray, o); | 74 | setgcref(g->gc.gray, o); |
| 75 | } | 75 | } |
diff --git a/src/lj_ir.c b/src/lj_ir.c index 9682e05e..567aec86 100644 --- a/src/lj_ir.c +++ b/src/lj_ir.c | |||
| @@ -209,24 +209,13 @@ void lj_ir_k64_freeall(jit_State *J) | |||
| 209 | lj_mem_free(J2G(J), k, sizeof(K64Array)); | 209 | lj_mem_free(J2G(J), k, sizeof(K64Array)); |
| 210 | k = next; | 210 | k = next; |
| 211 | } | 211 | } |
| 212 | setmref(J->k64, NULL); | ||
| 212 | } | 213 | } |
| 213 | 214 | ||
| 214 | /* Find 64 bit constant in chained array or add it. */ | 215 | /* Get new 64 bit constant slot. */ |
| 215 | cTValue *lj_ir_k64_find(jit_State *J, uint64_t u64) | 216 | static TValue *ir_k64_add(jit_State *J, K64Array *kp, uint64_t u64) |
| 216 | { | 217 | { |
| 217 | K64Array *k, *kp = NULL; | ||
| 218 | TValue *ntv; | 218 | TValue *ntv; |
| 219 | MSize idx; | ||
| 220 | /* Search for the constant in the whole chain of arrays. */ | ||
| 221 | for (k = mref(J->k64, K64Array); k; k = mref(k->next, K64Array)) { | ||
| 222 | kp = k; /* Remember previous element in list. */ | ||
| 223 | for (idx = 0; idx < k->numk; idx++) { /* Search one array. */ | ||
| 224 | TValue *tv = &k->k[idx]; | ||
| 225 | if (tv->u64 == u64) /* Needed for +-0/NaN/absmask. */ | ||
| 226 | return tv; | ||
| 227 | } | ||
| 228 | } | ||
| 229 | /* Constant was not found, need to add it. */ | ||
| 230 | if (!(kp && kp->numk < LJ_MIN_K64SZ)) { /* Allocate a new array. */ | 219 | if (!(kp && kp->numk < LJ_MIN_K64SZ)) { /* Allocate a new array. */ |
| 231 | K64Array *kn = lj_mem_newt(J->L, sizeof(K64Array), K64Array); | 220 | K64Array *kn = lj_mem_newt(J->L, sizeof(K64Array), K64Array); |
| 232 | setmref(kn->next, NULL); | 221 | setmref(kn->next, NULL); |
| @@ -242,6 +231,33 @@ cTValue *lj_ir_k64_find(jit_State *J, uint64_t u64) | |||
| 242 | return ntv; | 231 | return ntv; |
| 243 | } | 232 | } |
| 244 | 233 | ||
| 234 | /* Find 64 bit constant in chained array or add it. */ | ||
| 235 | cTValue *lj_ir_k64_find(jit_State *J, uint64_t u64) | ||
| 236 | { | ||
| 237 | K64Array *k, *kp = NULL; | ||
| 238 | MSize idx; | ||
| 239 | /* Search for the constant in the whole chain of arrays. */ | ||
| 240 | for (k = mref(J->k64, K64Array); k; k = mref(k->next, K64Array)) { | ||
| 241 | kp = k; /* Remember previous element in list. */ | ||
| 242 | for (idx = 0; idx < k->numk; idx++) { /* Search one array. */ | ||
| 243 | TValue *tv = &k->k[idx]; | ||
| 244 | if (tv->u64 == u64) /* Needed for +-0/NaN/absmask. */ | ||
| 245 | return tv; | ||
| 246 | } | ||
| 247 | } | ||
| 248 | /* Otherwise add a new constant. */ | ||
| 249 | return ir_k64_add(J, kp, u64); | ||
| 250 | } | ||
| 251 | |||
| 252 | TValue *lj_ir_k64_reserve(jit_State *J) | ||
| 253 | { | ||
| 254 | K64Array *k, *kp = NULL; | ||
| 255 | lj_ir_k64_find(J, 0); /* Intern dummy 0 to protect the reserved slot. */ | ||
| 256 | /* Find last K64Array, if any. */ | ||
| 257 | for (k = mref(J->k64, K64Array); k; k = mref(k->next, K64Array)) kp = k; | ||
| 258 | return ir_k64_add(J, kp, 0); /* Set to 0. Final value is set later. */ | ||
| 259 | } | ||
| 260 | |||
| 245 | /* Intern 64 bit constant, given by its address. */ | 261 | /* Intern 64 bit constant, given by its address. */ |
| 246 | TRef lj_ir_k64(jit_State *J, IROp op, cTValue *tv) | 262 | TRef lj_ir_k64(jit_State *J, IROp op, cTValue *tv) |
| 247 | { | 263 | { |
diff --git a/src/lj_iropt.h b/src/lj_iropt.h index 4e424e70..4106ef8a 100644 --- a/src/lj_iropt.h +++ b/src/lj_iropt.h | |||
| @@ -40,6 +40,7 @@ static LJ_AINLINE IRRef lj_ir_nextins(jit_State *J) | |||
| 40 | LJ_FUNC TRef LJ_FASTCALL lj_ir_kint(jit_State *J, int32_t k); | 40 | LJ_FUNC TRef LJ_FASTCALL lj_ir_kint(jit_State *J, int32_t k); |
| 41 | LJ_FUNC void lj_ir_k64_freeall(jit_State *J); | 41 | LJ_FUNC void lj_ir_k64_freeall(jit_State *J); |
| 42 | LJ_FUNC TRef lj_ir_k64(jit_State *J, IROp op, cTValue *tv); | 42 | LJ_FUNC TRef lj_ir_k64(jit_State *J, IROp op, cTValue *tv); |
| 43 | LJ_FUNC TValue *lj_ir_k64_reserve(jit_State *J); | ||
| 43 | LJ_FUNC cTValue *lj_ir_k64_find(jit_State *J, uint64_t u64); | 44 | LJ_FUNC cTValue *lj_ir_k64_find(jit_State *J, uint64_t u64); |
| 44 | LJ_FUNC TRef lj_ir_knum_u64(jit_State *J, uint64_t u64); | 45 | LJ_FUNC TRef lj_ir_knum_u64(jit_State *J, uint64_t u64); |
| 45 | LJ_FUNC TRef lj_ir_knumint(jit_State *J, lua_Number n); | 46 | LJ_FUNC TRef lj_ir_knumint(jit_State *J, lua_Number n); |
diff --git a/src/lj_jit.h b/src/lj_jit.h index 1df56cae..10900bf6 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h | |||
| @@ -381,6 +381,7 @@ typedef struct jit_State { | |||
| 381 | GCRef *trace; /* Array of traces. */ | 381 | GCRef *trace; /* Array of traces. */ |
| 382 | TraceNo freetrace; /* Start of scan for next free trace. */ | 382 | TraceNo freetrace; /* Start of scan for next free trace. */ |
| 383 | MSize sizetrace; /* Size of trace array. */ | 383 | MSize sizetrace; /* Size of trace array. */ |
| 384 | TValue *ktracep; /* Pointer to K64Array slot with GCtrace pointer. */ | ||
| 384 | 385 | ||
| 385 | IRRef1 chain[IR__MAX]; /* IR instruction skip-list chain anchors. */ | 386 | IRRef1 chain[IR__MAX]; /* IR instruction skip-list chain anchors. */ |
| 386 | TRef slot[LJ_MAX_JSLOTS+LJ_STACK_EXTRA]; /* Stack slot map. */ | 387 | TRef slot[LJ_MAX_JSLOTS+LJ_STACK_EXTRA]; /* Stack slot map. */ |
diff --git a/src/lj_snap.c b/src/lj_snap.c index d8e7987c..fa9abb74 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c | |||
| @@ -631,8 +631,8 @@ static void snap_restoreval(jit_State *J, GCtrace *T, ExitState *ex, | |||
| 631 | } else if (irt_isnum(t)) { | 631 | } else if (irt_isnum(t)) { |
| 632 | setnumV(o, ex->fpr[r-RID_MIN_FPR]); | 632 | setnumV(o, ex->fpr[r-RID_MIN_FPR]); |
| 633 | #endif | 633 | #endif |
| 634 | } else if (LJ_64 && irt_islightud(t)) { | 634 | } else if (LJ_64 && irt_is64(t)) { |
| 635 | /* 64 bit lightuserdata which may escape already has the tag bits. */ | 635 | /* 64 bit values that already have the tag bits. */ |
| 636 | o->u64 = ex->gpr[r-RID_MIN_GPR]; | 636 | o->u64 = ex->gpr[r-RID_MIN_GPR]; |
| 637 | } else if (irt_ispri(t)) { | 637 | } else if (irt_ispri(t)) { |
| 638 | setpriV(o, irt_toitype(t)); | 638 | setpriV(o, irt_toitype(t)); |
diff --git a/src/lj_trace.c b/src/lj_trace.c index 42f4321d..1d0c2e5e 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c | |||
| @@ -274,7 +274,7 @@ int lj_trace_flushall(lua_State *L) | |||
| 274 | if (T->root == 0) | 274 | if (T->root == 0) |
| 275 | trace_flushroot(J, T); | 275 | trace_flushroot(J, T); |
| 276 | lj_gdbjit_deltrace(J, T); | 276 | lj_gdbjit_deltrace(J, T); |
| 277 | T->traceno = 0; | 277 | T->traceno = T->link = 0; /* Blacklist the link for cont_stitch. */ |
| 278 | setgcrefnull(J->trace[i]); | 278 | setgcrefnull(J->trace[i]); |
| 279 | } | 279 | } |
| 280 | } | 280 | } |
| @@ -284,6 +284,7 @@ int lj_trace_flushall(lua_State *L) | |||
| 284 | memset(J->penalty, 0, sizeof(J->penalty)); | 284 | memset(J->penalty, 0, sizeof(J->penalty)); |
| 285 | /* Free the whole machine code and invalidate all exit stub groups. */ | 285 | /* Free the whole machine code and invalidate all exit stub groups. */ |
| 286 | lj_mcode_free(J); | 286 | lj_mcode_free(J); |
| 287 | lj_ir_k64_freeall(J); | ||
| 287 | memset(J->exitstubgroup, 0, sizeof(J->exitstubgroup)); | 288 | memset(J->exitstubgroup, 0, sizeof(J->exitstubgroup)); |
| 288 | lj_vmevent_send(L, TRACE, | 289 | lj_vmevent_send(L, TRACE, |
| 289 | setstrV(L, L->top++, lj_str_newlit(L, "flush")); | 290 | setstrV(L, L->top++, lj_str_newlit(L, "flush")); |
| @@ -402,6 +403,7 @@ static void trace_start(jit_State *J) | |||
| 402 | J->postproc = LJ_POST_NONE; | 403 | J->postproc = LJ_POST_NONE; |
| 403 | lj_resetsplit(J); | 404 | lj_resetsplit(J); |
| 404 | J->retryrec = 0; | 405 | J->retryrec = 0; |
| 406 | J->ktracep = NULL; | ||
| 405 | setgcref(J->cur.startpt, obj2gco(J->pt)); | 407 | setgcref(J->cur.startpt, obj2gco(J->pt)); |
| 406 | 408 | ||
| 407 | L = J->L; | 409 | L = J->L; |
| @@ -477,6 +479,9 @@ static void trace_stop(jit_State *J) | |||
| 477 | lj_mcode_commit(J, J->cur.mcode); | 479 | lj_mcode_commit(J, J->cur.mcode); |
| 478 | J->postproc = LJ_POST_NONE; | 480 | J->postproc = LJ_POST_NONE; |
| 479 | trace_save(J, T); | 481 | trace_save(J, T); |
| 482 | if (J->ktracep) { /* Patch K64Array slot with the final GCtrace pointer. */ | ||
| 483 | setgcV(J->L, J->ktracep, obj2gco(T), LJ_TTRACE); | ||
| 484 | } | ||
| 480 | 485 | ||
| 481 | L = J->L; | 486 | L = J->L; |
| 482 | lj_vmevent_send(L, TRACE, | 487 | lj_vmevent_send(L, TRACE, |
diff --git a/src/lj_traceerr.h b/src/lj_traceerr.h index 12e90d03..d434be15 100644 --- a/src/lj_traceerr.h +++ b/src/lj_traceerr.h | |||
| @@ -25,8 +25,6 @@ TREDEF(BADTYPE, "bad argument type") | |||
| 25 | TREDEF(CJITOFF, "JIT compilation disabled for function") | 25 | TREDEF(CJITOFF, "JIT compilation disabled for function") |
| 26 | TREDEF(CUNROLL, "call unroll limit reached") | 26 | TREDEF(CUNROLL, "call unroll limit reached") |
| 27 | TREDEF(DOWNREC, "down-recursion, restarting") | 27 | TREDEF(DOWNREC, "down-recursion, restarting") |
| 28 | TREDEF(NYICF, "NYI: C function %s") | ||
| 29 | TREDEF(NYIFF, "NYI: FastFunc %s") | ||
| 30 | TREDEF(NYIFFU, "NYI: unsupported variant of FastFunc %s") | 28 | TREDEF(NYIFFU, "NYI: unsupported variant of FastFunc %s") |
| 31 | TREDEF(NYIRETL, "NYI: return to lower frame") | 29 | TREDEF(NYIRETL, "NYI: return to lower frame") |
| 32 | 30 | ||
diff --git a/src/vm_arm.dasc b/src/vm_arm.dasc index 0bd9b147..af722f9e 100644 --- a/src/vm_arm.dasc +++ b/src/vm_arm.dasc | |||
| @@ -2086,7 +2086,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2086 | | // RA = resultptr, CARG4 = meta base | 2086 | | // RA = resultptr, CARG4 = meta base |
| 2087 | | ldr RB, SAVE_MULTRES | 2087 | | ldr RB, SAVE_MULTRES |
| 2088 | | ldr INS, [PC, #-4] | 2088 | | ldr INS, [PC, #-4] |
| 2089 | | ldr CARG3, [CARG4, #-24] // Save previous trace number. | 2089 | | ldr TRACE:CARG3, [CARG4, #-24] // Save previous trace. |
| 2090 | | subs RB, RB, #8 | 2090 | | subs RB, RB, #8 |
| 2091 | | decode_RA8 RC, INS // Call base. | 2091 | | decode_RA8 RC, INS // Call base. |
| 2092 | | beq >2 | 2092 | | beq >2 |
| @@ -2101,23 +2101,20 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2101 | | decode_RA8 RA, INS | 2101 | | decode_RA8 RA, INS |
| 2102 | | decode_RB8 RB, INS | 2102 | | decode_RB8 RB, INS |
| 2103 | | add RA, RA, RB | 2103 | | add RA, RA, RB |
| 2104 | | ldr CARG1, [DISPATCH, #DISPATCH_J(trace)] | ||
| 2105 | |3: | 2104 | |3: |
| 2106 | | cmp RA, RC | 2105 | | cmp RA, RC |
| 2107 | | mvn CARG2, #~LJ_TNIL | 2106 | | mvn CARG2, #~LJ_TNIL |
| 2108 | | bhi >9 // More results wanted? | 2107 | | bhi >9 // More results wanted? |
| 2109 | | | 2108 | | |
| 2110 | | ldr TRACE:RA, [CARG1, CARG3, lsl #2] | 2109 | | ldrh RA, TRACE:CARG3->traceno |
| 2111 | | cmp TRACE:RA, #0 | 2110 | | ldrh RC, TRACE:CARG3->link |
| 2112 | | beq ->cont_nop | 2111 | | cmp RC, RA |
| 2113 | | ldrh RC, TRACE:RA->link | ||
| 2114 | | cmp RC, CARG3 | ||
| 2115 | | beq ->cont_nop // Blacklisted. | 2112 | | beq ->cont_nop // Blacklisted. |
| 2116 | | cmp RC, #0 | 2113 | | cmp RC, #0 |
| 2117 | | bne =>BC_JLOOP // Jump to stitched trace. | 2114 | | bne =>BC_JLOOP // Jump to stitched trace. |
| 2118 | | | 2115 | | |
| 2119 | | // Stitch a new trace to the previous trace. | 2116 | | // Stitch a new trace to the previous trace. |
| 2120 | | str CARG3, [DISPATCH, #DISPATCH_J(exitno)] | 2117 | | str RA, [DISPATCH, #DISPATCH_J(exitno)] |
| 2121 | | str L, [DISPATCH, #DISPATCH_J(L)] | 2118 | | str L, [DISPATCH, #DISPATCH_J(L)] |
| 2122 | | str BASE, L->base | 2119 | | str BASE, L->base |
| 2123 | | sub CARG1, DISPATCH, #-GG_DISP2J | 2120 | | sub CARG1, DISPATCH, #-GG_DISP2J |
diff --git a/src/vm_mips.dasc b/src/vm_mips.dasc index 7cfdf4b1..134ed569 100644 --- a/src/vm_mips.dasc +++ b/src/vm_mips.dasc | |||
| @@ -2015,7 +2015,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2015 | |.if JIT | 2015 | |.if JIT |
| 2016 | | // RA = resultptr, RB = meta base | 2016 | | // RA = resultptr, RB = meta base |
| 2017 | | lw INS, -4(PC) | 2017 | | lw INS, -4(PC) |
| 2018 | | lw TMP3, -24+LO(RB) // Save previous trace number. | 2018 | | lw TMP2, -24+LO(RB) // Save previous trace. |
| 2019 | | decode_RA8a RC, INS | 2019 | | decode_RA8a RC, INS |
| 2020 | | addiu AT, MULTRES, -8 | 2020 | | addiu AT, MULTRES, -8 |
| 2021 | | decode_RA8b RC | 2021 | | decode_RA8b RC |
| @@ -2034,17 +2034,13 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2034 | | decode_RA8b RA | 2034 | | decode_RA8b RA |
| 2035 | | decode_RB8b RB | 2035 | | decode_RB8b RB |
| 2036 | | addu RA, RA, RB | 2036 | | addu RA, RA, RB |
| 2037 | | lw TMP1, DISPATCH_J(trace)(DISPATCH) | ||
| 2038 | | addu RA, BASE, RA | 2037 | | addu RA, BASE, RA |
| 2039 | |3: | 2038 | |3: |
| 2040 | | sltu AT, RC, RA | 2039 | | sltu AT, RC, RA |
| 2041 | | bnez AT, >9 // More results wanted? | 2040 | | bnez AT, >9 // More results wanted? |
| 2042 | |. sll TMP2, TMP3, 2 | 2041 | |. nop |
| 2043 | | | 2042 | | |
| 2044 | | addu TMP2, TMP1, TMP2 | 2043 | | lhu TMP3, TRACE:TMP2->traceno |
| 2045 | | lw TRACE:TMP2, 0(TMP2) | ||
| 2046 | | beqz TRACE:TMP2, ->cont_nop | ||
| 2047 | |. nop | ||
| 2048 | | lhu RD, TRACE:TMP2->link | 2044 | | lhu RD, TRACE:TMP2->link |
| 2049 | | beq RD, TMP3, ->cont_nop // Blacklisted. | 2045 | | beq RD, TMP3, ->cont_nop // Blacklisted. |
| 2050 | |. load_got lj_dispatch_stitch | 2046 | |. load_got lj_dispatch_stitch |
diff --git a/src/vm_ppc.dasc b/src/vm_ppc.dasc index 9299c554..0d6915fd 100644 --- a/src/vm_ppc.dasc +++ b/src/vm_ppc.dasc | |||
| @@ -2525,7 +2525,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2525 | |.if JIT | 2525 | |.if JIT |
| 2526 | | // RA = resultptr, RB = meta base | 2526 | | // RA = resultptr, RB = meta base |
| 2527 | | lwz INS, -4(PC) | 2527 | | lwz INS, -4(PC) |
| 2528 | | lwz TMP3, -20(RB) // Save previous trace number. | 2528 | | lwz TRACE:TMP2, -20(RB) // Save previous trace. |
| 2529 | | addic. TMP1, MULTRES, -8 | 2529 | | addic. TMP1, MULTRES, -8 |
| 2530 | | decode_RA8 RC, INS // Call base. | 2530 | | decode_RA8 RC, INS // Call base. |
| 2531 | | beq >2 | 2531 | | beq >2 |
| @@ -2540,15 +2540,11 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2540 | | decode_RA8 RA, INS | 2540 | | decode_RA8 RA, INS |
| 2541 | | decode_RB8 RB, INS | 2541 | | decode_RB8 RB, INS |
| 2542 | | add RA, RA, RB | 2542 | | add RA, RA, RB |
| 2543 | | lwz TMP1, DISPATCH_J(trace)(DISPATCH) | ||
| 2544 | |3: | 2543 | |3: |
| 2545 | | cmplw RA, RC | 2544 | | cmplw RA, RC |
| 2546 | | bgt >9 // More results wanted? | 2545 | | bgt >9 // More results wanted? |
| 2547 | | | 2546 | | |
| 2548 | | slwi TMP2, TMP3, 2 | 2547 | | lhz TMP3, TRACE:TMP2->traceno |
| 2549 | | lwzx TRACE:TMP2, TMP1, TMP2 | ||
| 2550 | | cmpwi TRACE:TMP2, 0 | ||
| 2551 | | beq ->cont_nop | ||
| 2552 | | lhz RD, TRACE:TMP2->link | 2548 | | lhz RD, TRACE:TMP2->link |
| 2553 | | cmpw RD, TMP3 | 2549 | | cmpw RD, TMP3 |
| 2554 | | cmpwi cr1, RD, 0 | 2550 | | cmpwi cr1, RD, 0 |
diff --git a/src/vm_x86.dasc b/src/vm_x86.dasc index f31e595b..96ac1da8 100644 --- a/src/vm_x86.dasc +++ b/src/vm_x86.dasc | |||
| @@ -2667,8 +2667,8 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2667 | |->cont_stitch: // Trace stitching. | 2667 | |->cont_stitch: // Trace stitching. |
| 2668 | |.if JIT | 2668 | |.if JIT |
| 2669 | | // BASE = base, RC = result, RB = mbase | 2669 | | // BASE = base, RC = result, RB = mbase |
| 2670 | | mov RA, [RB-24] // Save previous trace number. | 2670 | | mov TRACE:RA, [RB-24] // Save previous trace. |
| 2671 | | mov TMP1, RA | 2671 | | mov TMP1, TRACE:RA |
| 2672 | | mov TMP3, DISPATCH // Need one more register. | 2672 | | mov TMP3, DISPATCH // Need one more register. |
| 2673 | | mov DISPATCH, MULTRES | 2673 | | mov DISPATCH, MULTRES |
| 2674 | | movzx RA, PC_RA | 2674 | | movzx RA, PC_RA |
| @@ -2699,11 +2699,8 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2699 | | ja >9 // More results wanted? | 2699 | | ja >9 // More results wanted? |
| 2700 | | | 2700 | | |
| 2701 | | mov DISPATCH, TMP3 | 2701 | | mov DISPATCH, TMP3 |
| 2702 | | mov RB, TMP1 // Get previous trace number. | 2702 | | mov TRACE:RD, TMP1 // Get previous trace. |
| 2703 | | mov RA, [DISPATCH+DISPATCH_J(trace)] | 2703 | | movzx RB, word TRACE:RD->traceno |
| 2704 | | mov TRACE:RD, [RA+RB*4] | ||
| 2705 | | test TRACE:RD, TRACE:RD | ||
| 2706 | | jz ->cont_nop | ||
| 2707 | | movzx RD, word TRACE:RD->link | 2704 | | movzx RD, word TRACE:RD->link |
| 2708 | | cmp RD, RB | 2705 | | cmp RD, RB |
| 2709 | | je ->cont_nop // Blacklisted. | 2706 | | je ->cont_nop // Blacklisted. |
