1
0
mirror of https://github.com/lua/lua.git synced 2025-01-28 06:03:00 +08:00

A few more tweaks in the garbage collector

This commit is contained in:
Roberto Ierusalimschy 2024-01-10 14:45:58 -03:00
parent e7af9cdf0b
commit 7827c40c49
5 changed files with 33 additions and 14 deletions

4
config.lua Normal file
View File

@ -0,0 +1,4 @@
collectgarbage("setparam", "minormul", 25)
-- collectgarbage("generational")

14
lapi.c
View File

@ -53,6 +53,16 @@ const char lua_ident[] =
#define isupvalue(i) ((i) < LUA_REGISTRYINDEX) #define isupvalue(i) ((i) < LUA_REGISTRYINDEX)
/* Advance the garbage collector when creating large objects */
static void advancegc (lua_State *L, size_t delta) {
delta >>= 5; /* one object for each 32 bytes (empirical) */
if (delta > 0) {
global_State *g = G(L);
luaE_setdebt(g, g->GCdebt - delta);
}
}
/* /*
** Convert an acceptable index to a pointer to its respective value. ** Convert an acceptable index to a pointer to its respective value.
** Non-valid indices return the special nil value 'G(L)->nilvalue'. ** 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) {
ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len); ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len);
setsvalue2s(L, L->top.p, ts); setsvalue2s(L, L->top.p, ts);
api_incr_top(L); api_incr_top(L);
advancegc(L, len);
luaC_checkGC(L); luaC_checkGC(L);
lua_unlock(L); lua_unlock(L);
return getstr(ts); return getstr(ts);
@ -544,6 +555,8 @@ LUA_API const char *lua_pushextlstring (lua_State *L,
ts = luaS_newextlstr (L, s, len, falloc, ud); ts = luaS_newextlstr (L, s, len, falloc, ud);
setsvalue2s(L, L->top.p, ts); setsvalue2s(L, L->top.p, ts);
api_incr_top(L); api_incr_top(L);
if (falloc != NULL) /* non-static string? */
advancegc(L, len); /* count its memory */
luaC_checkGC(L); luaC_checkGC(L);
lua_unlock(L); lua_unlock(L);
return getstr(ts); return getstr(ts);
@ -1336,6 +1349,7 @@ LUA_API void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue) {
u = luaS_newudata(L, size, nuvalue); u = luaS_newudata(L, size, nuvalue);
setuvalue(L, s2v(L->top.p), u); setuvalue(L, s2v(L->top.p), u);
api_incr_top(L); api_incr_top(L);
advancegc(L, size);
luaC_checkGC(L); luaC_checkGC(L);
lua_unlock(L); lua_unlock(L);
return getudatamem(u); return getudatamem(u);

23
lgc.c
View File

@ -1052,6 +1052,7 @@ static void setpause (global_State *g) {
l_obj threshold = applygcparam(g, PAUSE, g->marked); l_obj threshold = applygcparam(g, PAUSE, g->marked);
l_obj debt = threshold - gettotalobjs(g); l_obj debt = threshold - gettotalobjs(g);
if (debt < 0) debt = 0; if (debt < 0) debt = 0;
//printf("pause: %ld %ld\n", debt, g->marked);
luaE_setdebt(g, debt); luaE_setdebt(g, debt);
} }
@ -1246,7 +1247,7 @@ static void minor2inc (lua_State *L, global_State *g, int kind) {
/* /*
** Decide whether to shift to major mode. It tests two conditions: ** Decide whether to shift to major mode. It tests two conditions:
** 1) Whether the number of added old objects in this collection is more ** 1) Whether the number of added old objects in this collection is more
** than half the number of new objects. ("step" is the number of objects ** than half the number of new objects. ('step' is the number of objects
** created between minor collections. Except for forward barriers, it ** created between minor collections. Except for forward barriers, it
** is the maximum number of objects that can become old in each minor ** is the maximum number of objects that can become old in each minor
** collection.) ** collection.)
@ -1254,15 +1255,11 @@ static void minor2inc (lua_State *L, global_State *g, int kind) {
** than 'minormajor'% of the number of lived objects after the last ** than 'minormajor'% of the number of lived objects after the last
** major collection. (That percentage is computed in 'limit'.) ** major collection. (That percentage is computed in 'limit'.)
*/ */
static int checkminormajor (lua_State *L, global_State *g, l_obj addedold1) { static int checkminormajor (global_State *g, l_obj addedold1) {
l_obj step = applygcparam(g, MINORMUL, g->GCmajorminor); l_obj step = applygcparam(g, MINORMUL, g->GCmajorminor);
l_obj limit = applygcparam(g, MINORMAJOR, g->GCmajorminor); l_obj limit = applygcparam(g, MINORMAJOR, g->GCmajorminor);
//printf("-> major? %ld %ld %ld %ld (%ld)\n", g->marked, limit, step, addedold1, gettotalobjs(g)); //printf("-> (%ld) major? marked: %ld limit: %ld step: %ld addedold1: %ld)\n", gettotalobjs(g), g->marked, limit, step, addedold1);
if (addedold1 >= (step >> 1) || g->marked >= limit) { return (addedold1 >= (step >> 1) || g->marked >= limit);
minor2inc(L, g, KGC_GENMAJOR); /* go to major mode */
return 1;
}
return 0; /* stay in minor mode */
} }
/* /*
@ -1309,7 +1306,11 @@ static void youngcollection (lua_State *L, global_State *g) {
g->marked = marked + addedold1; g->marked = marked + addedold1;
/* decide whether to shift to major mode */ /* decide whether to shift to major mode */
if (!checkminormajor(L, g, addedold1)) if (checkminormajor(g, addedold1)) {
minor2inc(L, g, KGC_GENMAJOR); /* go to major mode */
g->marked = 0; /* avoid pause in first major cycle */
}
else
finishgencycle(L, g); /* still in minor mode; finish it */ finishgencycle(L, g); /* still in minor mode; finish it */
} }
@ -1401,12 +1402,12 @@ static void fullgen (lua_State *L, global_State *g) {
** since the last collection ('addedobjs'). ** since the last collection ('addedobjs').
*/ */
static int checkmajorminor (lua_State *L, global_State *g) { static int checkmajorminor (lua_State *L, global_State *g) {
if (g->gckind == KGC_GENMAJOR) { if (g->gckind == KGC_GENMAJOR) { /* generational mode? */
l_obj numobjs = gettotalobjs(g); l_obj numobjs = gettotalobjs(g);
l_obj addedobjs = numobjs - g->GCmajorminor; l_obj addedobjs = numobjs - g->GCmajorminor;
l_obj limit = applygcparam(g, MAJORMINOR, addedobjs); l_obj limit = applygcparam(g, MAJORMINOR, addedobjs);
l_obj tobecollected = numobjs - g->marked; l_obj tobecollected = numobjs - g->marked;
//printf("-> minor? %ld %ld %ld\n", tobecollected, limit, numobjs); //printf("(%ld) -> minor? tobecollected: %ld limit: %ld\n", numobjs, tobecollected, limit);
if (tobecollected > limit) { if (tobecollected > limit) {
atomic2gen(L, g); /* return to generational mode */ atomic2gen(L, g); /* return to generational mode */
setminordebt(g); setminordebt(g);

2
lgc.h
View File

@ -183,7 +183,7 @@
/* incremental */ /* incremental */
/* Number of objects must be LUAI_GCPAUSE% before starting new cycle */ /* Number of objects must be LUAI_GCPAUSE% before starting new cycle */
#define LUAI_GCPAUSE 300 #define LUAI_GCPAUSE 200
/* Step multiplier. (Roughly, the collector handles LUAI_GCMUL% objects /* Step multiplier. (Roughly, the collector handles LUAI_GCMUL% objects
for each new allocated object.) */ for each new allocated object.) */

View File

@ -664,7 +664,7 @@ Values equal to or less than 100 mean the collector will not wait to
start a new cycle. start a new cycle.
A value of 200 means that the collector waits for A value of 200 means that the collector waits for
the total number of objects to double before starting a new cycle. the total number of objects to double before starting a new cycle.
The default value is 300; the maximum value is 1000. The default value is 200.
The garbage-collector step size controls the The garbage-collector step size controls the
size of each incremental step, size of each incremental step,
@ -681,7 +681,7 @@ in each step, @M{n%} objects for each created object.
Larger values make the collector more aggressive. Larger values make the collector more aggressive.
Beware that values too small can Beware that values too small can
make the collector too slow to ever finish a cycle. make the collector too slow to ever finish a cycle.
The default value is 200; the maximum value is 1000. The default value is 200.
As a special case, a zero value means unlimited work, As a special case, a zero value means unlimited work,
effectively producing a non-incremental, stop-the-world collector. effectively producing a non-incremental, stop-the-world collector.