aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c73
1 files changed, 58 insertions, 15 deletions
diff --git a/lgc.c b/lgc.c
index 17373f9a..20d97cf2 100644
--- a/lgc.c
+++ b/lgc.c
@@ -7,6 +7,7 @@
7#define LUA_PRIVATE 7#define LUA_PRIVATE
8#include "lua.h" 8#include "lua.h"
9 9
10#include "ldebug.h"
10#include "ldo.h" 11#include "ldo.h"
11#include "lfunc.h" 12#include "lfunc.h"
12#include "lgc.h" 13#include "lgc.h"
@@ -45,15 +46,12 @@ static void protomark (Proto *f) {
45 for (i=0; i<f->sizelocvars; i++) /* mark local-variable names */ 46 for (i=0; i<f->sizelocvars; i++) /* mark local-variable names */
46 strmark(f->locvars[i].varname); 47 strmark(f->locvars[i].varname);
47 } 48 }
49 lua_assert(luaG_checkcode(f));
48} 50}
49 51
50 52
51static void markclosure (GCState *st, Closure *cl) { 53static void markclosure (GCState *st, Closure *cl) {
52 if (!ismarked(cl)) { 54 if (!ismarked(cl)) {
53 if (!cl->isC) {
54 lua_assert(cl->nupvalues == cl->f.l->nupvalues);
55 protomark(cl->f.l);
56 }
57 cl->mark = st->cmark; /* chain it for later traversal */ 55 cl->mark = st->cmark; /* chain it for later traversal */
58 st->cmark = cl; 56 st->cmark = cl;
59 } 57 }
@@ -84,7 +82,10 @@ static void markobject (GCState *st, TObject *o) {
84 marktable(st, hvalue(o)); 82 marktable(st, hvalue(o));
85 break; 83 break;
86 } 84 }
87 default: break; /* numbers, etc */ 85 default: {
86 lua_assert(0 <= ttype(o) && ttype(o) <= LUA_TUPVAL);
87 break;
88 }
88 } 89 }
89} 90}
90 91
@@ -119,10 +120,26 @@ static void marktagmethods (global_State *G, GCState *st) {
119} 120}
120 121
121 122
122static void traverseclosure (GCState *st, Closure *f) { 123static void traverseclosure (GCState *st, Closure *cl) {
123 int i; 124 if (cl->isC) {
124 for (i=0; i<f->nupvalues; i++) /* mark its upvalues */ 125 int i;
125 markobject(st, &f->upvalue[i]); 126 for (i=0; i<cl->nupvalues; i++) /* mark its upvalues */
127 markobject(st, &cl->u.c.upvalue[i]);
128 }
129 else {
130 int i;
131 lua_assert(cl->nupvalues == cl->u.l.p->nupvalues);
132 protomark(cl->u.l.p);
133 for (i=0; i<cl->nupvalues; i++) { /* mark its upvalues */
134 if (luaF_isclosed(cl, i)) {
135 UpVal *u = cast(UpVal *, cl->u.l.upvals[i]);
136 if (!u->marked) {
137 u->marked = 1;
138 markobject(st, &u->val);
139 }
140 }
141 }
142 }
126} 143}
127 144
128 145
@@ -164,9 +181,9 @@ static void markall (lua_State *L) {
164 marktable(&st, G(L)->weakregistry); 181 marktable(&st, G(L)->weakregistry);
165 for (;;) { /* mark tables and closures */ 182 for (;;) { /* mark tables and closures */
166 if (st.cmark) { 183 if (st.cmark) {
167 Closure *f = st.cmark; /* get first closure from list */ 184 Closure *cl = st.cmark; /* get first closure from list */
168 st.cmark = f->mark; /* remove it from list */ 185 st.cmark = cl->mark; /* remove it from list */
169 traverseclosure(&st, f); 186 traverseclosure(&st, cl);
170 } 187 }
171 else if (st.tmark) { 188 else if (st.tmark) {
172 Hash *h = st.tmark; /* get first table from list */ 189 Hash *h = st.tmark; /* get first table from list */
@@ -232,8 +249,7 @@ static void collectproto (lua_State *L) {
232} 249}
233 250
234 251
235static void collectclosure (lua_State *L) { 252static void collectclosure (lua_State *L, Closure **p) {
236 Closure **p = &G(L)->rootcl;
237 Closure *curr; 253 Closure *curr;
238 while ((curr = *p) != NULL) { 254 while ((curr = *p) != NULL) {
239 if (ismarked(curr)) { 255 if (ismarked(curr)) {
@@ -248,6 +264,16 @@ static void collectclosure (lua_State *L) {
248} 264}
249 265
250 266
267static void collectclosures (lua_State *L) {
268 lua_State *L1 = L;
269 do { /* for each thread */
270 collectclosure(L1, &L1->opencl);
271 L1 = L1->next;
272 } while (L1 != L);
273 collectclosure(L, &G(L)->rootcl);
274}
275
276
251static void collecttable (lua_State *L) { 277static void collecttable (lua_State *L) {
252 Hash **p = &G(L)->roottable; 278 Hash **p = &G(L)->roottable;
253 Hash *curr; 279 Hash *curr;
@@ -264,6 +290,22 @@ static void collecttable (lua_State *L) {
264} 290}
265 291
266 292
293static void collectupval (lua_State *L) {
294 UpVal **v = &G(L)->rootupval;
295 UpVal *curr;
296 while ((curr = *v) != NULL) {
297 if (curr->marked) {
298 curr->marked = 0;
299 v = &curr->next;
300 }
301 else {
302 *v = curr->next;
303 luaM_freelem(L, curr);
304 }
305 }
306}
307
308
267static void collectudata (lua_State *L, int keep) { 309static void collectudata (lua_State *L, int keep) {
268 Udata **p = &G(L)->rootudata; 310 Udata **p = &G(L)->rootudata;
269 Udata *curr; 311 Udata *curr;
@@ -370,7 +412,8 @@ void luaC_collect (lua_State *L, int all) {
370 collectstrings(L, all); 412 collectstrings(L, all);
371 collecttable(L); 413 collecttable(L);
372 collectproto(L); 414 collectproto(L);
373 collectclosure(L); 415 collectupval(L);
416 collectclosures(L);
374} 417}
375 418
376 419