aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c57
1 files changed, 24 insertions, 33 deletions
diff --git a/lgc.c b/lgc.c
index 0d76d2b1..af16e882 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.19 2004/12/13 12:15:11 roberto Exp roberto $ 2** $Id: lgc.c,v 2.20 2005/01/05 18:20:51 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*/
@@ -23,11 +23,10 @@
23#include "ltm.h" 23#include "ltm.h"
24 24
25 25
26#define GCSTEPSIZE 1000 26#define GCSTEPSIZE 1024u
27#define GCSWEEPMAX 10 27#define GCSWEEPMAX 40
28#define GCSWEEPCOST 30 28#define GCSWEEPCOST 10
29#define GCFINALIZECOST 100 29#define GCFINALIZECOST 100
30#define GCSTEPMUL 8
31 30
32 31
33#define FIXEDMASK bitmask(FIXEDBIT) 32#define FIXEDMASK bitmask(FIXEDBIT)
@@ -411,12 +410,10 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_int32 count) {
411 global_State *g = G(L); 410 global_State *g = G(L);
412 int whitebit = otherwhite(g); 411 int whitebit = otherwhite(g);
413 int deadmask = whitebit | FIXEDMASK; 412 int deadmask = whitebit | FIXEDMASK;
414 int generational = g->gcgenerational;
415 while ((curr = *p) != NULL && count-- > 0) { 413 while ((curr = *p) != NULL && count-- > 0) {
416 if ((curr->gch.marked ^ whitebit) & deadmask) { 414 if ((curr->gch.marked ^ whitebit) & deadmask) {
417 lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); 415 lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT));
418 if (!generational || isdead(g, curr)) 416 makewhite(g, curr);
419 makewhite(g, curr);
420 if (curr->gch.tt == LUA_TTHREAD) 417 if (curr->gch.tt == LUA_TTHREAD)
421 sweepwholelist(L, &gco2th(curr)->openupval); 418 sweepwholelist(L, &gco2th(curr)->openupval);
422 p = &curr->gch.next; 419 p = &curr->gch.next;
@@ -532,7 +529,6 @@ static void remarkupvals (global_State *g) {
532static void atomic (lua_State *L) { 529static void atomic (lua_State *L) {
533 global_State *g = G(L); 530 global_State *g = G(L);
534 size_t udsize; /* total size of userdata to be finalized */ 531 size_t udsize; /* total size of userdata to be finalized */
535 int aux;
536 /* remark objects cautch by write barrier */ 532 /* remark objects cautch by write barrier */
537 propagateall(g); 533 propagateall(g);
538 /* remark occasional upvalues of (maybe) dead threads */ 534 /* remark occasional upvalues of (maybe) dead threads */
@@ -556,10 +552,6 @@ static void atomic (lua_State *L) {
556 g->sweepstrgc = 0; 552 g->sweepstrgc = 0;
557 g->sweepgc = &g->rootgc; 553 g->sweepgc = &g->rootgc;
558 g->gcstate = GCSsweepstring; 554 g->gcstate = GCSsweepstring;
559 aux = g->gcgenerational;
560 g->gcgenerational = g->incgc && (g->estimate/2 <= g->prevestimate);
561 if (!aux) /* last collection was full? */
562 g->prevestimate = g->estimate; /* keep estimate of last full collection */
563 g->estimate = g->totalbytes - udsize; /* first estimate */ 555 g->estimate = g->totalbytes - udsize; /* first estimate */
564} 556}
565 557
@@ -569,11 +561,7 @@ static l_mem singlestep (lua_State *L) {
569 /*lua_checkmemory(L);*/ 561 /*lua_checkmemory(L);*/
570 switch (g->gcstate) { 562 switch (g->gcstate) {
571 case GCSpause: { 563 case GCSpause: {
572 /* start a new collection */ 564 markroot(L); /* start a new collection */
573 if (g->gcgenerational)
574 atomic(L);
575 else
576 markroot(L);
577 return 0; 565 return 0;
578 } 566 }
579 case GCSpropagate: { 567 case GCSpropagate: {
@@ -613,6 +601,7 @@ static l_mem singlestep (lua_State *L) {
613 } 601 }
614 else { 602 else {
615 g->gcstate = GCSpause; /* end collection */ 603 g->gcstate = GCSpause; /* end collection */
604 g->gcdept = 0;
616 return 0; 605 return 0;
617 } 606 }
618 } 607 }
@@ -623,25 +612,31 @@ static l_mem singlestep (lua_State *L) {
623 612
624void luaC_step (lua_State *L) { 613void luaC_step (lua_State *L) {
625 global_State *g = G(L); 614 global_State *g = G(L);
626 l_mem lim = (g->totalbytes - (g->GCthreshold - GCSTEPSIZE)) * GCSTEPMUL; 615 l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul;
616 g->gcdept += g->totalbytes - g->GCthreshold;
627 do { 617 do {
628 lim -= singlestep(L); 618 lim -= singlestep(L);
629 if (g->gcstate == GCSpause) 619 if (g->gcstate == GCSpause)
630 break; 620 break;
631 } while (lim > 0 || !g->incgc); 621 } while (lim > 0);
632 if (g->gcstate != GCSpause) 622 if (g->gcstate != GCSpause) {
633 g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/STEPMUL; */ 623 if (g->gcdept < GCSTEPSIZE)
624 g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/
625 else {
626 g->gcdept -= GCSTEPSIZE;
627 g->GCthreshold = g->totalbytes;
628 }
629 }
634 else { 630 else {
635 lua_assert(g->totalbytes >= g->estimate); 631 lua_assert(g->totalbytes >= g->estimate);
636 g->GCthreshold = g->estimate + ((g->estimate/GCDIV) * g->gcpace); 632 g->GCthreshold = (g->estimate/100) * g->gcpace;
637 } 633 }
638} 634}
639 635
640 636
641void luaC_fullgc (lua_State *L) { 637void luaC_fullgc (lua_State *L) {
642 global_State *g = G(L); 638 global_State *g = G(L);
643 if (g->gcstate <= GCSpropagate || g->gcgenerational) { 639 if (g->gcstate <= GCSpropagate) {
644 g->gcgenerational = 0;
645 /* reset sweep marks to sweep all elements (returning them to white) */ 640 /* reset sweep marks to sweep all elements (returning them to white) */
646 g->sweepstrgc = 0; 641 g->sweepstrgc = 0;
647 g->sweepgc = &g->rootgc; 642 g->sweepgc = &g->rootgc;
@@ -657,10 +652,8 @@ void luaC_fullgc (lua_State *L) {
657 singlestep(L); 652 singlestep(L);
658 } 653 }
659 markroot(L); 654 markroot(L);
660 lua_assert(!g->gcgenerational);
661 while (g->gcstate != GCSpause) { 655 while (g->gcstate != GCSpause) {
662 singlestep(L); 656 singlestep(L);
663 g->gcgenerational = 0; /* keep it in this mode */
664 } 657 }
665 g->GCthreshold = 2*g->estimate; 658 g->GCthreshold = 2*g->estimate;
666} 659}
@@ -669,11 +662,10 @@ void luaC_fullgc (lua_State *L) {
669void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { 662void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
670 global_State *g = G(L); 663 global_State *g = G(L);
671 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); 664 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
672 lua_assert(g->gcgenerational || 665 lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
673 (g->gcstate != GCSfinalize && g->gcstate != GCSpause));
674 lua_assert(ttype(&o->gch) != LUA_TTABLE); 666 lua_assert(ttype(&o->gch) != LUA_TTABLE);
675 /* must keep invariant? */ 667 /* must keep invariant? */
676 if (g->gcstate == GCSpropagate || g->gcgenerational) 668 if (g->gcstate == GCSpropagate)
677 reallymarkobject(g, v); /* restore invariant */ 669 reallymarkobject(g, v); /* restore invariant */
678 else /* don't mind */ 670 else /* don't mind */
679 makewhite(g, o); /* mark as white just to avoid other barriers */ 671 makewhite(g, o); /* mark as white just to avoid other barriers */
@@ -683,8 +675,7 @@ void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
683void luaC_barrierback (lua_State *L, GCObject *o, GCObject *v) { 675void luaC_barrierback (lua_State *L, GCObject *o, GCObject *v) {
684 global_State *g = G(L); 676 global_State *g = G(L);
685 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); 677 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
686 lua_assert(g->gcgenerational || 678 lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
687 (g->gcstate != GCSfinalize && g->gcstate != GCSpause));
688 black2gray(o); /* make table gray (again) */ 679 black2gray(o); /* make table gray (again) */
689 gco2h(o)->gclist = g->grayagain; 680 gco2h(o)->gclist = g->grayagain;
690 g->grayagain = o; 681 g->grayagain = o;
@@ -706,7 +697,7 @@ void luaC_linkupval (lua_State *L, UpVal *uv) {
706 o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */ 697 o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */
707 g->rootgc = o; 698 g->rootgc = o;
708 if (isgray(o)) { 699 if (isgray(o)) {
709 if (g->gcstate == GCSpropagate || g->gcgenerational) { 700 if (g->gcstate == GCSpropagate) {
710 gray2black(o); /* closed upvalues need barrier */ 701 gray2black(o); /* closed upvalues need barrier */
711 luaC_barrier(L, uv, uv->v); 702 luaC_barrier(L, uv, uv->v);
712 } 703 }