Explorar o código

all collected userdata must go to the end of the list of finalizers

Roberto Ierusalimschy %!s(int64=20) %!d(string=hai) anos
pai
achega
678d2fb2ac
Modificáronse 2 ficheiros con 26 adicións e 18 borrados
  1. 24 16
      lgc.c
  2. 2 2
      lstate.h

+ 24 - 16
lgc.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lgc.c,v 2.22 2005/01/18 17:18:09 roberto Exp roberto $
+** $Id: lgc.c,v 2.23 2005/02/10 13:25:02 roberto Exp roberto $
 ** Garbage Collector
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -114,21 +114,23 @@ static void reallymarkobject (global_State *g, GCObject *o) {
 
 
 
 
 static void marktmu (global_State *g) {
 static void marktmu (global_State *g) {
-  GCObject *u;
-  for (u = g->tmudata; u; u = u->gch.next) {
-    makewhite(g, u);  /* may be marked, if left from previous GC */
-    reallymarkobject(g, u);
+  GCObject *u = g->tmudata;
+  if (u) {
+    do {
+      u = u->gch.next;
+      makewhite(g, u);  /* may be marked, if left from previous GC */
+      reallymarkobject(g, u);
+    } while (u != g->tmudata);
   }
   }
 }
 }
 
 
 
 
 /* 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, int all) {
 size_t luaC_separateudata (lua_State *L, int all) {
+  global_State *g = G(L);
   size_t deadmem = 0;
   size_t deadmem = 0;
-  GCObject **p = &G(L)->mainthread->next;
+  GCObject **p = &g->mainthread->next;
   GCObject *curr;
   GCObject *curr;
-  GCObject *collected = NULL;  /* to collect udata with gc event */
-  GCObject **lastcollected = &collected;
   while ((curr = *p) != NULL) {
   while ((curr = *p) != NULL) {
     if (!(iswhite(curr) || all) || isfinalized(gco2u(curr)))
     if (!(iswhite(curr) || all) || isfinalized(gco2u(curr)))
       p = &curr->gch.next;  /* don't bother with them */
       p = &curr->gch.next;  /* don't bother with them */
@@ -140,14 +142,16 @@ size_t luaC_separateudata (lua_State *L, int all) {
       deadmem += sizeudata(gco2u(curr));
       deadmem += sizeudata(gco2u(curr));
       markfinalized(gco2u(curr));
       markfinalized(gco2u(curr));
       *p = curr->gch.next;
       *p = curr->gch.next;
-      curr->gch.next = NULL;  /* link `curr' at the end of `collected' list */
-      *lastcollected = curr;
-      lastcollected = &curr->gch.next;
+      /* link `curr' at the end of `tmudata' list */
+      if (g->tmudata == NULL)  /* list is empty? */
+        g->tmudata = curr->gch.next = curr;  /* creates a circular list */
+      else {
+        curr->gch.next = g->tmudata->gch.next;
+        g->tmudata->gch.next = curr;
+        g->tmudata = curr;
+      }
     }
     }
   }
   }
-  /* insert collected udata with gc event into `tmudata' list */
-  *lastcollected = G(L)->tmudata;
-  G(L)->tmudata = collected;
   return deadmem;
   return deadmem;
 }
 }
 
 
@@ -443,10 +447,14 @@ static void checkSizes (lua_State *L) {
 
 
 static void GCTM (lua_State *L) {
 static void GCTM (lua_State *L) {
   global_State *g = G(L);
   global_State *g = G(L);
-  GCObject *o = g->tmudata;
+  GCObject *o = g->tmudata->gch.next;  /* get first element */
   Udata *udata = rawgco2u(o);
   Udata *udata = rawgco2u(o);
   const TValue *tm;
   const TValue *tm;
-  g->tmudata = udata->uv.next;  /* remove udata from `tmudata' */
+  /* remove udata from `tmudata' */
+  if (o == g->tmudata)  /* last element? */
+    g->tmudata = NULL;
+  else
+    g->tmudata->gch.next = udata->uv.next;
   udata->uv.next = g->mainthread->next;  /* return it to `root' list */
   udata->uv.next = g->mainthread->next;  /* return it to `root' list */
   g->mainthread->next = o;
   g->mainthread->next = o;
   makewhite(g, o);
   makewhite(g, o);

+ 2 - 2
lstate.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstate.h,v 2.12 2005/01/14 14:19:42 roberto Exp $
+** $Id: lstate.h,v 2.13 2005/01/18 17:18:09 roberto Exp roberto $
 ** Global State
 ** Global State
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -77,7 +77,7 @@ typedef struct global_State {
   GCObject *gray;  /* list of gray objects */
   GCObject *gray;  /* list of gray objects */
   GCObject *grayagain;  /* list of objects to be traversed atomically */
   GCObject *grayagain;  /* list of objects to be traversed atomically */
   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;  /* last element of list of userdata to be GC */
   Mbuffer buff;  /* temporary buffer for string concatentation */
   Mbuffer buff;  /* temporary buffer for string concatentation */
   lu_mem GCthreshold;
   lu_mem GCthreshold;
   lu_mem totalbytes;  /* number of bytes currently allocated */
   lu_mem totalbytes;  /* number of bytes currently allocated */