From e8c779736f3029df353038352c14c8ab63728811 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 1 Nov 2018 13:21:00 -0300 Subject: Removed internal cache for closures The mechanism of "caching the last closure created for a prototype to try to reuse it the next time a closure for that prototype is created" was removed. There are several reasons: - It is hard to find a natural example where this cache has a measurable impact on performance. - Programmers already perceive closure creation as something slow, so they tend to avoid it inside hot paths. (Any case where the cache could reuse a closure can be rewritten predefining the closure in some variable and using that variable.) - The implementation was somewhat complex, due to a bad interaction with the generational collector. (Typically, new closures are new, while prototypes are old. So, the cache breaks the invariant that old objects should not point to new ones.) --- lvm.c | 39 ++------------------------------------- 1 file changed, 2 insertions(+), 37 deletions(-) (limited to 'lvm.c') diff --git a/lvm.c b/lvm.c index 1535700f..d9671055 100644 --- a/lvm.c +++ b/lvm.c @@ -683,31 +683,9 @@ lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) { } -/* -** check whether cached closure in prototype 'p' may be reused, that is, -** whether there is a cached closure with the same upvalues needed by -** new closure to be created. -*/ -static LClosure *getcached (Proto *p, UpVal **encup, StkId base) { - LClosure *c = p->cache; - if (c != NULL) { /* is there a cached closure? */ - int nup = p->sizeupvalues; - Upvaldesc *uv = p->upvalues; - int i; - for (i = 0; i < nup; i++) { /* check whether it has right upvalues */ - TValue *v = uv[i].instack ? s2v(base + uv[i].idx) : encup[uv[i].idx]->v; - if (c->upvals[i]->v != v) - return NULL; /* wrong upvalue; cannot reuse closure */ - } - p->cachemiss = 0; /* got a hit */ - } - return c; /* return cached closure (or NULL if no cached closure) */ -} - - /* ** create a new Lua closure, push it in the stack, and initialize -** its upvalues. ??? +** its upvalues. */ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, StkId ra) { @@ -724,13 +702,6 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, ncl->upvals[i] = encup[uv[i].idx]; luaC_objbarrier(L, ncl, ncl->upvals[i]); } - if (p->cachemiss >= MAXMISS) /* too many missings? */ - p->cache = NULL; /* give up cache */ - else { - p->cache = ncl; /* save it on cache for reuse */ - luaC_protobarrier(L, p, ncl); - p->cachemiss++; - } } @@ -1811,13 +1782,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { } vmcase(OP_CLOSURE) { Proto *p = cl->p->p[GETARG_Bx(i)]; - LClosure *ncl = getcached(p, cl->upvals, base); /* cached closure */ - if (ncl == NULL) { /* no match? */ - savestate(L, ci); /* in case of allocation errors */ - pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ - } - else - setclLvalue2s(L, ra, ncl); /* push cashed closure */ + halfProtect(pushclosure(L, p, cl->upvals, base, ra)); checkGC(L, ra + 1); vmbreak; } -- cgit v1.2.3-55-g6feb