aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2005-02-11 18:03:35 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2005-02-11 18:03:35 -0200
commit678d2fb2ace2dbdf91fdac2752e1f4dfe73651df (patch)
treecf4ab13aee46788c66623009932f118c882d501c
parentaf39352632864b1961a554a560bee2c758666b2a (diff)
downloadlua-678d2fb2ace2dbdf91fdac2752e1f4dfe73651df.tar.gz
lua-678d2fb2ace2dbdf91fdac2752e1f4dfe73651df.tar.bz2
lua-678d2fb2ace2dbdf91fdac2752e1f4dfe73651df.zip
all collected userdata must go to the end of the list of finalizers
-rw-r--r--lgc.c40
-rw-r--r--lstate.h4
2 files changed, 26 insertions, 18 deletions
diff --git a/lgc.c b/lgc.c
index 27198217..c5b3005b 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.22 2005/01/18 17:18:09 roberto Exp roberto $ 2** $Id: lgc.c,v 2.23 2005/02/10 13:25:02 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -114,21 +114,23 @@ static void reallymarkobject (global_State *g, GCObject *o) {
114 114
115 115
116static void marktmu (global_State *g) { 116static void marktmu (global_State *g) {
117 GCObject *u; 117 GCObject *u = g->tmudata;
118 for (u = g->tmudata; u; u = u->gch.next) { 118 if (u) {
119 makewhite(g, u); /* may be marked, if left from previous GC */ 119 do {
120 reallymarkobject(g, u); 120 u = u->gch.next;
121 makewhite(g, u); /* may be marked, if left from previous GC */
122 reallymarkobject(g, u);
123 } while (u != g->tmudata);
121 } 124 }
122} 125}
123 126
124 127
125/* move `dead' udata that need finalization to list `tmudata' */ 128/* move `dead' udata that need finalization to list `tmudata' */
126size_t luaC_separateudata (lua_State *L, int all) { 129size_t luaC_separateudata (lua_State *L, int all) {
130 global_State *g = G(L);
127 size_t deadmem = 0; 131 size_t deadmem = 0;
128 GCObject **p = &G(L)->mainthread->next; 132 GCObject **p = &g->mainthread->next;
129 GCObject *curr; 133 GCObject *curr;
130 GCObject *collected = NULL; /* to collect udata with gc event */
131 GCObject **lastcollected = &collected;
132 while ((curr = *p) != NULL) { 134 while ((curr = *p) != NULL) {
133 if (!(iswhite(curr) || all) || isfinalized(gco2u(curr))) 135 if (!(iswhite(curr) || all) || isfinalized(gco2u(curr)))
134 p = &curr->gch.next; /* don't bother with them */ 136 p = &curr->gch.next; /* don't bother with them */
@@ -140,14 +142,16 @@ size_t luaC_separateudata (lua_State *L, int all) {
140 deadmem += sizeudata(gco2u(curr)); 142 deadmem += sizeudata(gco2u(curr));
141 markfinalized(gco2u(curr)); 143 markfinalized(gco2u(curr));
142 *p = curr->gch.next; 144 *p = curr->gch.next;
143 curr->gch.next = NULL; /* link `curr' at the end of `collected' list */ 145 /* link `curr' at the end of `tmudata' list */
144 *lastcollected = curr; 146 if (g->tmudata == NULL) /* list is empty? */
145 lastcollected = &curr->gch.next; 147 g->tmudata = curr->gch.next = curr; /* creates a circular list */
148 else {
149 curr->gch.next = g->tmudata->gch.next;
150 g->tmudata->gch.next = curr;
151 g->tmudata = curr;
152 }
146 } 153 }
147 } 154 }
148 /* insert collected udata with gc event into `tmudata' list */
149 *lastcollected = G(L)->tmudata;
150 G(L)->tmudata = collected;
151 return deadmem; 155 return deadmem;
152} 156}
153 157
@@ -443,10 +447,14 @@ static void checkSizes (lua_State *L) {
443 447
444static void GCTM (lua_State *L) { 448static void GCTM (lua_State *L) {
445 global_State *g = G(L); 449 global_State *g = G(L);
446 GCObject *o = g->tmudata; 450 GCObject *o = g->tmudata->gch.next; /* get first element */
447 Udata *udata = rawgco2u(o); 451 Udata *udata = rawgco2u(o);
448 const TValue *tm; 452 const TValue *tm;
449 g->tmudata = udata->uv.next; /* remove udata from `tmudata' */ 453 /* remove udata from `tmudata' */
454 if (o == g->tmudata) /* last element? */
455 g->tmudata = NULL;
456 else
457 g->tmudata->gch.next = udata->uv.next;
450 udata->uv.next = g->mainthread->next; /* return it to `root' list */ 458 udata->uv.next = g->mainthread->next; /* return it to `root' list */
451 g->mainthread->next = o; 459 g->mainthread->next = o;
452 makewhite(g, o); 460 makewhite(g, o);
diff --git a/lstate.h b/lstate.h
index 6c6d32e4..2ba5a91d 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 2.12 2005/01/14 14:19:42 roberto Exp $ 2** $Id: lstate.h,v 2.13 2005/01/18 17:18:09 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -77,7 +77,7 @@ typedef struct global_State {
77 GCObject *gray; /* list of gray objects */ 77 GCObject *gray; /* list of gray objects */
78 GCObject *grayagain; /* list of objects to be traversed atomically */ 78 GCObject *grayagain; /* list of objects to be traversed atomically */
79 GCObject *weak; /* list of weak tables (to be cleared) */ 79 GCObject *weak; /* list of weak tables (to be cleared) */
80 GCObject *tmudata; /* list of userdata to be GC */ 80 GCObject *tmudata; /* last element of list of userdata to be GC */
81 Mbuffer buff; /* temporary buffer for string concatentation */ 81 Mbuffer buff; /* temporary buffer for string concatentation */
82 lu_mem GCthreshold; 82 lu_mem GCthreshold;
83 lu_mem totalbytes; /* number of bytes currently allocated */ 83 lu_mem totalbytes; /* number of bytes currently allocated */