aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-10-02 13:45:03 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-10-02 13:45:03 -0300
commit15462edb0ff86bf1904011b29635420451cab2c5 (patch)
tree9a626d34736b830f83fda3f1b2f3342990a05b1f /lgc.c
parent6f936bc7931662d0460d47ad73eca308ba5fab2f (diff)
downloadlua-15462edb0ff86bf1904011b29635420451cab2c5.tar.gz
lua-15462edb0ff86bf1904011b29635420451cab2c5.tar.bz2
lua-15462edb0ff86bf1904011b29635420451cab2c5.zip
new definitions for closure structures
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c78
1 files changed, 32 insertions, 46 deletions
diff --git a/lgc.c b/lgc.c
index 20d97cf2..cb08df35 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.109 2001/06/28 14:57:17 roberto Exp $ 2** $Id: lgc.c,v 1.111 2001/09/07 17:39:10 roberto Exp $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -22,7 +22,6 @@
22 22
23typedef struct GCState { 23typedef struct GCState {
24 Hash *tmark; /* list of marked tables to be visited */ 24 Hash *tmark; /* list of marked tables to be visited */
25 Closure *cmark; /* list of marked closures to be visited */
26} GCState; 25} GCState;
27 26
28 27
@@ -32,6 +31,9 @@ typedef struct GCState {
32 31
33 32
34 33
34static void markobject (GCState *st, TObject *o);
35
36
35static void protomark (Proto *f) { 37static void protomark (Proto *f) {
36 if (!f->marked) { 38 if (!f->marked) {
37 int i; 39 int i;
@@ -51,9 +53,25 @@ static void protomark (Proto *f) {
51 53
52 54
53static void markclosure (GCState *st, Closure *cl) { 55static void markclosure (GCState *st, Closure *cl) {
54 if (!ismarked(cl)) { 56 if (!cl->c.marked) {
55 cl->mark = st->cmark; /* chain it for later traversal */ 57 cl->c.marked = 1;
56 st->cmark = cl; 58 if (cl->c.isC) {
59 int i;
60 for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */
61 markobject(st, &cl->c.upvalue[i]);
62 }
63 else {
64 int i;
65 lua_assert(cl->l.nupvalues == cl->l.p->nupvalues);
66 protomark(cl->l.p);
67 for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */
68 UpVal *u = cl->l.upvals[i].heap;
69 if (u && !u->marked) {
70 u->marked = 1;
71 markobject(st, &u->val);
72 }
73 }
74 }
57 } 75 }
58} 76}
59 77
@@ -120,29 +138,6 @@ static void marktagmethods (global_State *G, GCState *st) {
120} 138}
121 139
122 140
123static void traverseclosure (GCState *st, Closure *cl) {
124 if (cl->isC) {
125 int 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 }
143}
144
145
146static void removekey (Node *n) { 141static void removekey (Node *n) {
147 lua_assert(ttype(val(n)) == LUA_TNIL); 142 lua_assert(ttype(val(n)) == LUA_TNIL);
148 if (ttype(key(n)) != LUA_TNIL && ttype(key(n)) != LUA_TNUMBER) 143 if (ttype(key(n)) != LUA_TNIL && ttype(key(n)) != LUA_TNUMBER)
@@ -172,25 +167,16 @@ static void traversetable (GCState *st, Hash *h) {
172 167
173static void markall (lua_State *L) { 168static void markall (lua_State *L) {
174 GCState st; 169 GCState st;
175 st.cmark = NULL;
176 st.tmark = NULL; 170 st.tmark = NULL;
177 marktagmethods(G(L), &st); /* mark tag methods */ 171 marktagmethods(G(L), &st); /* mark tag methods */
178 markstacks(L, &st); /* mark all stacks */ 172 markstacks(L, &st); /* mark all stacks */
179 marktable(&st, G(L)->type2tag); 173 marktable(&st, G(L)->type2tag);
180 marktable(&st, G(L)->registry); 174 marktable(&st, G(L)->registry);
181 marktable(&st, G(L)->weakregistry); 175 marktable(&st, G(L)->weakregistry);
182 for (;;) { /* mark tables and closures */ 176 while (st.tmark) { /* mark tables */
183 if (st.cmark) { 177 Hash *h = st.tmark; /* get first table from list */
184 Closure *cl = st.cmark; /* get first closure from list */ 178 st.tmark = h->mark; /* remove it from list */
185 st.cmark = cl->mark; /* remove it from list */ 179 traversetable(&st, h);
186 traverseclosure(&st, cl);
187 }
188 else if (st.tmark) {
189 Hash *h = st.tmark; /* get first table from list */
190 st.tmark = h->mark; /* remove it from list */
191 traversetable(&st, h);
192 }
193 else break; /* nothing else to mark */
194 } 180 }
195} 181}
196 182
@@ -204,7 +190,7 @@ static int hasmark (const TObject *o) {
204 case LUA_TTABLE: 190 case LUA_TTABLE:
205 return ismarked(hvalue(o)); 191 return ismarked(hvalue(o));
206 case LUA_TFUNCTION: 192 case LUA_TFUNCTION:
207 return ismarked(clvalue(o)); 193 return clvalue(o)->c.marked;
208 default: /* number, nil */ 194 default: /* number, nil */
209 return 1; 195 return 1;
210 } 196 }
@@ -252,12 +238,12 @@ static void collectproto (lua_State *L) {
252static void collectclosure (lua_State *L, Closure **p) { 238static void collectclosure (lua_State *L, Closure **p) {
253 Closure *curr; 239 Closure *curr;
254 while ((curr = *p) != NULL) { 240 while ((curr = *p) != NULL) {
255 if (ismarked(curr)) { 241 if (curr->c.marked) {
256 curr->mark = curr; /* unmark */ 242 curr->c.marked = 0;
257 p = &curr->next; 243 p = &curr->c.next;
258 } 244 }
259 else { 245 else {
260 *p = curr->next; 246 *p = curr->c.next;
261 luaF_freeclosure(L, curr); 247 luaF_freeclosure(L, curr);
262 } 248 }
263 } 249 }