浏览代码

"fixed" objects kept in a separated list (instead of being kept in
'allgc' list with a bit marking them)

Roberto Ierusalimschy 12 年之前
父节点
当前提交
0df6635711
共有 7 个文件被更改,包括 33 次插入17 次删除
  1. 12 1
      lgc.c
  2. 3 3
      lgc.h
  3. 6 4
      llex.c
  4. 4 3
      lstate.c
  5. 5 1
      lstate.h
  6. 1 3
      lstring.h
  7. 2 2
      ltm.c

+ 12 - 1
lgc.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lgc.c,v 2.148 2013/08/20 17:46:34 roberto Exp roberto $
+** $Id: lgc.c,v 2.149 2013/08/21 19:21:16 roberto Exp roberto $
 ** Garbage Collector
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -189,6 +189,16 @@ void luaC_checkupvalcolor (global_State *g, UpVal *uv) {
 }
 }
 
 
 
 
+void luaC_fix (lua_State *L, GCObject *o) {
+  global_State *g = G(L);
+  lua_assert(g->allgc == o);
+  white2gray(o);
+  g->allgc = o->gch.next;  /* remove object from 'allgc' list */
+  o->gch.next = g->fixedgc;  /* link it to 'fixedgc' list */
+  g->fixedgc = o;
+}
+
+
 /*
 /*
 ** create a new collectable object (with given type and size) and link
 ** create a new collectable object (with given type and size) and link
 ** it to '*list'. 'offset' tells how many bytes to allocate before the
 ** it to '*list'. 'offset' tells how many bytes to allocate before the
@@ -927,6 +937,7 @@ void luaC_freeallobjects (lua_State *L) {
   g->gckind = KGC_NORMAL;
   g->gckind = KGC_NORMAL;
   sweepwholelist(L, &g->finobj);  /* finalizers can create objs. in 'finobj' */
   sweepwholelist(L, &g->finobj);  /* finalizers can create objs. in 'finobj' */
   sweepwholelist(L, &g->allgc);
   sweepwholelist(L, &g->allgc);
+  sweepwholelist(L, &g->fixedgc);  /* collect fixed objects */
   lua_assert(g->strt.nuse == 0);
   lua_assert(g->strt.nuse == 0);
 }
 }
 
 

+ 3 - 3
lgc.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lgc.h,v 2.63 2013/08/20 17:46:34 roberto Exp roberto $
+** $Id: lgc.h,v 2.64 2013/08/21 19:21:16 roberto Exp roberto $
 ** Garbage Collector
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -76,8 +76,7 @@
 #define WHITE1BIT	1  /* object is white (type 1) */
 #define WHITE1BIT	1  /* object is white (type 1) */
 #define BLACKBIT	2  /* object is black */
 #define BLACKBIT	2  /* object is black */
 #define FINALIZEDBIT	3  /* object has been marked for finalization */
 #define FINALIZEDBIT	3  /* object has been marked for finalization */
-#define FIXEDBIT	4  /* object is fixed (should not be collected) */
-#define LOCALBIT	5  /* object is not local */
+#define LOCALBIT	4  /* object is not local */
 /* bit 7 is currently used by tests (luaL_checkmemory) */
 /* bit 7 is currently used by tests (luaL_checkmemory) */
 
 
 #define WHITEBITS	bit2mask(WHITE0BIT, WHITE1BIT)
 #define WHITEBITS	bit2mask(WHITE0BIT, WHITE1BIT)
@@ -127,6 +126,7 @@
    { if (nolocal(obj2gco(o)), isblack(obj2gco(p)) && iswhite(obj2gco(o))) \
    { if (nolocal(obj2gco(o)), isblack(obj2gco(p)) && iswhite(obj2gco(o))) \
 	luaC_barrierback_(L,p); }
 	luaC_barrierback_(L,p); }
 
 
+LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o);
 LUAI_FUNC void luaC_freeallobjects (lua_State *L);
 LUAI_FUNC void luaC_freeallobjects (lua_State *L);
 LUAI_FUNC void luaC_step (lua_State *L);
 LUAI_FUNC void luaC_step (lua_State *L);
 LUAI_FUNC void luaC_forcestep (lua_State *L);
 LUAI_FUNC void luaC_forcestep (lua_State *L);

+ 6 - 4
llex.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: llex.c,v 2.66 2013/05/14 15:59:04 roberto Exp roberto $
+** $Id: llex.c,v 2.67 2013/06/19 14:27:00 roberto Exp roberto $
 ** Lexical Analyzer
 ** Lexical Analyzer
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -15,6 +15,7 @@
 
 
 #include "lctype.h"
 #include "lctype.h"
 #include "ldo.h"
 #include "ldo.h"
+#include "lgc.h"
 #include "llex.h"
 #include "llex.h"
 #include "lobject.h"
 #include "lobject.h"
 #include "lparser.h"
 #include "lparser.h"
@@ -64,9 +65,11 @@ static void save (LexState *ls, int c) {
 
 
 void luaX_init (lua_State *L) {
 void luaX_init (lua_State *L) {
   int i;
   int i;
+  TString *e = luaS_new(L, LUA_ENV);  /* create env name */
+  luaC_fix(L, obj2gco(e));  /* never collect this name */
   for (i=0; i<NUM_RESERVED; i++) {
   for (i=0; i<NUM_RESERVED; i++) {
     TString *ts = luaS_new(L, luaX_tokens[i]);
     TString *ts = luaS_new(L, luaX_tokens[i]);
-    luaS_fix(ts);  /* reserved words are never collected */
+    luaC_fix(L, obj2gco(ts));  /* reserved words are never collected */
     ts->tsv.extra = cast_byte(i+1);  /* reserved word */
     ts->tsv.extra = cast_byte(i+1);  /* reserved word */
   }
   }
 }
 }
@@ -163,8 +166,7 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
   ls->linenumber = 1;
   ls->linenumber = 1;
   ls->lastline = 1;
   ls->lastline = 1;
   ls->source = source;
   ls->source = source;
-  ls->envn = luaS_new(L, LUA_ENV);  /* create env name */
-  luaS_fix(ls->envn);  /* never collect this name */
+  ls->envn = luaS_new(L, LUA_ENV);  /* get env name */
   luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER);  /* initialize buffer */
   luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER);  /* initialize buffer */
 }
 }
 
 

+ 4 - 3
lstate.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstate.c,v 2.102 2013/08/16 18:55:49 roberto Exp roberto $
+** $Id: lstate.c,v 2.103 2013/08/21 19:21:16 roberto Exp roberto $
 ** Global State
 ** Global State
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -188,7 +188,7 @@ static void f_luaopen (lua_State *L, void *ud) {
   luaX_init(L);
   luaX_init(L);
   /* 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 */
+  luaC_fix(L, obj2gco(g->memerrmsg));  /* it should never be collected */
   g->gcrunning = 1;  /* allow gc */
   g->gcrunning = 1;  /* allow gc */
 }
 }
 
 
@@ -270,7 +270,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
   g = &l->g;
   g = &l->g;
   L->next = NULL;
   L->next = NULL;
   L->tt = LUA_TTHREAD;
   L->tt = LUA_TTHREAD;
-  g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
+  g->currentwhite = bitmask(WHITE0BIT);
   L->marked = luaC_white(g) | bitmask(LOCALBIT);
   L->marked = luaC_white(g) | bitmask(LOCALBIT);
   g->gckind = KGC_NORMAL;
   g->gckind = KGC_NORMAL;
   preinit_state(L, g);
   preinit_state(L, g);
@@ -290,6 +290,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
   g->allgc = NULL;
   g->allgc = NULL;
   g->finobj = NULL;
   g->finobj = NULL;
   g->tobefnz = NULL;
   g->tobefnz = NULL;
+  g->fixedgc = NULL;
   g->sweepgc = g->sweepfin = NULL;
   g->sweepgc = g->sweepfin = NULL;
   g->gray = g->grayagain = NULL;
   g->gray = g->grayagain = NULL;
   g->weak = g->ephemeron = g->allweak = NULL;
   g->weak = g->ephemeron = g->allweak = NULL;

+ 5 - 1
lstate.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstate.h,v 2.85 2013/08/20 17:46:34 roberto Exp roberto $
+** $Id: lstate.h,v 2.86 2013/08/21 19:21:16 roberto Exp roberto $
 ** Global State
 ** Global State
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -24,6 +24,9 @@
 ** at the end of the 'allgc' list, after the 'l_registry' (which is
 ** at the end of the 'allgc' list, after the 'l_registry' (which is
 ** the first object to be added to the list).
 ** the first object to be added to the list).
 **
 **
+** List 'fixedgc' keep objects that are not to be collected (currently
+** only small strings, such as reserved words).
+**
 ** Open upvalues are not subject to independent garbage collection. They
 ** Open upvalues are not subject to independent garbage collection. They
 ** are collected together with their respective threads. (They are
 ** are collected together with their respective threads. (They are
 ** always gray, so they must be remarked in the atomic step. Usually
 ** always gray, so they must be remarked in the atomic step. Usually
@@ -132,6 +135,7 @@ typedef struct global_State {
   GCObject *ephemeron;  /* list of ephemeron tables (weak keys) */
   GCObject *ephemeron;  /* list of ephemeron tables (weak keys) */
   GCObject *allweak;  /* list of all-weak tables */
   GCObject *allweak;  /* list of all-weak tables */
   GCObject *tobefnz;  /* list of userdata to be GC */
   GCObject *tobefnz;  /* list of userdata to be GC */
+  GCObject *fixedgc;  /* list of objects not to be collected */
   Mbuffer buff;  /* temporary buffer for string concatenation */
   Mbuffer buff;  /* temporary buffer for string concatenation */
   int gcpause;  /* size of pause between successive GCs */
   int gcpause;  /* size of pause between successive GCs */
   int gcstepmul;  /* GC `granularity' */
   int gcstepmul;  /* GC `granularity' */

+ 1 - 3
lstring.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstring.h,v 1.50 2013/08/16 18:55:49 roberto Exp roberto $
+** $Id: lstring.h,v 1.51 2013/08/21 19:21:16 roberto Exp roberto $
 ** String table (keep all strings handled by Lua)
 ** String table (keep all strings handled by Lua)
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -19,8 +19,6 @@
 #define luaS_newliteral(L, s)	(luaS_newlstr(L, "" s, \
 #define luaS_newliteral(L, s)	(luaS_newlstr(L, "" s, \
                                  (sizeof(s)/sizeof(char))-1))
                                  (sizeof(s)/sizeof(char))-1))
 
 
-#define luaS_fix(s)	setbits((s)->tsv.marked, bit2mask(FIXEDBIT, LOCALBIT))
-
 
 
 /*
 /*
 ** test whether a string is a reserved word
 ** test whether a string is a reserved word

+ 2 - 2
ltm.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ltm.c,v 2.19 2013/04/29 16:56:50 roberto Exp roberto $
+** $Id: ltm.c,v 2.20 2013/05/06 17:19:11 roberto Exp roberto $
 ** Tag methods
 ** Tag methods
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -43,7 +43,7 @@ void luaT_init (lua_State *L) {
   int i;
   int i;
   for (i=0; i<TM_N; i++) {
   for (i=0; i<TM_N; i++) {
     G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
     G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
-    luaS_fix(G(L)->tmname[i]);  /* never collect these names */
+    luaC_fix(L, obj2gco(G(L)->tmname[i]));  /* never collect these names */
   }
   }
 }
 }