atomic operations are not GC "states"

This commit is contained in:
Roberto Ierusalimschy 2003-12-12 16:29:34 -02:00
parent 47fc57a252
commit beb2aa5a46
3 changed files with 61 additions and 77 deletions

122
lgc.c
View File

@ -1,5 +1,5 @@
/* /*
** $Id: lgc.c,v 1.187 2003/12/09 16:56:11 roberto Exp roberto $ ** $Id: lgc.c,v 2.1 2003/12/10 12:13:36 roberto Exp roberto $
** Garbage Collector ** Garbage Collector
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -22,7 +22,7 @@
#include "ltm.h" #include "ltm.h"
#define GCSTEPSIZE (20*sizeof(TValue)) #define GCSTEPSIZE (40*sizeof(TValue))
#define gray2black(x) setbit((x)->gch.marked, BLACKBIT) #define gray2black(x) setbit((x)->gch.marked, BLACKBIT)
@ -104,8 +104,7 @@ static size_t objsize (GCObject *o) {
static void reallymarkobject (global_State *g, GCObject *o) { static void reallymarkobject (global_State *g, GCObject *o) {
lua_assert(iswhite(o)); lua_assert(iswhite(o) && !isdead(g, o));
lua_assert(!isdead(g, o));
white2gray(o); white2gray(o);
switch (o->gch.tt) { switch (o->gch.tt) {
case LUA_TSTRING: { case LUA_TSTRING: {
@ -348,7 +347,6 @@ static l_mem propagatemarks (global_State *g, l_mem lim) {
lim -= objsize(o); lim -= objsize(o);
if (lim <= 0) return lim; if (lim <= 0) return lim;
} }
g->gcstate = GCSatomic;
return lim; return lim;
} }
@ -499,26 +497,22 @@ static void checkSizes (lua_State *L) {
static void GCTM (lua_State *L) { static void GCTM (lua_State *L) {
global_State *g = G(L); global_State *g = G(L);
if (g->tmudata == NULL) GCObject *o = g->tmudata;
g->gcstate = GCSroot; /* will restart GC */ Udata *udata = rawgco2u(o);
else { const TValue *tm;
GCObject *o = g->tmudata; g->tmudata = udata->uv.next; /* remove udata from `tmudata' */
Udata *udata = rawgco2u(o); udata->uv.next = g->firstudata->uv.next; /* return it to `root' list */
const TValue *tm; g->firstudata->uv.next = o;
g->tmudata = udata->uv.next; /* remove udata from `tmudata' */ makewhite(g, o);
udata->uv.next = g->firstudata->uv.next; /* return it to `root' list */ tm = fasttm(L, udata->uv.metatable, TM_GC);
g->firstudata->uv.next = o; if (tm != NULL) {
makewhite(g, o); lu_byte oldah = L->allowhook;
tm = fasttm(L, udata->uv.metatable, TM_GC); L->allowhook = 0; /* stop debug hooks during GC tag method */
if (tm != NULL) { setobj2s(L, L->top, tm);
lu_byte oldah = L->allowhook; setuvalue(L, L->top+1, udata);
L->allowhook = 0; /* stop debug hooks during GC tag method */ L->top += 2;
setobj2s(L, L->top, tm); luaD_call(L, L->top - 2, 0);
setuvalue(L, L->top+1, udata); L->allowhook = oldah; /* restore hooks */
L->top += 2;
luaD_call(L, L->top - 2, 0);
L->allowhook = oldah; /* restore hooks */
}
} }
} }
@ -543,7 +537,7 @@ void luaC_sweepall (lua_State *L) {
/* mark root set */ /* mark root set */
static void markroot (lua_State *L) { static void markroot (lua_State *L) {
global_State *g = G(L); global_State *g = G(L);
lua_assert(g->gray == NULL); lua_assert(g->gray == NULL && g->grayagain == NULL);
g->weak = NULL; g->weak = NULL;
makewhite(g, obj2gco(g->mainthread)); makewhite(g, obj2gco(g->mainthread));
markobject(g, g->mainthread); markobject(g, g->mainthread);
@ -555,8 +549,6 @@ static void markroot (lua_State *L) {
static void atomic (lua_State *L) { static void atomic (lua_State *L) {
global_State *g = G(L); global_State *g = G(L);
/* there may be some gray elements due to the write barrier */
propagatemarks(g, MAXLMEM); /* traverse them */
lua_assert(g->gray == NULL); lua_assert(g->gray == NULL);
g->gray = g->grayagain; g->gray = g->grayagain;
g->grayagain = NULL; g->grayagain = NULL;
@ -577,60 +569,54 @@ static void atomic (lua_State *L) {
} }
static void sweepstringstep (lua_State *L) {
global_State *g = G(L);
l_mem lim = sweepstrings(L, 0, GCSTEPSIZE);
if (lim == GCSTEPSIZE) { /* nothing more to sweep? */
lua_assert(g->sweepstrgc > g->strt.size);
g->sweepstrgc = 0;
g->gcstate = GCSsweep; /* end sweep-string phase */
}
}
static void sweepstep (lua_State *L) {
global_State *g = G(L);
l_mem lim = GCSTEPSIZE;
g->sweepgc = sweeplist(L, g->sweepgc, 0, &lim);
if (lim == GCSTEPSIZE) { /* nothing more to sweep? */
g->gcstate = GCSfinalize; /* end sweep phase */
checkSizes(L);
}
}
void luaC_step (lua_State *L) { void luaC_step (lua_State *L) {
global_State *g = G(L); global_State *g = G(L);
l_mem lim = (g->nblocks - (g->GCthreshold - GCSTEPSIZE)) * 2;
switch (g->gcstate) { switch (g->gcstate) {
case GCSroot: case GCSpropagate: {
markroot(L); if (g->gray)
lim = propagatemarks(g, lim);
else { /* no more `gray' objects */
atomic(L); /* finish mark phase */
lim = 0;
}
break; break;
case GCSpropagate: }
propagatemarks(g, GCSTEPSIZE); case GCSsweepstring: {
lim = sweepstrings(L, 0, lim);
if (g->sweepstrgc >= g->strt.size) { /* nothing more to sweep? */
g->sweepstrgc = 0;
g->gcstate = GCSsweep; /* end sweep-string phase */
}
break; break;
case GCSatomic: }
atomic(L); case GCSsweep: {
g->sweepgc = sweeplist(L, g->sweepgc, 0, &lim);
if (*g->sweepgc == NULL) { /* nothing more to sweep? */
g->gcstate = GCSfinalize; /* end sweep phase */
checkSizes(L);
}
break; break;
case GCSsweepstring: }
sweepstringstep(L); case GCSfinalize: {
break; if (g->tmudata) {
case GCSsweep: GCTM(L);
sweepstep(L); lim = 0;
break; }
case GCSfinalize: else /* no more `udata' to finalize */
GCTM(L); markroot(L); /* may restart collection */
break; break;
}
default: lua_assert(0); default: lua_assert(0);
} }
g->GCthreshold = g->nblocks + GCSTEPSIZE; g->GCthreshold = g->nblocks + GCSTEPSIZE - lim/2;
} }
void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
global_State *g = G(L); global_State *g = G(L);
lua_assert(isblack(o) && iswhite(v)); lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
lua_assert(!isdead(g, v) && !isdead(g, o)); if (g->gcstate >= GCSsweepstring) /* sweeping phases? */
if (g->gcstate > GCSatomic) /* sweeping phases? */
black2gray(o); /* just mark as gray to avoid other barriers */ black2gray(o); /* just mark as gray to avoid other barriers */
else /* breaking invariant! */ else /* breaking invariant! */
reallymarkobject(g, v); /* restore it */ reallymarkobject(g, v); /* restore it */

12
lgc.h
View File

@ -1,5 +1,5 @@
/* /*
** $Id: lgc.h,v 1.28 2003/12/09 16:56:11 roberto Exp roberto $ ** $Id: lgc.h,v 2.1 2003/12/10 12:13:36 roberto Exp roberto $
** Garbage Collector ** Garbage Collector
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -14,12 +14,10 @@
/* /*
** Possible states of the Garbage Collector ** Possible states of the Garbage Collector
*/ */
#define GCSroot 0 #define GCSpropagate 0
#define GCSpropagate 1 #define GCSsweepstring 1
#define GCSatomic 2 #define GCSsweep 2
#define GCSsweepstring 3 #define GCSfinalize 3
#define GCSsweep 4
#define GCSfinalize 5
/* /*

View File

@ -1,5 +1,5 @@
/* /*
** $Id: lstate.c,v 1.134 2003/12/04 18:52:23 roberto Exp roberto $ ** $Id: lstate.c,v 2.1 2003/12/10 12:13:36 roberto Exp roberto $
** Global State ** Global State
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -167,7 +167,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
setnilvalue(registry(L)); setnilvalue(registry(L));
luaZ_initbuffer(L, &g->buff); luaZ_initbuffer(L, &g->buff);
g->panic = NULL; g->panic = NULL;
g->gcstate = 0; g->gcstate = GCSfinalize;
g->rootgc = NULL; g->rootgc = NULL;
g->sweepstrgc = 0; g->sweepstrgc = 0;
g->currentwhite = bitmask(WHITE0BIT); g->currentwhite = bitmask(WHITE0BIT);