diff options
author | Mike Pall <mike> | 2014-09-17 19:45:16 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2014-09-17 19:45:16 +0200 |
commit | b7d29b6e67c683f86306aa76a349c64a567c3dd1 (patch) | |
tree | b2686924e176cdf6ff4a2e2c604a8ba4e5fe1d52 /src | |
parent | 72c661e2b89939335b5d2e2437d3e17c26f1d898 (diff) | |
download | luajit-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.c | 15 |
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. */ |
1161 | static TRef rec_idx_key(jit_State *J, RecordIndex *ix) | 1161 | static 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; |