mirror of
https://github.com/lua/lua
synced 2024-11-21 20:31:22 +03:00
Some adjustments in transition minor->major
Plus extra comments and other details.
This commit is contained in:
parent
3d54b42d59
commit
d0815046d0
78
lgc.c
78
lgc.c
@ -424,10 +424,8 @@ static void cleargraylists (global_State *g) {
|
||||
|
||||
/*
|
||||
** mark root set and reset all gray lists, to start a new collection.
|
||||
** 'marked' is initialized with the number of fixed objects in the state,
|
||||
** to count the total number of live objects during a cycle. (That is
|
||||
** the metafield names, plus the reserved words, plus "_ENV" plus the
|
||||
** memory-error message.)
|
||||
** 'GCmarked' is initialized to count the total number of live bytes
|
||||
** during a cycle.
|
||||
*/
|
||||
static void restartcollection (global_State *g) {
|
||||
cleargraylists(g);
|
||||
@ -1067,10 +1065,25 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
** Fields 'GCmarked' and 'GCmajorminor' are used to control the pace and
|
||||
** the mode of the collector. They play several roles, depending on the
|
||||
** mode of the collector:
|
||||
** * KGC_INC:
|
||||
** GCmarked: number of marked bytes during a cycle.
|
||||
** GCmajorminor: not used.
|
||||
** * KGC_GENMINOR
|
||||
** GCmarked: number of bytes that became old since last major collection.
|
||||
** GCmajorminor: number of bytes marked in last major collection.
|
||||
** * KGC_GENMAJOR
|
||||
** GCmarked: number of bytes that became old sinse last major collection.
|
||||
** GCmajorminor: number of bytes marked in last major collection.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
** Set the "time" to wait before starting a new incremental cycle;
|
||||
** cycle will start when number of objects in use hits the threshold of
|
||||
** cycle will start when number of bytes in use hits the threshold of
|
||||
** approximately (marked * pause / 100).
|
||||
*/
|
||||
static void setpause (global_State *g) {
|
||||
@ -1258,7 +1271,7 @@ static void finishgencycle (lua_State *L, global_State *g) {
|
||||
** in generational mode.
|
||||
*/
|
||||
static void minor2inc (lua_State *L, global_State *g, lu_byte kind) {
|
||||
g->GCmajorminor = g->GCmarked; /* number of live objects */
|
||||
g->GCmajorminor = g->GCmarked; /* number of live bytes */
|
||||
g->gckind = kind;
|
||||
g->reallyold = g->old1 = g->survival = NULL;
|
||||
g->finobjrold = g->finobjold1 = g->finobjsur = NULL;
|
||||
@ -1269,21 +1282,16 @@ static void minor2inc (lua_State *L, global_State *g, lu_byte kind) {
|
||||
|
||||
|
||||
/*
|
||||
** Decide whether to shift to major mode. It tests two conditions:
|
||||
** 1) Whether the number of added old objects in this collection is more
|
||||
** than half the number of new objects. ('step' is equal to the debt set
|
||||
** to trigger the next minor collection; that is equal to the number
|
||||
** of objects created since the previous minor collection. Except for
|
||||
** forward barriers, it is the maximum number of objects that can become
|
||||
** old in each minor collection.)
|
||||
** 2) Whether the accumulated number of added old objects is larger
|
||||
** than 'minormajor'% of the number of lived objects after the last
|
||||
** major collection. (That percentage is computed in 'limit'.)
|
||||
** Decide whether to shift to major mode. It shifts if the accumulated
|
||||
** number of added old bytes (counted in 'GCmarked') is larger than
|
||||
** 'minormajor'% of the number of lived bytes after the last major
|
||||
** collection. (This number is kept in 'GCmajorminor'.)
|
||||
*/
|
||||
static int checkminormajor (global_State *g, l_mem addedold1) {
|
||||
l_mem step = applygcparam(g, MINORMUL, g->GCmajorminor);
|
||||
static int checkminormajor (global_State *g) {
|
||||
l_mem limit = applygcparam(g, MINORMAJOR, g->GCmajorminor);
|
||||
return (addedold1 >= (step >> 1) || g->GCmarked >= limit);
|
||||
if (limit == 0)
|
||||
return 0; /* special case: 'minormajor' 0 stops major collections */
|
||||
return (g->GCmarked >= limit);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1326,13 +1334,13 @@ static void youngcollection (lua_State *L, global_State *g) {
|
||||
|
||||
sweepgen(L, g, &g->tobefnz, NULL, &dummy, &addedold1);
|
||||
|
||||
/* keep total number of added old1 objects */
|
||||
/* keep total number of added old1 bytes */
|
||||
g->GCmarked = marked + addedold1;
|
||||
|
||||
/* decide whether to shift to major mode */
|
||||
if (checkminormajor(g, addedold1)) {
|
||||
if (checkminormajor(g)) {
|
||||
minor2inc(L, g, KGC_GENMAJOR); /* go to major mode */
|
||||
g->GCmarked = 0; /* avoid pause in first major cycle */
|
||||
g->GCmarked = 0; /* avoid pause in first major cycle (see 'setpause') */
|
||||
}
|
||||
else
|
||||
finishgencycle(L, g); /* still in minor mode; finish it */
|
||||
@ -1361,8 +1369,8 @@ static void atomic2gen (lua_State *L, global_State *g) {
|
||||
sweep2old(L, &g->tobefnz);
|
||||
|
||||
g->gckind = KGC_GENMINOR;
|
||||
g->GCmajorminor = g->GCmarked; /* "base" for number of objects */
|
||||
g->GCmarked = 0; /* to count the number of added old1 objects */
|
||||
g->GCmajorminor = g->GCmarked; /* "base" for number of bytes */
|
||||
g->GCmarked = 0; /* to count the number of added old1 bytes */
|
||||
finishgencycle(L, g);
|
||||
}
|
||||
|
||||
@ -1423,15 +1431,15 @@ static void fullgen (lua_State *L, global_State *g) {
|
||||
/*
|
||||
** After an atomic incremental step from a major collection,
|
||||
** check whether collector could return to minor collections.
|
||||
** It checks whether the number of objects 'tobecollected'
|
||||
** is greater than 'majorminor'% of the number of objects added
|
||||
** since the last collection ('addedobjs').
|
||||
** It checks whether the number of bytes 'tobecollected'
|
||||
** is greater than 'majorminor'% of the number of bytes added
|
||||
** since the last collection ('addedbytes').
|
||||
*/
|
||||
static int checkmajorminor (lua_State *L, global_State *g) {
|
||||
if (g->gckind == KGC_GENMAJOR) { /* generational mode? */
|
||||
l_mem numbytes = gettotalbytes(g);
|
||||
l_mem addedobjs = numbytes - g->GCmajorminor;
|
||||
l_mem limit = applygcparam(g, MAJORMINOR, addedobjs);
|
||||
l_mem addedbytes = numbytes - g->GCmajorminor;
|
||||
l_mem limit = applygcparam(g, MAJORMINOR, addedbytes);
|
||||
l_mem tobecollected = numbytes - g->GCmarked;
|
||||
if (tobecollected > limit) {
|
||||
atomic2gen(L, g); /* return to generational mode */
|
||||
@ -1670,9 +1678,7 @@ static void incstep (lua_State *L, global_State *g) {
|
||||
l_mem work2do = applygcparam(g, STEPMUL, stepsize);
|
||||
l_mem stres;
|
||||
int fast = (work2do == 0); /* special case: do a full collection */
|
||||
//printf("\n** %ld %ld %d\n", work2do, stepsize, g->gcstate);
|
||||
do { /* repeat until enough work */
|
||||
//printf("%d-", g->gcstate);
|
||||
stres = singlestep(L, fast); /* perform one single step */
|
||||
if (stres == step2minor) /* returned to minor collections? */
|
||||
return; /* nothing else to be done here */
|
||||
@ -1688,6 +1694,10 @@ static void incstep (lua_State *L, global_State *g) {
|
||||
}
|
||||
|
||||
|
||||
#if !defined(luai_tracegc)
|
||||
#define luai_tracegc(L) ((void)0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Performs a basic GC step if collector is running. (If collector is
|
||||
** not running, set a reasonable debt to avoid it being called at
|
||||
@ -1699,20 +1709,16 @@ void luaC_step (lua_State *L) {
|
||||
if (!gcrunning(g)) /* not running? */
|
||||
luaE_setdebt(g, 20000);
|
||||
else {
|
||||
//printf("mem: %ld kind: %s ", gettotalbytes(g),
|
||||
// g->gckind == KGC_INC ? "inc" : g->gckind == KGC_GENMAJOR ? "genmajor" :
|
||||
// "genminor");
|
||||
luai_tracegc(L); /* for internal debugging */
|
||||
switch (g->gckind) {
|
||||
case KGC_INC: case KGC_GENMAJOR:
|
||||
incstep(L, g);
|
||||
//printf("%d) ", g->gcstate);
|
||||
break;
|
||||
case KGC_GENMINOR:
|
||||
youngcollection(L, g);
|
||||
setminordebt(g);
|
||||
break;
|
||||
}
|
||||
//printf("-> mem: %ld debt: %ld\n", gettotalbytes(g), g->GCdebt);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -719,6 +719,8 @@ than the total after the previous major collection.
|
||||
For instance, for a multiplier of 100,
|
||||
the collector will do a major collection when the number of old bytes
|
||||
gets larger than twice the total after the previous major collection.
|
||||
As a special case,
|
||||
a value of 0 stops the collector from doing major collections.
|
||||
|
||||
The major-minor multiplier controls the shift back to minor collections.
|
||||
For a multiplier @M{x},
|
||||
@ -6441,7 +6443,8 @@ Changes the collector mode to generational and returns the previous mode.
|
||||
Changes and/or retrieves the values of a parameter of the collector.
|
||||
This option must be followed by one or two extra arguments:
|
||||
The name of the parameter being changed or retrieved (a string)
|
||||
and an optional new value for that parameter (an integer).
|
||||
and an optional new value for that parameter,
|
||||
an integer in the range @M{[0,100000]}.
|
||||
The first argument must have one of the following values:
|
||||
@description{
|
||||
@item{@St{minormul}| The minor multiplier. }
|
||||
|
Loading…
Reference in New Issue
Block a user