summaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-10-02 11:47:43 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-10-02 11:47:43 -0300
commit78bc8e553d4190fc3b90be5b621fc0f3507586ef (patch)
tree9bd9317e1a56960b944549d44a20b91024574c19 /lgc.c
parentdad808a73a98a23729614b8814728d76b4e5d577 (diff)
downloadlua-78bc8e553d4190fc3b90be5b621fc0f3507586ef.tar.gz
lua-78bc8e553d4190fc3b90be5b621fc0f3507586ef.tar.bz2
lua-78bc8e553d4190fc3b90be5b621fc0f3507586ef.zip
new API for garbage collector
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c68
1 files changed, 31 insertions, 37 deletions
diff --git a/lgc.c b/lgc.c
index 296179a6..4ff8bf3c 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.67 2000/09/25 14:52:10 roberto Exp roberto $ 2** $Id: lgc.c,v 1.68 2000/09/29 12:42:13 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*/
@@ -235,18 +235,13 @@ static void checktab (lua_State *L, stringtable *tb) {
235} 235}
236 236
237 237
238/* 238static void collectstrings (lua_State *L, int all) {
239** collect all elements with `marked' <= `limit'.
240** with limit=0, that means all unmarked elements;
241** with limit=MAX_INT, that means all elements.
242*/
243static void collectstringtab (lua_State *L, int limit) {
244 int i; 239 int i;
245 for (i=0; i<L->strt.size; i++) { /* for each list */ 240 for (i=0; i<L->strt.size; i++) { /* for each list */
246 TString **p = &L->strt.hash[i]; 241 TString **p = &L->strt.hash[i];
247 TString *next; 242 TString *next;
248 while ((next = *p) != NULL) { 243 while ((next = *p) != NULL) {
249 if ((int)next->marked > limit) { /* preserve? */ 244 if (next->marked && !all) { /* preserve? */
250 if (next->marked < FIXMARK) /* does not change FIXMARKs */ 245 if (next->marked < FIXMARK) /* does not change FIXMARKs */
251 next->marked = 0; 246 next->marked = 0;
252 p = &next->nexthash; 247 p = &next->nexthash;
@@ -263,14 +258,14 @@ static void collectstringtab (lua_State *L, int limit) {
263} 258}
264 259
265 260
266static void collectudatatab (lua_State *L, int all) { 261static void collectudata (lua_State *L, int all) {
267 int i; 262 int i;
268 for (i=0; i<L->udt.size; i++) { /* for each list */ 263 for (i=0; i<L->udt.size; i++) { /* for each list */
269 TString **p = &L->udt.hash[i]; 264 TString **p = &L->udt.hash[i];
270 TString *next; 265 TString *next;
271 while ((next = *p) != NULL) { 266 while ((next = *p) != NULL) {
272 LUA_ASSERT(next->marked <= 1, "udata cannot be fixed"); 267 LUA_ASSERT(next->marked <= 1, "udata cannot be fixed");
273 if ((int)next->marked > all) { /* preserve? */ 268 if (next->marked && !all) { /* preserve? */
274 next->marked = 0; 269 next->marked = 0;
275 p = &next->nexthash; 270 p = &next->nexthash;
276 } 271 }
@@ -289,14 +284,28 @@ static void collectudatatab (lua_State *L, int all) {
289} 284}
290 285
291 286
287#define MINBUFFER 256
288static void checkMbuffer (lua_State *L) {
289 if (L->Mbuffsize > MINBUFFER*2) { /* is buffer too big? */
290 size_t newsize = L->Mbuffsize/2; /* still larger than MINBUFFER */
291 L->nblocks += (newsize - L->Mbuffsize)*sizeof(char);
292 L->Mbuffsize = newsize;
293 luaM_reallocvector(L, L->Mbuffer, newsize, char);
294 }
295}
296
297
292static void callgcTM (lua_State *L, const TObject *o) { 298static void callgcTM (lua_State *L, const TObject *o) {
293 const TObject *im = luaT_getimbyObj(L, o, IM_GC); 299 const TObject *im = luaT_getimbyObj(L, o, IM_GC);
294 if (ttype(im) != TAG_NIL) { 300 if (ttype(im) != TAG_NIL) {
301 int oldah = L->allowhooks;
302 L->allowhooks = 0; /* stop debug hooks during GC tag methods */
295 luaD_checkstack(L, 2); 303 luaD_checkstack(L, 2);
296 *(L->top) = *im; 304 *(L->top) = *im;
297 *(L->top+1) = *o; 305 *(L->top+1) = *o;
298 L->top += 2; 306 L->top += 2;
299 luaD_call(L, L->top-2, 0); 307 luaD_call(L, L->top-2, 0);
308 L->allowhooks = oldah; /* restore hooks */
300 } 309 }
301} 310}
302 311
@@ -305,56 +314,41 @@ static void callgcTMudata (lua_State *L) {
305 int tag; 314 int tag;
306 TObject o; 315 TObject o;
307 ttype(&o) = TAG_USERDATA; 316 ttype(&o) = TAG_USERDATA;
308 for (tag=L->last_tag; tag>=0; tag--) { 317 L->GCthreshold = 2*L->nblocks; /* avoid GC during tag methods */
309 TString *udata = L->IMtable[tag].collected; 318 for (tag=L->last_tag; tag>=0; tag--) { /* for each tag (in reverse order) */
310 L->IMtable[tag].collected = NULL; 319 TString *udata;
311 while (udata) { 320 while ((udata = L->IMtable[tag].collected) != NULL) {
312 TString *next = udata->nexthash; 321 L->IMtable[tag].collected = udata->nexthash; /* remove it from list */
313 tsvalue(&o) = udata; 322 tsvalue(&o) = udata;
314 callgcTM(L, &o); 323 callgcTM(L, &o);
315 luaM_free(L, udata); 324 luaM_free(L, udata);
316 udata = next;
317 } 325 }
318 } 326 }
319} 327}
320 328
321 329
322void luaC_collect (lua_State *L, int all) { 330void luaC_collect (lua_State *L, int all) {
323 int oldah = L->allowhooks; 331 collectudata(L, all);
324 L->allowhooks = 0; /* stop debug hooks during GC */
325 L->GCthreshold *= 4; /* to avoid GC during GC */
326 collectudatatab(L, all);
327 callgcTMudata(L); 332 callgcTMudata(L);
328 collectstringtab(L, all?MAX_INT:0); 333 collectstrings(L, all);
329 collecttable(L); 334 collecttable(L);
330 collectproto(L); 335 collectproto(L);
331 collectclosure(L); 336 collectclosure(L);
332 L->allowhooks = oldah; /* restore hooks */
333} 337}
334 338
335 339
336#define MINBUFFER 256 340static void luaC_collectgarbage (lua_State *L) {
337
338long lua_collectgarbage (lua_State *L, long limit) {
339 unsigned long recovered = L->nblocks; /* to subtract `nblocks' after gc */
340 markall(L); 341 markall(L);
341 invalidaterefs(L); 342 invalidaterefs(L); /* check unlocked references */
342 luaC_collect(L, 0); 343 luaC_collect(L, 0);
343 recovered = recovered - L->nblocks; 344 checkMbuffer(L);
344 L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit; 345 L->GCthreshold = 2*L->nblocks; /* set new threshold */
345 if (L->Mbuffsize > MINBUFFER*2) { /* is buffer too big? */
346 size_t diff = L->Mbuffsize/2;
347 L->Mbuffsize -= diff; /* still larger than MINBUFFER */
348 L->nblocks -= diff*sizeof(char);
349 luaM_reallocvector(L, L->Mbuffer, L->Mbuffsize, char);
350 }
351 callgcTM(L, &luaO_nilobject); 346 callgcTM(L, &luaO_nilobject);
352 return recovered;
353} 347}
354 348
355 349
356void luaC_checkGC (lua_State *L) { 350void luaC_checkGC (lua_State *L) {
357 if (L->nblocks >= L->GCthreshold) 351 if (L->nblocks >= L->GCthreshold)
358 lua_collectgarbage(L, 0); 352 luaC_collectgarbage(L);
359} 353}
360 354