diff options
-rw-r--r-- | config.lua | 4 | ||||
-rw-r--r-- | lapi.c | 14 | ||||
-rw-r--r-- | lgc.c | 23 | ||||
-rw-r--r-- | lgc.h | 2 | ||||
-rw-r--r-- | manual/manual.of | 4 |
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 @@ | |||
1 | collectgarbage("setparam", "minormul", 25) | ||
2 | -- collectgarbage("generational") | ||
3 | |||
4 | |||
@@ -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 */ | ||
57 | static 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); |
@@ -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 | */ |
1257 | static int checkminormajor (lua_State *L, global_State *g, l_obj addedold1) { | 1258 | static 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 | */ |
1403 | static int checkmajorminor (lua_State *L, global_State *g) { | 1404 | static 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); |
@@ -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 | |||
664 | start a new cycle. | 664 | start a new cycle. |
665 | A value of 200 means that the collector waits for | 665 | A value of 200 means that the collector waits for |
666 | the total number of objects to double before starting a new cycle. | 666 | the total number of objects to double before starting a new cycle. |
667 | The default value is 300; the maximum value is 1000. | 667 | The default value is 200. |
668 | 668 | ||
669 | The garbage-collector step size controls the | 669 | The garbage-collector step size controls the |
670 | size of each incremental step, | 670 | size of each incremental step, |
@@ -681,7 +681,7 @@ in each step, @M{n%} objects for each created object. | |||
681 | Larger values make the collector more aggressive. | 681 | Larger values make the collector more aggressive. |
682 | Beware that values too small can | 682 | Beware that values too small can |
683 | make the collector too slow to ever finish a cycle. | 683 | make the collector too slow to ever finish a cycle. |
684 | The default value is 200; the maximum value is 1000. | 684 | The default value is 200. |
685 | As a special case, a zero value means unlimited work, | 685 | As a special case, a zero value means unlimited work, |
686 | effectively producing a non-incremental, stop-the-world collector. | 686 | effectively producing a non-incremental, stop-the-world collector. |
687 | 687 | ||