Bläddra i källkod

new way to control GC speed

Roberto Ierusalimschy 15 år sedan
förälder
incheckning
3410dcd375
2 ändrade filer med 26 tillägg och 16 borttagningar
  1. 7 4
      lmem.c
  2. 19 12
      lstate.c

+ 7 - 4
lmem.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lmem.c,v 1.74 2009/12/16 16:42:58 roberto Exp roberto $
+** $Id: lmem.c,v 1.75 2010/04/02 14:37:41 roberto Exp roberto $
 ** Interface to Memory Manager
 ** Interface to Memory Manager
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -79,13 +79,14 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
   size_t realosize = (block) ? osize : 0;
   size_t realosize = (block) ? osize : 0;
   lua_assert((realosize == 0) == (block == NULL));
   lua_assert((realosize == 0) == (block == NULL));
 #if defined(HARDMEMTESTS)
 #if defined(HARDMEMTESTS)
-  if (nsize > realosize && g->GCthreshold != MAX_LUMEM)
+  if (nsize > realosize && !gcstopped(g))
     luaC_fullgc(L, 1);  /* force a GC whenever possible */
     luaC_fullgc(L, 1);  /* force a GC whenever possible */
 #endif
 #endif
   newblock = (*g->frealloc)(g->ud, block, osize, nsize);
   newblock = (*g->frealloc)(g->ud, block, osize, nsize);
   if (newblock == NULL && nsize > 0) {
   if (newblock == NULL && nsize > 0) {
-    lua_assert(nsize > realosize);  /* cannot fail when shrinking a block */
-    if (g->GCthreshold != MAX_LUMEM) {
+    api_check(L, nsize > realosize,
+                 "realloc cannot fail when shrinking a block");
+    if (!gcstopped(g)) {
       luaC_fullgc(L, 1);  /* try to free some memory... */
       luaC_fullgc(L, 1);  /* try to free some memory... */
       newblock = (*g->frealloc)(g->ud, block, osize, nsize);  /* try again */
       newblock = (*g->frealloc)(g->ud, block, osize, nsize);  /* try again */
     }
     }
@@ -94,6 +95,8 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
   }
   }
   lua_assert((nsize == 0) == (newblock == NULL));
   lua_assert((nsize == 0) == (newblock == NULL));
   g->totalbytes = (g->totalbytes - realosize) + nsize;
   g->totalbytes = (g->totalbytes - realosize) + nsize;
+  if (!gcstopped(g))  /* new object? */
+    g->GCdebt += nsize;  /* give some credit to garbage collector */
 #if defined(TRACEMEM)
 #if defined(TRACEMEM)
   { /* auxiliar patch to monitor garbage collection.
   { /* auxiliar patch to monitor garbage collection.
     ** To plot, gnuplot with following command:
     ** To plot, gnuplot with following command:

+ 19 - 12
lstate.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstate.c,v 2.81 2010/04/19 16:34:46 roberto Exp roberto $
+** $Id: lstate.c,v 2.82 2010/04/19 17:40:13 roberto Exp roberto $
 ** Global State
 ** Global State
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -90,7 +90,7 @@ void luaE_freeCI (lua_State *L) {
 
 
 
 
 static void stack_init (lua_State *L1, lua_State *L) {
 static void stack_init (lua_State *L1, lua_State *L) {
-  int i;
+  int i; CallInfo *ci;
   /* initialize stack array */
   /* initialize stack array */
   L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue);
   L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue);
   L1->stacksize = BASIC_STACK_SIZE;
   L1->stacksize = BASIC_STACK_SIZE;
@@ -99,17 +99,22 @@ static void stack_init (lua_State *L1, lua_State *L) {
   L1->top = L1->stack;
   L1->top = L1->stack;
   L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
   L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
   /* initialize first ci */
   /* initialize first ci */
-  L1->ci->func = L1->top;
+  ci = &L1->base_ci;
+  ci->next = ci->previous = NULL;
+  ci->callstatus = 0;
+  ci->func = L1->top;
   setnilvalue(L1->top++);  /* 'function' entry for this 'ci' */
   setnilvalue(L1->top++);  /* 'function' entry for this 'ci' */
-  L1->ci->top = L1->top + LUA_MINSTACK;
-  L1->ci->callstatus = 0;
+  ci->top = L1->top + LUA_MINSTACK;
+  L1->ci = ci;
 }
 }
 
 
 
 
 static void freestack (lua_State *L) {
 static void freestack (lua_State *L) {
-  L->ci = &L->base_ci;  /* reset 'ci' list */
-  luaE_freeCI(L);
-  luaM_freearray(L, L->stack, L->stacksize);
+  if (L->ci != NULL) {  /* is there a 'ci' list? */
+    L->ci = &L->base_ci;  /* free the entire list */
+    luaE_freeCI(L);
+  }
+  luaM_freearray(L, L->stack, L->stacksize);  /* free stack array */
 }
 }
 
 
 
 
@@ -145,7 +150,7 @@ static void f_luaopen (lua_State *L, void *ud) {
   /* pre-create memory-error message */
   /* pre-create memory-error message */
   g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
   g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
   luaS_fix(g->memerrmsg);  /* it should never be collected */
   luaS_fix(g->memerrmsg);  /* it should never be collected */
-  g->GCthreshold = 4*g->totalbytes;
+  g->GCdebt = 0;
 }
 }
 
 
 
 
@@ -156,6 +161,7 @@ static void f_luaopen (lua_State *L, void *ud) {
 static void preinit_state (lua_State *L, global_State *g) {
 static void preinit_state (lua_State *L, global_State *g) {
   G(L) = g;
   G(L) = g;
   L->stack = NULL;
   L->stack = NULL;
+  L->ci = NULL;
   L->stacksize = 0;
   L->stacksize = 0;
   L->errorJmp = NULL;
   L->errorJmp = NULL;
   L->hook = NULL;
   L->hook = NULL;
@@ -166,8 +172,6 @@ static void preinit_state (lua_State *L, global_State *g) {
   L->openupval = NULL;
   L->openupval = NULL;
   L->nny = 1;
   L->nny = 1;
   L->status = LUA_OK;
   L->status = LUA_OK;
-  L->base_ci.next = L->base_ci.previous = NULL;
-  L->ci = &L->base_ci;
   L->errfunc = 0;
   L->errfunc = 0;
 }
 }
 
 
@@ -233,7 +237,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
   g->mainthread = L;
   g->mainthread = L;
   g->uvhead.u.l.prev = &g->uvhead;
   g->uvhead.u.l.prev = &g->uvhead;
   g->uvhead.u.l.next = &g->uvhead;
   g->uvhead.u.l.next = &g->uvhead;
-  g->GCthreshold = MAX_LUMEM;  /* no GC while building state */
+  stopgc(g);  /* no GC while building state */
   g->lastmajormem = 0;
   g->lastmajormem = 0;
   g->strt.size = 0;
   g->strt.size = 0;
   g->strt.nuse = 0;
   g->strt.nuse = 0;
@@ -246,6 +250,9 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
   g->allgc = NULL;
   g->allgc = NULL;
   g->udgc = NULL;
   g->udgc = NULL;
   g->tobefnz = NULL;
   g->tobefnz = NULL;
+  g->gray = NULL;
+  g->grayagain = NULL;
+  g->weak = g->ephemeron = g->allweak = NULL;
   g->totalbytes = sizeof(LG);
   g->totalbytes = sizeof(LG);
   g->gcpause = LUAI_GCPAUSE;
   g->gcpause = LUAI_GCPAUSE;
   g->gcstepmul = LUAI_GCMUL;
   g->gcstepmul = LUAI_GCMUL;