Explorar o código

code reorganization (only changed comments and order of functions)

Roberto Ierusalimschy %!s(int64=17) %!d(string=hai) anos
pai
achega
7ba62e2985
Modificáronse 1 ficheiros con 203 adicións e 154 borrados
  1. 203 154
      lgc.c

+ 203 - 154
lgc.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lgc.c,v 2.43 2008/02/11 15:46:03 roberto Exp roberto $
+** $Id: lgc.c,v 2.44 2008/02/19 18:55:09 roberto Exp roberto $
 ** Garbage Collector
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -53,6 +53,15 @@
 #define setthreshold(g)  (g->GCthreshold = (g->estimate/100) * g->gcpause)
 #define setthreshold(g)  (g->GCthreshold = (g->estimate/100) * g->gcpause)
 
 
 
 
+static void reallymarkobject (global_State *g, GCObject *o);
+
+
+/*
+** {======================================================
+** Generic functions
+** =======================================================
+*/
+
 static void linktable (Table *h, GCObject **p) {
 static void linktable (Table *h, GCObject **p) {
   h->gclist = *p;
   h->gclist = *p;
   *p = obj2gco(h);
   *p = obj2gco(h);
@@ -83,6 +92,65 @@ static int iscleared (const TValue *o, int iskey) {
     (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o))));
     (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o))));
 }
 }
 
 
+void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
+  global_State *g = G(L);
+  lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
+  lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
+  lua_assert(ttype(gch(o)) != LUA_TTABLE);
+  /* must keep invariant? */
+  if (g->gcstate == GCSpropagate)
+    reallymarkobject(g, v);  /* restore invariant */
+  else  /* don't mind */
+    makewhite(g, o);  /* mark as white just to avoid other barriers */
+}
+
+
+void luaC_barrierback (lua_State *L, Table *t) {
+  global_State *g = G(L);
+  GCObject *o = obj2gco(t);
+  lua_assert(isblack(o) && !isdead(g, o));
+  lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
+  black2gray(o);  /* make table gray (again) */
+  t->gclist = g->grayagain;
+  g->grayagain = o;
+}
+
+
+void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {
+  global_State *g = G(L);
+  gch(o)->marked = luaC_white(g);
+  gch(o)->tt = tt;
+  gch(o)->next = g->rootgc;
+  g->rootgc = o;
+}
+
+
+void luaC_linkupval (lua_State *L, UpVal *uv) {
+  global_State *g = G(L);
+  GCObject *o = obj2gco(uv);
+  gch(o)->next = g->rootgc;  /* link upvalue into `rootgc' list */
+  g->rootgc = o;
+  if (isgray(o)) {
+    if (g->gcstate == GCSpropagate) {
+      gray2black(o);  /* closed upvalues need barrier */
+      luaC_barrier(L, uv, uv->v);
+    }
+    else {  /* sweep phase: sweep it (turning it into white) */
+      makewhite(g, o);
+      lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
+    }
+  }
+}
+
+/* }====================================================== */
+
+
+
+/*
+** {======================================================
+** Mark functions
+** =======================================================
+*/
 
 
 static void reallymarkobject (global_State *g, GCObject *o) {
 static void reallymarkobject (global_State *g, GCObject *o) {
   lua_assert(iswhite(o) && !isdead(g, o));
   lua_assert(iswhite(o) && !isdead(g, o));
@@ -129,36 +197,60 @@ static void reallymarkobject (global_State *g, GCObject *o) {
 }
 }
 
 
 
 
-/* move 'dead' udata that need finalization to list 'tobefnz' */
-size_t luaC_separateudata (lua_State *L, int all) {
+static void markmt (global_State *g) {
+  int i;
+  for (i=0; i<NUM_TAGS; i++)
+    markobject(g, g->mt[i]);
+}
+
+
+static void markbeingfnz (global_State *g) {
+  GCObject *u = g->tobefnz;
+  if (u) {
+    do {
+      u = gch(u)->next;
+      lua_assert(testbit(gch(u)->marked, SEPARATED));
+      lua_assert(!iswhite(u));  /* must be marked, if left from previous GC */
+      makewhite(g, u);
+      reallymarkobject(g, u);
+    } while (u != g->tobefnz);
+  }
+}
+
+
+/* mark root set */
+static void markroot (lua_State *L) {
   global_State *g = G(L);
   global_State *g = G(L);
-  size_t deadmem = 0;
-  GCObject **p = &g->tmudata;
-  GCObject *curr;
-  while ((curr = *p) != NULL) {
-    lua_assert(ttisuserdata(gch(curr)) && !isfinalized(gco2u(curr)));
-    lua_assert(testbit(gch(curr)->marked, SEPARATED));
-    if (all) makewhite(g, curr);  /* if 'all', collect all objects */
-    if (!iswhite(curr))  /* not being collected? */
-      p = &gch(curr)->next;  /* don't bother with it */
-    else {
-      l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */
-      reallymarkobject(g, curr);  /* won't be collected now */
-      deadmem += sizeudata(gco2u(curr));
-      *p = gch(curr)->next;  /* remove 'curr' from 'tmudata' list */
-      /* link 'curr' at the end of 'tobefnz' list */
-      if (g->tobefnz == NULL)  /* list is empty? */
-        g->tobefnz = gch(curr)->next = curr;  /* creates a circular list */
-      else {
-        gch(curr)->next = gch(g->tobefnz)->next;
-        gch(g->tobefnz)->next = curr;
-        g->tobefnz = curr;
-      }
-    }
+  g->gray = NULL;
+  g->grayagain = NULL;
+  g->weak = g->ephemeron = g->allweak = NULL;
+  markobject(g, g->mainthread);
+  /* make global table be traversed before main stack */
+  markvalue(g, gt(g->mainthread));
+  markvalue(g, registry(L));
+  markmt(g);
+  markbeingfnz(g);  /* mark any finalizing userdata left from previous cycle */
+  g->gcstate = GCSpropagate;
+}
+
+
+static void remarkupvals (global_State *g) {
+  UpVal *uv;
+  for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
+    lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
+    if (isgray(obj2gco(uv)))
+      markvalue(g, uv->v);
   }
   }
-  return deadmem;
 }
 }
 
 
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** Traverse functions
+** =======================================================
+*/
 
 
 static void traverseweakvalue (global_State *g, Table *h) {
 static void traverseweakvalue (global_State *g, Table *h) {
   int i = sizenode(h);
   int i = sizenode(h);
@@ -382,6 +474,14 @@ static size_t propagateall (global_State *g) {
 }
 }
 
 
 
 
+static void traverselistofgrays (global_State *g, GCObject **l) {
+  lua_assert(g->gray == NULL);  /* no grays left */
+  g->gray = *l;  /* now 'l' is new gray list */
+  *l = NULL;
+  propagateall(g);
+}
+
+
 static void convergeephemerons (global_State *g) {
 static void convergeephemerons (global_State *g) {
   int changed;
   int changed;
   do {
   do {
@@ -399,11 +499,16 @@ static void convergeephemerons (global_State *g) {
   } while (changed);
   } while (changed);
 }
 }
 
 
+/* }====================================================== */
 
 
 
 
 /*
 /*
-** clear collected entries from weaktables
+** {======================================================
+** Sweep Functions
+** =======================================================
 */
 */
+
+/* clear collected entries from weaktables */
 static void cleartable (GCObject *l) {
 static void cleartable (GCObject *l) {
   while (l) {
   while (l) {
     Table *h = gco2t(l);
     Table *h = gco2t(l);
@@ -445,7 +550,6 @@ static void freeobj (lua_State *L, GCObject *o) {
 }
 }
 
 
 
 
-
 #define sweepwholelist(L,p)	sweeplist(L,p,MAX_LUMEM)
 #define sweepwholelist(L,p)	sweeplist(L,p,MAX_LUMEM)
 
 
 
 
@@ -471,6 +575,8 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
 }
 }
 
 
 
 
+/* sweep list where all objects are alive (dead udata were removed
+   when separated from this list) */
 static GCObject **unmarklist (global_State *g, GCObject **p, lu_mem count) {
 static GCObject **unmarklist (global_State *g, GCObject **p, lu_mem count) {
   for (; *p != NULL && count-- > 0; p = &gch(*p)->next) {
   for (; *p != NULL && count-- > 0; p = &gch(*p)->next) {
      lua_assert(ttisuserdata(gch(*p)) && !isdead(g, *p));
      lua_assert(ttisuserdata(gch(*p)) && !isdead(g, *p));
@@ -479,6 +585,14 @@ static GCObject **unmarklist (global_State *g, GCObject **p, lu_mem count) {
   return p;
   return p;
 }
 }
 
 
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** Finalization
+** =======================================================
+*/
 
 
 static void checkSizes (lua_State *L) {
 static void checkSizes (lua_State *L) {
   global_State *g = G(L);
   global_State *g = G(L);
@@ -541,6 +655,63 @@ void luaC_callGCTM (lua_State *L) {
 }
 }
 
 
 
 
+/* move 'dead' udata that need finalization to list 'tobefnz' */
+size_t luaC_separateudata (lua_State *L, int all) {
+  global_State *g = G(L);
+  size_t deadmem = 0;
+  GCObject **p = &g->tmudata;
+  GCObject *curr;
+  while ((curr = *p) != NULL) {
+    lua_assert(ttisuserdata(gch(curr)) && !isfinalized(gco2u(curr)));
+    lua_assert(testbit(gch(curr)->marked, SEPARATED));
+    if (all) makewhite(g, curr);  /* if 'all', collect all objects */
+    if (!iswhite(curr))  /* not being collected? */
+      p = &gch(curr)->next;  /* don't bother with it */
+    else {
+      l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */
+      reallymarkobject(g, curr);  /* won't be collected now */
+      deadmem += sizeudata(gco2u(curr));
+      *p = gch(curr)->next;  /* remove 'curr' from 'tmudata' list */
+      /* link 'curr' at the end of 'tobefnz' list */
+      if (g->tobefnz == NULL)  /* list is empty? */
+        g->tobefnz = gch(curr)->next = curr;  /* creates a circular list */
+      else {
+        gch(curr)->next = gch(g->tobefnz)->next;
+        gch(g->tobefnz)->next = curr;
+        g->tobefnz = curr;
+      }
+    }
+  }
+  return deadmem;
+}
+
+
+void luaC_checkfinalizer (lua_State *L, Udata *u) {
+  global_State *g = G(L);
+  if (testbit(u->uv.marked, SEPARATED) || /* userdata is already separated... */
+      isfinalized(&u->uv) ||                        /* ... or is finalized... */
+      gfasttm(g, u->uv.metatable, TM_GC) == NULL)  /* or has no finalization? */
+    return;  /* nothing to be done */
+  else {  /* move 'u' from root list to 'tmudata' list */
+    GCObject **p;
+    for (p = &g->rootgc; *p != obj2gco(u); p = &gch(*p)->next)
+      lua_assert(*p != NULL);  /* 'u' must be in this list */
+    *p = u->uv.next;  /* remove 'u' from root list */
+    u->uv.next = g->tmudata;  /* link it in 'tmudata' list */
+    g->tmudata = obj2gco(u);
+    l_setbit(u->uv.marked, SEPARATED);  /* mark it as such */
+  }
+}
+
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** GC control
+** =======================================================
+*/
+
 void luaC_freeall (lua_State *L) {
 void luaC_freeall (lua_State *L) {
   global_State *g = G(L);
   global_State *g = G(L);
   int i;
   int i;
@@ -557,61 +728,6 @@ void luaC_freeall (lua_State *L) {
 }
 }
 
 
 
 
-static void markmt (global_State *g) {
-  int i;
-  for (i=0; i<NUM_TAGS; i++)
-    markobject(g, g->mt[i]);
-}
-
-
-static void markbeingfnz (global_State *g) {
-  GCObject *u = g->tobefnz;
-  if (u) {
-    do {
-      u = gch(u)->next;
-      lua_assert(testbit(gch(u)->marked, SEPARATED));
-      lua_assert(!iswhite(u));  /* must be marked, if left from previous GC */
-      makewhite(g, u);
-      reallymarkobject(g, u);
-    } while (u != g->tobefnz);
-  }
-}
-
-
-/* mark root set */
-static void markroot (lua_State *L) {
-  global_State *g = G(L);
-  g->gray = NULL;
-  g->grayagain = NULL;
-  g->weak = g->ephemeron = g->allweak = NULL;
-  markobject(g, g->mainthread);
-  /* make global table be traversed before main stack */
-  markvalue(g, gt(g->mainthread));
-  markvalue(g, registry(L));
-  markmt(g);
-  markbeingfnz(g);  /* mark any finalizing userdata left from previous cycle */
-  g->gcstate = GCSpropagate;
-}
-
-
-static void remarkupvals (global_State *g) {
-  UpVal *uv;
-  for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
-    lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
-    if (isgray(obj2gco(uv)))
-      markvalue(g, uv->v);
-  }
-}
-
-
-static void marklistofgrays (global_State *g, GCObject **l) {
-  lua_assert(g->gray == NULL);  /* no grays left */
-  g->gray = *l;  /* now 'l' is new gray list */
-  *l = NULL;
-  propagateall(g);
-}
-
-
 static void atomic (lua_State *L) {
 static void atomic (lua_State *L) {
   global_State *g = G(L);
   global_State *g = G(L);
   size_t udsize;  /* total size of userdata to be finalized */
   size_t udsize;  /* total size of userdata to be finalized */
@@ -626,8 +742,8 @@ static void atomic (lua_State *L) {
   markobject(g, L);  /* mark running thread */
   markobject(g, L);  /* mark running thread */
   markmt(g);  /* mark basic metatables (again) */
   markmt(g);  /* mark basic metatables (again) */
   propagateall(g);
   propagateall(g);
-  marklistofgrays(g, &g->ephemeron);  /* remark ephemeron tables */
-  marklistofgrays(g, &g->grayagain);  /* remark gray again */
+  traverselistofgrays(g, &g->ephemeron);  /* remark ephemeron tables */
+  traverselistofgrays(g, &g->grayagain);  /* remark gray again */
   convergeephemerons(g);
   convergeephemerons(g);
   udsize = luaC_separateudata(L, 0);  /* separate userdata to be finalized */
   udsize = luaC_separateudata(L, 0);  /* separate userdata to be finalized */
   udsize += propagateall(g);  /* remark, to propagate `preserveness' */
   udsize += propagateall(g);  /* remark, to propagate `preserveness' */
@@ -762,73 +878,6 @@ void luaC_fullgc (lua_State *L, int isemergency) {
   setthreshold(g);
   setthreshold(g);
 }
 }
 
 
-
-void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
-  global_State *g = G(L);
-  lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
-  lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
-  lua_assert(ttype(gch(o)) != LUA_TTABLE);
-  /* must keep invariant? */
-  if (g->gcstate == GCSpropagate)
-    reallymarkobject(g, v);  /* restore invariant */
-  else  /* don't mind */
-    makewhite(g, o);  /* mark as white just to avoid other barriers */
-}
-
-
-void luaC_barrierback (lua_State *L, Table *t) {
-  global_State *g = G(L);
-  GCObject *o = obj2gco(t);
-  lua_assert(isblack(o) && !isdead(g, o));
-  lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
-  black2gray(o);  /* make table gray (again) */
-  t->gclist = g->grayagain;
-  g->grayagain = o;
-}
-
-
-void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {
-  global_State *g = G(L);
-  gch(o)->marked = luaC_white(g);
-  gch(o)->tt = tt;
-  gch(o)->next = g->rootgc;
-  g->rootgc = o;
-}
-
-
-void luaC_linkupval (lua_State *L, UpVal *uv) {
-  global_State *g = G(L);
-  GCObject *o = obj2gco(uv);
-  gch(o)->next = g->rootgc;  /* link upvalue into `rootgc' list */
-  g->rootgc = o;
-  if (isgray(o)) {
-    if (g->gcstate == GCSpropagate) {
-      gray2black(o);  /* closed upvalues need barrier */
-      luaC_barrier(L, uv, uv->v);
-    }
-    else {  /* sweep phase: sweep it (turning it into white) */
-      makewhite(g, o);
-      lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
-    }
-  }
-}
-
-
-void luaC_checkfinalizer (lua_State *L, Udata *u) {
-  global_State *g = G(L);
-  if (testbit(u->uv.marked, SEPARATED) || /* userdata is already separated... */
-      isfinalized(&u->uv) ||                        /* ... or is finalized... */
-      gfasttm(g, u->uv.metatable, TM_GC) == NULL)  /* or has no finalization? */
-    return;  /* nothing to be done */
-  else {  /* move 'u' from root list to tobefnz list */
-    GCObject **p;
-    for (p = &g->rootgc; *p != obj2gco(u); p = &gch(*p)->next)
-      lua_assert(*p != NULL);  /* 'u' must be in this list */
-    *p = u->uv.next;  /* remove 'u' from root list */
-    u->uv.next = g->tmudata;  /* link it in tobefnz list */
-    g->tmudata = obj2gco(u);
-    l_setbit(u->uv.marked, SEPARATED);  /* mark it as such */
-  }
-}
+/* }====================================================== */