aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2013-08-05 13:58:28 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2013-08-05 13:58:28 -0300
commit677d90165ffef728231340c6328e9661824dbc34 (patch)
tree3338e6f1b0c2f82db84def5751ea418a58fbc31a /lgc.c
parent4244da96bfcf205624487b99b69e9d8dd1857293 (diff)
downloadlua-677d90165ffef728231340c6328e9661824dbc34.tar.gz
lua-677d90165ffef728231340c6328e9661824dbc34.tar.bz2
lua-677d90165ffef728231340c6328e9661824dbc34.zip
no more generational collection !!!
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c115
1 files changed, 19 insertions, 96 deletions
diff --git a/lgc.c b/lgc.c
index 52460dcd..8e73ff21 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.140.1.2 2013/04/26 18:22:05 roberto Exp $ 2** $Id: lgc.c,v 2.141 2013/04/26 18:26:49 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*/
@@ -52,10 +52,10 @@
52 52
53 53
54/* 54/*
55** 'makewhite' erases all color bits plus the old bit and then 55** 'makewhite' erases all color bits then sets only the current white
56** sets only the current white bit 56** bit
57*/ 57*/
58#define maskcolors (~(bit2mask(BLACKBIT, OLDBIT) | WHITEBITS)) 58#define maskcolors (~(bitmask(BLACKBIT) | WHITEBITS))
59#define makewhite(g,x) \ 59#define makewhite(g,x) \
60 (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g))) 60 (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g)))
61 61
@@ -137,7 +137,7 @@ void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) {
137 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); 137 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
138 lua_assert(g->gcstate != GCSpause); 138 lua_assert(g->gcstate != GCSpause);
139 lua_assert(gch(o)->tt != LUA_TTABLE); 139 lua_assert(gch(o)->tt != LUA_TTABLE);
140 if (keepinvariantout(g)) /* must keep invariant? */ 140 if (keepinvariant(g)) /* must keep invariant? */
141 reallymarkobject(g, v); /* restore invariant */ 141 reallymarkobject(g, v); /* restore invariant */
142 else { /* sweep phase */ 142 else { /* sweep phase */
143 lua_assert(issweepphase(g)); 143 lua_assert(issweepphase(g));
@@ -184,7 +184,7 @@ LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c) {
184 184
185 185
186/* 186/*
187** check color (and invariants) for an upvalue that was closed, 187** check color (and invariants) for an upvalue that is being closed,
188** i.e., moved into the 'allgc' list 188** i.e., moved into the 'allgc' list
189*/ 189*/
190void luaC_checkupvalcolor (global_State *g, UpVal *uv) { 190void luaC_checkupvalcolor (global_State *g, UpVal *uv) {
@@ -192,7 +192,6 @@ void luaC_checkupvalcolor (global_State *g, UpVal *uv) {
192 lua_assert(!isblack(o)); /* open upvalues are never black */ 192 lua_assert(!isblack(o)); /* open upvalues are never black */
193 if (isgray(o)) { 193 if (isgray(o)) {
194 if (keepinvariant(g)) { 194 if (keepinvariant(g)) {
195 resetoldbit(o); /* see MOVE OLD rule */
196 gray2black(o); /* it is being visited now */ 195 gray2black(o); /* it is being visited now */
197 markvalue(g, uv->v); 196 markvalue(g, uv->v);
198 } 197 }
@@ -331,8 +330,7 @@ static void remarkupvals (global_State *g) {
331 330
332 331
333/* 332/*
334** mark root set and reset all gray lists, to start a new 333** mark root set and reset all gray lists, to start a new collection
335** incremental (or full) collection
336*/ 334*/
337static void restartcollection (global_State *g) { 335static void restartcollection (global_State *g) {
338 g->gray = g->grayagain = NULL; 336 g->gray = g->grayagain = NULL;
@@ -708,29 +706,14 @@ static void sweepthread (lua_State *L, lua_State *L1) {
708/* 706/*
709** sweep at most 'count' elements from a list of GCObjects erasing dead 707** sweep at most 'count' elements from a list of GCObjects erasing dead
710** objects, where a dead (not alive) object is one marked with the "old" 708** objects, where a dead (not alive) object is one marked with the "old"
711** (non current) white and not fixed. 709** (non current) white and not fixed; change all non-dead objects back
712** In non-generational mode, change all non-dead objects back to white, 710** to white, preparing for next collection cycle.
713** preparing for next collection cycle.
714** In generational mode, keep black objects black, and also mark them as
715** old; stop when hitting an old object, as all objects after that
716** one will be old too.
717** When object is a thread, sweep its list of open upvalues too. 711** When object is a thread, sweep its list of open upvalues too.
718*/ 712*/
719static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { 713static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
720 global_State *g = G(L); 714 global_State *g = G(L);
721 int ow = otherwhite(g); 715 int ow = otherwhite(g);
722 int toclear, toset; /* bits to clear and to set in all live objects */ 716 int white = luaC_white(g); /* current white */
723 int tostop; /* stop sweep when this is true */
724 if (isgenerational(g)) { /* generational mode? */
725 toclear = ~0; /* clear nothing */
726 toset = bitmask(OLDBIT); /* set the old bit of all surviving objects */
727 tostop = bitmask(OLDBIT); /* do not sweep old generation */
728 }
729 else { /* normal mode */
730 toclear = maskcolors; /* clear all color bits + old bit */
731 toset = luaC_white(g); /* make object white */
732 tostop = 0; /* do not stop */
733 }
734 while (*p != NULL && count-- > 0) { 717 while (*p != NULL && count-- > 0) {
735 GCObject *curr = *p; 718 GCObject *curr = *p;
736 int marked = gch(curr)->marked; 719 int marked = gch(curr)->marked;
@@ -739,12 +722,10 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
739 freeobj(L, curr); /* erase 'curr' */ 722 freeobj(L, curr); /* erase 'curr' */
740 } 723 }
741 else { 724 else {
742 if (testbits(marked, tostop))
743 return NULL; /* stop sweeping this list */
744 if (gch(curr)->tt == LUA_TTHREAD) 725 if (gch(curr)->tt == LUA_TTHREAD)
745 sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */ 726 sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */
746 /* update marks */ 727 /* update marks */
747 gch(curr)->marked = cast_byte((marked & toclear) | toset); 728 gch(curr)->marked = cast_byte((marked & maskcolors) | white);
748 p = &gch(curr)->next; /* go to next element */ 729 p = &gch(curr)->next; /* go to next element */
749 } 730 }
750 } 731 }
@@ -793,8 +774,7 @@ static GCObject *udata2finalize (global_State *g) {
793 gch(o)->next = g->allgc; /* return it to 'allgc' list */ 774 gch(o)->next = g->allgc; /* return it to 'allgc' list */
794 g->allgc = o; 775 g->allgc = o;
795 resetbit(gch(o)->marked, SEPARATED); /* mark that it is not in 'tobefnz' */ 776 resetbit(gch(o)->marked, SEPARATED); /* mark that it is not in 'tobefnz' */
796 lua_assert(!isold(o)); /* see MOVE OLD rule */ 777 if (!keepinvariant(g)) /* not keeping invariant? */
797 if (!keepinvariantout(g)) /* not keeping invariant? */
798 makewhite(g, o); /* "sweep" object */ 778 makewhite(g, o); /* "sweep" object */
799 return o; 779 return o;
800} 780}
@@ -889,10 +869,8 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
889 ho->next = g->finobj; /* link it in list 'finobj' */ 869 ho->next = g->finobj; /* link it in list 'finobj' */
890 g->finobj = o; 870 g->finobj = o;
891 l_setbit(ho->marked, SEPARATED); /* mark it as such */ 871 l_setbit(ho->marked, SEPARATED); /* mark it as such */
892 if (!keepinvariantout(g)) /* not keeping invariant? */ 872 if (!keepinvariant(g)) /* not keeping invariant? */
893 makewhite(g, o); /* "sweep" object */ 873 makewhite(g, o); /* "sweep" object */
894 else
895 resetoldbit(o); /* see MOVE OLD rule */
896 } 874 }
897} 875}
898 876
@@ -947,36 +925,12 @@ static int entersweep (lua_State *L) {
947 925
948 926
949/* 927/*
950** change GC mode
951*/
952void luaC_changemode (lua_State *L, int mode) {
953 global_State *g = G(L);
954 if (mode == g->gckind) return; /* nothing to change */
955 if (mode == KGC_GEN) { /* change to generational mode */
956 /* make sure gray lists are consistent */
957 luaC_runtilstate(L, bitmask(GCSpropagate));
958 g->GCestimate = gettotalbytes(g);
959 g->gckind = KGC_GEN;
960 }
961 else { /* change to incremental mode */
962 /* sweep all objects to turn them back to white
963 (as white has not changed, nothing extra will be collected) */
964 g->gckind = KGC_NORMAL;
965 entersweep(L);
966 luaC_runtilstate(L, ~sweepphases);
967 }
968}
969
970
971/*
972** call all pending finalizers 928** call all pending finalizers
973*/ 929*/
974static void callallpendingfinalizers (lua_State *L, int propagateerrors) { 930static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
975 global_State *g = G(L); 931 global_State *g = G(L);
976 while (g->tobefnz) { 932 while (g->tobefnz)
977 resetoldbit(g->tobefnz);
978 GCTM(L, propagateerrors); 933 GCTM(L, propagateerrors);
979 }
980} 934}
981 935
982 936
@@ -1014,7 +968,7 @@ static l_mem atomic (lua_State *L) {
1014 work -= g->GCmemtrav; /* restart counting */ 968 work -= g->GCmemtrav; /* restart counting */
1015 convergeephemerons(g); 969 convergeephemerons(g);
1016 /* at this point, all strongly accessible objects are marked. */ 970 /* at this point, all strongly accessible objects are marked. */
1017 /* clear values from weak tables, before checking finalizers */ 971 /* Clear values from weak tables, before checking finalizers */
1018 clearvalues(g, g->weak, NULL); 972 clearvalues(g, g->weak, NULL);
1019 clearvalues(g, g->allweak, NULL); 973 clearvalues(g, g->allweak, NULL);
1020 origweak = g->weak; origall = g->allweak; 974 origweak = g->weak; origall = g->allweak;
@@ -1043,7 +997,6 @@ static lu_mem singlestep (lua_State *L) {
1043 case GCSpause: { 997 case GCSpause: {
1044 /* start to count memory traversed */ 998 /* start to count memory traversed */
1045 g->GCmemtrav = g->strt.size * sizeof(GCObject*); 999 g->GCmemtrav = g->strt.size * sizeof(GCObject*);
1046 lua_assert(!isgenerational(g));
1047 restartcollection(g); 1000 restartcollection(g);
1048 g->gcstate = GCSpropagate; 1001 g->gcstate = GCSpropagate;
1049 return g->GCmemtrav; 1002 return g->GCmemtrav;
@@ -1114,28 +1067,6 @@ void luaC_runtilstate (lua_State *L, int statesmask) {
1114} 1067}
1115 1068
1116 1069
1117static void generationalcollection (lua_State *L) {
1118 global_State *g = G(L);
1119 lua_assert(g->gcstate == GCSpropagate);
1120 if (g->GCestimate == 0) { /* signal for another major collection? */
1121 luaC_fullgc(L, 0); /* perform a full regular collection */
1122 g->GCestimate = gettotalbytes(g); /* update control */
1123 }
1124 else {
1125 lu_mem estimate = g->GCestimate;
1126 luaC_runtilstate(L, bitmask(GCSpause)); /* run complete (minor) cycle */
1127 g->gcstate = GCSpropagate; /* skip restart */
1128 if (gettotalbytes(g) > (estimate / 100) * g->gcmajorinc)
1129 g->GCestimate = 0; /* signal for a major collection */
1130 else
1131 g->GCestimate = estimate; /* keep estimate from last major coll. */
1132
1133 }
1134 setpause(g, gettotalbytes(g));
1135 lua_assert(g->gcstate == GCSpropagate);
1136}
1137
1138
1139static void incstep (lua_State *L) { 1070static void incstep (lua_State *L) {
1140 global_State *g = G(L); 1071 global_State *g = G(L);
1141 l_mem debt = g->GCdebt; 1072 l_mem debt = g->GCdebt;
@@ -1163,8 +1094,7 @@ static void incstep (lua_State *L) {
1163void luaC_forcestep (lua_State *L) { 1094void luaC_forcestep (lua_State *L) {
1164 global_State *g = G(L); 1095 global_State *g = G(L);
1165 int i; 1096 int i;
1166 if (isgenerational(g)) generationalcollection(L); 1097 incstep(L);
1167 else incstep(L);
1168 /* run a few finalizers (or all of them at the end of a collect cycle) */ 1098 /* run a few finalizers (or all of them at the end of a collect cycle) */
1169 for (i = 0; g->tobefnz && (i < GCFINALIZENUM || g->gcstate == GCSpause); i++) 1099 for (i = 0; g->tobefnz && (i < GCFINALIZENUM || g->gcstate == GCSpause); i++)
1170 GCTM(L, 1); /* call one finalizer */ 1100 GCTM(L, 1); /* call one finalizer */
@@ -1188,14 +1118,11 @@ void luaC_step (lua_State *L) {
1188*/ 1118*/
1189void luaC_fullgc (lua_State *L, int isemergency) { 1119void luaC_fullgc (lua_State *L, int isemergency) {
1190 global_State *g = G(L); 1120 global_State *g = G(L);
1191 int origkind = g->gckind; 1121 lua_assert(g->gckind == KGC_NORMAL);
1192 lua_assert(origkind != KGC_EMERGENCY);
1193 if (isemergency) /* do not run finalizers during emergency GC */ 1122 if (isemergency) /* do not run finalizers during emergency GC */
1194 g->gckind = KGC_EMERGENCY; 1123 g->gckind = KGC_EMERGENCY;
1195 else { 1124 else
1196 g->gckind = KGC_NORMAL;
1197 callallpendingfinalizers(L, 1); 1125 callallpendingfinalizers(L, 1);
1198 }
1199 if (keepinvariant(g)) { /* may there be some black objects? */ 1126 if (keepinvariant(g)) { /* may there be some black objects? */
1200 /* must sweep all objects to turn them back to white 1127 /* must sweep all objects to turn them back to white
1201 (as white has not changed, nothing will be collected) */ 1128 (as white has not changed, nothing will be collected) */
@@ -1205,11 +1132,7 @@ void luaC_fullgc (lua_State *L, int isemergency) {
1205 luaC_runtilstate(L, bitmask(GCSpause)); 1132 luaC_runtilstate(L, bitmask(GCSpause));
1206 luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */ 1133 luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */
1207 luaC_runtilstate(L, bitmask(GCSpause)); /* run entire collection */ 1134 luaC_runtilstate(L, bitmask(GCSpause)); /* run entire collection */
1208 if (origkind == KGC_GEN) { /* generational mode? */ 1135 g->gckind = KGC_NORMAL;
1209 /* generational mode must be kept in propagate phase */
1210 luaC_runtilstate(L, bitmask(GCSpropagate));
1211 }
1212 g->gckind = origkind;
1213 setpause(g, gettotalbytes(g)); 1136 setpause(g, gettotalbytes(g));
1214 if (!isemergency) /* do not run finalizers during emergency GC */ 1137 if (!isemergency) /* do not run finalizers during emergency GC */
1215 callallpendingfinalizers(L, 1); 1138 callallpendingfinalizers(L, 1);