diff options
| -rw-r--r-- | lib/dump.lua | 2 | ||||
| -rw-r--r-- | src/lj_asm.c | 6 | ||||
| -rw-r--r-- | src/lj_func.c | 3 | ||||
| -rw-r--r-- | src/lj_obj.h | 2 | ||||
| -rw-r--r-- | src/lj_opt_fold.c | 4 | ||||
| -rw-r--r-- | src/lj_opt_mem.c | 17 | ||||
| -rw-r--r-- | src/lj_record.c | 11 |
7 files changed, 32 insertions, 13 deletions
diff --git a/lib/dump.lua b/lib/dump.lua index 41feff44..00f59977 100644 --- a/lib/dump.lua +++ b/lib/dump.lua | |||
| @@ -397,6 +397,8 @@ local function dump_ir(tr, dumpsnap, dumpreg) | |||
| 397 | local litn = litname[op] | 397 | local litn = litname[op] |
| 398 | if litn and litn[op2] then | 398 | if litn and litn[op2] then |
| 399 | out:write(" ", litn[op2]) | 399 | out:write(" ", litn[op2]) |
| 400 | elseif op == "UREFO " or op == "UREFC " then | ||
| 401 | out:write(format(" #%-3d", shr(op2, 8))) | ||
| 400 | else | 402 | else |
| 401 | out:write(format(" #%-3d", op2)) | 403 | out:write(format(" #%-3d", op2)) |
| 402 | end | 404 | end |
diff --git a/src/lj_asm.c b/src/lj_asm.c index 50f877e7..20d26278 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
| @@ -1105,7 +1105,7 @@ static void asm_fuseahuref(ASMState *as, IRRef ref, RegSet allow) | |||
| 1105 | case IR_UREFC: | 1105 | case IR_UREFC: |
| 1106 | if (irref_isk(ir->op1)) { | 1106 | if (irref_isk(ir->op1)) { |
| 1107 | GCfunc *fn = ir_kfunc(IR(ir->op1)); | 1107 | GCfunc *fn = ir_kfunc(IR(ir->op1)); |
| 1108 | GCupval *uv = &gcref(fn->l.uvptr[ir->op2])->uv; | 1108 | GCupval *uv = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv; |
| 1109 | as->mrm.ofs = ptr2addr(&uv->tv); | 1109 | as->mrm.ofs = ptr2addr(&uv->tv); |
| 1110 | as->mrm.base = as->mrm.idx = RID_NONE; | 1110 | as->mrm.base = as->mrm.idx = RID_NONE; |
| 1111 | return; | 1111 | return; |
| @@ -1702,7 +1702,7 @@ static void asm_uref(ASMState *as, IRIns *ir) | |||
| 1702 | Reg dest = ra_dest(as, ir, RSET_GPR); | 1702 | Reg dest = ra_dest(as, ir, RSET_GPR); |
| 1703 | if (irref_isk(ir->op1)) { | 1703 | if (irref_isk(ir->op1)) { |
| 1704 | GCfunc *fn = ir_kfunc(IR(ir->op1)); | 1704 | GCfunc *fn = ir_kfunc(IR(ir->op1)); |
| 1705 | MRef *v = &gcref(fn->l.uvptr[ir->op2])->uv.v; | 1705 | MRef *v = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.v; |
| 1706 | emit_rma(as, XO_MOV, dest, v); | 1706 | emit_rma(as, XO_MOV, dest, v); |
| 1707 | } else { | 1707 | } else { |
| 1708 | Reg uv = ra_scratch(as, RSET_GPR); | 1708 | Reg uv = ra_scratch(as, RSET_GPR); |
| @@ -1716,7 +1716,7 @@ static void asm_uref(ASMState *as, IRIns *ir) | |||
| 1716 | emit_rmro(as, XO_MOV, dest, uv, offsetof(GCupval, v)); | 1716 | emit_rmro(as, XO_MOV, dest, uv, offsetof(GCupval, v)); |
| 1717 | } | 1717 | } |
| 1718 | emit_rmro(as, XO_MOV, uv, func, | 1718 | emit_rmro(as, XO_MOV, uv, func, |
| 1719 | (int32_t)offsetof(GCfuncL, uvptr) + 4*(int32_t)ir->op2); | 1719 | (int32_t)offsetof(GCfuncL, uvptr) + 4*(int32_t)(ir->op2 >> 8)); |
| 1720 | } | 1720 | } |
| 1721 | } | 1721 | } |
| 1722 | } | 1722 | } |
diff --git a/src/lj_func.c b/src/lj_func.c index 231701db..078ced92 100644 --- a/src/lj_func.c +++ b/src/lj_func.c | |||
| @@ -169,10 +169,11 @@ GCfunc *lj_func_newL_gc(lua_State *L, GCproto *pt, GCfuncL *parent) | |||
| 169 | nuv = fn->l.nupvalues; | 169 | nuv = fn->l.nupvalues; |
| 170 | base = L->base; | 170 | base = L->base; |
| 171 | for (i = 0; i < nuv; i++) { | 171 | for (i = 0; i < nuv; i++) { |
| 172 | ptrdiff_t v = pt->uv[i]; | 172 | uint32_t v = pt->uv[i]; |
| 173 | GCupval *uv; | 173 | GCupval *uv; |
| 174 | if ((v & 0x8000)) { | 174 | if ((v & 0x8000)) { |
| 175 | uv = func_finduv(L, base + (v & 0xff)); | 175 | uv = func_finduv(L, base + (v & 0xff)); |
| 176 | uv->dhash = (uint32_t)(uintptr_t)gcref(parent->pt) ^ (v << 24); | ||
| 176 | } else { | 177 | } else { |
| 177 | uv = &gcref(puv[v])->uv; | 178 | uv = &gcref(puv[v])->uv; |
| 178 | } | 179 | } |
diff --git a/src/lj_obj.h b/src/lj_obj.h index 85d904f3..ecce03ed 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h | |||
| @@ -397,7 +397,7 @@ typedef struct GCupval { | |||
| 397 | }; | 397 | }; |
| 398 | }; | 398 | }; |
| 399 | MRef v; /* Points to stack slot (open) or above (closed). */ | 399 | MRef v; /* Points to stack slot (open) or above (closed). */ |
| 400 | int32_t unusedv; /* For consistent alignment. */ | 400 | uint32_t dhash; /* Disambiguation hash: dh1 != dh2 => cannot alias. */ |
| 401 | } GCupval; | 401 | } GCupval; |
| 402 | 402 | ||
| 403 | #define uvprev(uv_) (&gcref((uv_)->prev)->uv) | 403 | #define uvprev(uv_) (&gcref((uv_)->prev)->uv) |
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index 41c87e2f..a8550e1f 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c | |||
| @@ -1146,12 +1146,12 @@ LJFOLDF(cse_uref) | |||
| 1146 | if (LJ_LIKELY(J->flags & JIT_F_OPT_CSE)) { | 1146 | if (LJ_LIKELY(J->flags & JIT_F_OPT_CSE)) { |
| 1147 | IRRef ref = J->chain[fins->o]; | 1147 | IRRef ref = J->chain[fins->o]; |
| 1148 | GCfunc *fn = ir_kfunc(fleft); | 1148 | GCfunc *fn = ir_kfunc(fleft); |
| 1149 | GCupval *uv = gco2uv(gcref(fn->l.uvptr[fins->op2])); | 1149 | GCupval *uv = gco2uv(gcref(fn->l.uvptr[(fins->op2 >> 8)])); |
| 1150 | while (ref > 0) { | 1150 | while (ref > 0) { |
| 1151 | IRIns *ir = IR(ref); | 1151 | IRIns *ir = IR(ref); |
| 1152 | if (irref_isk(ir->op1)) { | 1152 | if (irref_isk(ir->op1)) { |
| 1153 | GCfunc *fn2 = ir_kfunc(IR(ir->op1)); | 1153 | GCfunc *fn2 = ir_kfunc(IR(ir->op1)); |
| 1154 | if (gco2uv(gcref(fn2->l.uvptr[ir->op2])) == uv) { | 1154 | if (gco2uv(gcref(fn2->l.uvptr[(ir->op2 >> 8)])) == uv) { |
| 1155 | if (fins->o == IR_UREFO && gcstep_barrier(J, ref)) | 1155 | if (fins->o == IR_UREFO && gcstep_barrier(J, ref)) |
| 1156 | break; | 1156 | break; |
| 1157 | return ref; | 1157 | return ref; |
diff --git a/src/lj_opt_mem.c b/src/lj_opt_mem.c index 521c8590..57948311 100644 --- a/src/lj_opt_mem.c +++ b/src/lj_opt_mem.c | |||
| @@ -277,12 +277,17 @@ static AliasRet aa_uref(IRIns *refa, IRIns *refb) | |||
| 277 | { | 277 | { |
| 278 | if (refa->o != refb->o) | 278 | if (refa->o != refb->o) |
| 279 | return ALIAS_NO; /* Different UREFx type. */ | 279 | return ALIAS_NO; /* Different UREFx type. */ |
| 280 | if (refa->op1 != refb->op1) | 280 | if (refa->op1 == refb->op1) { /* Same function. */ |
| 281 | return ALIAS_MAY; /* Different function. */ | 281 | if (refa->op2 == refb->op2) |
| 282 | else if (refa->op2 == refb->op2) | 282 | return ALIAS_MUST; /* Same function, same upvalue idx. */ |
| 283 | return ALIAS_MUST; /* Same function, same upvalue idx. */ | 283 | else |
| 284 | else | 284 | return ALIAS_NO; /* Same function, different upvalue idx. */ |
| 285 | return ALIAS_NO; /* Same function, different upvalue idx. */ | 285 | } else { /* Different functions, check disambiguation hash values. */ |
| 286 | if (((refa->op2 ^ refb->op2) & 0xff)) | ||
| 287 | return ALIAS_NO; /* Upvalues with different hash values cannot alias. */ | ||
| 288 | else | ||
| 289 | return ALIAS_MAY; /* No conclusion can be drawn for same hash value. */ | ||
| 290 | } | ||
| 286 | } | 291 | } |
| 287 | 292 | ||
| 288 | /* ULOAD forwarding. */ | 293 | /* ULOAD forwarding. */ |
diff --git a/src/lj_record.c b/src/lj_record.c index 0dfd1f73..b998c020 100644 --- a/src/lj_record.c +++ b/src/lj_record.c | |||
| @@ -781,6 +781,15 @@ static TRef rec_idx(jit_State *J, RecordIndex *ix) | |||
| 781 | 781 | ||
| 782 | /* -- Upvalue access ------------------------------------------------------ */ | 782 | /* -- Upvalue access ------------------------------------------------------ */ |
| 783 | 783 | ||
| 784 | /* Shrink disambiguation hash into an 8 bit value. */ | ||
| 785 | static uint32_t shrink_dhash(uint32_t lo, uint32_t hi) | ||
| 786 | { | ||
| 787 | lo ^= hi; hi = lj_rol(hi, 14); | ||
| 788 | lo -= hi; hi = lj_rol(hi, 5); | ||
| 789 | hi ^= lo; hi -= lj_rol(lo, 27); | ||
| 790 | return (hi & 0xff); | ||
| 791 | } | ||
| 792 | |||
| 784 | /* Record upvalue load/store. */ | 793 | /* Record upvalue load/store. */ |
| 785 | static TRef rec_upvalue(jit_State *J, uint32_t uv, TRef val) | 794 | static TRef rec_upvalue(jit_State *J, uint32_t uv, TRef val) |
| 786 | { | 795 | { |
| @@ -788,6 +797,8 @@ static TRef rec_upvalue(jit_State *J, uint32_t uv, TRef val) | |||
| 788 | TRef fn = getcurrf(J); | 797 | TRef fn = getcurrf(J); |
| 789 | IRRef uref; | 798 | IRRef uref; |
| 790 | int needbarrier = 0; | 799 | int needbarrier = 0; |
| 800 | /* Note: this effectively limits LJ_MAX_UPVAL to 127. */ | ||
| 801 | uv = (uv << 8) | shrink_dhash(uvp->dhash, uvp->dhash-0x04c11db7); | ||
| 791 | if (!uvp->closed) { | 802 | if (!uvp->closed) { |
| 792 | /* In current stack? */ | 803 | /* In current stack? */ |
| 793 | if (uvval(uvp) >= J->L->stack && uvval(uvp) < J->L->maxstack) { | 804 | if (uvval(uvp) >= J->L->stack && uvval(uvp) < J->L->maxstack) { |
