diff options
Diffstat (limited to 'src/lj_record.c')
-rw-r--r-- | src/lj_record.c | 35 |
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. */ | ||
191 | TRef 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 | } | ||
1300 | noconstify: | ||
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) { |