From beb2aa5a46d0f0a8464f4045b1cfb790e97f08c7 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 12 Dec 2003 16:29:34 -0200 Subject: atomic operations are not GC "states" --- lgc.c | 122 +++++++++++++++++++++++++++++------------------------------------- 1 file changed, 54 insertions(+), 68 deletions(-) (limited to 'lgc.c') diff --git a/lgc.c b/lgc.c index 147593b0..fe6461c0 100644 --- a/lgc.c +++ b/lgc.c @@ -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 ** See Copyright Notice in lua.h */ @@ -22,7 +22,7 @@ #include "ltm.h" -#define GCSTEPSIZE (20*sizeof(TValue)) +#define GCSTEPSIZE (40*sizeof(TValue)) #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) { - lua_assert(iswhite(o)); - lua_assert(!isdead(g, o)); + lua_assert(iswhite(o) && !isdead(g, o)); white2gray(o); switch (o->gch.tt) { case LUA_TSTRING: { @@ -348,7 +347,6 @@ static l_mem propagatemarks (global_State *g, l_mem lim) { lim -= objsize(o); if (lim <= 0) return lim; } - g->gcstate = GCSatomic; return lim; } @@ -499,26 +497,22 @@ static void checkSizes (lua_State *L) { static void GCTM (lua_State *L) { global_State *g = G(L); - if (g->tmudata == NULL) - g->gcstate = GCSroot; /* will restart GC */ - else { - GCObject *o = g->tmudata; - Udata *udata = rawgco2u(o); - const TValue *tm; - g->tmudata = udata->uv.next; /* remove udata from `tmudata' */ - udata->uv.next = g->firstudata->uv.next; /* return it to `root' list */ - g->firstudata->uv.next = o; - makewhite(g, o); - tm = fasttm(L, udata->uv.metatable, TM_GC); - if (tm != NULL) { - lu_byte oldah = L->allowhook; - L->allowhook = 0; /* stop debug hooks during GC tag method */ - setobj2s(L, L->top, tm); - setuvalue(L, L->top+1, udata); - L->top += 2; - luaD_call(L, L->top - 2, 0); - L->allowhook = oldah; /* restore hooks */ - } + GCObject *o = g->tmudata; + Udata *udata = rawgco2u(o); + const TValue *tm; + g->tmudata = udata->uv.next; /* remove udata from `tmudata' */ + udata->uv.next = g->firstudata->uv.next; /* return it to `root' list */ + g->firstudata->uv.next = o; + makewhite(g, o); + tm = fasttm(L, udata->uv.metatable, TM_GC); + if (tm != NULL) { + lu_byte oldah = L->allowhook; + L->allowhook = 0; /* stop debug hooks during GC tag method */ + setobj2s(L, L->top, tm); + setuvalue(L, L->top+1, udata); + 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 */ static void markroot (lua_State *L) { global_State *g = G(L); - lua_assert(g->gray == NULL); + lua_assert(g->gray == NULL && g->grayagain == NULL); g->weak = NULL; makewhite(g, obj2gco(g->mainthread)); markobject(g, g->mainthread); @@ -555,8 +549,6 @@ static void markroot (lua_State *L) { static void atomic (lua_State *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); g->gray = g->grayagain; 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) { global_State *g = G(L); + l_mem lim = (g->nblocks - (g->GCthreshold - GCSTEPSIZE)) * 2; switch (g->gcstate) { - case GCSroot: - markroot(L); - break; - case GCSpropagate: - propagatemarks(g, GCSTEPSIZE); - break; - case GCSatomic: - atomic(L); + case GCSpropagate: { + if (g->gray) + lim = propagatemarks(g, lim); + else { /* no more `gray' objects */ + atomic(L); /* finish mark phase */ + lim = 0; + } break; - case GCSsweepstring: - sweepstringstep(L); + } + 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; - case GCSsweep: - sweepstep(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; - case GCSfinalize: - GCTM(L); + } + case GCSfinalize: { + if (g->tmudata) { + GCTM(L); + lim = 0; + } + else /* no more `udata' to finalize */ + markroot(L); /* may restart collection */ break; + } 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) { global_State *g = G(L); - lua_assert(isblack(o) && iswhite(v)); - lua_assert(!isdead(g, v) && !isdead(g, o)); - if (g->gcstate > GCSatomic) /* sweeping phases? */ + lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); + if (g->gcstate >= GCSsweepstring) /* sweeping phases? */ black2gray(o); /* just mark as gray to avoid other barriers */ else /* breaking invariant! */ reallymarkobject(g, v); /* restore it */ -- cgit v1.2.3-55-g6feb