Browse Source

single list for all collectible objects, with udata separated at the
end of the list

Roberto Ierusalimschy 21 years ago
parent
commit
8878554b85
4 changed files with 24 additions and 20 deletions
  1. 10 10
      lgc.c
  2. 8 3
      lstate.c
  3. 3 4
      lstate.h
  4. 3 3
      lstring.c

+ 10 - 10
lgc.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lgc.c,v 1.181 2003/12/01 16:33:30 roberto Exp roberto $
+** $Id: lgc.c,v 1.182 2003/12/01 18:22:56 roberto Exp roberto $
 ** Garbage Collector
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -158,7 +158,7 @@ static void marktmu (global_State *g) {
 /* move `dead' udata that need finalization to list `tmudata' */
 /* move `dead' udata that need finalization to list `tmudata' */
 size_t luaC_separateudata (lua_State *L) {
 size_t luaC_separateudata (lua_State *L) {
   size_t deadmem = 0;
   size_t deadmem = 0;
-  GCObject **p = &G(L)->rootudata;
+  GCObject **p = &G(L)->firstudata;
   GCObject *curr;
   GCObject *curr;
   GCObject *collected = NULL;  /* to collect udata with gc event */
   GCObject *collected = NULL;  /* to collect udata with gc event */
   GCObject **lastcollected = &collected;
   GCObject **lastcollected = &collected;
@@ -495,8 +495,8 @@ static void GCTM (lua_State *L) {
     Udata *udata = gcotou(o);
     Udata *udata = gcotou(o);
     const TObject *tm;
     const TObject *tm;
     g->tmudata = udata->uv.next;  /* remove udata from `tmudata' */
     g->tmudata = udata->uv.next;  /* remove udata from `tmudata' */
-    udata->uv.next = g->rootudata;  /* return it to `root' list */
-    g->rootudata = o;
+    udata->uv.next = g->firstudata->uv.next;  /* return it to `root' list */
+    g->firstudata->uv.next = o;
     makewhite(o);
     makewhite(o);
     tm = fasttm(L, udata->uv.metatable, TM_GC);
     tm = fasttm(L, udata->uv.metatable, TM_GC);
     if (tm != NULL) {
     if (tm != NULL) {
@@ -524,7 +524,6 @@ void luaC_callGCTM (lua_State *L) {
 void luaC_sweepall (lua_State *L) {
 void luaC_sweepall (lua_State *L) {
   l_mem dummy = MAXLMEM;
   l_mem dummy = MAXLMEM;
   sweepstrings(L, 0);
   sweepstrings(L, 0);
-  sweeplist(L, &G(L)->rootudata, 0, &dummy);
   sweeplist(L, &G(L)->rootgc, 0, &dummy);
   sweeplist(L, &G(L)->rootgc, 0, &dummy);
 }
 }
 
 
@@ -537,8 +536,8 @@ static void markroot (lua_State *L) {
   makewhite(valtogco(g->mainthread));
   makewhite(valtogco(g->mainthread));
   markobject(g, g->mainthread);
   markobject(g, g->mainthread);
   markvalue(g, registry(L));
   markvalue(g, registry(L));
-  if (L != g->mainthread)  /* another thread is running? */
-    markobject(g, L);  /* cannot collect it */
+  markobject(g, g->firstudata);
+  markobject(g, L);  /* mark running thread */
   g->gcstate = GCSpropagate;
   g->gcstate = GCSpropagate;
 }
 }
 
 
@@ -549,8 +548,10 @@ static void atomic (lua_State *L) {
   marktmu(g);  /* mark `preserved' userdata */
   marktmu(g);  /* mark `preserved' userdata */
   propagatemarks(g, MAXLMEM);  /* remark, to propagate `preserveness' */
   propagatemarks(g, MAXLMEM);  /* remark, to propagate `preserveness' */
   cleartable(g->weak);  /* remove collected objects from weak tables */
   cleartable(g->weak);  /* remove collected objects from weak tables */
-  g->sweepgc = &g->rootgc;
-  g->sweepudata = &g->rootudata;
+  /* first element of root list will be used as temporary head for sweep
+     phase, so it won't be seeped */
+  makewhite(g->rootgc);
+  g->sweepgc = &g->rootgc->gch.next;
   sweepstrings(L, maskbf);
   sweepstrings(L, maskbf);
   g->gcstate = GCSsweep;
   g->gcstate = GCSsweep;
 }
 }
@@ -559,7 +560,6 @@ static void atomic (lua_State *L) {
 static void sweepstep (lua_State *L) {
 static void sweepstep (lua_State *L) {
   global_State *g = G(L);
   global_State *g = G(L);
   l_mem lim = GCSTEPSIZE;
   l_mem lim = GCSTEPSIZE;
-  g->sweepudata = sweeplist(L, g->sweepudata, maskbf, &lim);
   g->sweepgc = sweeplist(L, g->sweepgc, maskbf, &lim);
   g->sweepgc = sweeplist(L, g->sweepgc, maskbf, &lim);
   if (lim == GCSTEPSIZE) {  /* nothing more to sweep? */
   if (lim == GCSTEPSIZE) {  /* nothing more to sweep? */
     g->gcstate = GCSfinalize;  /* end sweep phase */
     g->gcstate = GCSfinalize;  /* end sweep phase */

+ 8 - 3
lstate.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstate.c,v 1.129 2003/12/01 16:33:30 roberto Exp roberto $
+** $Id: lstate.c,v 1.130 2003/12/01 18:22:56 roberto Exp roberto $
 ** Global State
 ** Global State
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -74,7 +74,13 @@ static void freestack (lua_State *L, lua_State *L1) {
 ** open parts that may cause memory-allocation errors
 ** open parts that may cause memory-allocation errors
 */
 */
 static void f_luaopen (lua_State *L, void *ud) {
 static void f_luaopen (lua_State *L, void *ud) {
+  Udata *u;  /* head of udata list */
   UNUSED(ud);
   UNUSED(ud);
+  u = cast(Udata *, luaM_malloc(L, sizeudata(0)));
+  u->uv.len = 0;
+  u->uv.metatable = NULL;
+  G(L)->firstudata = valtogco(u);
+  luaC_link(L, valtogco(u), LUA_TUSERDATA);
   stack_init(L, L);  /* init stack */
   stack_init(L, L);  /* init stack */
   sethvalue(gt(L), luaH_new(L, 0, 4));  /* table of globals */
   sethvalue(gt(L), luaH_new(L, 0, 4));  /* table of globals */
   sethvalue(registry(L), luaH_new(L, 4, 4));  /* registry */
   sethvalue(registry(L), luaH_new(L, 4, 4));  /* registry */
@@ -110,7 +116,6 @@ static void close_state (lua_State *L) {
   luaF_close(L, L->stack);  /* close all upvalues for this thread */
   luaF_close(L, L->stack);  /* close all upvalues for this thread */
   luaC_sweepall(L);  /* collect all elements */
   luaC_sweepall(L);  /* collect all elements */
   lua_assert(g->rootgc == NULL);
   lua_assert(g->rootgc == NULL);
-  lua_assert(g->rootudata == NULL);
   luaS_freeall(L);
   luaS_freeall(L);
   luaZ_freebuffer(L, &g->buff);
   luaZ_freebuffer(L, &g->buff);
   freestack(L, L);
   freestack(L, L);
@@ -162,7 +167,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
   g->panic = NULL;
   g->panic = NULL;
   g->gcstate = 0;
   g->gcstate = 0;
   g->rootgc = NULL;
   g->rootgc = NULL;
-  g->rootudata = NULL;
+  g->firstudata = NULL;
   g->gray = NULL;
   g->gray = NULL;
   g->weak = NULL;
   g->weak = NULL;
   g->tmudata = NULL;
   g->tmudata = NULL;

+ 3 - 4
lstate.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstate.h,v 1.114 2003/12/01 16:33:30 roberto Exp roberto $
+** $Id: lstate.h,v 1.115 2003/12/01 18:22:56 roberto Exp roberto $
 ** Global State
 ** Global State
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -97,10 +97,9 @@ typedef struct global_State {
   stringtable strt;  /* hash table for strings */
   stringtable strt;  /* hash table for strings */
   lua_Alloc realloc;  /* function to reallocate memory */
   lua_Alloc realloc;  /* function to reallocate memory */
   void *ud;         /* auxiliary data to `realloc' */
   void *ud;         /* auxiliary data to `realloc' */
-  GCObject *rootgc;  /* list of (almost) all collectable objects */
-  GCObject *rootudata;   /* (separated) list of all userdata */
+  GCObject *rootgc;  /* list of all collectable objects */
+  GCObject *firstudata;   /* udata go to the end of `rootgc' */
   GCObject **sweepgc;  /* position of sweep in `rootgc' */
   GCObject **sweepgc;  /* position of sweep in `rootgc' */
-  GCObject **sweepudata;  /* position of sweep in `rootudata' */
   GCObject *gray;  /* list of gray objects */
   GCObject *gray;  /* list of gray objects */
   GCObject *weak;  /* list of weak tables (to be cleared) */
   GCObject *weak;  /* list of weak tables (to be cleared) */
   GCObject *tmudata;  /* list of userdata to be GC */
   GCObject *tmudata;  /* list of userdata to be GC */

+ 3 - 3
lstring.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstring.c,v 1.80 2003/11/17 19:50:05 roberto Exp roberto $
+** $Id: lstring.c,v 1.81 2003/12/01 18:22:56 roberto Exp roberto $
 ** String table (keeps all strings handled by Lua)
 ** String table (keeps all strings handled by Lua)
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -96,8 +96,8 @@ Udata *luaS_newudata (lua_State *L, size_t s) {
   u->uv.len = s;
   u->uv.len = s;
   u->uv.metatable = NULL;
   u->uv.metatable = NULL;
   /* chain it on udata list */
   /* chain it on udata list */
-  u->uv.next = G(L)->rootudata;
-  G(L)->rootudata = valtogco(u);
+  u->uv.next = G(L)->firstudata->uv.next;
+  G(L)->firstudata->uv.next = valtogco(u);
   return u;
   return u;
 }
 }