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:
parent
e7af9cdf0b
commit
7827c40c49
4
config.lua
Normal file
4
config.lua
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
collectgarbage("setparam", "minormul", 25)
|
||||||
|
-- collectgarbage("generational")
|
||||||
|
|
||||||
|
|
14
lapi.c
14
lapi.c
@ -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
23
lgc.c
@ -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
2
lgc.h
@ -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.) */
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user