فهرست منبع

more robust treatment of GC tag methods (now they can create new
objects while running...)

Roberto Ierusalimschy 24 سال پیش
والد
کامیت
89e8303f4e
3فایلهای تغییر یافته به همراه16 افزوده شده و 26 حذف شده
  1. 7 22
      lgc.c
  2. 3 1
      lgc.h
  3. 6 3
      lstate.c

+ 7 - 22
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 1.101 2001/06/07 15:01:21 roberto Exp roberto $
+** $Id: lgc.c,v 1.102 2001/06/08 19:01:38 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -18,18 +18,6 @@
 #include "ltm.h"
 
 
-/*
-** optional lock for GC
-** (when Lua calls GC tag methods it unlocks the regular lock)
-*/
-#ifndef lua_lockgc
-#define lua_lockgc(L)		{
-#endif
-
-#ifndef lua_unlockgc
-#define lua_unlockgc(L)		}
-#endif
-
 
 typedef struct GCState {
   Hash *tmark;  /* list of marked tables to be visited */
@@ -281,7 +269,7 @@ static void collecttable (lua_State *L) {
 }
 
 
-static void collectudata (lua_State *L) {
+void luaC_collectudata (lua_State *L) {
   Udata **p = &G(L)->rootudata;
   Udata *next;
   while ((next = *p) != NULL) {
@@ -351,9 +339,8 @@ static void callgcTM (lua_State *L, const TObject *obj) {
 }
 
 
-static void callgcTMudata (lua_State *L) {
+void luaC_callgcTMudata (lua_State *L) {
   int tag;
-  G(L)->GCthreshold = 2*G(L)->nblocks;  /* avoid GC during tag methods */
   for (tag=G(L)->ntag-1; tag>=0; tag--) {  /* for each tag (in reverse order) */
     Udata *udata;
     while ((udata = G(L)->TMtable[tag].collected) != NULL) {
@@ -368,14 +355,14 @@ static void callgcTMudata (lua_State *L) {
 
 
 void luaC_collect (lua_State *L, int all) {
-  lua_lockgc(L);
-  collectudata(L);
-  callgcTMudata(L);
+  luaC_collectudata(L);
   collectstrings(L, all);
   collecttable(L);
   collectproto(L);
   collectclosure(L);
-  lua_unlockgc(L);
+  checkMbuffer(L);
+  G(L)->GCthreshold = 2*G(L)->nblocks;  /* set new threshold */
+  luaC_callgcTMudata(L);
 }
 
 
@@ -383,8 +370,6 @@ void luaC_collectgarbage (lua_State *L) {
   markall(L);
   invalidatetables(G(L));
   luaC_collect(L, 0);
-  checkMbuffer(L);
-  G(L)->GCthreshold = 2*G(L)->nblocks;  /* set new threshold */
   callgcTM(L, &luaO_nilobject);
 }
 

+ 3 - 1
lgc.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.h,v 1.9 2001/02/02 16:23:20 roberto Exp roberto $
+** $Id: lgc.h,v 1.10 2001/06/05 19:27:32 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -15,6 +15,8 @@
 			  luaC_collectgarbage(L)
 
 
+void luaC_collectudata (lua_State *L);
+void luaC_callgcTMudata (lua_State *L);
 void luaC_collect (lua_State *L, int all);
 void luaC_collectgarbage (lua_State *L);
 

+ 6 - 3
lstate.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.c,v 1.62 2001/04/17 17:35:54 roberto Exp roberto $
+** $Id: lstate.c,v 1.63 2001/06/06 18:00:19 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -112,11 +112,14 @@ static void close_state (lua_State *L, lua_State *OL) {
     L->next->previous = L->previous;
   }
   else if (G(L)) {  /* last thread; close global state */
-    luaC_collect(L, 1);  /* collect all elements */
+    while (G(L)->rootudata) {
+      luaC_collectudata(L);  /* collect all user data */
+      luaC_callgcTMudata(L);  /* call their tag methods */
+    }  /* repeat, as tag methods may create new userdata objects */
+    luaC_collect(L, 1);  /* collect all other elements */
     lua_assert(G(L)->rootproto == NULL);
     lua_assert(G(L)->rootcl == NULL);
     lua_assert(G(L)->roottable == NULL);
-    lua_assert(G(L)->rootudata == NULL);
     luaS_freeall(L);
     luaM_freearray(L, G(L)->TMtable, G(L)->sizeTM, struct TM);
     luaM_freearray(L, G(L)->Mbuffer, G(L)->Mbuffsize, l_char);