aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c53
1 files changed, 28 insertions, 25 deletions
diff --git a/lgc.c b/lgc.c
index a3ec58f0..ab3d0ace 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.83 2010/04/30 18:37:14 roberto Exp roberto $ 2** $Id: lgc.c,v 2.84 2010/05/03 11:55:40 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*/
@@ -27,7 +27,7 @@
27#define GCSTEPSIZE 1024 27#define GCSTEPSIZE 1024
28#define GCSWEEPMAX 40 28#define GCSWEEPMAX 40
29#define GCSWEEPCOST 1 29#define GCSWEEPCOST 1
30#define GCFINALIZECOST 50 30#define GCFINALIZENUM 4
31#define GCROOTCOST 10 31#define GCROOTCOST 10
32#define GCATOMICCOST 1000 32#define GCATOMICCOST 1000
33 33
@@ -115,8 +115,7 @@ static int iscleared (const TValue *o, int iskey) {
115void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { 115void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
116 global_State *g = G(L); 116 global_State *g = G(L);
117 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); 117 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
118 lua_assert(g->gckind == KGC_GEN || 118 lua_assert(g->gckind == KGC_GEN || g->gcstate != GCSpause);
119 (g->gcstate != GCSfinalize && g->gcstate != GCSpause));
120 lua_assert(gch(o)->tt != LUA_TTABLE); 119 lua_assert(gch(o)->tt != LUA_TTABLE);
121 if (keepinvariant(g)) /* must keep invariant? */ 120 if (keepinvariant(g)) /* must keep invariant? */
122 reallymarkobject(g, v); /* restore invariant */ 121 reallymarkobject(g, v); /* restore invariant */
@@ -643,6 +642,7 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
643static void checkSizes (lua_State *L) { 642static void checkSizes (lua_State *L) {
644 global_State *g = G(L); 643 global_State *g = G(L);
645 int hs = g->strt.size / 2; /* half the size of the string table */ 644 int hs = g->strt.size / 2; /* half the size of the string table */
645 if (g->gcstate == KGC_EMERGENCY) return;
646 if (g->strt.nuse < cast(lu_int32, hs)) { /* using less than half its size? */ 646 if (g->strt.nuse < cast(lu_int32, hs)) { /* using less than half its size? */
647 luaS_resize(L, hs); /* halve its size */ 647 luaS_resize(L, hs); /* halve its size */
648 } 648 }
@@ -755,10 +755,18 @@ void luaC_checkfinalizer (lua_State *L, Udata *u) {
755** ======================================================= 755** =======================================================
756*/ 756*/
757 757
758/*
759** call all pending finalizers */
760static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
761 global_State *g = G(L);
762 while (g->tobefnz) GCTM(L, propagateerrors);
763}
764
765
758void luaC_freeallobjects (lua_State *L) { 766void luaC_freeallobjects (lua_State *L) {
759 global_State *g = G(L); 767 global_State *g = G(L);
760 int i; 768 int i;
761 while (g->tobefnz) GCTM(L, 0); /* Call all pending finalizers */ 769 callallpendingfinalizers(L, 0);
762 /* following "white" makes all objects look dead */ 770 /* following "white" makes all objects look dead */
763 g->currentwhite = WHITEBITS; 771 g->currentwhite = WHITEBITS;
764 sweepwholelist(L, &g->udgc); 772 sweepwholelist(L, &g->udgc);
@@ -795,7 +803,7 @@ static void atomic (lua_State *L) {
795 cleartable(g->weak); 803 cleartable(g->weak);
796 cleartable(g->ephemeron); 804 cleartable(g->ephemeron);
797 cleartable(g->allweak); 805 cleartable(g->allweak);
798 lua_checkmemory(L); 806 /*lua_checkmemory(L);*/
799 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ 807 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
800} 808}
801 809
@@ -850,19 +858,9 @@ static l_mem singlestep (lua_State *L) {
850 else { 858 else {
851 /* sweep main thread */ 859 /* sweep main thread */
852 sweeplist(L, cast(GCObject **, &g->mainthread), 1); 860 sweeplist(L, cast(GCObject **, &g->mainthread), 1);
853 g->gcstate = GCSfinalize; /* go to next phase */
854 return GCSWEEPCOST;
855 }
856 }
857 case GCSfinalize: {
858 if (g->tobefnz) {
859 GCTM(L, 1);
860 return GCFINALIZECOST;
861 }
862 else {
863 checkSizes(L); 861 checkSizes(L);
864 g->gcstate = GCSpause; /* end collection */ 862 g->gcstate = GCSpause; /* finish collection */
865 return 0; 863 return GCSWEEPCOST;
866 } 864 }
867 } 865 }
868 default: lua_assert(0); return 0; 866 default: lua_assert(0); return 0;
@@ -913,8 +911,11 @@ static void step (lua_State *L) {
913 911
914 912
915void luaC_step (lua_State *L) { 913void luaC_step (lua_State *L) {
914 int i;
916 if (G(L)->gckind == KGC_GEN) generationalcollection(L); 915 if (G(L)->gckind == KGC_GEN) generationalcollection(L);
917 else step(L); 916 else step(L);
917 for (i = 0; i < GCFINALIZENUM && G(L)->tobefnz; i++)
918 GCTM(L, 1); /* Call a few pending finalizers */
918} 919}
919 920
920 921
@@ -926,6 +927,8 @@ void luaC_fullgc (lua_State *L, int isemergency) {
926 global_State *g = G(L); 927 global_State *g = G(L);
927 int origkind = g->gckind; 928 int origkind = g->gckind;
928 lua_assert(origkind == KGC_NORMAL || origkind == KGC_GEN); 929 lua_assert(origkind == KGC_NORMAL || origkind == KGC_GEN);
930 if (!isemergency) /* do not run finalizers during emergency GC */
931 callallpendingfinalizers(L, 1);
929 g->gckind = isemergency ? KGC_EMERGENCY : KGC_FORCED; 932 g->gckind = isemergency ? KGC_EMERGENCY : KGC_FORCED;
930 if (g->gcstate == GCSpropagate) { /* marking phase? */ 933 if (g->gcstate == GCSpropagate) { /* marking phase? */
931 /* must sweep all objects to turn them back to white 934 /* must sweep all objects to turn them back to white
@@ -934,16 +937,16 @@ void luaC_fullgc (lua_State *L, int isemergency) {
934 g->gcstate = GCSsweepstring; 937 g->gcstate = GCSsweepstring;
935 } 938 }
936 /* finish any pending sweep phase */ 939 /* finish any pending sweep phase */
937 luaC_runtilstate(L, bit2mask(GCSpause, GCSfinalize)); 940 luaC_runtilstate(L, bitmask(GCSpause));
938 g->gcstate = GCSpause; /* start a new collection */ 941 /* run entire collector */
939 /* run collector up to finalizers */ 942 luaC_runtilstate(L, ~bitmask(GCSpause));
940 luaC_runtilstate(L, bitmask(GCSfinalize)); 943 luaC_runtilstate(L, bitmask(GCSpause));
941 g->gckind = origkind; 944 g->gckind = origkind;
942 if (!isemergency) /* do not run finalizers during emergency GC */ 945 if (!isemergency) /* do not run finalizers during emergency GC */
943 luaC_runtilstate(L, bitmask(GCSpause)); 946 callallpendingfinalizers(L, 1);
944 if (origkind == KGC_GEN) { /* generational mode? */ 947 if (origkind == KGC_GEN) { /* generational mode? */
945 g->gcstate = GCSpause; /* collector must be always in... */ 948 /* collector must be always in propagate phase */
946 luaC_runtilstate(L, bitmask(GCSpropagate)); /* ...propagate phase */ 949 luaC_runtilstate(L, bitmask(GCSpropagate));
947 } 950 }
948 g->GCdebt = stddebt(g); 951 g->GCdebt = stddebt(g);
949} 952}