aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lfunc.c5
-rw-r--r--lgc.c102
-rw-r--r--lgc.h3
-rw-r--r--lstate.c4
-rw-r--r--lstate.h4
-rw-r--r--lstring.c4
6 files changed, 107 insertions, 15 deletions
diff --git a/lfunc.c b/lfunc.c
index cb0b4ef6..d1185ec6 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lfunc.c,v 2.32 2013/08/07 12:18:11 roberto Exp roberto $ 2** $Id: lfunc.c,v 2.33 2013/08/16 18:55:49 roberto Exp roberto $
3** Auxiliary functions to manipulate prototypes and closures 3** Auxiliary functions to manipulate prototypes and closures
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -21,7 +21,8 @@
21 21
22 22
23Closure *luaF_newCclosure (lua_State *L, int n) { 23Closure *luaF_newCclosure (lua_State *L, int n) {
24 Closure *c = &luaC_newobj(L, LUA_TCCL, sizeCclosure(n), NULL, 0)->cl; 24 Closure *c = &luaC_newobj(L, LUA_TCCL, sizeCclosure(n),
25 &G(L)->localgc, 0)->cl;
25 c->c.nupvalues = cast_byte(n); 26 c->c.nupvalues = cast_byte(n);
26 return c; 27 return c;
27} 28}
diff --git a/lgc.c b/lgc.c
index fddc43cf..c261bd73 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.149 2013/08/21 19:21:16 roberto Exp roberto $ 2** $Id: lgc.c,v 2.150 2013/08/21 20:09:51 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*/
@@ -25,6 +25,12 @@
25 25
26 26
27/* 27/*
28** How memory to allocate before a new local collection
29*/
30#define GCLOCALPAUSE 8000
31
32
33/*
28** cost of sweeping one element (the size of a small object divided 34** cost of sweeping one element (the size of a small object divided
29** by some adjust for the sweep speed) 35** by some adjust for the sweep speed)
30*/ 36*/
@@ -191,9 +197,9 @@ void luaC_checkupvalcolor (global_State *g, UpVal *uv) {
191 197
192void luaC_fix (lua_State *L, GCObject *o) { 198void luaC_fix (lua_State *L, GCObject *o) {
193 global_State *g = G(L); 199 global_State *g = G(L);
194 lua_assert(g->allgc == o); 200 lua_assert(g->localgc == o);
195 white2gray(o); 201 white2gray(o);
196 g->allgc = o->gch.next; /* remove object from 'allgc' list */ 202 g->localgc = o->gch.next; /* remove object from 'localgc' list */
197 o->gch.next = g->fixedgc; /* link it to 'fixedgc' list */ 203 o->gch.next = g->fixedgc; /* link it to 'fixedgc' list */
198 g->fixedgc = o; 204 g->fixedgc = o;
199} 205}
@@ -875,6 +881,72 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
875 881
876/* 882/*
877** {====================================================== 883** {======================================================
884** Local Collection
885** =======================================================
886*/
887
888/*
889** Traverse a thread, local marking all its collectable objects
890*/
891static void localmarkthread (lua_State *l) {
892 StkId o = l->stack;
893 if (o == NULL)
894 return; /* stack not completely built yet */
895 for (; o < l->top; o++) { /* mark live elements in the stack */
896 if (iscollectable(o))
897 l_setbit(gcvalue(o)->gch.marked, LOCALBLACK);
898 }
899}
900
901
902/*
903** Mark all that is locally accessible (accessible directly from
904** a thread)
905*/
906static void localmark (global_State *g) {
907 GCObject *thread = hvalue(&g->l_registry)->next;
908 for (; thread != NULL; thread = gch(thread)->next) /* traverse all threads */
909 localmarkthread(gco2th(thread));
910 localmarkthread(g->mainthread);
911}
912
913
914static void localsweep (lua_State *L, global_State *g) {
915 GCObject **p = &g->localgc;
916 while (*p != NULL) {
917 GCObject *curr = *p;
918 if (!islocal(curr)) { /* is 'curr' no more local? */
919 *p = curr->gch.next; /* remove 'curr' from list */
920 curr->gch.next = g->allgc; /* link 'curr' in 'allgc' list */
921 g->allgc = curr;
922 }
923 else { /* still local */
924 if (testbit(curr->gch.marked, LOCALBLACK)) { /* locally alive? */
925 resetbit(curr->gch.marked, LOCALBLACK);
926 p = &curr->gch.next; /* go to next element */
927 }
928 else { /* object is dead */
929 *p = curr->gch.next; /* remove 'curr' from list */
930 freeobj(L, curr); /* erase 'curr' */
931 }
932 }
933 }
934}
935
936
937static void luaC_localcollection (lua_State *L) {
938 global_State *g = G(L);
939 lua_assert(g->gcstate == GCSpause);
940 localmark(g);
941 localsweep(L, g);
942}
943
944/* }====================================================== */
945
946
947
948/*
949** {======================================================
878** GC control 950** GC control
879** ======================================================= 951** =======================================================
880*/ 952*/
@@ -885,13 +957,13 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
885** cycle will start when memory use hits threshold 957** cycle will start when memory use hits threshold
886*/ 958*/
887static void setpause (global_State *g, l_mem estimate) { 959static void setpause (global_State *g, l_mem estimate) {
888 l_mem debt, threshold; 960 l_mem threshold;
889 estimate = estimate / PAUSEADJ; /* adjust 'estimate' */ 961 estimate = estimate / PAUSEADJ; /* adjust 'estimate' */
890 threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */ 962 threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */
891 ? estimate * g->gcpause /* no overflow */ 963 ? estimate * g->gcpause /* no overflow */
892 : MAX_LMEM; /* overflow; truncate to maximum */ 964 : MAX_LMEM; /* overflow; truncate to maximum */
893 debt = -cast(l_mem, threshold - gettotalbytes(g)); 965 g->GCthreshold = threshold;
894 luaE_setdebt(g, debt); 966 luaE_setdebt(g, -GCLOCALPAUSE);
895} 967}
896 968
897 969
@@ -936,6 +1008,7 @@ void luaC_freeallobjects (lua_State *L) {
936 g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */ 1008 g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */
937 g->gckind = KGC_NORMAL; 1009 g->gckind = KGC_NORMAL;
938 sweepwholelist(L, &g->finobj); /* finalizers can create objs. in 'finobj' */ 1010 sweepwholelist(L, &g->finobj); /* finalizers can create objs. in 'finobj' */
1011 sweepwholelist(L, &g->localgc);
939 sweepwholelist(L, &g->allgc); 1012 sweepwholelist(L, &g->allgc);
940 sweepwholelist(L, &g->fixedgc); /* collect fixed objects */ 1013 sweepwholelist(L, &g->fixedgc); /* collect fixed objects */
941 lua_assert(g->strt.nuse == 0); 1014 lua_assert(g->strt.nuse == 0);
@@ -1017,8 +1090,9 @@ static lu_mem singlestep (lua_State *L) {
1017 return GCSWEEPMAX*GCSWEEPCOST; 1090 return GCSWEEPMAX*GCSWEEPCOST;
1018 } 1091 }
1019 else { 1092 else {
1093 sweepwholelist(L, &g->localgc);
1020 g->gcstate = GCSsweep; 1094 g->gcstate = GCSsweep;
1021 return 0; 1095 return GCLOCALPAUSE / 4; /* some magic for now */
1022 } 1096 }
1023 } 1097 }
1024 case GCSsweep: { 1098 case GCSsweep: {
@@ -1090,7 +1164,19 @@ void luaC_forcestep (lua_State *L) {
1090*/ 1164*/
1091void luaC_step (lua_State *L) { 1165void luaC_step (lua_State *L) {
1092 global_State *g = G(L); 1166 global_State *g = G(L);
1093 if (g->gcrunning) luaC_forcestep(L); 1167 if (g->gcrunning) {
1168 if (g->gcstate != GCSpause) {
1169 luaC_forcestep(L);
1170 }
1171 else {
1172 luaC_localcollection(L);
1173 if (gettotalbytes(g) > g->GCthreshold) {
1174 luaC_forcestep(L); /* restart collection */
1175 }
1176 else
1177 luaE_setdebt(g, -GCLOCALPAUSE);
1178 }
1179 }
1094 else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */ 1180 else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */
1095} 1181}
1096 1182
diff --git a/lgc.h b/lgc.h
index ccaaeab3..b931ae1a 100644
--- a/lgc.h
+++ b/lgc.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.h,v 2.64 2013/08/21 19:21:16 roberto Exp roberto $ 2** $Id: lgc.h,v 2.65 2013/08/21 20:09:51 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*/
@@ -77,6 +77,7 @@
77#define BLACKBIT 2 /* object is black */ 77#define BLACKBIT 2 /* object is black */
78#define FINALIZEDBIT 3 /* object has been marked for finalization */ 78#define FINALIZEDBIT 3 /* object has been marked for finalization */
79#define LOCALBIT 4 /* object is not local */ 79#define LOCALBIT 4 /* object is not local */
80#define LOCALBLACK 5 /* object is 'locally black' */
80/* bit 7 is currently used by tests (luaL_checkmemory) */ 81/* bit 7 is currently used by tests (luaL_checkmemory) */
81 82
82#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) 83#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
diff --git a/lstate.c b/lstate.c
index c8fc27c5..30fbc27c 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 2.103 2013/08/21 19:21:16 roberto Exp roberto $ 2** $Id: lstate.c,v 2.104 2013/08/21 20:09:51 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*/
@@ -280,6 +280,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
280 g->seed = makeseed(L); 280 g->seed = makeseed(L);
281 g->gcrunning = 0; /* no GC while building state */ 281 g->gcrunning = 0; /* no GC while building state */
282 g->GCestimate = 0; 282 g->GCestimate = 0;
283 g->GCthreshold = 10000;
283 g->strt.size = g->strt.nuse = g->strt.empty = 0; 284 g->strt.size = g->strt.nuse = g->strt.empty = 0;
284 g->strt.hash = NULL; 285 g->strt.hash = NULL;
285 setnilvalue(&g->l_registry); 286 setnilvalue(&g->l_registry);
@@ -288,6 +289,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
288 g->version = lua_version(NULL); 289 g->version = lua_version(NULL);
289 g->gcstate = GCSpause; 290 g->gcstate = GCSpause;
290 g->allgc = NULL; 291 g->allgc = NULL;
292 g->localgc = NULL;
291 g->finobj = NULL; 293 g->finobj = NULL;
292 g->tobefnz = NULL; 294 g->tobefnz = NULL;
293 g->fixedgc = NULL; 295 g->fixedgc = NULL;
diff --git a/lstate.h b/lstate.h
index 2c89aad6..9c0434b9 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 2.87 2013/08/21 20:09:51 roberto Exp roberto $ 2** $Id: lstate.h,v 2.88 2013/08/22 15:21:48 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*/
@@ -118,6 +118,7 @@ typedef struct global_State {
118 l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ 118 l_mem GCdebt; /* bytes allocated not yet compensated by the collector */
119 lu_mem GCmemtrav; /* memory traversed by the GC */ 119 lu_mem GCmemtrav; /* memory traversed by the GC */
120 lu_mem GCestimate; /* an estimate of the non-garbage memory in use */ 120 lu_mem GCestimate; /* an estimate of the non-garbage memory in use */
121 lu_mem GCthreshold; /* threshold to start a new GC cycle */
121 stringtable strt; /* hash table for strings */ 122 stringtable strt; /* hash table for strings */
122 TValue l_registry; 123 TValue l_registry;
123 unsigned int seed; /* randomized seed for hashes */ 124 unsigned int seed; /* randomized seed for hashes */
@@ -126,6 +127,7 @@ typedef struct global_State {
126 lu_byte gckind; /* kind of GC running */ 127 lu_byte gckind; /* kind of GC running */
127 lu_byte gcrunning; /* true if GC is running */ 128 lu_byte gcrunning; /* true if GC is running */
128 GCObject *allgc; /* list of all collectable objects */ 129 GCObject *allgc; /* list of all collectable objects */
130 GCObject *localgc; /* list of local objects */
129 GCObject *finobj; /* list of collectable objects with finalizers */ 131 GCObject *finobj; /* list of collectable objects with finalizers */
130 GCObject **sweepgc; /* current position of sweep in list 'allgc' */ 132 GCObject **sweepgc; /* current position of sweep in list 'allgc' */
131 GCObject **sweepfin; /* current position of sweep in list 'finobj' */ 133 GCObject **sweepfin; /* current position of sweep in list 'finobj' */
diff --git a/lstring.c b/lstring.c
index e53c6375..6d1ce978 100644
--- a/lstring.c
+++ b/lstring.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.c,v 2.29 2013/08/21 19:21:16 roberto Exp roberto $ 2** $Id: lstring.c,v 2.30 2013/08/22 15:21:48 roberto Exp roberto $
3** String table (keeps all strings handled by Lua) 3** String table (keeps all strings handled by Lua)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -106,7 +106,7 @@ static TString *createstrobj (lua_State *L, const char *str, size_t l,
106 TString *ts; 106 TString *ts;
107 size_t totalsize; /* total size of TString object */ 107 size_t totalsize; /* total size of TString object */
108 totalsize = sizeof(TString) + ((l + 1) * sizeof(char)); 108 totalsize = sizeof(TString) + ((l + 1) * sizeof(char));
109 ts = &luaC_newobj(L, tag, totalsize, NULL, 0)->ts; 109 ts = &luaC_newobj(L, tag, totalsize, &G(L)->localgc, 0)->ts;
110 ts->tsv.len = l; 110 ts->tsv.len = l;
111 ts->tsv.hash = h; 111 ts->tsv.hash = h;
112 ts->tsv.extra = 0; 112 ts->tsv.extra = 0;