diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-05-05 15:58:36 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-05-05 15:58:36 -0300 |
| commit | d2ea5b00b7c1832d2889fe0cb6bbf4b82e7a9f98 (patch) | |
| tree | 71b520531f05aaf04ab8a7ddb66c5572ad5c4b33 | |
| parent | d77898597ef659907d6698cae319c8be13fcdcde (diff) | |
| download | lua-d2ea5b00b7c1832d2889fe0cb6bbf4b82e7a9f98.tar.gz lua-d2ea5b00b7c1832d2889fe0cb6bbf4b82e7a9f98.tar.bz2 lua-d2ea5b00b7c1832d2889fe0cb6bbf4b82e7a9f98.zip | |
new function 'luaC_changemode' +
bug: objects entering the 'allgc' list must have their OLDBIT cleared
(upvalues being cleared) + bug: in 'checkSizes', KGC_EMERGENCY is
stored in 'gckind' field, not in 'gcstate' + current white changes when
entering sweep phase (so there are dead objects only in that phase)
Diffstat (limited to '')
| -rw-r--r-- | lgc.c | 55 |
1 files changed, 42 insertions, 13 deletions
| @@ -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 | */ |
| 305 | static void markroot (lua_State *L) { | 307 | static 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 | ||
| 656 | static void checkSizes (lua_State *L) { | 658 | static 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 | */ | ||
| 782 | void 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 */ |
| 774 | static void callallpendingfinalizers (lua_State *L, int propagateerrors) { | 804 | static 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 | */ |
| 939 | void luaC_fullgc (lua_State *L, int isemergency) { | 968 | void 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)); |
