no need for field 'gch' anymore

This commit is contained in:
Roberto Ierusalimschy
2014-07-17 14:27:49 -03:00
parent 5a9cc57a5e
commit 9aec500a26
5 changed files with 71 additions and 81 deletions

64
lgc.c
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lgc.c,v 2.183 2014/05/25 19:08:32 roberto Exp roberto $ ** $Id: lgc.c,v 2.184 2014/06/30 19:48:08 roberto Exp roberto $
** Garbage Collector ** Garbage Collector
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -62,10 +62,10 @@
*/ */
#define maskcolors (~(bitmask(BLACKBIT) | WHITEBITS)) #define maskcolors (~(bitmask(BLACKBIT) | WHITEBITS))
#define makewhite(g,x) \ #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 white2gray(x) resetbits(x->marked, WHITEBITS)
#define black2gray(x) resetbit(gch(x)->marked, BLACKBIT) #define black2gray(x) resetbit(x->marked, BLACKBIT)
#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x)))
@@ -141,7 +141,7 @@ void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) {
global_State *g = G(L); global_State *g = G(L);
lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
lua_assert(g->gcstate != GCSpause); lua_assert(g->gcstate != GCSpause);
lua_assert(gch(o)->tt != LUA_TTABLE); /* tables use a back barrier */ lua_assert(o->tt != LUA_TTABLE); /* tables use a back barrier */
if (keepinvariant(g)) /* must keep invariant? */ if (keepinvariant(g)) /* must keep invariant? */
reallymarkobject(g, v); /* restore invariant */ reallymarkobject(g, v); /* restore invariant */
else { /* sweep phase */ else { /* sweep phase */
@@ -159,7 +159,7 @@ void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) {
*/ */
void luaC_barrierback_ (lua_State *L, GCObject *o) { void luaC_barrierback_ (lua_State *L, GCObject *o) {
global_State *g = G(L); global_State *g = G(L);
lua_assert(isblack(o) && !isdead(g, o) && gch(o)->tt == LUA_TTABLE); lua_assert(isblack(o) && !isdead(g, o) && o->tt == LUA_TTABLE);
black2gray(o); /* make object gray (again) */ black2gray(o); /* make object gray (again) */
gco2t(o)->gclist = g->grayagain; gco2t(o)->gclist = g->grayagain;
g->grayagain = o; g->grayagain = o;
@@ -185,8 +185,8 @@ void luaC_fix (lua_State *L, GCObject *o) {
global_State *g = G(L); global_State *g = G(L);
lua_assert(g->allgc == o); /* object must be 1st in 'allgc' list! */ lua_assert(g->allgc == o); /* object must be 1st in 'allgc' list! */
white2gray(o); /* they will be gray forever */ white2gray(o); /* they will be gray forever */
g->allgc = o->gch.next; /* remove object from 'allgc' list */ g->allgc = o->next; /* remove object from 'allgc' list */
o->gch.next = g->fixedgc; /* link it to 'fixedgc' list */ o->next = g->fixedgc; /* link it to 'fixedgc' list */
g->fixedgc = o; g->fixedgc = o;
} }
@@ -198,9 +198,9 @@ void luaC_fix (lua_State *L, GCObject *o) {
GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) { GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) {
global_State *g = G(L); global_State *g = G(L);
GCObject *o = cast(GCObject *, luaM_newobject(L, novariant(tt), sz)); GCObject *o = cast(GCObject *, luaM_newobject(L, novariant(tt), sz));
gch(o)->marked = luaC_white(g); o->marked = luaC_white(g);
gch(o)->tt = tt; o->tt = tt;
gch(o)->next = g->allgc; o->next = g->allgc;
g->allgc = o; g->allgc = o;
return o; return o;
} }
@@ -225,7 +225,7 @@ GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) {
static void reallymarkobject (global_State *g, GCObject *o) { static void reallymarkobject (global_State *g, GCObject *o) {
reentry: reentry:
white2gray(o); white2gray(o);
switch (gch(o)->tt) { switch (o->tt) {
case LUA_TSHRSTR: case LUA_TSHRSTR:
case LUA_TLNGSTR: { case LUA_TLNGSTR: {
gray2black(o); gray2black(o);
@@ -288,7 +288,7 @@ static void markmt (global_State *g) {
*/ */
static void markbeingfnz (global_State *g) { static void markbeingfnz (global_State *g) {
GCObject *o; GCObject *o;
for (o = g->tobefnz; o != NULL; o = gch(o)->next) for (o = g->tobefnz; o != NULL; o = o->next)
markobject(g, o); markobject(g, o);
} }
@@ -528,7 +528,7 @@ static void propagatemark (global_State *g) {
GCObject *o = g->gray; GCObject *o = g->gray;
lua_assert(isgray(o)); lua_assert(isgray(o));
gray2black(o); gray2black(o);
switch (gch(o)->tt) { switch (o->tt) {
case LUA_TTABLE: { case LUA_TTABLE: {
Table *h = gco2t(o); Table *h = gco2t(o);
g->gray = h->gclist; /* remove from 'gray' list */ g->gray = h->gclist; /* remove from 'gray' list */
@@ -685,7 +685,7 @@ static void freeLclosure (lua_State *L, LClosure *cl) {
static void freeobj (lua_State *L, GCObject *o) { 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_TPROTO: luaF_freeproto(L, gco2p(o)); break;
case LUA_TLCL: { case LUA_TLCL: {
freeLclosure(L, gco2lcl(o)); freeLclosure(L, gco2lcl(o));
@@ -727,14 +727,14 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
int white = luaC_white(g); /* current white */ int white = luaC_white(g); /* current white */
while (*p != NULL && count-- > 0) { while (*p != NULL && count-- > 0) {
GCObject *curr = *p; GCObject *curr = *p;
int marked = gch(curr)->marked; int marked = curr->marked;
if (isdeadm(ow, marked)) { /* is 'curr' dead? */ 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' */ freeobj(L, curr); /* erase 'curr' */
} }
else { /* update marks */ else { /* update marks */
gch(curr)->marked = cast_byte((marked & maskcolors) | white); curr->marked = cast_byte((marked & maskcolors) | white);
p = &gch(curr)->next; /* go to next element */ p = &curr->next; /* go to next element */
} }
} }
return (*p == NULL) ? NULL : p; return (*p == NULL) ? NULL : p;
@@ -781,10 +781,10 @@ static void checkSizes (lua_State *L, global_State *g) {
static GCObject *udata2finalize (global_State *g) { static GCObject *udata2finalize (global_State *g) {
GCObject *o = g->tobefnz; /* get first element */ GCObject *o = g->tobefnz; /* get first element */
lua_assert(tofinalize(o)); lua_assert(tofinalize(o));
g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */ g->tobefnz = o->next; /* remove it from 'tobefnz' list */
gch(o)->next = g->allgc; /* return it to 'allgc' list */ o->next = g->allgc; /* return it to 'allgc' list */
g->allgc = o; g->allgc = o;
resetbit(gch(o)->marked, FINALIZEDBIT); /* object is "normal" again */ resetbit(o->marked, FINALIZEDBIT); /* object is "normal" again */
if (issweepphase(g)) if (issweepphase(g))
makewhite(g, o); /* "sweep" object */ makewhite(g, o); /* "sweep" object */
return o; return o;
@@ -859,7 +859,7 @@ static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
*/ */
static GCObject **findlast (GCObject **p) { static GCObject **findlast (GCObject **p) {
while (*p != NULL) while (*p != NULL)
p = &gch(*p)->next; p = &(*p)->next;
return p; return p;
} }
@@ -875,12 +875,12 @@ static void separatetobefnz (global_State *g, int all) {
while ((curr = *p) != NULL) { /* traverse all finalizable objects */ while ((curr = *p) != NULL) { /* traverse all finalizable objects */
lua_assert(tofinalize(curr)); lua_assert(tofinalize(curr));
if (!(iswhite(curr) || all)) /* not being collected? */ 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 { else {
*p = gch(curr)->next; /* remove 'curr' from "fin" list */ *p = curr->next; /* remove 'curr' from "fin" list */
gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */ curr->next = *lastnext; /* link at the end of 'tobefnz' list */
*lastnext = curr; *lastnext = curr;
lastnext = &gch(curr)->next; lastnext = &curr->next;
} }
} }
} }
@@ -899,15 +899,15 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
GCObject **p; GCObject **p;
if (issweepphase(g)) { if (issweepphase(g)) {
makewhite(g, o); /* "sweep" object 'o' */ makewhite(g, o); /* "sweep" object 'o' */
if (g->sweepgc == &o->gch.next) /* should not remove 'sweepgc' object */ if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */
g->sweepgc = sweeptolive(L, g->sweepgc, NULL); /* change 'sweepgc' */ g->sweepgc = sweeptolive(L, g->sweepgc, NULL); /* change 'sweepgc' */
} }
/* search for pointer pointing to 'o' */ /* search for pointer pointing to 'o' */
for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ } for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ }
*p = o->gch.next; /* remove 'o' from 'allgc' list */ *p = o->next; /* remove 'o' from 'allgc' list */
o->gch.next = g->finobj; /* link it in "fin" list */ o->next = g->finobj; /* link it in "fin" list */
g->finobj = o; g->finobj = o;
l_setbit(o->gch.marked, FINALIZEDBIT); /* mark it as such */ l_setbit(o->marked, FINALIZEDBIT); /* mark it as such */
} }
} }

16
lgc.h
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lgc.h,v 2.81 2014/02/18 13:46:26 roberto Exp roberto $ ** $Id: lgc.h,v 2.82 2014/03/19 18:51:16 roberto Exp roberto $
** Garbage Collector ** Garbage Collector
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -84,19 +84,19 @@
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
#define iswhite(x) testbits((x)->gch.marked, WHITEBITS) #define iswhite(x) testbits((x)->marked, WHITEBITS)
#define isblack(x) testbit((x)->gch.marked, BLACKBIT) #define isblack(x) testbit((x)->marked, BLACKBIT)
#define isgray(x) /* neither white nor black */ \ #define isgray(x) /* neither white nor black */ \
(!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT))) (!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT)))
#define tofinalize(x) testbit((x)->gch.marked, FINALIZEDBIT) #define tofinalize(x) testbit((x)->marked, FINALIZEDBIT)
#define otherwhite(g) ((g)->currentwhite ^ WHITEBITS) #define otherwhite(g) ((g)->currentwhite ^ WHITEBITS)
#define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow))) #define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow)))
#define isdead(g,v) isdeadm(otherwhite(g), (v)->gch.marked) #define isdead(g,v) isdeadm(otherwhite(g), (v)->marked)
#define changewhite(x) ((x)->gch.marked ^= WHITEBITS) #define changewhite(x) ((x)->marked ^= WHITEBITS)
#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) #define gray2black(x) l_setbit((x)->marked, BLACKBIT)
#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)

View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lobject.h,v 2.94 2014/06/19 18:39:36 roberto Exp roberto $ ** $Id: lobject.h,v 2.95 2014/07/17 17:09:50 roberto Exp roberto $
** Type definitions for Lua objects ** Type definitions for Lua objects
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -85,9 +85,7 @@ typedef struct GCObject GCObject;
** Common type has only the common header ** Common type has only the common header
*/ */
struct GCObject { struct GCObject {
struct { CommonHeader;
CommonHeader;
} gch;
}; };
@@ -179,7 +177,7 @@ typedef struct lua_TValue TValue;
/* Macros for internal tests */ /* Macros for internal tests */
#define righttt(obj) (ttype(obj) == gcvalue(obj)->gch.tt) #define righttt(obj) (ttype(obj) == gcvalue(obj)->tt)
#define checkliveness(g,obj) \ #define checkliveness(g,obj) \
lua_longassert(!iscollectable(obj) || \ lua_longassert(!iscollectable(obj) || \
@@ -208,7 +206,7 @@ typedef struct lua_TValue TValue;
#define setgcovalue(L,obj,x) \ #define setgcovalue(L,obj,x) \
{ TValue *io = (obj); GCObject *i_g=(x); \ { TValue *io = (obj); GCObject *i_g=(x); \
val_(io).gc = i_g; settt_(io, ctb(gch(i_g)->tt)); } val_(io).gc = i_g; settt_(io, ctb(i_g->tt)); }
#define setsvalue(L,obj,x) \ #define setsvalue(L,obj,x) \
{ TValue *io = (obj); TString *x_ = (x); \ { TValue *io = (obj); TString *x_ = (x); \

View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lstate.h,v 2.108 2014/07/17 13:53:37 roberto Exp roberto $ ** $Id: lstate.h,v 2.109 2014/07/17 17:09:50 roberto Exp roberto $
** Global State ** Global State
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -183,29 +183,21 @@ union GCUnion {
}; };
#define gch(o) (&(o)->gch)
#define cast_u(o) cast(union GCUnion *, (o)) #define cast_u(o) cast(union GCUnion *, (o))
/* macros to convert a GCObject into a specific value */ /* macros to convert a GCObject into a specific value */
#define rawgco2ts(o) \ #define rawgco2ts(o) \
check_exp(novariant((o)->gch.tt) == LUA_TSTRING, &((cast_u(o))->ts)) check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts))
#define gco2ts(o) (&rawgco2ts(o)->tsv) #define gco2ts(o) (&rawgco2ts(o)->tsv)
#define rawgco2u(o) \ #define rawgco2u(o) check_exp((o)->tt == LUA_TUSERDATA, &((cast_u(o))->u))
check_exp((o)->gch.tt == LUA_TUSERDATA, &((cast_u(o))->u))
#define gco2u(o) (&rawgco2u(o)->uv) #define gco2u(o) (&rawgco2u(o)->uv)
#define gco2lcl(o) \ #define gco2lcl(o) check_exp((o)->tt == LUA_TLCL, &((cast_u(o))->cl.l))
check_exp((o)->gch.tt == LUA_TLCL, &((cast_u(o))->cl.l)) #define gco2ccl(o) check_exp((o)->tt == LUA_TCCL, &((cast_u(o))->cl.c))
#define gco2ccl(o) \
check_exp((o)->gch.tt == LUA_TCCL, &((cast_u(o))->cl.c))
#define gco2cl(o) \ #define gco2cl(o) \
check_exp(novariant((o)->gch.tt) == LUA_TFUNCTION, &((cast_u(o))->cl)) check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl))
#define gco2t(o) \ #define gco2t(o) check_exp((o)->tt == LUA_TTABLE, &((cast_u(o))->h))
check_exp((o)->gch.tt == LUA_TTABLE, &((cast_u(o))->h)) #define gco2p(o) check_exp((o)->tt == LUA_TPROTO, &((cast_u(o))->p))
#define gco2p(o) \ #define gco2th(o) check_exp((o)->tt == LUA_TTHREAD, &((cast_u(o))->th))
check_exp((o)->gch.tt == LUA_TPROTO, &((cast_u(o))->p))
#define gco2th(o) \
check_exp((o)->gch.tt == LUA_TTHREAD, &((cast_u(o))->th))
/* macro to convert any Lua object into a GCObject */ /* macro to convert any Lua object into a GCObject */

View File

@@ -1,5 +1,5 @@
/* /*
** $Id: ltests.c,v 2.175 2014/07/16 14:51:36 roberto Exp roberto $ ** $Id: ltests.c,v 2.176 2014/07/17 13:53:37 roberto Exp roberto $
** Internal Module for Debugging of the Lua Implementation ** Internal Module for Debugging of the Lua Implementation
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -190,8 +190,8 @@ static int testobjref1 (global_State *g, GCObject *f, GCObject *t) {
static void printobj (global_State *g, GCObject *o) { static void printobj (global_State *g, GCObject *o) {
printf("||%s(%p)-%c(%02X)||", printf("||%s(%p)-%c(%02X)||",
ttypename(novariant(gch(o)->tt)), (void *)o, ttypename(novariant(o->tt)), (void *)o,
isdead(g,o)?'d':isblack(o)?'b':iswhite(o)?'w':'g', gch(o)->marked); isdead(g,o)?'d':isblack(o)?'b':iswhite(o)?'w':'g', o->marked);
} }
@@ -316,7 +316,7 @@ static void checkobject (global_State *g, GCObject *o, int maybedead) {
lua_assert(maybedead); lua_assert(maybedead);
else { else {
lua_assert(g->gcstate != GCSpause || iswhite(o)); lua_assert(g->gcstate != GCSpause || iswhite(o));
switch (gch(o)->tt) { switch (o->tt) {
case LUA_TUSERDATA: { case LUA_TUSERDATA: {
TValue uservalue; TValue uservalue;
Table *mt = gco2u(o)->metatable; Table *mt = gco2u(o)->metatable;
@@ -362,9 +362,9 @@ static void checkgraylist (global_State *g, GCObject *o) {
((void)g); /* better to keep it available if we need to print an object */ ((void)g); /* better to keep it available if we need to print an object */
while (o) { while (o) {
lua_assert(isgray(o)); lua_assert(isgray(o));
lua_assert(!testbit(o->gch.marked, TESTGRAYBIT)); lua_assert(!testbit(o->marked, TESTGRAYBIT));
l_setbit(o->gch.marked, TESTGRAYBIT); l_setbit(o->marked, TESTGRAYBIT);
switch (gch(o)->tt) { switch (o->tt) {
case LUA_TTABLE: o = gco2t(o)->gclist; break; case LUA_TTABLE: o = gco2t(o)->gclist; break;
case LUA_TLCL: o = gco2lcl(o)->gclist; break; case LUA_TLCL: o = gco2lcl(o)->gclist; break;
case LUA_TCCL: o = gco2ccl(o)->gclist; break; case LUA_TCCL: o = gco2ccl(o)->gclist; break;
@@ -391,12 +391,12 @@ static void markgrays (global_State *g) {
static void checkgray (global_State *g, GCObject *o) { static void checkgray (global_State *g, GCObject *o) {
for (; o != NULL; o = gch(o)->next) { for (; o != NULL; o = o->next) {
if (isgray(o)) { if (isgray(o)) {
lua_assert(!keepinvariant(g) || testbit(o->gch.marked, TESTGRAYBIT)); lua_assert(!keepinvariant(g) || testbit(o->marked, TESTGRAYBIT));
resetbit(o->gch.marked, TESTGRAYBIT); resetbit(o->marked, TESTGRAYBIT);
} }
lua_assert(!testbit(o->gch.marked, TESTGRAYBIT)); lua_assert(!testbit(o->marked, TESTGRAYBIT));
} }
} }
@@ -415,29 +415,29 @@ int lua_checkmemory (lua_State *L) {
lua_assert(g->sweepgc == NULL || issweepphase(g)); lua_assert(g->sweepgc == NULL || issweepphase(g));
markgrays(g); markgrays(g);
/* check 'fixedgc' list */ /* check 'fixedgc' list */
for (o = g->fixedgc; o != NULL; o = gch(o)->next) { for (o = g->fixedgc; o != NULL; o = o->next) {
lua_assert(gch(o)->tt == LUA_TSHRSTR && isgray(o)); lua_assert(o->tt == LUA_TSHRSTR && isgray(o));
} }
/* check 'allgc' list */ /* check 'allgc' list */
checkgray(g, g->allgc); checkgray(g, g->allgc);
maybedead = (GCSatomic < g->gcstate && g->gcstate <= GCSswpallgc); maybedead = (GCSatomic < g->gcstate && g->gcstate <= GCSswpallgc);
for (o = g->allgc; o != NULL; o = gch(o)->next) { for (o = g->allgc; o != NULL; o = o->next) {
checkobject(g, o, maybedead); checkobject(g, o, maybedead);
lua_assert(!tofinalize(o)); lua_assert(!tofinalize(o));
} }
/* check 'finobj' list */ /* check 'finobj' list */
checkgray(g, g->finobj); checkgray(g, g->finobj);
for (o = g->finobj; o != NULL; o = gch(o)->next) { for (o = g->finobj; o != NULL; o = o->next) {
checkobject(g, o, 0); checkobject(g, o, 0);
lua_assert(tofinalize(o)); lua_assert(tofinalize(o));
lua_assert(gch(o)->tt == LUA_TUSERDATA || gch(o)->tt == LUA_TTABLE); lua_assert(o->tt == LUA_TUSERDATA || o->tt == LUA_TTABLE);
} }
/* check 'tobefnz' list */ /* check 'tobefnz' list */
checkgray(g, g->tobefnz); checkgray(g, g->tobefnz);
for (o = g->tobefnz; o != NULL; o = gch(o)->next) { for (o = g->tobefnz; o != NULL; o = o->next) {
checkobject(g, o, 0); checkobject(g, o, 0);
lua_assert(tofinalize(o)); lua_assert(tofinalize(o));
lua_assert(gch(o)->tt == LUA_TUSERDATA || gch(o)->tt == LUA_TTABLE); lua_assert(o->tt == LUA_TUSERDATA || o->tt == LUA_TTABLE);
} }
return 0; return 0;
} }