diff --git a/lfunc.c b/lfunc.c index 898104ac..5c6ebd27 100644 --- a/lfunc.c +++ b/lfunc.c @@ -1,5 +1,5 @@ /* -** $Id: lfunc.c,v 2.46 2017/04/06 13:08:56 roberto Exp roberto $ +** $Id: lfunc.c,v 2.47 2017/04/11 18:41:09 roberto Exp roberto $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ @@ -115,6 +115,7 @@ Proto *luaF_newproto (lua_State *L) { f->sizep = 0; f->code = NULL; f->cache = NULL; + f->cachemiss = 0; f->sizecode = 0; f->lineinfo = NULL; f->sizelineinfo = 0; diff --git a/lgc.c b/lgc.c index 692326f3..65f4909c 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.225 2017/04/24 16:59:26 roberto Exp $ +** $Id: lgc.c,v 2.226 2017/04/24 17:52:18 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -485,6 +485,7 @@ static int traverseproto (global_State *g, Proto *f) { int i; if (f->cache && iswhite(f->cache)) f->cache = NULL; /* allow cache to be collected */ + f->cachemiss = 0; /* restart counting */ markobjectN(g, f->source); for (i = 0; i < f->sizek; i++) /* mark literals */ markvalue(g, &f->k[i]); diff --git a/lobject.h b/lobject.h index c8f9adb3..f8a73a14 100644 --- a/lobject.h +++ b/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 2.118 2017/04/11 18:41:09 roberto Exp roberto $ +** $Id: lobject.h,v 2.119 2017/04/24 18:06:12 roberto Exp roberto $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -410,6 +410,7 @@ typedef struct Proto { lu_byte numparams; /* number of fixed parameters */ lu_byte is_vararg; lu_byte maxstacksize; /* number of registers needed by this function */ + lu_byte cachemiss; /* count for successive misses for 'cache' field */ int sizeupvalues; /* size of 'upvalues' */ int sizek; /* size of 'k' */ int sizecode; diff --git a/lvm.c b/lvm.c index 9fa9daf5..744ca6dd 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 2.273 2017/04/26 17:46:52 roberto Exp roberto $ +** $Id: lvm.c,v 2.274 2017/04/28 20:57:45 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -618,6 +618,7 @@ static LClosure *getcached (Proto *p, UpVal **encup, StkId base) { 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) */ } @@ -644,8 +645,13 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, ncl->upvals[i] = encup[uv[i].idx]; /* new closure is white, so we do not need a barrier here */ } - if (!isblack(p)) /* cache will not break GC invariant? */ - p->cache = ncl; /* save it on cache for reuse */ + if (p->cachemiss >= 10) /* too many missings? */ + p->cache = NULL; /* give up cache */ + else { + if (!isblack(p)) /* cache will not break GC invariant? */ + p->cache = ncl; /* save it on cache for reuse */ + p->cachemiss++; + } }