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]); |
