summaryrefslogtreecommitdiff
path: root/src/lj_record.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_record.c')
-rw-r--r--src/lj_record.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/src/lj_record.c b/src/lj_record.c
index be5c618f..a593af99 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -187,6 +187,21 @@ int lj_record_objcmp(jit_State *J, TRef a, TRef b, cTValue *av, cTValue *bv)
187 return diff; 187 return diff;
188} 188}
189 189
190/* Constify a value. Returns 0 for non-representable object types. */
191TRef lj_record_constify(jit_State *J, cTValue *o)
192{
193 if (tvisgcv(o))
194 return lj_ir_kgc(J, gcV(o), itype2irt(o));
195 else if (tvisint(o))
196 return lj_ir_kint(J, intV(o));
197 else if (tvisnum(o))
198 return lj_ir_knumint(J, numV(o));
199 else if (tvisbool(o))
200 return TREF_PRI(itype2irt(o));
201 else
202 return 0; /* Can't represent lightuserdata (pointless). */
203}
204
190/* -- Record loop ops ----------------------------------------------------- */ 205/* -- Record loop ops ----------------------------------------------------- */
191 206
192/* Loop event. */ 207/* Loop event. */
@@ -569,8 +584,8 @@ static TRef rec_call_specialize(jit_State *J, GCfunc *fn, TRef tr)
569 TRef kfunc; 584 TRef kfunc;
570 if (isluafunc(fn)) { 585 if (isluafunc(fn)) {
571 GCproto *pt = funcproto(fn); 586 GCproto *pt = funcproto(fn);
572 /* 3 or more closures created? Probably not a monomorphic function. */ 587 /* Too many closures created? Probably not a monomorphic function. */
573 if (pt->flags >= 3*PROTO_CLCOUNT) { /* Specialize to prototype instead. */ 588 if (pt->flags >= PROTO_CLC_POLY) { /* Specialize to prototype instead. */
574 TRef trpt = emitir(IRT(IR_FLOAD, IRT_P32), tr, IRFL_FUNC_PC); 589 TRef trpt = emitir(IRT(IR_FLOAD, IRT_P32), tr, IRFL_FUNC_PC);
575 emitir(IRTG(IR_EQ, IRT_P32), trpt, lj_ir_kptr(J, proto_bc(pt))); 590 emitir(IRTG(IR_EQ, IRT_P32), trpt, lj_ir_kptr(J, proto_bc(pt)));
576 (void)lj_ir_kgc(J, obj2gco(pt), IRT_PROTO); /* Prevent GC of proto. */ 591 (void)lj_ir_kgc(J, obj2gco(pt), IRT_PROTO); /* Prevent GC of proto. */
@@ -1267,6 +1282,22 @@ static TRef rec_upvalue(jit_State *J, uint32_t uv, TRef val)
1267 TRef fn = getcurrf(J); 1282 TRef fn = getcurrf(J);
1268 IRRef uref; 1283 IRRef uref;
1269 int needbarrier = 0; 1284 int needbarrier = 0;
1285 if (uvp->immutable) { /* Try to constify immutable upvalue. */
1286 TRef tr, kfunc;
1287 lua_assert(val == 0);
1288 if (!tref_isk(fn)) { /* Late specialization of current function. */
1289 if (J->pt->flags >= PROTO_CLC_POLY)
1290 goto noconstify;
1291 kfunc = lj_ir_kfunc(J, J->fn);
1292 emitir(IRTG(IR_EQ, IRT_FUNC), fn, kfunc);
1293 J->base[-1] = TREF_FRAME | kfunc;
1294 fn = kfunc;
1295 }
1296 tr = lj_record_constify(J, uvval(uvp));
1297 if (tr)
1298 return tr;
1299 }
1300noconstify:
1270 /* Note: this effectively limits LJ_MAX_UPVAL to 127. */ 1301 /* Note: this effectively limits LJ_MAX_UPVAL to 127. */
1271 uv = (uv << 8) | (hashrot(uvp->dhash, uvp->dhash + HASH_BIAS) & 0xff); 1302 uv = (uv << 8) | (hashrot(uvp->dhash, uvp->dhash + HASH_BIAS) & 0xff);
1272 if (!uvp->closed) { 1303 if (!uvp->closed) {