mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-08 07:34:07 +00:00
Eliminate hmask guard for forwarded HREFK.
This commit is contained in:
parent
72c661e2b8
commit
b7d29b6e67
@ -1158,11 +1158,12 @@ static void rec_idx_abc(jit_State *J, TRef asizeref, TRef ikey, uint32_t asize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Record indexed key lookup. */
|
/* Record indexed key lookup. */
|
||||||
static TRef rec_idx_key(jit_State *J, RecordIndex *ix)
|
static TRef rec_idx_key(jit_State *J, RecordIndex *ix, IRRef *rbref)
|
||||||
{
|
{
|
||||||
TRef key;
|
TRef key;
|
||||||
GCtab *t = tabV(&ix->tabv);
|
GCtab *t = tabV(&ix->tabv);
|
||||||
ix->oldv = lj_tab_get(J->L, t, &ix->keyv); /* Lookup previous value. */
|
ix->oldv = lj_tab_get(J->L, t, &ix->keyv); /* Lookup previous value. */
|
||||||
|
*rbref = 0;
|
||||||
|
|
||||||
/* Integer keys are looked up in the array part first. */
|
/* Integer keys are looked up in the array part first. */
|
||||||
key = ix->key;
|
key = ix->key;
|
||||||
@ -1212,8 +1213,9 @@ static TRef rec_idx_key(jit_State *J, RecordIndex *ix)
|
|||||||
MSize hslot = (MSize)((char *)ix->oldv - (char *)&noderef(t->node)[0].val);
|
MSize hslot = (MSize)((char *)ix->oldv - (char *)&noderef(t->node)[0].val);
|
||||||
if (t->hmask > 0 && hslot <= t->hmask*(MSize)sizeof(Node) &&
|
if (t->hmask > 0 && hslot <= t->hmask*(MSize)sizeof(Node) &&
|
||||||
hslot <= 65535*(MSize)sizeof(Node)) {
|
hslot <= 65535*(MSize)sizeof(Node)) {
|
||||||
TRef node, kslot;
|
TRef node, kslot, hm;
|
||||||
TRef hm = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_HMASK);
|
*rbref = J->cur.nins; /* Mark possible rollback point. */
|
||||||
|
hm = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_HMASK);
|
||||||
emitir(IRTGI(IR_EQ), hm, lj_ir_kint(J, (int32_t)t->hmask));
|
emitir(IRTGI(IR_EQ), hm, lj_ir_kint(J, (int32_t)t->hmask));
|
||||||
node = emitir(IRT(IR_FLOAD, IRT_P32), ix->tab, IRFL_TAB_NODE);
|
node = emitir(IRT(IR_FLOAD, IRT_P32), ix->tab, IRFL_TAB_NODE);
|
||||||
kslot = lj_ir_kslot(J, key, hslot / sizeof(Node));
|
kslot = lj_ir_kslot(J, key, hslot / sizeof(Node));
|
||||||
@ -1246,6 +1248,7 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix)
|
|||||||
{
|
{
|
||||||
TRef xref;
|
TRef xref;
|
||||||
IROp xrefop, loadop;
|
IROp xrefop, loadop;
|
||||||
|
IRRef rbref;
|
||||||
cTValue *oldv;
|
cTValue *oldv;
|
||||||
|
|
||||||
while (!tref_istab(ix->tab)) { /* Handle non-table lookup. */
|
while (!tref_istab(ix->tab)) { /* Handle non-table lookup. */
|
||||||
@ -1291,7 +1294,7 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Record the key lookup. */
|
/* Record the key lookup. */
|
||||||
xref = rec_idx_key(J, ix);
|
xref = rec_idx_key(J, ix, &rbref);
|
||||||
xrefop = IR(tref_ref(xref))->o;
|
xrefop = IR(tref_ref(xref))->o;
|
||||||
loadop = xrefop == IR_AREF ? IR_ALOAD : IR_HLOAD;
|
loadop = xrefop == IR_AREF ? IR_ALOAD : IR_HLOAD;
|
||||||
/* The lj_meta_tset() inconsistency is gone, but better play safe. */
|
/* The lj_meta_tset() inconsistency is gone, but better play safe. */
|
||||||
@ -1306,6 +1309,8 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix)
|
|||||||
} else {
|
} else {
|
||||||
res = emitir(IRTG(loadop, t), xref, 0);
|
res = emitir(IRTG(loadop, t), xref, 0);
|
||||||
}
|
}
|
||||||
|
if (tref_ref(res) < rbref) /* HREFK + load forwarded? */
|
||||||
|
lj_ir_rollback(J, rbref); /* Rollback to eliminate hmask guard. */
|
||||||
if (t == IRT_NIL && ix->idxchain && lj_record_mm_lookup(J, ix, MM_index))
|
if (t == IRT_NIL && ix->idxchain && lj_record_mm_lookup(J, ix, MM_index))
|
||||||
goto handlemm;
|
goto handlemm;
|
||||||
if (irtype_ispri(t)) res = TREF_PRI(t); /* Canonicalize primitives. */
|
if (irtype_ispri(t)) res = TREF_PRI(t); /* Canonicalize primitives. */
|
||||||
@ -1313,6 +1318,8 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix)
|
|||||||
} else { /* Indexed store. */
|
} else { /* Indexed store. */
|
||||||
GCtab *mt = tabref(tabV(&ix->tabv)->metatable);
|
GCtab *mt = tabref(tabV(&ix->tabv)->metatable);
|
||||||
int keybarrier = tref_isgcv(ix->key) && !tref_isnil(ix->val);
|
int keybarrier = tref_isgcv(ix->key) && !tref_isnil(ix->val);
|
||||||
|
if (tref_ref(xref) < rbref) /* HREFK forwarded? */
|
||||||
|
lj_ir_rollback(J, rbref); /* Rollback to eliminate hmask guard. */
|
||||||
if (tvisnil(oldv)) { /* Previous value was nil? */
|
if (tvisnil(oldv)) { /* Previous value was nil? */
|
||||||
/* Need to duplicate the hasmm check for the early guards. */
|
/* Need to duplicate the hasmm check for the early guards. */
|
||||||
int hasmm = 0;
|
int hasmm = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user