aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lgc.c55
1 files changed, 42 insertions, 13 deletions
diff --git a/lgc.c b/lgc.c
index bb21b74c..e51b2b0d 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.87 2010/05/04 18:09:06 roberto Exp roberto $ 2** $Id: lgc.c,v 2.88 2010/05/05 13:39:58 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*/
@@ -170,6 +170,7 @@ void luaC_checkupvalcolor (global_State *g, UpVal *uv) {
170 lua_assert(!isblack(o)); /* open upvalues are never black */ 170 lua_assert(!isblack(o)); /* open upvalues are never black */
171 if (isgray(o)) { 171 if (isgray(o)) {
172 if (keepinvariant(g)) { 172 if (keepinvariant(g)) {
173 resetbit(o->gch.marked, OLDBIT);
173 gray2black(o); /* it is being visited now */ 174 gray2black(o); /* it is being visited now */
174 markvalue(g, uv->v); 175 markvalue(g, uv->v);
175 } 176 }
@@ -300,7 +301,8 @@ static void remarkupvals (global_State *g) {
300 301
301 302
302/* 303/*
303** mark root set 304** mark root set and reset all gray lists, to start a new
305** incremental (or full) collection
304*/ 306*/
305static void markroot (lua_State *L) { 307static void markroot (lua_State *L) {
306 global_State *g = G(L); 308 global_State *g = G(L);
@@ -655,12 +657,12 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
655 657
656static void checkSizes (lua_State *L) { 658static void checkSizes (lua_State *L) {
657 global_State *g = G(L); 659 global_State *g = G(L);
658 int hs = g->strt.size / 2; /* half the size of the string table */ 660 if (g->gckind != KGC_EMERGENCY) { /* do not change sizes in emergency */
659 if (g->gcstate == KGC_EMERGENCY) return; 661 int hs = g->strt.size / 2; /* half the size of the string table */
660 if (g->strt.nuse < cast(lu_int32, hs)) { /* using less than half its size? */ 662 if (g->strt.nuse < cast(lu_int32, hs)) /* using less than that half? */
661 luaS_resize(L, hs); /* halve its size */ 663 luaS_resize(L, hs); /* halve its size */
664 luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */
662 } 665 }
663 luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */
664} 666}
665 667
666 668
@@ -668,6 +670,7 @@ static Udata *udata2finalize (global_State *g) {
668 GCObject *o = g->tobefnz; /* get first element */ 670 GCObject *o = g->tobefnz; /* get first element */
669 Udata *u = rawgco2u(o); 671 Udata *u = rawgco2u(o);
670 lua_assert(isfinalized(&u->uv)); 672 lua_assert(isfinalized(&u->uv));
673 lua_assert(!testbit(u->uv.marked, OLDBIT));
671 g->tobefnz = u->uv.next; /* remove it from 'tobefnz' list */ 674 g->tobefnz = u->uv.next; /* remove it from 'tobefnz' list */
672 u->uv.next = g->allgc; /* return it to 'allgc' list */ 675 u->uv.next = g->allgc; /* return it to 'allgc' list */
673 g->allgc = o; 676 g->allgc = o;
@@ -769,6 +772,33 @@ void luaC_checkfinalizer (lua_State *L, Udata *u) {
769** ======================================================= 772** =======================================================
770*/ 773*/
771 774
775
776#define sweepphases \
777 (bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep))
778
779/*
780** change GC mode
781*/
782void luaC_changemode (lua_State *L, int mode) {
783 global_State *g = G(L);
784 if (mode == g->gckind) return; /* nothing to change */
785 if (mode == KGC_GEN) { /* change to generational mode */
786 /* make sure gray lists are consistent */
787 luaC_runtilstate(L, bitmask(GCSpropagate));
788 g->lastmajormem = g->totalbytes;
789 g->gckind = KGC_GEN;
790 }
791 else { /* change to incremental mode */
792 /* sweep all objects to turn them back to white
793 (as white has not changed, nothing extra will be collected) */
794 g->sweepstrgc = 0;
795 g->gcstate = GCSsweepstring;
796 g->gckind = KGC_NORMAL;
797 luaC_runtilstate(L, ~sweepphases);
798 }
799}
800
801
772/* 802/*
773** call all pending finalizers */ 803** call all pending finalizers */
774static void callallpendingfinalizers (lua_State *L, int propagateerrors) { 804static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
@@ -817,7 +847,8 @@ static void atomic (lua_State *L) {
817 cleartable(g->weak); 847 cleartable(g->weak);
818 cleartable(g->ephemeron); 848 cleartable(g->ephemeron);
819 cleartable(g->allweak); 849 cleartable(g->allweak);
820 lua_checkmemory(L); 850 g->sweepstrgc = 0; /* prepare to sweep strings */
851 g->gcstate = GCSsweepstring;
821 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ 852 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
822} 853}
823 854
@@ -837,8 +868,6 @@ static l_mem singlestep (lua_State *L) {
837 else { /* no more `gray' objects */ 868 else { /* no more `gray' objects */
838 g->gcstate = GCSatomic; /* finish mark phase */ 869 g->gcstate = GCSatomic; /* finish mark phase */
839 atomic(L); 870 atomic(L);
840 g->sweepstrgc = 0; /* prepare to sweep strings */
841 g->gcstate = GCSsweepstring;
842 return GCATOMICCOST; 871 return GCATOMICCOST;
843 } 872 }
844 } 873 }
@@ -933,7 +962,7 @@ void luaC_step (lua_State *L) {
933 962
934 963
935/* 964/*
936** performs a full GC cycle; if "isememrgency", does not call 965** performs a full GC cycle; if "isemergency", does not call
937** finalizers (which could change stack positions) 966** finalizers (which could change stack positions)
938*/ 967*/
939void luaC_fullgc (lua_State *L, int isemergency) { 968void luaC_fullgc (lua_State *L, int isemergency) {
@@ -942,14 +971,14 @@ void luaC_fullgc (lua_State *L, int isemergency) {
942 lua_assert(origkind != KGC_EMERGENCY); 971 lua_assert(origkind != KGC_EMERGENCY);
943 if (!isemergency) /* do not run finalizers during emergency GC */ 972 if (!isemergency) /* do not run finalizers during emergency GC */
944 callallpendingfinalizers(L, 1); 973 callallpendingfinalizers(L, 1);
945 g->gckind = isemergency ? KGC_EMERGENCY : KGC_NORMAL; 974 if (keepinvariant(g)) { /* marking phase? */
946 if (g->gcstate == GCSpropagate) { /* marking phase? */
947 /* must sweep all objects to turn them back to white 975 /* must sweep all objects to turn them back to white
948 (as white has not changed, nothing will be collected) */ 976 (as white has not changed, nothing will be collected) */
949 g->sweepstrgc = 0; 977 g->sweepstrgc = 0;
950 g->gcstate = GCSsweepstring; 978 g->gcstate = GCSsweepstring;
951 } 979 }
952 /* finish any pending sweep phase */ 980 g->gckind = isemergency ? KGC_EMERGENCY : KGC_NORMAL;
981 /* finish any pending sweep phase to start a new cycle */
953 luaC_runtilstate(L, bitmask(GCSpause)); 982 luaC_runtilstate(L, bitmask(GCSpause));
954 /* run entire collector */ 983 /* run entire collector */
955 luaC_runtilstate(L, ~bitmask(GCSpause)); 984 luaC_runtilstate(L, ~bitmask(GCSpause));