瀏覽代碼

Some adjustments in transition minor->major

Plus extra comments and other details.
Roberto Ierusalimschy 9 月之前
父節點
當前提交
d0815046d0
共有 2 個文件被更改,包括 46 次插入37 次删除
  1. 42 36
      lgc.c
  2. 4 1
      manual/manual.of

+ 42 - 36
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);
   }
 }
 

+ 4 - 1
manual/manual.of

@@ -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. }