diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-01-19 11:20:30 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-01-19 11:20:30 -0200 |
commit | 4ac58853dc820127a11a14ed8bde1fae9458369e (patch) | |
tree | e8179692c97e935ba921c8ebd17abf9c8510d89e /lgc.c | |
parent | f2c451d7455aad3496f32dfa2bfca7f7e8b5376d (diff) | |
download | lua-4ac58853dc820127a11a14ed8bde1fae9458369e.tar.gz lua-4ac58853dc820127a11a14ed8bde1fae9458369e.tar.bz2 lua-4ac58853dc820127a11a14ed8bde1fae9458369e.zip |
thead-specific state separated from "global" state
Diffstat (limited to 'lgc.c')
-rw-r--r-- | lgc.c | 85 |
1 files changed, 42 insertions, 43 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 1.75 2000/12/28 12:55:41 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.76 2001/01/18 15:59:09 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 | */ |
@@ -54,11 +54,11 @@ static void markstack (lua_State *L, GCState *st) { | |||
54 | } | 54 | } |
55 | 55 | ||
56 | 56 | ||
57 | static void marklock (lua_State *L, GCState *st) { | 57 | static void marklock (global_State *G, GCState *st) { |
58 | int i; | 58 | int i; |
59 | for (i=0; i<L->nref; i++) { | 59 | for (i=0; i<G->nref; i++) { |
60 | if (L->refArray[i].st == LOCK) | 60 | if (G->refArray[i].st == LOCK) |
61 | markobject(st, &L->refArray[i].o); | 61 | markobject(st, &G->refArray[i].o); |
62 | } | 62 | } |
63 | } | 63 | } |
64 | 64 | ||
@@ -73,12 +73,12 @@ static void markclosure (GCState *st, Closure *cl) { | |||
73 | } | 73 | } |
74 | 74 | ||
75 | 75 | ||
76 | static void marktagmethods (lua_State *L, GCState *st) { | 76 | static void marktagmethods (global_State *G, GCState *st) { |
77 | int e; | 77 | int e; |
78 | for (e=0; e<TM_N; e++) { | 78 | for (e=0; e<TM_N; e++) { |
79 | int t; | 79 | int t; |
80 | for (t=0; t<L->ntag; t++) { | 80 | for (t=0; t<G->ntag; t++) { |
81 | Closure *cl = luaT_gettm(L, t, e); | 81 | Closure *cl = luaT_gettm(G, t, e); |
82 | if (cl) markclosure(st, cl); | 82 | if (cl) markclosure(st, cl); |
83 | } | 83 | } |
84 | } | 84 | } |
@@ -113,9 +113,9 @@ static void markall (lua_State *L) { | |||
113 | st.cmark = NULL; | 113 | st.cmark = NULL; |
114 | st.tmark = L->gt; /* put table of globals in mark list */ | 114 | st.tmark = L->gt; /* put table of globals in mark list */ |
115 | L->gt->mark = NULL; | 115 | L->gt->mark = NULL; |
116 | marktagmethods(L, &st); /* mark tag methods */ | 116 | marktagmethods(G(L), &st); /* mark tag methods */ |
117 | markstack(L, &st); /* mark stack objects */ | 117 | markstack(L, &st); /* mark stack objects */ |
118 | marklock(L, &st); /* mark locked objects */ | 118 | marklock(G(L), &st); /* mark locked objects */ |
119 | for (;;) { /* mark tables and closures */ | 119 | for (;;) { /* mark tables and closures */ |
120 | if (st.cmark) { | 120 | if (st.cmark) { |
121 | int i; | 121 | int i; |
@@ -161,27 +161,26 @@ static int hasmark (const TObject *o) { | |||
161 | /* macro for internal debugging; check if a link of free refs is valid */ | 161 | /* macro for internal debugging; check if a link of free refs is valid */ |
162 | #define VALIDLINK(L, st,n) (NONEXT <= (st) && (st) < (n)) | 162 | #define VALIDLINK(L, st,n) (NONEXT <= (st) && (st) < (n)) |
163 | 163 | ||
164 | static void invalidaterefs (lua_State *L) { | 164 | static void invalidaterefs (global_State *G) { |
165 | int n = L->nref; | 165 | int n = G->nref; |
166 | int i; | 166 | int i; |
167 | for (i=0; i<n; i++) { | 167 | for (i=0; i<n; i++) { |
168 | struct Ref *r = &L->refArray[i]; | 168 | struct Ref *r = &G->refArray[i]; |
169 | if (r->st == HOLD && !hasmark(&r->o)) | 169 | if (r->st == HOLD && !hasmark(&r->o)) |
170 | r->st = COLLECTED; | 170 | r->st = COLLECTED; |
171 | LUA_ASSERT((r->st == LOCK && hasmark(&r->o)) || | 171 | lua_assert((r->st == LOCK && hasmark(&r->o)) || |
172 | (r->st == HOLD && hasmark(&r->o)) || | 172 | (r->st == HOLD && hasmark(&r->o)) || |
173 | r->st == COLLECTED || | 173 | r->st == COLLECTED || |
174 | r->st == NONEXT || | 174 | r->st == NONEXT || |
175 | (r->st < n && VALIDLINK(L, L->refArray[r->st].st, n)), | 175 | (r->st < n && VALIDLINK(L, G->refArray[r->st].st, n))); |
176 | "inconsistent ref table"); | ||
177 | } | 176 | } |
178 | LUA_ASSERT(VALIDLINK(L, L->refFree, n), "inconsistent ref table"); | 177 | lua_assert(VALIDLINK(L, G->refFree, n)); |
179 | } | 178 | } |
180 | 179 | ||
181 | 180 | ||
182 | 181 | ||
183 | static void collectproto (lua_State *L) { | 182 | static void collectproto (lua_State *L) { |
184 | Proto **p = &L->rootproto; | 183 | Proto **p = &G(L)->rootproto; |
185 | Proto *next; | 184 | Proto *next; |
186 | while ((next = *p) != NULL) { | 185 | while ((next = *p) != NULL) { |
187 | if (next->marked) { | 186 | if (next->marked) { |
@@ -197,7 +196,7 @@ static void collectproto (lua_State *L) { | |||
197 | 196 | ||
198 | 197 | ||
199 | static void collectclosure (lua_State *L) { | 198 | static void collectclosure (lua_State *L) { |
200 | Closure **p = &L->rootcl; | 199 | Closure **p = &G(L)->rootcl; |
201 | Closure *next; | 200 | Closure *next; |
202 | while ((next = *p) != NULL) { | 201 | while ((next = *p) != NULL) { |
203 | if (ismarked(next)) { | 202 | if (ismarked(next)) { |
@@ -213,7 +212,7 @@ static void collectclosure (lua_State *L) { | |||
213 | 212 | ||
214 | 213 | ||
215 | static void collecttable (lua_State *L) { | 214 | static void collecttable (lua_State *L) { |
216 | Hash **p = &L->roottable; | 215 | Hash **p = &G(L)->roottable; |
217 | Hash *next; | 216 | Hash *next; |
218 | while ((next = *p) != NULL) { | 217 | while ((next = *p) != NULL) { |
219 | if (ismarked(next)) { | 218 | if (ismarked(next)) { |
@@ -236,8 +235,8 @@ static void checktab (lua_State *L, stringtable *tb) { | |||
236 | 235 | ||
237 | static void collectstrings (lua_State *L, int all) { | 236 | static void collectstrings (lua_State *L, int all) { |
238 | int i; | 237 | int i; |
239 | for (i=0; i<L->strt.size; i++) { /* for each list */ | 238 | for (i=0; i<G(L)->strt.size; i++) { /* for each list */ |
240 | TString **p = &L->strt.hash[i]; | 239 | TString **p = &G(L)->strt.hash[i]; |
241 | TString *next; | 240 | TString *next; |
242 | while ((next = *p) != NULL) { | 241 | while ((next = *p) != NULL) { |
243 | if (next->marked && !all) { /* preserve? */ | 242 | if (next->marked && !all) { /* preserve? */ |
@@ -247,22 +246,22 @@ static void collectstrings (lua_State *L, int all) { | |||
247 | } | 246 | } |
248 | else { /* collect */ | 247 | else { /* collect */ |
249 | *p = next->nexthash; | 248 | *p = next->nexthash; |
250 | L->strt.nuse--; | 249 | G(L)->strt.nuse--; |
251 | luaM_free(L, next, sizestring(next->len)); | 250 | luaM_free(L, next, sizestring(next->len)); |
252 | } | 251 | } |
253 | } | 252 | } |
254 | } | 253 | } |
255 | checktab(L, &L->strt); | 254 | checktab(L, &G(L)->strt); |
256 | } | 255 | } |
257 | 256 | ||
258 | 257 | ||
259 | static void collectudata (lua_State *L, int all) { | 258 | static void collectudata (lua_State *L, int all) { |
260 | int i; | 259 | int i; |
261 | for (i=0; i<L->udt.size; i++) { /* for each list */ | 260 | for (i=0; i<G(L)->udt.size; i++) { /* for each list */ |
262 | TString **p = &L->udt.hash[i]; | 261 | TString **p = &G(L)->udt.hash[i]; |
263 | TString *next; | 262 | TString *next; |
264 | while ((next = *p) != NULL) { | 263 | while ((next = *p) != NULL) { |
265 | LUA_ASSERT(next->marked <= 1, "udata cannot be fixed"); | 264 | lua_assert(next->marked <= 1); |
266 | if (next->marked && !all) { /* preserve? */ | 265 | if (next->marked && !all) { /* preserve? */ |
267 | next->marked = 0; | 266 | next->marked = 0; |
268 | p = &next->nexthash; | 267 | p = &next->nexthash; |
@@ -270,28 +269,28 @@ static void collectudata (lua_State *L, int all) { | |||
270 | else { /* collect */ | 269 | else { /* collect */ |
271 | int tag = next->u.d.tag; | 270 | int tag = next->u.d.tag; |
272 | *p = next->nexthash; | 271 | *p = next->nexthash; |
273 | next->nexthash = L->TMtable[tag].collected; /* chain udata */ | 272 | next->nexthash = G(L)->TMtable[tag].collected; /* chain udata */ |
274 | L->TMtable[tag].collected = next; | 273 | G(L)->TMtable[tag].collected = next; |
275 | L->udt.nuse--; | 274 | G(L)->udt.nuse--; |
276 | } | 275 | } |
277 | } | 276 | } |
278 | } | 277 | } |
279 | checktab(L, &L->udt); | 278 | checktab(L, &G(L)->udt); |
280 | } | 279 | } |
281 | 280 | ||
282 | 281 | ||
283 | #define MINBUFFER 256 | 282 | #define MINBUFFER 256 |
284 | static void checkMbuffer (lua_State *L) { | 283 | static void checkMbuffer (lua_State *L) { |
285 | if (L->Mbuffsize > MINBUFFER*2) { /* is buffer too big? */ | 284 | if (G(L)->Mbuffsize > MINBUFFER*2) { /* is buffer too big? */ |
286 | size_t newsize = L->Mbuffsize/2; /* still larger than MINBUFFER */ | 285 | size_t newsize = G(L)->Mbuffsize/2; /* still larger than MINBUFFER */ |
287 | luaM_reallocvector(L, L->Mbuffer, L->Mbuffsize, newsize, char); | 286 | luaM_reallocvector(L, G(L)->Mbuffer, G(L)->Mbuffsize, newsize, char); |
288 | L->Mbuffsize = newsize; | 287 | G(L)->Mbuffsize = newsize; |
289 | } | 288 | } |
290 | } | 289 | } |
291 | 290 | ||
292 | 291 | ||
293 | static void callgcTM (lua_State *L, const TObject *obj) { | 292 | static void callgcTM (lua_State *L, const TObject *obj) { |
294 | Closure *tm = luaT_gettmbyObj(L, obj, TM_GC); | 293 | Closure *tm = luaT_gettmbyObj(G(L), obj, TM_GC); |
295 | if (tm != NULL) { | 294 | if (tm != NULL) { |
296 | int oldah = L->allowhooks; | 295 | int oldah = L->allowhooks; |
297 | L->allowhooks = 0; /* stop debug hooks during GC tag methods */ | 296 | L->allowhooks = 0; /* stop debug hooks during GC tag methods */ |
@@ -307,12 +306,12 @@ static void callgcTM (lua_State *L, const TObject *obj) { | |||
307 | 306 | ||
308 | static void callgcTMudata (lua_State *L) { | 307 | static void callgcTMudata (lua_State *L) { |
309 | int tag; | 308 | int tag; |
310 | L->GCthreshold = 2*L->nblocks; /* avoid GC during tag methods */ | 309 | G(L)->GCthreshold = 2*G(L)->nblocks; /* avoid GC during tag methods */ |
311 | for (tag=L->ntag-1; tag>=0; tag--) { /* for each tag (in reverse order) */ | 310 | for (tag=G(L)->ntag-1; tag>=0; tag--) { /* for each tag (in reverse order) */ |
312 | TString *udata; | 311 | TString *udata; |
313 | while ((udata = L->TMtable[tag].collected) != NULL) { | 312 | while ((udata = G(L)->TMtable[tag].collected) != NULL) { |
314 | TObject obj; | 313 | TObject obj; |
315 | L->TMtable[tag].collected = udata->nexthash; /* remove it from list */ | 314 | G(L)->TMtable[tag].collected = udata->nexthash; /* remove it from list */ |
316 | setuvalue(&obj, udata); | 315 | setuvalue(&obj, udata); |
317 | callgcTM(L, &obj); | 316 | callgcTM(L, &obj); |
318 | luaM_free(L, udata, sizeudata(udata->len)); | 317 | luaM_free(L, udata, sizeudata(udata->len)); |
@@ -333,16 +332,16 @@ void luaC_collect (lua_State *L, int all) { | |||
333 | 332 | ||
334 | static void luaC_collectgarbage (lua_State *L) { | 333 | static void luaC_collectgarbage (lua_State *L) { |
335 | markall(L); | 334 | markall(L); |
336 | invalidaterefs(L); /* check unlocked references */ | 335 | invalidaterefs(G(L)); /* check unlocked references */ |
337 | luaC_collect(L, 0); | 336 | luaC_collect(L, 0); |
338 | checkMbuffer(L); | 337 | checkMbuffer(L); |
339 | L->GCthreshold = 2*L->nblocks; /* set new threshold */ | 338 | G(L)->GCthreshold = 2*G(L)->nblocks; /* set new threshold */ |
340 | callgcTM(L, &luaO_nilobject); | 339 | callgcTM(L, &luaO_nilobject); |
341 | } | 340 | } |
342 | 341 | ||
343 | 342 | ||
344 | void luaC_checkGC (lua_State *L) { | 343 | void luaC_checkGC (lua_State *L) { |
345 | if (L->nblocks >= L->GCthreshold) | 344 | if (G(L)->nblocks >= G(L)->GCthreshold) |
346 | luaC_collectgarbage(L); | 345 | luaC_collectgarbage(L); |
347 | } | 346 | } |
348 | 347 | ||