Browse Source

"barrier" for link prototype->cache changed to be consistent with

GC behavior (link is cleared to preserve invariant)
pull/9/head
Roberto Ierusalimschy 11 years ago
parent
commit
9eff921f8f
  1. 24
      lgc.c
  2. 5
      lgc.h
  3. 12
      lvm.c

24
lgc.c

@ -1,5 +1,5 @@
/* /*
** $Id: lgc.c,v 2.145 2013/08/13 17:36:44 roberto Exp roberto $ ** $Id: lgc.c,v 2.146 2013/08/16 18:55:49 roberto Exp roberto $
** Garbage Collector ** Garbage Collector
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -171,28 +171,6 @@ void luaC_barrierback_ (lua_State *L, GCObject *o) {
} }
/*
** barrier for prototypes. When creating first closure (cache is
** NULL), use a forward barrier; this may be the only closure of the
** prototype (if it is a "regular" function, with a single instance)
** and the prototype may be big, so it is better to avoid traversing
** it again. Otherwise, use a backward barrier, to avoid marking all
** possible instances.
*/
LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c) {
global_State *g = G(L);
lua_assert(isblack(obj2gco(p)));
if (p->cache == NULL) { /* first time? */
luaC_objbarrier(L, p, c);
}
else { /* use a backward barrier */
black2gray(obj2gco(p)); /* make prototype gray (again) */
p->gclist = g->grayagain;
g->grayagain = obj2gco(p);
}
}
/* /*
** check color (and invariants) for an upvalue that is being closed, ** check color (and invariants) for an upvalue that is being closed,
** i.e., moved into the 'allgc' list ** i.e., moved into the 'allgc' list

5
lgc.h

@ -1,5 +1,5 @@
/* /*
** $Id: lgc.h,v 2.60 2013/08/13 17:36:44 roberto Exp roberto $ ** $Id: lgc.h,v 2.61 2013/08/16 18:55:49 roberto Exp roberto $
** Garbage Collector ** Garbage Collector
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -128,9 +128,6 @@
{ if (nolocal(obj2gco(o)), isblack(obj2gco(p)) && iswhite(obj2gco(o))) \ { if (nolocal(obj2gco(o)), isblack(obj2gco(p)) && iswhite(obj2gco(o))) \
luaC_barrierback_(L,p); } luaC_barrierback_(L,p); }
#define luaC_barrierproto(L,p,c) \
{ if (nolocal(obj2gco(c)), isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); }
LUAI_FUNC void luaC_freeallobjects (lua_State *L); LUAI_FUNC void luaC_freeallobjects (lua_State *L);
LUAI_FUNC void luaC_step (lua_State *L); LUAI_FUNC void luaC_step (lua_State *L);
LUAI_FUNC void luaC_forcestep (lua_State *L); LUAI_FUNC void luaC_forcestep (lua_State *L);

12
lvm.c

@ -1,5 +1,5 @@
/* /*
** $Id: lvm.c,v 2.176 2013/07/10 17:15:12 roberto Exp roberto $ ** $Id: lvm.c,v 2.177 2013/08/16 18:55:49 roberto Exp roberto $
** Lua virtual machine ** Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -399,9 +399,9 @@ static Closure *getcached (Proto *p, UpVal **encup, StkId base) {
/* /*
** create a new Lua closure, push it in the stack, and initialize ** create a new Lua closure, push it in the stack, and initialize
** its upvalues. Note that the call to 'luaC_barrierproto' must come ** its upvalues. Note that the closure is not cached if prototype is
** before the assignment to 'p->cache', as the function needs the ** already black (which means that 'cache' was already cleared by the
** original value of that field. ** GC).
*/ */
static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
StkId ra) { StkId ra) {
@ -418,8 +418,8 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
ncl->l.upvals[i] = encup[uv[i].idx]; ncl->l.upvals[i] = encup[uv[i].idx];
/* new closure is white and local, so we do not need a barrier here */ /* new closure is white and local, so we do not need a barrier here */
} }
luaC_barrierproto(L, p, ncl); if (!isblack(obj2gco(p))) /* cache will not break GC invariant? */
p->cache = ncl; /* save it on cache for reuse */ p->cache = ncl; /* save it on cache for reuse */
} }

Loading…
Cancel
Save