diff --git a/src/Makefile.dep b/src/Makefile.dep index b869fdff..de46c57e 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep @@ -75,9 +75,9 @@ lj_cparse.o: lj_cparse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_ctype.h lj_cparse.h lj_frame.h \ lj_bc.h lj_vm.h lj_char.h lj_crecord.o: lj_crecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ - lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_gc.h lj_cparse.h \ - lj_cconv.h lj_clib.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h \ - lj_dispatch.h lj_bc.h lj_traceerr.h lj_ffrecord.h lj_crecord.h + lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h \ + lj_gc.h lj_cparse.h lj_cconv.h lj_clib.h lj_ir.h lj_jit.h lj_iropt.h \ + lj_trace.h lj_dispatch.h lj_traceerr.h lj_ffrecord.h lj_crecord.h lj_ctype.o: lj_ctype.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_dispatch.o: lj_dispatch.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ diff --git a/src/lj_crecord.c b/src/lj_crecord.c index e5413fb3..b4bfd0c2 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c @@ -13,6 +13,7 @@ #include "lj_err.h" #include "lj_str.h" #include "lj_tab.h" +#include "lj_frame.h" #include "lj_ctype.h" #include "lj_cparse.h" #include "lj_cconv.h" @@ -835,6 +836,15 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd) err_type: lj_trace_err(J, LJ_TRERR_BADTYPE); } + /* Fixup cdata comparisons, too. Avoids some cdata escapes. */ + if (J->postproc == LJ_POST_FIXGUARD && frame_iscont(J->L->base-1)) { + const BCIns *pc = frame_contpc(J->L->base-1) - 1; + if (bc_op(*pc) <= BC_ISNEP) { + setframe_pc(&J2G(J)->tmptv, pc); + J2G(J)->tmptv.u32.lo = ((tref_istrue(tr) ^ bc_op(*pc)) & 1); + J->postproc = LJ_POST_FIXCOMP; + } + } J->base[0] = tr; } } diff --git a/src/lj_jit.h b/src/lj_jit.h index 38970fc7..2f3df2a0 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h @@ -111,6 +111,7 @@ typedef enum { /* Post-processing action. */ typedef enum { LJ_POST_NONE, /* No action. */ + LJ_POST_FIXCOMP, /* Fixup comparison and emit pending guard. */ LJ_POST_FIXGUARD /* Fixup and emit pending guard. */ } PostProc; diff --git a/src/lj_record.c b/src/lj_record.c index 94bd0ed4..d8c67499 100644 --- a/src/lj_record.c +++ b/src/lj_record.c @@ -1355,10 +1355,10 @@ static void rec_comp_prep(jit_State *J) } /* Fixup comparison. */ -static void rec_comp_fixup(jit_State *J, int cond) +static void rec_comp_fixup(jit_State *J, const BCIns *pc, int cond) { - BCIns jmpins = J->pc[1]; - const BCIns *npc = J->pc + 2 + (cond ? bc_j(jmpins) : 0); + BCIns jmpins = pc[1]; + const BCIns *npc = pc + 2 + (cond ? bc_j(jmpins) : 0); SnapShot *snap = &J->cur.snap[J->cur.nsnap-1]; /* Set PC to opposite target to avoid re-recording the comp. in side trace. */ J->cur.snapmap[snap->mapofs + snap->nent] = SNAP_MKPC(npc); @@ -1383,6 +1383,10 @@ void lj_record_ins(jit_State *J) /* Perform post-processing action before recording the next instruction. */ if (LJ_UNLIKELY(J->postproc != LJ_POST_NONE)) { switch (J->postproc) { + case LJ_POST_FIXCOMP: /* Fixup comparison. */ + pc = frame_pc(&J2G(J)->tmptv); + rec_comp_fixup(J, pc, (!tvistruecond(&J2G(J)->tmptv2) ^ (bc_op(*pc)&1))); + /* fallthrough */ case LJ_POST_FIXGUARD: /* Fixup and emit pending guard. */ if (!tvistruecond(&J2G(J)->tmptv2)) { BCReg s; @@ -1505,7 +1509,7 @@ void lj_record_ins(jit_State *J) break; } emitir(IRTG(irop, ta), ra, rc); - rec_comp_fixup(J, ((int)op ^ irop) & 1); + rec_comp_fixup(J, J->pc, ((int)op ^ irop) & 1); } break; @@ -1529,7 +1533,7 @@ void lj_record_ins(jit_State *J) rec_mm_equal(J, &ix, (int)op); break; } - rec_comp_fixup(J, ((int)op & 1) == !diff); + rec_comp_fixup(J, J->pc, ((int)op & 1) == !diff); } break;