aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2014-09-17 19:45:16 +0200
committerMike Pall <mike>2014-09-17 19:45:16 +0200
commitb7d29b6e67c683f86306aa76a349c64a567c3dd1 (patch)
treeb2686924e176cdf6ff4a2e2c604a8ba4e5fe1d52 /src
parent72c661e2b89939335b5d2e2437d3e17c26f1d898 (diff)
downloadluajit-b7d29b6e67c683f86306aa76a349c64a567c3dd1.tar.gz
luajit-b7d29b6e67c683f86306aa76a349c64a567c3dd1.tar.bz2
luajit-b7d29b6e67c683f86306aa76a349c64a567c3dd1.zip
Eliminate hmask guard for forwarded HREFK.
Diffstat (limited to 'src')
-rw-r--r--src/lj_record.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/lj_record.c b/src/lj_record.c
index 02171300..3ccba777 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -1158,11 +1158,12 @@ static void rec_idx_abc(jit_State *J, TRef asizeref, TRef ikey, uint32_t asize)
1158} 1158}
1159 1159
1160/* Record indexed key lookup. */ 1160/* Record indexed key lookup. */
1161static TRef rec_idx_key(jit_State *J, RecordIndex *ix) 1161static TRef rec_idx_key(jit_State *J, RecordIndex *ix, IRRef *rbref)
1162{ 1162{
1163 TRef key; 1163 TRef key;
1164 GCtab *t = tabV(&ix->tabv); 1164 GCtab *t = tabV(&ix->tabv);
1165 ix->oldv = lj_tab_get(J->L, t, &ix->keyv); /* Lookup previous value. */ 1165 ix->oldv = lj_tab_get(J->L, t, &ix->keyv); /* Lookup previous value. */
1166 *rbref = 0;
1166 1167
1167 /* Integer keys are looked up in the array part first. */ 1168 /* Integer keys are looked up in the array part first. */
1168 key = ix->key; 1169 key = ix->key;
@@ -1212,8 +1213,9 @@ static TRef rec_idx_key(jit_State *J, RecordIndex *ix)
1212 MSize hslot = (MSize)((char *)ix->oldv - (char *)&noderef(t->node)[0].val); 1213 MSize hslot = (MSize)((char *)ix->oldv - (char *)&noderef(t->node)[0].val);
1213 if (t->hmask > 0 && hslot <= t->hmask*(MSize)sizeof(Node) && 1214 if (t->hmask > 0 && hslot <= t->hmask*(MSize)sizeof(Node) &&
1214 hslot <= 65535*(MSize)sizeof(Node)) { 1215 hslot <= 65535*(MSize)sizeof(Node)) {
1215 TRef node, kslot; 1216 TRef node, kslot, hm;
1216 TRef hm = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_HMASK); 1217 *rbref = J->cur.nins; /* Mark possible rollback point. */
1218 hm = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_HMASK);
1217 emitir(IRTGI(IR_EQ), hm, lj_ir_kint(J, (int32_t)t->hmask)); 1219 emitir(IRTGI(IR_EQ), hm, lj_ir_kint(J, (int32_t)t->hmask));
1218 node = emitir(IRT(IR_FLOAD, IRT_P32), ix->tab, IRFL_TAB_NODE); 1220 node = emitir(IRT(IR_FLOAD, IRT_P32), ix->tab, IRFL_TAB_NODE);
1219 kslot = lj_ir_kslot(J, key, hslot / sizeof(Node)); 1221 kslot = lj_ir_kslot(J, key, hslot / sizeof(Node));
@@ -1246,6 +1248,7 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix)
1246{ 1248{
1247 TRef xref; 1249 TRef xref;
1248 IROp xrefop, loadop; 1250 IROp xrefop, loadop;
1251 IRRef rbref;
1249 cTValue *oldv; 1252 cTValue *oldv;
1250 1253
1251 while (!tref_istab(ix->tab)) { /* Handle non-table lookup. */ 1254 while (!tref_istab(ix->tab)) { /* Handle non-table lookup. */
@@ -1291,7 +1294,7 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix)
1291 } 1294 }
1292 1295
1293 /* Record the key lookup. */ 1296 /* Record the key lookup. */
1294 xref = rec_idx_key(J, ix); 1297 xref = rec_idx_key(J, ix, &rbref);
1295 xrefop = IR(tref_ref(xref))->o; 1298 xrefop = IR(tref_ref(xref))->o;
1296 loadop = xrefop == IR_AREF ? IR_ALOAD : IR_HLOAD; 1299 loadop = xrefop == IR_AREF ? IR_ALOAD : IR_HLOAD;
1297 /* The lj_meta_tset() inconsistency is gone, but better play safe. */ 1300 /* The lj_meta_tset() inconsistency is gone, but better play safe. */
@@ -1306,6 +1309,8 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix)
1306 } else { 1309 } else {
1307 res = emitir(IRTG(loadop, t), xref, 0); 1310 res = emitir(IRTG(loadop, t), xref, 0);
1308 } 1311 }
1312 if (tref_ref(res) < rbref) /* HREFK + load forwarded? */
1313 lj_ir_rollback(J, rbref); /* Rollback to eliminate hmask guard. */
1309 if (t == IRT_NIL && ix->idxchain && lj_record_mm_lookup(J, ix, MM_index)) 1314 if (t == IRT_NIL && ix->idxchain && lj_record_mm_lookup(J, ix, MM_index))
1310 goto handlemm; 1315 goto handlemm;
1311 if (irtype_ispri(t)) res = TREF_PRI(t); /* Canonicalize primitives. */ 1316 if (irtype_ispri(t)) res = TREF_PRI(t); /* Canonicalize primitives. */
@@ -1313,6 +1318,8 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix)
1313 } else { /* Indexed store. */ 1318 } else { /* Indexed store. */
1314 GCtab *mt = tabref(tabV(&ix->tabv)->metatable); 1319 GCtab *mt = tabref(tabV(&ix->tabv)->metatable);
1315 int keybarrier = tref_isgcv(ix->key) && !tref_isnil(ix->val); 1320 int keybarrier = tref_isgcv(ix->key) && !tref_isnil(ix->val);
1321 if (tref_ref(xref) < rbref) /* HREFK forwarded? */
1322 lj_ir_rollback(J, rbref); /* Rollback to eliminate hmask guard. */
1316 if (tvisnil(oldv)) { /* Previous value was nil? */ 1323 if (tvisnil(oldv)) { /* Previous value was nil? */
1317 /* Need to duplicate the hasmm check for the early guards. */ 1324 /* Need to duplicate the hasmm check for the early guards. */
1318 int hasmm = 0; 1325 int hasmm = 0;