aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-01-19 11:20:30 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-01-19 11:20:30 -0200
commit4ac58853dc820127a11a14ed8bde1fae9458369e (patch)
treee8179692c97e935ba921c8ebd17abf9c8510d89e /lgc.c
parentf2c451d7455aad3496f32dfa2bfca7f7e8b5376d (diff)
downloadlua-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.c85
1 files changed, 42 insertions, 43 deletions
diff --git a/lgc.c b/lgc.c
index 90630cd7..abe78425 100644
--- a/lgc.c
+++ b/lgc.c
@@ -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
57static void marklock (lua_State *L, GCState *st) { 57static 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
76static void marktagmethods (lua_State *L, GCState *st) { 76static 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
164static void invalidaterefs (lua_State *L) { 164static 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
183static void collectproto (lua_State *L) { 182static 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
199static void collectclosure (lua_State *L) { 198static 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
215static void collecttable (lua_State *L) { 214static 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
237static void collectstrings (lua_State *L, int all) { 236static 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
259static void collectudata (lua_State *L, int all) { 258static 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
284static void checkMbuffer (lua_State *L) { 283static 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
293static void callgcTM (lua_State *L, const TObject *obj) { 292static 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
308static void callgcTMudata (lua_State *L) { 307static 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
334static void luaC_collectgarbage (lua_State *L) { 333static 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
344void luaC_checkGC (lua_State *L) { 343void 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