summaryrefslogtreecommitdiff
path: root/src/lgc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lgc.c')
-rw-r--r--src/lgc.c102
1 files changed, 50 insertions, 52 deletions
diff --git a/src/lgc.c b/src/lgc.c
index 74cacdae..84e8778d 100644
--- a/src/lgc.c
+++ b/src/lgc.c
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.c,v 2.183 2014/05/25 19:08:32 roberto Exp $
+** $Id: lgc.c,v 2.192 2014/07/29 16:22:24 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -62,10 +62,10 @@
*/
#define maskcolors (~(bitmask(BLACKBIT) | WHITEBITS))
#define makewhite(g,x) \
- (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g)))
+ (x->marked = cast_byte((x->marked & maskcolors) | luaC_white(g)))
-#define white2gray(x) resetbits(gch(x)->marked, WHITEBITS)
-#define black2gray(x) resetbit(gch(x)->marked, BLACKBIT)
+#define white2gray(x) resetbits(x->marked, WHITEBITS)
+#define black2gray(x) resetbit(x->marked, BLACKBIT)
#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x)))
@@ -81,7 +81,7 @@
if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }
#define markobject(g,t) \
- { if ((t) && iswhite(obj2gco(t))) reallymarkobject(g, obj2gco(t)); }
+ { if ((t) && iswhite(t)) reallymarkobject(g, obj2gco(t)); }
static void reallymarkobject (global_State *g, GCObject *o);
@@ -112,7 +112,7 @@ static void reallymarkobject (global_State *g, GCObject *o);
static void removeentry (Node *n) {
lua_assert(ttisnil(gval(n)));
if (valiswhite(gkey(n)))
- setdeadvalue(gkey(n)); /* unused and unmarked key; remove it */
+ setdeadvalue(wgkey(n)); /* unused and unmarked key; remove it */
}
@@ -126,7 +126,7 @@ static void removeentry (Node *n) {
static int iscleared (global_State *g, const TValue *o) {
if (!iscollectable(o)) return 0;
else if (ttisstring(o)) {
- markobject(g, rawtsvalue(o)); /* strings are `values', so are never weak */
+ markobject(g, tsvalue(o)); /* strings are `values', so are never weak */
return 0;
}
else return iswhite(gcvalue(o));
@@ -135,13 +135,13 @@ static int iscleared (global_State *g, const TValue *o) {
/*
** barrier that moves collector forward, that is, mark the white object
-** being pointed by a black object.
+** being pointed by a black object. (If in sweep phase, clear the black
+** object to white [sweep it] to avoid other barrier calls for this
+** same object.)
*/
void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) {
global_State *g = G(L);
lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
- lua_assert(g->gcstate != GCSpause);
- lua_assert(gch(o)->tt != LUA_TTABLE); /* tables use a back barrier */
if (keepinvariant(g)) /* must keep invariant? */
reallymarkobject(g, v); /* restore invariant */
else { /* sweep phase */
@@ -153,16 +153,14 @@ void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) {
/*
** barrier that moves collector backward, that is, mark the black object
-** pointing to a white object as gray again. (Current implementation
-** only works for tables; access to 'gclist' is not uniform across
-** different types.)
+** pointing to a white object as gray again.
*/
-void luaC_barrierback_ (lua_State *L, GCObject *o) {
+void luaC_barrierback_ (lua_State *L, Table *t) {
global_State *g = G(L);
- lua_assert(isblack(o) && !isdead(g, o) && gch(o)->tt == LUA_TTABLE);
- black2gray(o); /* make object gray (again) */
- gco2t(o)->gclist = g->grayagain;
- g->grayagain = o;
+ lua_assert(isblack(t) && !isdead(g, t));
+ black2gray(t); /* make table gray (again) */
+ t->gclist = g->grayagain;
+ g->grayagain = obj2gco(t);
}
@@ -185,8 +183,8 @@ void luaC_fix (lua_State *L, GCObject *o) {
global_State *g = G(L);
lua_assert(g->allgc == o); /* object must be 1st in 'allgc' list! */
white2gray(o); /* they will be gray forever */
- g->allgc = o->gch.next; /* remove object from 'allgc' list */
- o->gch.next = g->fixedgc; /* link it to 'fixedgc' list */
+ g->allgc = o->next; /* remove object from 'allgc' list */
+ o->next = g->fixedgc; /* link it to 'fixedgc' list */
g->fixedgc = o;
}
@@ -198,9 +196,9 @@ void luaC_fix (lua_State *L, GCObject *o) {
GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) {
global_State *g = G(L);
GCObject *o = cast(GCObject *, luaM_newobject(L, novariant(tt), sz));
- gch(o)->marked = luaC_white(g);
- gch(o)->tt = tt;
- gch(o)->next = g->allgc;
+ o->marked = luaC_white(g);
+ o->tt = tt;
+ o->next = g->allgc;
g->allgc = o;
return o;
}
@@ -225,7 +223,7 @@ GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) {
static void reallymarkobject (global_State *g, GCObject *o) {
reentry:
white2gray(o);
- switch (gch(o)->tt) {
+ switch (o->tt) {
case LUA_TSHRSTR:
case LUA_TLNGSTR: {
gray2black(o);
@@ -237,7 +235,7 @@ static void reallymarkobject (global_State *g, GCObject *o) {
markobject(g, gco2u(o)->metatable); /* mark its metatable */
gray2black(o);
g->GCmemtrav += sizeudata(gco2u(o));
- getuservalue(g->mainthread, rawgco2u(o), &uvalue);
+ getuservalue(g->mainthread, gco2u(o), &uvalue);
if (valiswhite(&uvalue)) { /* markvalue(g, &uvalue); */
o = gcvalue(&uvalue);
goto reentry;
@@ -288,7 +286,7 @@ static void markmt (global_State *g) {
*/
static void markbeingfnz (global_State *g) {
GCObject *o;
- for (o = g->tobefnz; o != NULL; o = gch(o)->next)
+ for (o = g->tobefnz; o != NULL; o = o->next)
markobject(g, o);
}
@@ -303,8 +301,8 @@ static void remarkupvals (global_State *g) {
lua_State *thread;
lua_State **p = &g->twups;
while ((thread = *p) != NULL) {
- lua_assert(!isblack(obj2gco(thread))); /* threads are never black */
- if (isgray(obj2gco(thread)) && thread->openupval != NULL)
+ lua_assert(!isblack(thread)); /* threads are never black */
+ if (isgray(thread) && thread->openupval != NULL)
p = &thread->twups; /* keep marked thread with upvalues in the list */
else { /* thread is not marked or without upvalues */
UpVal *uv;
@@ -429,7 +427,7 @@ static lu_mem traversetable (global_State *g, Table *h) {
((weakkey = strchr(svalue(mode), 'k')),
(weakvalue = strchr(svalue(mode), 'v')),
(weakkey || weakvalue))) { /* is really weak? */
- black2gray(obj2gco(h)); /* keep table gray */
+ black2gray(h); /* keep table gray */
if (!weakkey) /* strong keys? */
traverseweakvalue(g, h);
else if (!weakvalue) /* strong values? */
@@ -446,7 +444,7 @@ static lu_mem traversetable (global_State *g, Table *h) {
static int traverseproto (global_State *g, Proto *f) {
int i;
- if (f->cache && iswhite(obj2gco(f->cache)))
+ if (f->cache && iswhite(f->cache))
f->cache = NULL; /* allow cache to be collected */
markobject(g, f->source);
for (i = 0; i < f->sizek; i++) /* mark literals */
@@ -528,7 +526,7 @@ static void propagatemark (global_State *g) {
GCObject *o = g->gray;
lua_assert(isgray(o));
gray2black(o);
- switch (gch(o)->tt) {
+ switch (o->tt) {
case LUA_TTABLE: {
Table *h = gco2t(o);
g->gray = h->gclist; /* remove from 'gray' list */
@@ -685,7 +683,7 @@ static void freeLclosure (lua_State *L, LClosure *cl) {
static void freeobj (lua_State *L, GCObject *o) {
- switch (gch(o)->tt) {
+ switch (o->tt) {
case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
case LUA_TLCL: {
freeLclosure(L, gco2lcl(o));
@@ -699,7 +697,7 @@ static void freeobj (lua_State *L, GCObject *o) {
case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;
case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
case LUA_TSHRSTR:
- luaS_remove(L, rawgco2ts(o)); /* remove it from hash table */
+ luaS_remove(L, gco2ts(o)); /* remove it from hash table */
/* go through */
case LUA_TLNGSTR: {
luaM_freemem(L, o, sizestring(gco2ts(o)));
@@ -727,14 +725,14 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
int white = luaC_white(g); /* current white */
while (*p != NULL && count-- > 0) {
GCObject *curr = *p;
- int marked = gch(curr)->marked;
+ int marked = curr->marked;
if (isdeadm(ow, marked)) { /* is 'curr' dead? */
- *p = gch(curr)->next; /* remove 'curr' from list */
+ *p = curr->next; /* remove 'curr' from list */
freeobj(L, curr); /* erase 'curr' */
}
else { /* update marks */
- gch(curr)->marked = cast_byte((marked & maskcolors) | white);
- p = &gch(curr)->next; /* go to next element */
+ curr->marked = cast_byte((marked & maskcolors) | white);
+ p = &curr->next; /* go to next element */
}
}
return (*p == NULL) ? NULL : p;
@@ -781,10 +779,10 @@ static void checkSizes (lua_State *L, global_State *g) {
static GCObject *udata2finalize (global_State *g) {
GCObject *o = g->tobefnz; /* get first element */
lua_assert(tofinalize(o));
- g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */
- gch(o)->next = g->allgc; /* return it to 'allgc' list */
+ g->tobefnz = o->next; /* remove it from 'tobefnz' list */
+ o->next = g->allgc; /* return it to 'allgc' list */
g->allgc = o;
- resetbit(gch(o)->marked, FINALIZEDBIT); /* object is "normal" again */
+ resetbit(o->marked, FINALIZEDBIT); /* object is "normal" again */
if (issweepphase(g))
makewhite(g, o); /* "sweep" object */
return o;
@@ -859,7 +857,7 @@ static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
*/
static GCObject **findlast (GCObject **p) {
while (*p != NULL)
- p = &gch(*p)->next;
+ p = &(*p)->next;
return p;
}
@@ -875,12 +873,12 @@ static void separatetobefnz (global_State *g, int all) {
while ((curr = *p) != NULL) { /* traverse all finalizable objects */
lua_assert(tofinalize(curr));
if (!(iswhite(curr) || all)) /* not being collected? */
- p = &gch(curr)->next; /* don't bother with it */
+ p = &curr->next; /* don't bother with it */
else {
- *p = gch(curr)->next; /* remove 'curr' from "fin" list */
- gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */
+ *p = curr->next; /* remove 'curr' from "fin" list */
+ curr->next = *lastnext; /* link at the end of 'tobefnz' list */
*lastnext = curr;
- lastnext = &gch(curr)->next;
+ lastnext = &curr->next;
}
}
}
@@ -899,15 +897,15 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
GCObject **p;
if (issweepphase(g)) {
makewhite(g, o); /* "sweep" object 'o' */
- if (g->sweepgc == &o->gch.next) /* shoud not remove 'sweepgc' object */
+ if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */
g->sweepgc = sweeptolive(L, g->sweepgc, NULL); /* change 'sweepgc' */
}
/* search for pointer pointing to 'o' */
- for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ }
- *p = o->gch.next; /* remove 'o' from 'allgc' list */
- o->gch.next = g->finobj; /* link it in "fin" list */
+ for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ }
+ *p = o->next; /* remove 'o' from 'allgc' list */
+ o->next = g->finobj; /* link it in "fin" list */
g->finobj = o;
- l_setbit(o->gch.marked, FINALIZEDBIT); /* mark it as such */
+ l_setbit(o->marked, FINALIZEDBIT); /* mark it as such */
}
}
@@ -975,7 +973,7 @@ static l_mem atomic (lua_State *L) {
l_mem work;
GCObject *origweak, *origall;
g->GCmemtrav = 0; /* start counting work */
- lua_assert(!iswhite(obj2gco(g->mainthread)));
+ lua_assert(!iswhite(g->mainthread));
g->gcstate = GCSinsideatomic;
markobject(g, L); /* mark running thread */
/* registry and global metatables may be changed by API */
@@ -1066,7 +1064,7 @@ static lu_mem singlestep (lua_State *L) {
return sweepstep(L, g, GCSswpend, NULL);
}
case GCSswpend: { /* finish sweeps */
- makewhite(g, obj2gco(g->mainthread)); /* sweep main thread */
+ makewhite(g, g->mainthread); /* sweep main thread */
checkSizes(L, g);
g->gcstate = GCScallfin;
return 0;