diff options
-rw-r--r-- | lgc.c | 53 | ||||
-rw-r--r-- | lgc.h | 5 | ||||
-rw-r--r-- | ltests.c | 6 |
3 files changed, 33 insertions, 31 deletions
@@ -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) { | |||
115 | void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { | 115 | void 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) { | |||
643 | static void checkSizes (lua_State *L) { | 642 | static 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 */ | ||
760 | static void callallpendingfinalizers (lua_State *L, int propagateerrors) { | ||
761 | global_State *g = G(L); | ||
762 | while (g->tobefnz) GCTM(L, propagateerrors); | ||
763 | } | ||
764 | |||
765 | |||
758 | void luaC_freeallobjects (lua_State *L) { | 766 | void 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 | ||
915 | void luaC_step (lua_State *L) { | 913 | void 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 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.h,v 2.33 2010/04/30 18:36:45 roberto Exp roberto $ | 2 | ** $Id: lgc.h,v 2.34 2010/05/03 11:24:30 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 | */ |
@@ -33,8 +33,7 @@ | |||
33 | #define GCSsweepstring 2 | 33 | #define GCSsweepstring 2 |
34 | #define GCSsweepudata 3 | 34 | #define GCSsweepudata 3 |
35 | #define GCSsweep 4 | 35 | #define GCSsweep 4 |
36 | #define GCSfinalize 5 | 36 | #define GCSpause 5 |
37 | #define GCSpause 6 | ||
38 | 37 | ||
39 | 38 | ||
40 | #define issweepphase(g) \ | 39 | #define issweepphase(g) \ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltests.c,v 2.99 2010/04/30 18:37:14 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 2.100 2010/05/03 11:55:40 roberto Exp roberto $ |
3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -580,9 +580,9 @@ static int get_gccolor (lua_State *L) { | |||
580 | 580 | ||
581 | static int gc_state (lua_State *L) { | 581 | static int gc_state (lua_State *L) { |
582 | static const char *statenames[] = {"", "pause", "propagate", "atomic", | 582 | static const char *statenames[] = {"", "pause", "propagate", "atomic", |
583 | "sweepstring", "sweepudata", "sweep", "finalize"}; | 583 | "sweepstring", "sweepudata", "sweep"}; |
584 | static const int states[] = {0, GCSpause, GCSpropagate, GCSatomic, | 584 | static const int states[] = {0, GCSpause, GCSpropagate, GCSatomic, |
585 | GCSsweepstring, GCSsweepudata, GCSsweep, GCSfinalize}; | 585 | GCSsweepstring, GCSsweepudata, GCSsweep}; |
586 | int option = luaL_checkoption(L, 1, "", statenames); | 586 | int option = luaL_checkoption(L, 1, "", statenames); |
587 | if (option == 0) { | 587 | if (option == 0) { |
588 | lua_pushstring(L, statenames[G(L)->gcstate]); | 588 | lua_pushstring(L, statenames[G(L)->gcstate]); |