aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2012-05-22 14:32:25 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2012-05-22 14:32:25 -0300
commitb36b4b521f53e5ff2e18fff3c194d28f9a840868 (patch)
treef8a96d20fcb95efcd07fcb7218d088406c3020dc
parent398811a3131cb025ca61d1a0839e3f99ba632ae9 (diff)
downloadlua-b36b4b521f53e5ff2e18fff3c194d28f9a840868.tar.gz
lua-b36b4b521f53e5ff2e18fff3c194d28f9a840868.tar.bz2
lua-b36b4b521f53e5ff2e18fff3c194d28f9a840868.zip
try to avoid sweeping new objects created with new white (and
therefore not collectable in the current cycle)
-rw-r--r--lgc.c62
-rw-r--r--lstate.c3
-rw-r--r--lstate.h5
3 files changed, 43 insertions, 27 deletions
diff --git a/lgc.c b/lgc.c
index 435c5e48..9831dce9 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.123 2012/05/20 20:36:44 roberto Exp roberto $ 2** $Id: lgc.c,v 2.124 2012/05/21 13:18:10 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*/
@@ -49,6 +49,7 @@
49#define workrate(x,mul) \ 49#define workrate(x,mul) \
50 ((x) < MAX_INT/80 ? ((x) * 80) / mul : ((x) / mul) * 80) 50 ((x) < MAX_INT/80 ? ((x) * 80) / mul : ((x) / mul) * 80)
51 51
52
52/* 53/*
53** standard negative debt for GC; a reasonable "time" to wait before 54** standard negative debt for GC; a reasonable "time" to wait before
54** starting a new cycle 55** starting a new cycle
@@ -738,19 +739,16 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
738 freeobj(L, curr); /* erase 'curr' */ 739 freeobj(L, curr); /* erase 'curr' */
739 } 740 }
740 else { 741 else {
742 if (testbits(marked, tostop))
743 return NULL; /* stop sweeping this list */
741 if (gch(curr)->tt == LUA_TTHREAD) 744 if (gch(curr)->tt == LUA_TTHREAD)
742 sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */ 745 sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */
743 if (testbits(marked, tostop)) {
744 static GCObject *nullp = NULL;
745 p = &nullp; /* stop sweeping this list */
746 break;
747 }
748 /* update marks */ 746 /* update marks */
749 gch(curr)->marked = cast_byte((marked & toclear) | toset); 747 gch(curr)->marked = cast_byte((marked & toclear) | toset);
750 p = &gch(curr)->next; /* go to next element */ 748 p = &gch(curr)->next; /* go to next element */
751 } 749 }
752 } 750 }
753 return p; 751 return (*p == NULL) ? NULL : p;
754} 752}
755 753
756/* }====================================================== */ 754/* }====================================================== */
@@ -865,7 +863,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
865 GCObject **p; 863 GCObject **p;
866 GCheader *ho = gch(o); 864 GCheader *ho = gch(o);
867 /* avoid removing current sweep object */ 865 /* avoid removing current sweep object */
868 if (g->gcstate == GCSsweep && g->sweepgc == &ho->next) { 866 if (g->sweepgc == &ho->next) {
869 /* step to next object in the list */ 867 /* step to next object in the list */
870 g->sweepgc = (ho->next == NULL) ? NULL : &gch(ho->next)->next; 868 g->sweepgc = (ho->next == NULL) ? NULL : &gch(ho->next)->next;
871 } 869 }
@@ -892,6 +890,24 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
892#define sweepphases \ 890#define sweepphases \
893 (bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep)) 891 (bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep))
894 892
893
894/*
895** enter first sweep phase (strings) and prepare pointers for other
896** sweep phases. The calls to 'sweeplist' attempt to make pointers
897** point to an object inside the list (instead of to the header), so
898** that the real sweep do not need to skip objects created between "now"
899** and the start of the real sweep.
900*/
901static void entersweep (lua_State *L) {
902 global_State *g = G(L);
903 g->gcstate = GCSsweepstring;
904 lua_assert(g->sweepgc == NULL && g->sweepfin == NULL);
905 g->sweepstrgc = 0; /* prepare to sweep strings, ... */
906 g->sweepfin = sweeplist(L, &g->finobj, 1); /* finalizable objects, ... */
907 g->sweepgc = sweeplist(L, &g->allgc, 1); /* and regular objects */
908}
909
910
895/* 911/*
896** change GC mode 912** change GC mode
897*/ 913*/
@@ -907,9 +923,8 @@ void luaC_changemode (lua_State *L, int mode) {
907 else { /* change to incremental mode */ 923 else { /* change to incremental mode */
908 /* sweep all objects to turn them back to white 924 /* sweep all objects to turn them back to white
909 (as white has not changed, nothing extra will be collected) */ 925 (as white has not changed, nothing extra will be collected) */
910 g->sweepstrgc = 0;
911 g->gcstate = GCSsweepstring;
912 g->gckind = KGC_NORMAL; 926 g->gckind = KGC_NORMAL;
927 entersweep(L);
913 luaC_runtilstate(L, ~sweepphases); 928 luaC_runtilstate(L, ~sweepphases);
914 } 929 }
915} 930}
@@ -972,9 +987,8 @@ static void atomic (lua_State *L) {
972 /* clear values from resurrected weak tables */ 987 /* clear values from resurrected weak tables */
973 clearvalues(g, g->weak, origweak); 988 clearvalues(g, g->weak, origweak);
974 clearvalues(g, g->allweak, origall); 989 clearvalues(g, g->allweak, origall);
975 g->sweepstrgc = 0; /* prepare to sweep strings */
976 g->gcstate = GCSsweepstring;
977 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ 990 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
991 entersweep(L); /* prepare to sweep strings */
978 /*lua_checkmemory(L);*/ 992 /*lua_checkmemory(L);*/
979} 993}
980 994
@@ -1010,25 +1024,22 @@ static lu_mem singlestep (lua_State *L) {
1010 for (i = 0; i < GCSWEEPMAX && g->sweepstrgc + i < g->strt.size; i++) 1024 for (i = 0; i < GCSWEEPMAX && g->sweepstrgc + i < g->strt.size; i++)
1011 sweepwholelist(L, &g->strt.hash[g->sweepstrgc + i]); 1025 sweepwholelist(L, &g->strt.hash[g->sweepstrgc + i]);
1012 g->sweepstrgc += i; 1026 g->sweepstrgc += i;
1013 if (g->sweepstrgc >= g->strt.size) { /* no more strings to sweep? */ 1027 if (g->sweepstrgc >= g->strt.size) /* no more strings to sweep? */
1014 g->sweepgc = &g->finobj; /* prepare to sweep finalizable objects */
1015 g->gcstate = GCSsweepudata; 1028 g->gcstate = GCSsweepudata;
1016 }
1017 return i * GCSWEEPCOST; 1029 return i * GCSWEEPCOST;
1018 } 1030 }
1019 case GCSsweepudata: { 1031 case GCSsweepudata: {
1020 if (*g->sweepgc) { 1032 if (g->sweepfin) {
1021 g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); 1033 g->sweepfin = sweeplist(L, g->sweepfin, GCSWEEPMAX);
1022 return GCSWEEPMAX*GCSWEEPCOST; 1034 return GCSWEEPMAX*GCSWEEPCOST;
1023 } 1035 }
1024 else { 1036 else {
1025 g->sweepgc = &g->allgc; /* go to next phase */
1026 g->gcstate = GCSsweep; 1037 g->gcstate = GCSsweep;
1027 return 0; 1038 return 0;
1028 } 1039 }
1029 } 1040 }
1030 case GCSsweep: { 1041 case GCSsweep: {
1031 if (*g->sweepgc) { 1042 if (g->sweepgc) {
1032 g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); 1043 g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
1033 return GCSWEEPMAX*GCSWEEPCOST; 1044 return GCSWEEPMAX*GCSWEEPCOST;
1034 } 1045 }
@@ -1121,16 +1132,19 @@ void luaC_step (lua_State *L) {
1121void luaC_fullgc (lua_State *L, int isemergency) { 1132void luaC_fullgc (lua_State *L, int isemergency) {
1122 global_State *g = G(L); 1133 global_State *g = G(L);
1123 int origkind = g->gckind; 1134 int origkind = g->gckind;
1135 int someblack = keepinvariant(g);
1124 lua_assert(origkind != KGC_EMERGENCY); 1136 lua_assert(origkind != KGC_EMERGENCY);
1125 if (!isemergency) /* do not run finalizers during emergency GC */ 1137 if (isemergency) /* do not run finalizers during emergency GC */
1138 g->gckind = KGC_EMERGENCY;
1139 else {
1140 g->gckind = KGC_NORMAL;
1126 callallpendingfinalizers(L, 1); 1141 callallpendingfinalizers(L, 1);
1127 if (keepinvariant(g)) { /* marking phase? */ 1142 }
1143 if (someblack) { /* may there be some black objects? */
1128 /* must sweep all objects to turn them back to white 1144 /* must sweep all objects to turn them back to white
1129 (as white has not changed, nothing will be collected) */ 1145 (as white has not changed, nothing will be collected) */
1130 g->sweepstrgc = 0; 1146 entersweep(L);
1131 g->gcstate = GCSsweepstring;
1132 } 1147 }
1133 g->gckind = isemergency ? KGC_EMERGENCY : KGC_NORMAL;
1134 /* finish any pending sweep phase to start a new cycle */ 1148 /* finish any pending sweep phase to start a new cycle */
1135 luaC_runtilstate(L, bitmask(GCSpause)); 1149 luaC_runtilstate(L, bitmask(GCSpause));
1136 /* run entire collector */ 1150 /* run entire collector */
diff --git a/lstate.c b/lstate.c
index 0a61ea1a..fecd0fba 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 2.93 2012/02/01 21:57:15 roberto Exp roberto $ 2** $Id: lstate.c,v 2.94 2012/05/11 14:06:07 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -292,6 +292,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
292 g->allgc = NULL; 292 g->allgc = NULL;
293 g->finobj = NULL; 293 g->finobj = NULL;
294 g->tobefnz = NULL; 294 g->tobefnz = NULL;
295 g->sweepgc = g->sweepfin = NULL;
295 g->gray = g->grayagain = NULL; 296 g->gray = g->grayagain = NULL;
296 g->weak = g->ephemeron = g->allweak = NULL; 297 g->weak = g->ephemeron = g->allweak = NULL;
297 g->totalbytes = sizeof(LG); 298 g->totalbytes = sizeof(LG);
diff --git a/lstate.h b/lstate.h
index 85359fe3..302834ab 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 2.77 2012/02/01 21:57:15 roberto Exp roberto $ 2** $Id: lstate.h,v 2.78 2012/05/20 20:36:44 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -126,7 +126,8 @@ typedef struct global_State {
126 int sweepstrgc; /* position of sweep in `strt' */ 126 int sweepstrgc; /* position of sweep in `strt' */
127 GCObject *allgc; /* list of all collectable objects */ 127 GCObject *allgc; /* list of all collectable objects */
128 GCObject *finobj; /* list of collectable objects with finalizers */ 128 GCObject *finobj; /* list of collectable objects with finalizers */
129 GCObject **sweepgc; /* current position of sweep */ 129 GCObject **sweepgc; /* current position of sweep in list 'allgc' */
130 GCObject **sweepfin; /* current position of sweep in list 'finobj' */
130 GCObject *gray; /* list of gray objects */ 131 GCObject *gray; /* list of gray objects */
131 GCObject *grayagain; /* list of objects to be traversed atomically */ 132 GCObject *grayagain; /* list of objects to be traversed atomically */
132 GCObject *weak; /* list of tables with weak values */ 133 GCObject *weak; /* list of tables with weak values */