diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-10-02 13:45:03 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-10-02 13:45:03 -0300 |
commit | 15462edb0ff86bf1904011b29635420451cab2c5 (patch) | |
tree | 9a626d34736b830f83fda3f1b2f3342990a05b1f /lgc.c | |
parent | 6f936bc7931662d0460d47ad73eca308ba5fab2f (diff) | |
download | lua-15462edb0ff86bf1904011b29635420451cab2c5.tar.gz lua-15462edb0ff86bf1904011b29635420451cab2c5.tar.bz2 lua-15462edb0ff86bf1904011b29635420451cab2c5.zip |
new definitions for closure structures
Diffstat (limited to 'lgc.c')
-rw-r--r-- | lgc.c | 78 |
1 files changed, 32 insertions, 46 deletions
@@ -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 | ||
23 | typedef struct GCState { | 23 | typedef 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 | ||
34 | static void markobject (GCState *st, TObject *o); | ||
35 | |||
36 | |||
35 | static void protomark (Proto *f) { | 37 | static 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 | ||
53 | static void markclosure (GCState *st, Closure *cl) { | 55 | static 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 | ||
123 | static 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 | |||
146 | static void removekey (Node *n) { | 141 | static 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 | ||
173 | static void markall (lua_State *L) { | 168 | static 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) { | |||
252 | static void collectclosure (lua_State *L, Closure **p) { | 238 | static 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 | } |