Kaynağa Gözat

only one instance of registry and default metatable per global state

Roberto Ierusalimschy 23 yıl önce
ebeveyn
işleme
81bc5711a8
3 değiştirilmiş dosya ile 23 ekleme ve 26 silme
  1. 12 8
      lgc.c
  2. 4 6
      lstate.c
  3. 7 12
      lstate.h

+ 12 - 8
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 1.151 2002/09/19 19:54:22 roberto Exp roberto $
+** $Id: lgc.c,v 1.152 2002/10/08 18:46:08 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -34,7 +34,6 @@ typedef struct GCState {
 #define resetbit(x,b)	((x) &= cast(lu_byte, ~(1<<(b))))
 #define testbit(x,b)	((x) & (1<<(b)))
 
-#define mark(x)		setbit((x)->gch.marked, 0)
 #define unmark(x)	resetbit((x)->gch.marked, 0)
 #define ismarked(x)	((x)->gch.marked & ((1<<4)|1))
 
@@ -101,7 +100,7 @@ static void markclosure (GCState *st, Closure *cl) {
 
 
 static void reallymarkobject (GCState *st, GCObject *o) {
-  mark(o);
+  setbit(o->gch.marked, 0);  /* mark object */
   switch (o->gch.tt) {
     case LUA_TFUNCTION: {
       markclosure(st, &o->cl);
@@ -135,15 +134,13 @@ static void traversestacks (GCState *st) {
   do {  /* for each thread */
     StkId o, lim;
     CallInfo *ci;
-    if (ttisnil(defaultmeta(L1))) {  /* incomplete state? */
+    if (ttisnil(gt(L1))) {  /* incomplete state? */
       lua_assert(L1 != st->L);
       L1 = L1->next;
       luaE_closethread(st->L, L1->previous);  /* collect it */
       continue;
     }
-    markobject(st, defaultmeta(L1));
     markobject(st, gt(L1));
-    markobject(st, registry(L1));
     for (o=L1->stack; o<L1->top; o++)
       markobject(st, o);
     lim = o;
@@ -156,6 +153,8 @@ static void traversestacks (GCState *st) {
     lua_assert(L1->previous->next == L1 && L1->next->previous == L1);
     L1 = L1->next;
   } while (L1 != st->L);
+  markobject(st, defaultmeta(L1));
+  markobject(st, registry(L1));
 }
 
 
@@ -342,6 +341,7 @@ static void checkSizes (lua_State *L) {
     size_t newsize = luaZ_sizebuffer(&G(L)->buff) / 2;
     luaZ_resizebuffer(L, &G(L)->buff, newsize);
   }
+  G(L)->GCthreshold = 2*G(L)->nblocks;  /* new threshold */
 }
 
 
@@ -389,7 +389,7 @@ void luaC_sweep (lua_State *L, int all) {
 }
 
 
-void luaC_collectgarbage (lua_State *L) {
+static void mark (lua_State *L) {
   GCState st;
   Table *toclear;
   st.L = L;
@@ -407,9 +407,13 @@ void luaC_collectgarbage (lua_State *L) {
   /* `propagatemarks' may reborne some weak tables; clear them too */
   cleartablekeys(st.toclear);
   cleartablevalues(st.toclear);
+}
+
+
+void luaC_collectgarbage (lua_State *L) {
+  mark(L);
   luaC_sweep(L, 0);
   checkSizes(L);
-  G(L)->GCthreshold = 2*G(L)->nblocks;  /* new threshold */
   callGCTM(L);
 }
 

+ 4 - 6
lstate.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.c,v 1.105 2002/08/30 19:09:21 roberto Exp roberto $
+** $Id: lstate.c,v 1.106 2002/10/08 18:46:08 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -25,7 +25,7 @@ static void close_state (lua_State *L);
 
 
 /*
-** you can change this function through the official API
+** you can change this function through the official API:
 ** call `lua_setpanicf'
 */
 static int default_panic (lua_State *L) {
@@ -61,6 +61,8 @@ static void f_luaopen (lua_State *L, void *ud) {
   G(L)->strt.size = 0;
   G(L)->strt.nuse = 0;
   G(L)->strt.hash = NULL;
+  setnilvalue(defaultmeta(L));
+  setnilvalue(registry(L));
   luaZ_initbuffer(L, &G(L)->buff);
   G(L)->panic = &default_panic;
   G(L)->rootgc = NULL;
@@ -97,9 +99,7 @@ static void preinit_state (lua_State *L) {
   L->size_ci = 0;
   L->base_ci = L->ci = NULL;
   L->errfunc = 0;
-  setnilvalue(defaultmeta(L));
   setnilvalue(gt(L));
-  setnilvalue(registry(L));
 }
 
 
@@ -114,9 +114,7 @@ LUA_API lua_State *lua_newthread (lua_State *OL) {
   OL->next = L;
   L->previous = OL;
   stack_init(L, OL);  /* init stack */
-  setobj(defaultmeta(L), defaultmeta(OL));  /* share default meta table */
   setobj(gt(L), gt(OL));  /* share table of globals */
-  setobj(registry(L), registry(OL));  /* share registry */
   lua_unlock(OL);
   lua_userstateopen(L);
   return L;

+ 7 - 12
lstate.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.h,v 1.96 2002/09/19 13:03:53 roberto Exp roberto $
+** $Id: lstate.h,v 1.97 2002/10/08 18:46:08 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -48,21 +48,14 @@
 struct lua_longjmp;  /* defined in ldo.c */
 
 
-
-/*
-** array of `global' objects
-*/
-
-#define NUMGLOBS	3
-
 /* default meta table (both for tables and udata) */
-#define defaultmeta(L)	(L->globs)
+#define defaultmeta(L)	(&G(L)->_defaultmeta)
 
 /* table of globals */
-#define gt(L)	(L->globs + 1)
+#define gt(L)	(&L->_gt)
 
 /* registry */
-#define registry(L)	(L->globs + 2)
+#define registry(L)	(&G(L)->_registry)
 
 
 /* extra stack space to handle TM calls and some other extras */
@@ -129,6 +122,8 @@ typedef struct global_State {
   lu_mem GCthreshold;
   lu_mem nblocks;  /* number of `bytes' currently allocated */
   lua_CFunction panic;  /* to be called in unprotected errors */
+  TObject _registry;
+  TObject _defaultmeta;
   Node dummynode[1];  /* common node array for all empty tables */
   TString *tmname[TM_N];  /* array with tag-method names */
 } global_State;
@@ -151,12 +146,12 @@ struct lua_State {
   unsigned long hookmask;
   ls_count hookcount;
   lua_Hook hook;
+  TObject _gt;  /* table of globals */
   GCObject *openupval;  /* list of open upvalues in this stack */
   struct lua_longjmp *errorJmp;  /* current error recover point */
   ptrdiff_t errfunc;  /* current error handling function (stack index) */
   lua_State *next;  /* circular double linked list of states */
   lua_State *previous;
-  TObject globs[NUMGLOBS];  /* registry, table of globals, etc. */
 };