aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-03-23 09:57:12 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-03-23 09:57:12 -0300
commit178246062ccda6f8bd2cc2dc847ceb3b8800850c (patch)
tree4ea7f813b293dd24428171367d9538ff78d82a34 /lgc.c
parent24f2d1183c6bda0832456168c59109b6708b0738 (diff)
downloadlua-178246062ccda6f8bd2cc2dc847ceb3b8800850c.tar.gz
lua-178246062ccda6f8bd2cc2dc847ceb3b8800850c.tar.bz2
lua-178246062ccda6f8bd2cc2dc847ceb3b8800850c.zip
reuse `sweeplist' for all lists
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c83
1 files changed, 36 insertions, 47 deletions
diff --git a/lgc.c b/lgc.c
index c7d5ad61..cd8bf720 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.4 2004/03/09 17:34:35 roberto Exp roberto $ 2** $Id: lgc.c,v 2.5 2004/03/15 21:04:33 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*/
@@ -25,6 +25,7 @@
25#define GCSTEPSIZE (40*sizeof(TValue)) 25#define GCSTEPSIZE (40*sizeof(TValue))
26#define GCFREECOST (sizeof(TValue)/2) 26#define GCFREECOST (sizeof(TValue)/2)
27#define GCSWEEPCOST sizeof(TValue) 27#define GCSWEEPCOST sizeof(TValue)
28#define GCFINALIZECOST (10*sizeof(TValue))
28 29
29 30
30#define FIXEDMASK bitmask(FIXEDBIT) 31#define FIXEDMASK bitmask(FIXEDBIT)
@@ -392,31 +393,22 @@ static void freeobj (lua_State *L, GCObject *o) {
392} 393}
393 394
394 395
395static void sweepupvalues (global_State *g, lua_State *l) { 396static l_mem sweepwholelist (lua_State *L, GCObject **p, int keepfixed,
396 GCObject *curr; 397 lu_int32 *count);
397 for (curr = l->openupval; curr != NULL; curr = curr->gch.next)
398 makewhite(g, curr);
399}
400
401
402/*
403** macros to test dead bit and optionally the fix bit
404*/
405#define makedeadmask(g,kf) (otherwhite(g) | ((kf) ? FIXEDMASK : 0))
406#define notdead(mark,mask) ((((mark) ^ FIXEDMASK) & mask) != mask)
407 398
408 399
409static GCObject **sweeplist (lua_State *L, GCObject **p, int keepfixed, 400static GCObject **sweeplist (lua_State *L, GCObject **p, int keepfixed,
410 l_mem *plim) { 401 l_mem *plim, lu_int32 *count) {
411 GCObject *curr; 402 GCObject *curr;
412 global_State *g = G(L); 403 global_State *g = G(L);
413 l_mem lim = *plim; 404 l_mem lim = *plim;
414 int deadmask = makedeadmask(g, keepfixed); 405 int deadmask = otherwhite(g);
406 if (keepfixed) deadmask |= FIXEDMASK;
415 while ((curr = *p) != NULL) { 407 while ((curr = *p) != NULL) {
416 if (notdead(curr->gch.marked, deadmask)) { 408 if (((curr->gch.marked ^ FIXEDMASK) & deadmask) != deadmask) {
417 makewhite(g, curr); 409 makewhite(g, curr);
418 if (curr->gch.tt == LUA_TTHREAD) 410 if (curr->gch.tt == LUA_TTHREAD)
419 sweepupvalues(g, gco2th(curr)); 411 lim -= sweepwholelist(L, &gco2th(curr)->openupval, keepfixed, count);
420 p = &curr->gch.next; 412 p = &curr->gch.next;
421 lim -= GCSWEEPCOST; 413 lim -= GCSWEEPCOST;
422 } 414 }
@@ -427,6 +419,7 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, int keepfixed,
427 g->rootgc = curr->gch.next; /* adjust first */ 419 g->rootgc = curr->gch.next; /* adjust first */
428 freeobj(L, curr); 420 freeobj(L, curr);
429 lim -= GCFREECOST; 421 lim -= GCFREECOST;
422 if (count) (*count)--;
430 } 423 }
431 if (lim <= 0) break; 424 if (lim <= 0) break;
432 } 425 }
@@ -435,28 +428,20 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, int keepfixed,
435} 428}
436 429
437 430
431static l_mem sweepwholelist (lua_State *L, GCObject **p, int keepfixed,
432 lu_int32 *count) {
433 l_mem lim = MAXLMEM;
434 /* empty lists are quite common here, so avoid useless calls */
435 if (*p) sweeplist(L, p, keepfixed, &lim, count);
436 return MAXLMEM - lim;
437}
438
439
438static l_mem sweepstrings (lua_State *L, int keepfixed, l_mem lim) { 440static l_mem sweepstrings (lua_State *L, int keepfixed, l_mem lim) {
439 int i; 441 int i;
440 global_State *g = G(L); 442 global_State *g = G(L);
441 int deadmask = makedeadmask(g, keepfixed);
442 for (i = g->sweepstrgc; i < g->strt.size; i++) { /* for each list */ 443 for (i = g->sweepstrgc; i < g->strt.size; i++) { /* for each list */
443 GCObject *curr; 444 lim -= sweepwholelist(L, &G(L)->strt.hash[i], keepfixed, &g->strt.nuse);
444 GCObject **p = &G(L)->strt.hash[i];
445 while ((curr = *p) != NULL) {
446 lu_mem size = sizestring(gco2ts(curr)->len);
447 if (notdead(curr->gch.marked, deadmask)) {
448 makewhite(g, curr);
449 lua_assert(iswhite(curr) && !isdead(g, curr));
450 p = &curr->gch.next;
451 }
452 else {
453 lua_assert(iswhite(curr));
454 g->strt.nuse--;
455 *p = curr->gch.next;
456 luaM_free(L, curr, size);
457 }
458 lim -= size;
459 }
460 if (lim <= 0) break; 445 if (lim <= 0) break;
461 } 446 }
462 g->sweepstrgc = i+1; 447 g->sweepstrgc = i+1;
@@ -513,16 +498,15 @@ void luaC_sweepall (lua_State *L) {
513 global_State *g = G(L); 498 global_State *g = G(L);
514 l_mem dummy = MAXLMEM; 499 l_mem dummy = MAXLMEM;
515 /* finish (occasional) current sweep */ 500 /* finish (occasional) current sweep */
516 markobject(g, g->mainthread); /* cannot collect main thread */
517 sweepstrings(L, 0, MAXLMEM); 501 sweepstrings(L, 0, MAXLMEM);
518 sweeplist(L, &g->rootgc, 0, &dummy); 502 sweeplist(L, &g->rootgc, 0, &dummy, NULL);
519 /* do a whole new sweep */ 503 /* do a whole new sweep */
520 markobject(g, g->mainthread); /* cannot collect main thread */ 504 markobject(g, g->mainthread); /* cannot collect main thread */
521 g->currentwhite = otherwhite(g); 505 g->currentwhite = otherwhite(g);
522 g->sweepgc = &g->rootgc; 506 g->sweepgc = &g->rootgc;
523 g->sweepstrgc = 0; 507 g->sweepstrgc = 0;
524 sweepstrings(L, 0, MAXLMEM); 508 sweepstrings(L, 0, MAXLMEM);
525 sweeplist(L, &g->rootgc, 0, &dummy); 509 sweeplist(L, &g->rootgc, 0, &dummy, NULL);
526} 510}
527 511
528 512
@@ -532,10 +516,10 @@ static void markroot (lua_State *L) {
532 lua_assert(g->gray == NULL); 516 lua_assert(g->gray == NULL);
533 g->grayagain = NULL; 517 g->grayagain = NULL;
534 g->weak = NULL; 518 g->weak = NULL;
535 makewhite(g, obj2gco(g->mainthread));
536 markobject(g, g->mainthread); 519 markobject(g, g->mainthread);
520 /* make global table be traversed before main stack */
521 markvalue(g, gt(g->mainthread));
537 markvalue(g, registry(L)); 522 markvalue(g, registry(L));
538 markobject(g, L); /* mark running thread */
539 g->gcstate = GCSpropagate; 523 g->gcstate = GCSpropagate;
540} 524}
541 525
@@ -600,7 +584,7 @@ static l_mem singlestep (lua_State *L, l_mem lim) {
600 break; 584 break;
601 } 585 }
602 case GCSsweep: { 586 case GCSsweep: {
603 g->sweepgc = sweeplist(L, g->sweepgc, 1, &lim); 587 g->sweepgc = sweeplist(L, g->sweepgc, 1, &lim, NULL);
604 if (*g->sweepgc == NULL) { /* nothing more to sweep? */ 588 if (*g->sweepgc == NULL) { /* nothing more to sweep? */
605 checkSizes(L); 589 checkSizes(L);
606 g->sweepgc = &g->rootgc; 590 g->sweepgc = &g->rootgc;
@@ -609,11 +593,14 @@ static l_mem singlestep (lua_State *L, l_mem lim) {
609 break; 593 break;
610 } 594 }
611 case GCSfinalize: { 595 case GCSfinalize: {
612 if (g->tmudata) 596 if (g->tmudata) {
613 GCTM(L); 597 GCTM(L);
614 else /* no more `udata' to finalize */ 598 lim -= GCFINALIZECOST;
599 }
600 else { /* no more `udata' to finalize */
615 markroot(L); /* may restart collection */ 601 markroot(L); /* may restart collection */
616 lim = 0; 602 lim = 0;
603 }
617 break; 604 break;
618 } 605 }
619 default: lua_assert(0); 606 default: lua_assert(0);
@@ -625,10 +612,12 @@ static l_mem singlestep (lua_State *L, l_mem lim) {
625void luaC_step (lua_State *L) { 612void luaC_step (lua_State *L) {
626 global_State *g = G(L); 613 global_State *g = G(L);
627 l_mem lim = (g->nblocks - (g->GCthreshold - GCSTEPSIZE)) * 2; 614 l_mem lim = (g->nblocks - (g->GCthreshold - GCSTEPSIZE)) * 2;
628/*printf("+ %d %lu %lu %ld\n", g->gcstate, g->nblocks, g->GCthreshold, lim);*/ 615 do {
629 while (lim > 0) lim = singlestep(L, lim); 616 lim = singlestep(L, lim);
617 if (g->gcstate == GCSfinalize && g->tmudata == NULL)
618 break; /* do not start new collection */
619 } while (lim > 0);
630 g->GCthreshold = g->nblocks + GCSTEPSIZE - lim/2; 620 g->GCthreshold = g->nblocks + GCSTEPSIZE - lim/2;
631/*printf("- %d %lu %lu %ld\n", g->gcstate, g->nblocks, g->GCthreshold, lim);*/
632 lua_assert((long)g->nblocks + (long)GCSTEPSIZE >= lim/2); 621 lua_assert((long)g->nblocks + (long)GCSTEPSIZE >= lim/2);
633} 622}
634 623