From da19c436cc361401563eeda2cca3d161a6ddeef7 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 16 Aug 2002 11:45:55 -0300 Subject: [PATCH] cleaning the stage for generational collection --- lfunc.c | 5 ++++- lgc.c | 62 +++++++++++++++++++++++++++---------------------------- llex.c | 9 ++++---- lobject.h | 12 +++++++---- lstring.c | 5 +++-- lstring.h | 12 ++--------- ltable.c | 4 ++-- 7 files changed, 54 insertions(+), 55 deletions(-) diff --git a/lfunc.c b/lfunc.c index e973d850..71cff734 100644 --- a/lfunc.c +++ b/lfunc.c @@ -1,5 +1,5 @@ /* -** $Id: lfunc.c,v 1.56 2002/05/02 13:06:20 roberto Exp roberto $ +** $Id: lfunc.c,v 1.57 2002/06/20 20:41:46 roberto Exp roberto $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ @@ -54,6 +54,7 @@ UpVal *luaF_findupval (lua_State *L, StkId level) { pp = &p->next; } p = luaM_new(L, UpVal); /* not found: create a new one */ + p->marked = 1; /* open upvalues should not be collected */ p->v = level; /* current value lives in the stack */ p->next = *pp; /* chain it in the proper position */ *pp = p; @@ -64,6 +65,8 @@ UpVal *luaF_findupval (lua_State *L, StkId level) { void luaF_close (lua_State *L, StkId level) { UpVal *p; while ((p = L->openupval) != NULL && p->v >= level) { + lua_assert(p->marked); + p->marked = 0; setobj(&p->value, p->v); /* save current value */ p->v = &p->value; /* now current value lives here */ L->openupval = p->next; /* remove from `open' list */ diff --git a/lgc.c b/lgc.c index 7dde65c3..282eb03d 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 1.144 2002/08/05 14:50:39 roberto Exp roberto $ +** $Id: lgc.c,v 1.145 2002/08/06 17:06:56 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -27,27 +27,26 @@ typedef struct GCState { } GCState; -/* mark a string; marks larger than 1 cannot be changed */ -#define strmark(s) {if ((s)->tsv.marked == 0) (s)->tsv.marked = 1;} +/* +** some userful bit tricks +*/ +#define setbit(x,b) ((x) |= (1<<(b))) +#define resetbit(x,b) ((x) &= cast(lu_byte, ~(1<<(b)))) +#define testbit(x,b) ((x) & (1<<(b))) -/* unmarked tables are represented by pointing `mark' to themselves */ -#define ismarked(x) ((x)->mark != (x)) +#define strmark(s) setbit((s)->tsv.marked, 0) +#define strunmark(s) resetbit((s)->tsv.marked, 0) /* mark tricks for userdata */ -#define isudmarked(u) (u->uv.len & 1) -#define markud(u) (u->uv.len |= 1) -#define unmarkud(u) (u->uv.len &= (~(size_t)1)) - -#define isfinalized(u) (u->uv.len & 2) -#define markfinalized(u) (u->uv.len |= 2) - - -/* mark tricks for upvalues (assume that open upvalues are always marked) */ -#define isupvalmarked(uv) ((uv)->v != &(uv)->value) +#define isudmarked(u) testbit(u->uv.marked, 0) +#define markud(u) setbit(u->uv.marked, 0) +#define unmarkud(u) resetbit(u->uv.marked, 0) +#define isfinalized(u) testbit(u->uv.marked, 1) +#define markfinalized(u) setbit(u->uv.marked, 1) #define ismarkable(o) (!((1 << ttype(o)) & \ @@ -78,8 +77,9 @@ static void protomark (Proto *f) { static void marktable (GCState *st, Table *h) { - if (!ismarked(h)) { - h->mark = st->tmark; /* chain it for later traversal */ + if (!h->marked) { + h->marked = 1; + h->gclist = st->tmark; /* chain it for later traversal */ st->tmark = h; } } @@ -100,9 +100,9 @@ static void markclosure (GCState *st, Closure *cl) { protomark(cl->l.p); for (i=0; il.nupvalues; i++) { /* mark its upvalues */ UpVal *u = cl->l.upvals[i]; - if (!isupvalmarked(u)) { + if (!u->marked) { markobject(st, &u->value); - u->v = NULL; /* mark it! */ + u->marked = 1; } } } @@ -222,7 +222,7 @@ static void traversetable (GCState *st, Table *h) { if (h->mode & (WEAKKEY | WEAKVALUE)) { /* weak table? */ weakkey = h->mode & WEAKKEY; weakvalue = h->mode & WEAKVALUE; - h->mark = st->toclear; /* must be cleared after GC, ... */ + h->gclist = st->toclear; /* must be cleared after GC, ... */ st->toclear = h; /* ... so put in the appropriate list */ } if (!weakvalue) { @@ -245,7 +245,7 @@ static void traversetable (GCState *st, Table *h) { static void propagatemarks (GCState *st) { while (st->tmark) { /* traverse marked tables */ Table *h = st->tmark; /* get first table from list */ - st->tmark = h->mark; /* remove it from list */ + st->tmark = h->gclist; /* remove it from list */ traversetable(st, h); } } @@ -256,7 +256,7 @@ static int hasmark (const TObject *o) { case LUA_TUSERDATA: return isudmarked(uvalue(o)); case LUA_TTABLE: - return ismarked(hvalue(o)); + return hvalue(o)->marked; case LUA_TFUNCTION: return clvalue(o)->c.marked; case LUA_TSTRING: @@ -273,7 +273,7 @@ static int hasmark (const TObject *o) { */ static void cleartablekeys (GCState *st) { Table *h; - for (h = st->toclear; h; h = h->mark) { + for (h = st->toclear; h; h = h->gclist) { lua_assert(h->mode & (WEAKKEY | WEAKVALUE)); if ((h->mode & WEAKKEY)) { /* table may have collected keys? */ int i = sizenode(h); @@ -292,7 +292,7 @@ static void cleartablekeys (GCState *st) { */ static void cleartablevalues (GCState *st) { Table *h; - for (h = st->toclear; h; h = h->mark) { + for (h = st->toclear; h; h = h->gclist) { if ((h->mode & WEAKVALUE)) { /* table may have collected values? */ int i = sizearray(h); while (i--) { @@ -347,9 +347,8 @@ static void collectupval (lua_State *L) { UpVal **v = &G(L)->rootupval; UpVal *curr; while ((curr = *v) != NULL) { - if (isupvalmarked(curr)) { - lua_assert(curr->v == NULL); - curr->v = &curr->value; /* unmark */ + if (curr->marked) { + curr->marked = 0; /* unmark */ v = &curr->next; /* next */ } else { @@ -364,8 +363,8 @@ static void collecttable (lua_State *L) { Table **p = &G(L)->roottable; Table *curr; while ((curr = *p) != NULL) { - if (ismarked(curr)) { - curr->mark = curr; /* unmark */ + if (curr->marked) { + curr->marked = 0; p = &curr->next; } else { @@ -387,7 +386,7 @@ static void collectudata (lua_State *L) { } else { *p = curr->uv.next; - luaM_free(L, curr, sizeudata(curr->uv.len & (~(size_t)3))); + luaM_free(L, curr, sizeudata(curr->uv.len)); } } } @@ -400,8 +399,7 @@ static void collectstrings (lua_State *L, int all) { TString *curr; while ((curr = *p) != NULL) { if (curr->tsv.marked && !all) { /* preserve? */ - if (curr->tsv.marked < FIXMARK) /* does not change FIXMARKs */ - curr->tsv.marked = 0; + strunmark(curr); p = &curr->tsv.nexthash; } else { /* collect */ diff --git a/llex.c b/llex.c index 27f11134..339b92a1 100644 --- a/llex.c +++ b/llex.c @@ -1,5 +1,5 @@ /* -** $Id: llex.c,v 1.107 2002/07/08 18:14:36 roberto Exp roberto $ +** $Id: llex.c,v 1.108 2002/07/10 20:43:53 roberto Exp roberto $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ @@ -39,8 +39,9 @@ void luaX_init (lua_State *L) { int i; for (i=0; itsv.marked = cast(unsigned short, RESERVEDMARK+i); /* reserved word */ + ts->tsv.reserved = cast(lu_byte, i+1); /* reserved word */ } } @@ -388,8 +389,8 @@ int luaX_lex (LexState *LS, SemInfo *seminfo) { /* identifier or reserved word */ size_t l = readname(LS); TString *ts = luaS_newlstr(LS->L, cast(char *, G(LS->L)->Mbuffer), l); - if (ts->tsv.marked >= RESERVEDMARK) /* reserved word? */ - return ts->tsv.marked-RESERVEDMARK+FIRST_RESERVED; + if (ts->tsv.reserved > 0) /* reserved word? */ + return ts->tsv.reserved - 1 + FIRST_RESERVED; seminfo->ts = ts; return TK_NAME; } diff --git a/lobject.h b/lobject.h index 805be05e..36a5b323 100644 --- a/lobject.h +++ b/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 1.141 2002/08/05 14:08:02 roberto Exp roberto $ +** $Id: lobject.h,v 1.142 2002/08/06 17:06:56 roberto Exp roberto $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -101,8 +101,9 @@ typedef union TString { struct { lu_hash hash; size_t len; - int marked; union TString *nexthash; /* chain for hash table */ + lu_byte marked; + lu_byte reserved; } tsv; } TString; @@ -117,7 +118,8 @@ typedef union Udata { struct { struct Table *metatable; union Udata *next; /* chain for list of all udata */ - size_t len; /* least 2 bits reserved for gc mark */ + size_t len; + lu_byte marked; } uv; } Udata; @@ -164,6 +166,7 @@ typedef struct UpVal { TObject *v; /* points to stack or to its own value */ struct UpVal *next; TObject value; /* the value (when closed) */ + lu_byte marked; } UpVal; @@ -219,11 +222,12 @@ typedef struct Table { Node *node; Node *firstfree; /* this position is free; all positions after it are full */ struct Table *next; - struct Table *mark; /* marked tables (point to itself when not marked) */ + struct Table *gclist; int sizearray; /* size of `array' array */ lu_byte flags; /* 1<

tsv.len = l; ts->tsv.hash = h; ts->tsv.marked = 0; + ts->tsv.reserved = 0; memcpy(ts+1, str, l*sizeof(char)); ((char *)(ts+1))[l] = '\0'; /* ending 0 */ tb = &G(L)->strt; @@ -85,8 +86,8 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { Udata *luaS_newudata (lua_State *L, size_t s) { Udata *u; - s = (s+3) & (~(size_t)3); /* make sure size is multiple of 4 */ u = cast(Udata *, luaM_malloc(L, sizeudata(s))); + u->uv.marked = 0; u->uv.len = s; u->uv.metatable = hvalue(defaultmeta(L)); /* chain it on udata list */ diff --git a/lstring.h b/lstring.h index d1b0f14a..13a12a5a 100644 --- a/lstring.h +++ b/lstring.h @@ -1,5 +1,5 @@ /* -** $Id: lstring.h,v 1.35 2001/11/28 20:13:13 roberto Exp roberto $ +** $Id: lstring.h,v 1.36 2002/04/30 13:01:48 roberto Exp roberto $ ** String table (keep all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -13,14 +13,6 @@ -/* -** any TString with mark>=FIXMARK is never collected. -** Marks>=RESERVEDMARK are used to identify reserved words. -*/ -#define FIXMARK 2 -#define RESERVEDMARK 3 - - #define sizestring(l) (cast(lu_mem, sizeof(union TString))+ \ (cast(lu_mem, l)+1)*sizeof(char)) @@ -30,7 +22,7 @@ #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ (sizeof(s)/sizeof(char))-1)) -#define luaS_fix(s) ((s)->tsv.marked = FIXMARK) +#define luaS_fix(s) ((s)->tsv.marked |= (1<<4)) void luaS_resize (lua_State *L, int newsize); Udata *luaS_newudata (lua_State *L, size_t s); diff --git a/ltable.c b/ltable.c index 6ef7aa57..64afbef9 100644 --- a/ltable.c +++ b/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 1.115 2002/08/05 14:45:32 roberto Exp roberto $ +** $Id: ltable.c,v 1.116 2002/08/06 17:06:56 roberto Exp roberto $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -307,8 +307,8 @@ Table *luaH_new (lua_State *L, int narray, int lnhash) { t->metatable = hvalue(defaultmeta(L)); t->next = G(L)->roottable; G(L)->roottable = t; - t->mark = t; t->flags = cast(lu_byte, ~0); + t->marked = 0; t->mode = 0; /* temporary values (kept only if some malloc fails) */ t->array = NULL;