aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c62
1 files changed, 40 insertions, 22 deletions
diff --git a/lgc.c b/lgc.c
index 61162d42..515267e7 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.170 2014/02/11 12:28:47 roberto Exp roberto $ 2** $Id: lgc.c,v 2.171 2014/02/13 12:11: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*/
@@ -33,8 +33,8 @@
33/* maximum number of elements to sweep in each single step */ 33/* maximum number of elements to sweep in each single step */
34#define GCSWEEPMAX (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4)) 34#define GCSWEEPMAX (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4))
35 35
36/* maximum number of finalizers to call in each GC step */ 36/* cost of calling one finalizer */
37#define GCFINALIZENUM 4 37#define GCFINALIZECOST GCSWEEPCOST
38 38
39 39
40/* 40/*
@@ -960,6 +960,7 @@ static l_mem atomic (lua_State *L) {
960 origweak = g->weak; origall = g->allweak; 960 origweak = g->weak; origall = g->allweak;
961 work += g->GCmemtrav; /* stop counting (objects being finalized) */ 961 work += g->GCmemtrav; /* stop counting (objects being finalized) */
962 separatetobefnz(g, 0); /* separate objects to be finalized */ 962 separatetobefnz(g, 0); /* separate objects to be finalized */
963 g->gcfinnum = 1; /* there may be objects to be finalized */
963 markbeingfnz(g); /* mark objects that will be finalized */ 964 markbeingfnz(g); /* mark objects that will be finalized */
964 propagateall(g); /* remark, to propagate 'resurrection' */ 965 propagateall(g); /* remark, to propagate 'resurrection' */
965 work -= g->GCmemtrav; /* restart counting */ 966 work -= g->GCmemtrav; /* restart counting */
@@ -1014,7 +1015,7 @@ static lu_mem singlestep (lua_State *L) {
1014 int sw; 1015 int sw;
1015 propagateall(g); /* make sure gray list is empty */ 1016 propagateall(g); /* make sure gray list is empty */
1016 g->GCestimate = g->GCmemtrav; /* save what was counted */; 1017 g->GCestimate = g->GCmemtrav; /* save what was counted */;
1017 work = atomic(L); /* add what was traversed by 'atomic' */ 1018 work = atomic(L); /* work is what was traversed by 'atomic' */
1018 g->GCestimate += work; /* estimate of total memory traversed */ 1019 g->GCestimate += work; /* estimate of total memory traversed */
1019 sw = entersweep(L); 1020 sw = entersweep(L);
1020 return work + sw * GCSWEEPCOST; 1021 return work + sw * GCSWEEPCOST;
@@ -1034,8 +1035,13 @@ static lu_mem singlestep (lua_State *L) {
1034 case GCSswpend: { /* finish sweeps */ 1035 case GCSswpend: { /* finish sweeps */
1035 makewhite(g, obj2gco(g->mainthread)); /* sweep main thread */ 1036 makewhite(g, obj2gco(g->mainthread)); /* sweep main thread */
1036 checkSizes(L, g); 1037 checkSizes(L, g);
1038 g->gcstate = GCScallfin;
1039 return 0;
1040 }
1041 case GCScallfin: { /* state to finish calling finalizers */
1042 /* do nothing here; should be handled by 'luaC_forcestep' */
1037 g->gcstate = GCSpause; /* finish collection */ 1043 g->gcstate = GCSpause; /* finish collection */
1038 return GCSWEEPCOST; 1044 return 0;
1039 } 1045 }
1040 default: lua_assert(0); return 0; 1046 default: lua_assert(0); return 0;
1041 } 1047 }
@@ -1053,7 +1059,25 @@ void luaC_runtilstate (lua_State *L, int statesmask) {
1053} 1059}
1054 1060
1055 1061
1056static void incstep (lua_State *L) { 1062/*
1063** run a few finalizers
1064*/
1065static int dosomefinalization (lua_State *L) {
1066 global_State *g = G(L);
1067 unsigned int i;
1068 lua_assert(!g->tobefnz || g->gcfinnum > 0);
1069 for (i = 0; g->tobefnz && i < g->gcfinnum; i++)
1070 GCTM(L, 1); /* call one finalizer */
1071 g->gcfinnum = (!g->tobefnz) ? 0 /* nothing more to finalize? */
1072 : g->gcfinnum * 2; /* else call a few more next time */
1073 return i;
1074}
1075
1076
1077/*
1078** performs a basic GC step
1079*/
1080void luaC_forcestep (lua_State *L) {
1057 global_State *g = G(L); 1081 global_State *g = G(L);
1058 l_mem debt = g->GCdebt; 1082 l_mem debt = g->GCdebt;
1059 int stepmul = g->gcstepmul; 1083 int stepmul = g->gcstepmul;
@@ -1061,33 +1085,27 @@ static void incstep (lua_State *L) {
1061 /* convert debt from Kb to 'work units' (avoid zero debt and overflows) */ 1085 /* convert debt from Kb to 'work units' (avoid zero debt and overflows) */
1062 debt = (debt / STEPMULADJ) + 1; 1086 debt = (debt / STEPMULADJ) + 1;
1063 debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM; 1087 debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM;
1064 do { /* always perform at least one single step */ 1088 do {
1065 lu_mem work = singlestep(L); /* do some work */ 1089 if (g->gcstate == GCScallfin && g->tobefnz) {
1066 debt -= work; 1090 unsigned int n = dosomefinalization(L);
1091 debt -= (n * GCFINALIZECOST);
1092 }
1093 else { /* perform one single step */
1094 lu_mem work = singlestep(L);
1095 debt -= work;
1096 }
1067 } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause); 1097 } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause);
1068 if (g->gcstate == GCSpause) 1098 if (g->gcstate == GCSpause)
1069 setpause(g, g->GCestimate); /* pause until next cycle */ 1099 setpause(g, g->GCestimate); /* pause until next cycle */
1070 else { 1100 else {
1071 debt = (debt / stepmul) * STEPMULADJ; /* convert 'work units' to Kb */ 1101 debt = (debt / stepmul) * STEPMULADJ; /* convert 'work units' to Kb */
1072 luaE_setdebt(g, debt); 1102 luaE_setdebt(g, debt);
1103 dosomefinalization(L);
1073 } 1104 }
1074} 1105}
1075 1106
1076 1107
1077/* 1108/*
1078** performs a basic GC step
1079*/
1080void luaC_forcestep (lua_State *L) {
1081 global_State *g = G(L);
1082 int i;
1083 incstep(L);
1084 /* run a few finalizers (or all of them at the end of a collect cycle) */
1085 for (i = 0; g->tobefnz && (i < GCFINALIZENUM || g->gcstate == GCSpause); i++)
1086 GCTM(L, 1); /* call one finalizer */
1087}
1088
1089
1090/*
1091** performs a basic GC step when collector is running 1109** performs a basic GC step when collector is running
1092*/ 1110*/
1093void luaC_step (lua_State *L) { 1111void luaC_step (lua_State *L) {