aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lj_record.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/lj_record.c b/src/lj_record.c
index dc5f2d54..480c80c1 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -1236,12 +1236,14 @@ static void rec_idx_abc(jit_State *J, TRef asizeref, TRef ikey, uint32_t asize)
1236} 1236}
1237 1237
1238/* Record indexed key lookup. */ 1238/* Record indexed key lookup. */
1239static TRef rec_idx_key(jit_State *J, RecordIndex *ix, IRRef *rbref) 1239static TRef rec_idx_key(jit_State *J, RecordIndex *ix, IRRef *rbref,
1240 IRType1 *rbguard)
1240{ 1241{
1241 TRef key; 1242 TRef key;
1242 GCtab *t = tabV(&ix->tabv); 1243 GCtab *t = tabV(&ix->tabv);
1243 ix->oldv = lj_tab_get(J->L, t, &ix->keyv); /* Lookup previous value. */ 1244 ix->oldv = lj_tab_get(J->L, t, &ix->keyv); /* Lookup previous value. */
1244 *rbref = 0; 1245 *rbref = 0;
1246 rbguard->irt = 0;
1245 1247
1246 /* Integer keys are looked up in the array part first. */ 1248 /* Integer keys are looked up in the array part first. */
1247 key = ix->key; 1249 key = ix->key;
@@ -1293,6 +1295,7 @@ static TRef rec_idx_key(jit_State *J, RecordIndex *ix, IRRef *rbref)
1293 hslot <= 65535*(MSize)sizeof(Node)) { 1295 hslot <= 65535*(MSize)sizeof(Node)) {
1294 TRef node, kslot, hm; 1296 TRef node, kslot, hm;
1295 *rbref = J->cur.nins; /* Mark possible rollback point. */ 1297 *rbref = J->cur.nins; /* Mark possible rollback point. */
1298 *rbguard = J->guardemit;
1296 hm = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_HMASK); 1299 hm = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_HMASK);
1297 emitir(IRTGI(IR_EQ), hm, lj_ir_kint(J, (int32_t)t->hmask)); 1300 emitir(IRTGI(IR_EQ), hm, lj_ir_kint(J, (int32_t)t->hmask));
1298 node = emitir(IRT(IR_FLOAD, IRT_P32), ix->tab, IRFL_TAB_NODE); 1301 node = emitir(IRT(IR_FLOAD, IRT_P32), ix->tab, IRFL_TAB_NODE);
@@ -1327,6 +1330,7 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix)
1327 TRef xref; 1330 TRef xref;
1328 IROp xrefop, loadop; 1331 IROp xrefop, loadop;
1329 IRRef rbref; 1332 IRRef rbref;
1333 IRType1 rbguard;
1330 cTValue *oldv; 1334 cTValue *oldv;
1331 1335
1332 while (!tref_istab(ix->tab)) { /* Handle non-table lookup. */ 1336 while (!tref_istab(ix->tab)) { /* Handle non-table lookup. */
@@ -1373,7 +1377,7 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix)
1373 } 1377 }
1374 1378
1375 /* Record the key lookup. */ 1379 /* Record the key lookup. */
1376 xref = rec_idx_key(J, ix, &rbref); 1380 xref = rec_idx_key(J, ix, &rbref, &rbguard);
1377 xrefop = IR(tref_ref(xref))->o; 1381 xrefop = IR(tref_ref(xref))->o;
1378 loadop = xrefop == IR_AREF ? IR_ALOAD : IR_HLOAD; 1382 loadop = xrefop == IR_AREF ? IR_ALOAD : IR_HLOAD;
1379 /* The lj_meta_tset() inconsistency is gone, but better play safe. */ 1383 /* The lj_meta_tset() inconsistency is gone, but better play safe. */
@@ -1388,8 +1392,10 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix)
1388 } else { 1392 } else {
1389 res = emitir(IRTG(loadop, t), xref, 0); 1393 res = emitir(IRTG(loadop, t), xref, 0);
1390 } 1394 }
1391 if (tref_ref(res) < rbref) /* HREFK + load forwarded? */ 1395 if (tref_ref(res) < rbref) { /* HREFK + load forwarded? */
1392 lj_ir_rollback(J, rbref); /* Rollback to eliminate hmask guard. */ 1396 lj_ir_rollback(J, rbref); /* Rollback to eliminate hmask guard. */
1397 J->guardemit = rbguard;
1398 }
1393 if (t == IRT_NIL && ix->idxchain && lj_record_mm_lookup(J, ix, MM_index)) 1399 if (t == IRT_NIL && ix->idxchain && lj_record_mm_lookup(J, ix, MM_index))
1394 goto handlemm; 1400 goto handlemm;
1395 if (irtype_ispri(t)) res = TREF_PRI(t); /* Canonicalize primitives. */ 1401 if (irtype_ispri(t)) res = TREF_PRI(t); /* Canonicalize primitives. */
@@ -1397,8 +1403,10 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix)
1397 } else { /* Indexed store. */ 1403 } else { /* Indexed store. */
1398 GCtab *mt = tabref(tabV(&ix->tabv)->metatable); 1404 GCtab *mt = tabref(tabV(&ix->tabv)->metatable);
1399 int keybarrier = tref_isgcv(ix->key) && !tref_isnil(ix->val); 1405 int keybarrier = tref_isgcv(ix->key) && !tref_isnil(ix->val);
1400 if (tref_ref(xref) < rbref) /* HREFK forwarded? */ 1406 if (tref_ref(xref) < rbref) { /* HREFK forwarded? */
1401 lj_ir_rollback(J, rbref); /* Rollback to eliminate hmask guard. */ 1407 lj_ir_rollback(J, rbref); /* Rollback to eliminate hmask guard. */
1408 J->guardemit = rbguard;
1409 }
1402 if (tvisnil(oldv)) { /* Previous value was nil? */ 1410 if (tvisnil(oldv)) { /* Previous value was nil? */
1403 /* Need to duplicate the hasmm check for the early guards. */ 1411 /* Need to duplicate the hasmm check for the early guards. */
1404 int hasmm = 0; 1412 int hasmm = 0;