diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2013-08-21 16:21:16 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2013-08-21 16:21:16 -0300 |
commit | ae800656c9f82b54f6fae1497022d3484ad0c920 (patch) | |
tree | e3124387f4e29fc452ebb3c15b7e6cd0c1f4bbb7 /lgc.c | |
parent | 8c688639605f3ec0b5a57d906cacc27981b066da (diff) | |
download | lua-ae800656c9f82b54f6fae1497022d3484ad0c920.tar.gz lua-ae800656c9f82b54f6fae1497022d3484ad0c920.tar.bz2 lua-ae800656c9f82b54f6fae1497022d3484ad0c920.zip |
change in string table: string table is now independent of GC lists; all
strings live in 'normal' GC lists
Diffstat (limited to 'lgc.c')
-rw-r--r-- | lgc.c | 46 |
1 files changed, 14 insertions, 32 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 2.147 2013/08/19 14:18:43 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.148 2013/08/20 17:46:34 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 | */ |
@@ -667,7 +667,7 @@ static void freeobj (lua_State *L, GCObject *o) { | |||
667 | case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break; | 667 | case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break; |
668 | case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break; | 668 | case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break; |
669 | case LUA_TSHRSTR: | 669 | case LUA_TSHRSTR: |
670 | G(L)->strt.nuse--; | 670 | luaS_remove(L, rawgco2ts(o)); /* remove it from hash table */ |
671 | /* go through */ | 671 | /* go through */ |
672 | case LUA_TLNGSTR: { | 672 | case LUA_TLNGSTR: { |
673 | luaM_freemem(L, o, sizestring(gco2ts(o))); | 673 | luaM_freemem(L, o, sizestring(gco2ts(o))); |
@@ -749,14 +749,10 @@ static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) { | |||
749 | ** ======================================================= | 749 | ** ======================================================= |
750 | */ | 750 | */ |
751 | 751 | ||
752 | static void checkSizes (lua_State *L) { | 752 | static void checkBuffer (lua_State *L) { |
753 | global_State *g = G(L); | 753 | global_State *g = G(L); |
754 | if (g->gckind != KGC_EMERGENCY) { /* do not change sizes in emergency */ | 754 | if (g->gckind != KGC_EMERGENCY) |
755 | int hs = g->strt.size / 2; /* half the size of the string table */ | ||
756 | if (g->strt.nuse < cast(lu_int32, hs)) /* using less than that half? */ | ||
757 | luaS_resize(L, hs); /* halve its size */ | ||
758 | luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */ | 755 | luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */ |
759 | } | ||
760 | } | 756 | } |
761 | 757 | ||
762 | 758 | ||
@@ -855,7 +851,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { | |||
855 | } | 851 | } |
856 | /* search for pointer pointing to 'o' */ | 852 | /* search for pointer pointing to 'o' */ |
857 | for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ } | 853 | for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ } |
858 | *p = ho->next; /* remove 'o' from root list */ | 854 | *p = ho->next; /* remove 'o' from 'allgc' list */ |
859 | ho->next = g->finobj; /* link it in list 'finobj' */ | 855 | ho->next = g->finobj; /* link it in list 'finobj' */ |
860 | g->finobj = o; | 856 | g->finobj = o; |
861 | l_setbit(ho->marked, FINALIZEDBIT); /* mark it as such */ | 857 | l_setbit(ho->marked, FINALIZEDBIT); /* mark it as such */ |
@@ -889,25 +885,23 @@ static void setpause (global_State *g, l_mem estimate) { | |||
889 | } | 885 | } |
890 | 886 | ||
891 | 887 | ||
892 | #define sweepphases \ | 888 | #define sweepphases (bitmask(GCSsweepudata) | bitmask(GCSsweep)) |
893 | (bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep)) | ||
894 | 889 | ||
895 | 890 | ||
896 | /* | 891 | /* |
897 | ** enter first sweep phase (strings) and prepare pointers for other | 892 | ** enter first sweep phase and prepare pointers for other sweep phases. |
898 | ** sweep phases. The calls to 'sweeptolive' make pointers point to an | 893 | ** The calls to 'sweeptolive' make pointers point to an object inside |
899 | ** object inside the list (instead of to the header), so that the real | 894 | ** the list (instead of to the header), so that the real sweep do not |
900 | ** sweep do not need to skip objects created between "now" and the start | 895 | ** need to skip objects created between "now" and the start of the real |
901 | ** of the real sweep. | 896 | ** sweep. |
902 | ** Returns how many objects it swept. | 897 | ** Returns how many objects it swept. |
903 | */ | 898 | */ |
904 | static int entersweep (lua_State *L) { | 899 | static int entersweep (lua_State *L) { |
905 | global_State *g = G(L); | 900 | global_State *g = G(L); |
906 | int n = 0; | 901 | int n = 0; |
907 | g->gcstate = GCSsweepstring; | 902 | g->gcstate = GCSsweepudata; |
908 | lua_assert(g->sweepgc == NULL && g->sweepfin == NULL); | 903 | lua_assert(g->sweepgc == NULL && g->sweepfin == NULL); |
909 | /* prepare to sweep strings, finalizable objects, and regular objects */ | 904 | /* prepare to sweep finalizable objects and regular objects */ |
910 | g->sweepstrgc = 0; | ||
911 | g->sweepfin = sweeptolive(L, &g->finobj, &n); | 905 | g->sweepfin = sweeptolive(L, &g->finobj, &n); |
912 | g->sweepgc = sweeptolive(L, &g->allgc, &n); | 906 | g->sweepgc = sweeptolive(L, &g->allgc, &n); |
913 | return n; | 907 | return n; |
@@ -926,7 +920,6 @@ static void callallpendingfinalizers (lua_State *L, int propagateerrors) { | |||
926 | 920 | ||
927 | void luaC_freeallobjects (lua_State *L) { | 921 | void luaC_freeallobjects (lua_State *L) { |
928 | global_State *g = G(L); | 922 | global_State *g = G(L); |
929 | int i; | ||
930 | separatetobefnz(L, 1); /* separate all objects with finalizers */ | 923 | separatetobefnz(L, 1); /* separate all objects with finalizers */ |
931 | lua_assert(g->finobj == NULL); | 924 | lua_assert(g->finobj == NULL); |
932 | callallpendingfinalizers(L, 0); | 925 | callallpendingfinalizers(L, 0); |
@@ -934,8 +927,6 @@ void luaC_freeallobjects (lua_State *L) { | |||
934 | g->gckind = KGC_NORMAL; | 927 | g->gckind = KGC_NORMAL; |
935 | sweepwholelist(L, &g->finobj); /* finalizers can create objs. in 'finobj' */ | 928 | sweepwholelist(L, &g->finobj); /* finalizers can create objs. in 'finobj' */ |
936 | sweepwholelist(L, &g->allgc); | 929 | sweepwholelist(L, &g->allgc); |
937 | for (i = 0; i < g->strt.size; i++) /* free all string lists */ | ||
938 | sweepwholelist(L, &g->strt.hash[i]); | ||
939 | lua_assert(g->strt.nuse == 0); | 930 | lua_assert(g->strt.nuse == 0); |
940 | } | 931 | } |
941 | 932 | ||
@@ -1009,15 +1000,6 @@ static lu_mem singlestep (lua_State *L) { | |||
1009 | sw = entersweep(L); | 1000 | sw = entersweep(L); |
1010 | return work + sw * GCSWEEPCOST; | 1001 | return work + sw * GCSWEEPCOST; |
1011 | } | 1002 | } |
1012 | case GCSsweepstring: { | ||
1013 | int i; | ||
1014 | for (i = 0; i < GCSWEEPMAX && g->sweepstrgc + i < g->strt.size; i++) | ||
1015 | sweepwholelist(L, &g->strt.hash[g->sweepstrgc + i]); | ||
1016 | g->sweepstrgc += i; | ||
1017 | if (g->sweepstrgc >= g->strt.size) /* no more strings to sweep? */ | ||
1018 | g->gcstate = GCSsweepudata; | ||
1019 | return i * GCSWEEPCOST; | ||
1020 | } | ||
1021 | case GCSsweepudata: { | 1003 | case GCSsweepudata: { |
1022 | if (g->sweepfin) { | 1004 | if (g->sweepfin) { |
1023 | g->sweepfin = sweeplist(L, g->sweepfin, GCSWEEPMAX); | 1005 | g->sweepfin = sweeplist(L, g->sweepfin, GCSWEEPMAX); |
@@ -1037,7 +1019,7 @@ static lu_mem singlestep (lua_State *L) { | |||
1037 | /* sweep main thread */ | 1019 | /* sweep main thread */ |
1038 | GCObject *mt = obj2gco(g->mainthread); | 1020 | GCObject *mt = obj2gco(g->mainthread); |
1039 | sweeplist(L, &mt, 1); | 1021 | sweeplist(L, &mt, 1); |
1040 | checkSizes(L); | 1022 | checkBuffer(L); |
1041 | g->gcstate = GCSpause; /* finish collection */ | 1023 | g->gcstate = GCSpause; /* finish collection */ |
1042 | return GCSWEEPCOST; | 1024 | return GCSWEEPCOST; |
1043 | } | 1025 | } |