aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lj_asm.c6
-rw-r--r--src/lj_func.c3
-rw-r--r--src/lj_obj.h2
-rw-r--r--src/lj_opt_fold.c4
-rw-r--r--src/lj_opt_mem.c17
-rw-r--r--src/lj_record.c11
6 files changed, 30 insertions, 13 deletions
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. */
785static 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. */
785static TRef rec_upvalue(jit_State *J, uint32_t uv, TRef val) 794static 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) {