浏览代码

cleaning the stage for generational collection

Roberto Ierusalimschy 23 年之前
父节点
当前提交
da19c436cc
共有 7 个文件被更改,包括 54 次插入55 次删除
  1. 4 1
      lfunc.c
  2. 30 32
      lgc.c
  3. 5 4
      llex.c
  4. 8 4
      lobject.h
  5. 3 2
      lstring.c
  6. 2 10
      lstring.h
  7. 2 2
      ltable.c

+ 4 - 1
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 */

+ 30 - 32
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; i<cl->l.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 */

+ 5 - 4
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; i<NUM_RESERVED; i++) {
     TString *ts = luaS_new(L, token2string[i]);
+    luaS_fix(ts);  /* reserved words are never collected */
     lua_assert(strlen(token2string[i])+1 <= TOKEN_LEN);
-    ts->tsv.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;
         }

+ 8 - 4
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<<p means tagmethod(p) is not present */ 
   lu_byte lsizenode;  /* log2 of size of `node' array */
   lu_byte mode;
+  lu_byte marked;
 } Table;
 
 /* bit masks for `mode' */

+ 3 - 2
lstring.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstring.c,v 1.73 2002/03/20 18:37:13 roberto Exp roberto $
+** $Id: lstring.c,v 1.74 2002/04/05 18:54:31 roberto Exp roberto $
 ** String table (keeps all strings handled by Lua)
 ** See Copyright Notice in lua.h
 */
@@ -53,6 +53,7 @@ static TString *newlstr (lua_State *L, const char *str, size_t l, lu_hash h) {
   ts->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 */

+ 2 - 10
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);

+ 2 - 2
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;