aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.lua4
-rw-r--r--lapi.c14
-rw-r--r--lgc.c23
-rw-r--r--lgc.h2
-rw-r--r--manual/manual.of4
5 files changed, 33 insertions, 14 deletions
diff --git a/config.lua b/config.lua
new file mode 100644
index 00000000..14afdc8a
--- /dev/null
+++ b/config.lua
@@ -0,0 +1,4 @@
1collectgarbage("setparam", "minormul", 25)
2-- collectgarbage("generational")
3
4
diff --git a/lapi.c b/lapi.c
index 9ff1b851..d18445e0 100644
--- a/lapi.c
+++ b/lapi.c
@@ -53,6 +53,16 @@ const char lua_ident[] =
53#define isupvalue(i) ((i) < LUA_REGISTRYINDEX) 53#define isupvalue(i) ((i) < LUA_REGISTRYINDEX)
54 54
55 55
56/* Advance the garbage collector when creating large objects */
57static void advancegc (lua_State *L, size_t delta) {
58 delta >>= 5; /* one object for each 32 bytes (empirical) */
59 if (delta > 0) {
60 global_State *g = G(L);
61 luaE_setdebt(g, g->GCdebt - delta);
62 }
63}
64
65
56/* 66/*
57** Convert an acceptable index to a pointer to its respective value. 67** Convert an acceptable index to a pointer to its respective value.
58** Non-valid indices return the special nil value 'G(L)->nilvalue'. 68** Non-valid indices return the special nil value 'G(L)->nilvalue'.
@@ -530,6 +540,7 @@ LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
530 ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len); 540 ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len);
531 setsvalue2s(L, L->top.p, ts); 541 setsvalue2s(L, L->top.p, ts);
532 api_incr_top(L); 542 api_incr_top(L);
543 advancegc(L, len);
533 luaC_checkGC(L); 544 luaC_checkGC(L);
534 lua_unlock(L); 545 lua_unlock(L);
535 return getstr(ts); 546 return getstr(ts);
@@ -544,6 +555,8 @@ LUA_API const char *lua_pushextlstring (lua_State *L,
544 ts = luaS_newextlstr (L, s, len, falloc, ud); 555 ts = luaS_newextlstr (L, s, len, falloc, ud);
545 setsvalue2s(L, L->top.p, ts); 556 setsvalue2s(L, L->top.p, ts);
546 api_incr_top(L); 557 api_incr_top(L);
558 if (falloc != NULL) /* non-static string? */
559 advancegc(L, len); /* count its memory */
547 luaC_checkGC(L); 560 luaC_checkGC(L);
548 lua_unlock(L); 561 lua_unlock(L);
549 return getstr(ts); 562 return getstr(ts);
@@ -1336,6 +1349,7 @@ LUA_API void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue) {
1336 u = luaS_newudata(L, size, nuvalue); 1349 u = luaS_newudata(L, size, nuvalue);
1337 setuvalue(L, s2v(L->top.p), u); 1350 setuvalue(L, s2v(L->top.p), u);
1338 api_incr_top(L); 1351 api_incr_top(L);
1352 advancegc(L, size);
1339 luaC_checkGC(L); 1353 luaC_checkGC(L);
1340 lua_unlock(L); 1354 lua_unlock(L);
1341 return getudatamem(u); 1355 return getudatamem(u);
diff --git a/lgc.c b/lgc.c
index bc4ddb0b..4cdea02a 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1052,6 +1052,7 @@ static void setpause (global_State *g) {
1052 l_obj threshold = applygcparam(g, PAUSE, g->marked); 1052 l_obj threshold = applygcparam(g, PAUSE, g->marked);
1053 l_obj debt = threshold - gettotalobjs(g); 1053 l_obj debt = threshold - gettotalobjs(g);
1054 if (debt < 0) debt = 0; 1054 if (debt < 0) debt = 0;
1055//printf("pause: %ld %ld\n", debt, g->marked);
1055 luaE_setdebt(g, debt); 1056 luaE_setdebt(g, debt);
1056} 1057}
1057 1058
@@ -1246,7 +1247,7 @@ static void minor2inc (lua_State *L, global_State *g, int kind) {
1246/* 1247/*
1247** Decide whether to shift to major mode. It tests two conditions: 1248** Decide whether to shift to major mode. It tests two conditions:
1248** 1) Whether the number of added old objects in this collection is more 1249** 1) Whether the number of added old objects in this collection is more
1249** than half the number of new objects. ("step" is the number of objects 1250** than half the number of new objects. ('step' is the number of objects
1250** created between minor collections. Except for forward barriers, it 1251** created between minor collections. Except for forward barriers, it
1251** is the maximum number of objects that can become old in each minor 1252** is the maximum number of objects that can become old in each minor
1252** collection.) 1253** collection.)
@@ -1254,15 +1255,11 @@ static void minor2inc (lua_State *L, global_State *g, int kind) {
1254** than 'minormajor'% of the number of lived objects after the last 1255** than 'minormajor'% of the number of lived objects after the last
1255** major collection. (That percentage is computed in 'limit'.) 1256** major collection. (That percentage is computed in 'limit'.)
1256*/ 1257*/
1257static int checkminormajor (lua_State *L, global_State *g, l_obj addedold1) { 1258static int checkminormajor (global_State *g, l_obj addedold1) {
1258 l_obj step = applygcparam(g, MINORMUL, g->GCmajorminor); 1259 l_obj step = applygcparam(g, MINORMUL, g->GCmajorminor);
1259 l_obj limit = applygcparam(g, MINORMAJOR, g->GCmajorminor); 1260 l_obj limit = applygcparam(g, MINORMAJOR, g->GCmajorminor);
1260//printf("-> major? %ld %ld %ld %ld (%ld)\n", g->marked, limit, step, addedold1, gettotalobjs(g)); 1261//printf("-> (%ld) major? marked: %ld limit: %ld step: %ld addedold1: %ld)\n", gettotalobjs(g), g->marked, limit, step, addedold1);
1261 if (addedold1 >= (step >> 1) || g->marked >= limit) { 1262 return (addedold1 >= (step >> 1) || g->marked >= limit);
1262 minor2inc(L, g, KGC_GENMAJOR); /* go to major mode */
1263 return 1;
1264 }
1265 return 0; /* stay in minor mode */
1266} 1263}
1267 1264
1268/* 1265/*
@@ -1309,7 +1306,11 @@ static void youngcollection (lua_State *L, global_State *g) {
1309 g->marked = marked + addedold1; 1306 g->marked = marked + addedold1;
1310 1307
1311 /* decide whether to shift to major mode */ 1308 /* decide whether to shift to major mode */
1312 if (!checkminormajor(L, g, addedold1)) 1309 if (checkminormajor(g, addedold1)) {
1310 minor2inc(L, g, KGC_GENMAJOR); /* go to major mode */
1311 g->marked = 0; /* avoid pause in first major cycle */
1312 }
1313 else
1313 finishgencycle(L, g); /* still in minor mode; finish it */ 1314 finishgencycle(L, g); /* still in minor mode; finish it */
1314} 1315}
1315 1316
@@ -1401,12 +1402,12 @@ static void fullgen (lua_State *L, global_State *g) {
1401** since the last collection ('addedobjs'). 1402** since the last collection ('addedobjs').
1402*/ 1403*/
1403static int checkmajorminor (lua_State *L, global_State *g) { 1404static int checkmajorminor (lua_State *L, global_State *g) {
1404 if (g->gckind == KGC_GENMAJOR) { 1405 if (g->gckind == KGC_GENMAJOR) { /* generational mode? */
1405 l_obj numobjs = gettotalobjs(g); 1406 l_obj numobjs = gettotalobjs(g);
1406 l_obj addedobjs = numobjs - g->GCmajorminor; 1407 l_obj addedobjs = numobjs - g->GCmajorminor;
1407 l_obj limit = applygcparam(g, MAJORMINOR, addedobjs); 1408 l_obj limit = applygcparam(g, MAJORMINOR, addedobjs);
1408 l_obj tobecollected = numobjs - g->marked; 1409 l_obj tobecollected = numobjs - g->marked;
1409//printf("-> minor? %ld %ld %ld\n", tobecollected, limit, numobjs); 1410//printf("(%ld) -> minor? tobecollected: %ld limit: %ld\n", numobjs, tobecollected, limit);
1410 if (tobecollected > limit) { 1411 if (tobecollected > limit) {
1411 atomic2gen(L, g); /* return to generational mode */ 1412 atomic2gen(L, g); /* return to generational mode */
1412 setminordebt(g); 1413 setminordebt(g);
diff --git a/lgc.h b/lgc.h
index b4c4f234..5e474114 100644
--- a/lgc.h
+++ b/lgc.h
@@ -183,7 +183,7 @@
183/* incremental */ 183/* incremental */
184 184
185/* Number of objects must be LUAI_GCPAUSE% before starting new cycle */ 185/* Number of objects must be LUAI_GCPAUSE% before starting new cycle */
186#define LUAI_GCPAUSE 300 186#define LUAI_GCPAUSE 200
187 187
188/* Step multiplier. (Roughly, the collector handles LUAI_GCMUL% objects 188/* Step multiplier. (Roughly, the collector handles LUAI_GCMUL% objects
189 for each new allocated object.) */ 189 for each new allocated object.) */
diff --git a/manual/manual.of b/manual/manual.of
index 6fd0df6d..ae38d7c6 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -664,7 +664,7 @@ Values equal to or less than 100 mean the collector will not wait to
664start a new cycle. 664start a new cycle.
665A value of 200 means that the collector waits for 665A value of 200 means that the collector waits for
666the total number of objects to double before starting a new cycle. 666the total number of objects to double before starting a new cycle.
667The default value is 300; the maximum value is 1000. 667The default value is 200.
668 668
669The garbage-collector step size controls the 669The garbage-collector step size controls the
670size of each incremental step, 670size of each incremental step,
@@ -681,7 +681,7 @@ in each step, @M{n%} objects for each created object.
681Larger values make the collector more aggressive. 681Larger values make the collector more aggressive.
682Beware that values too small can 682Beware that values too small can
683make the collector too slow to ever finish a cycle. 683make the collector too slow to ever finish a cycle.
684The default value is 200; the maximum value is 1000. 684The default value is 200.
685As a special case, a zero value means unlimited work, 685As a special case, a zero value means unlimited work,
686effectively producing a non-incremental, stop-the-world collector. 686effectively producing a non-incremental, stop-the-world collector.
687 687