From 81bc5711a8b71ced34eef8750deb0ce4475d5cd5 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 22 Oct 2002 14:58:14 -0300 Subject: [PATCH] only one instance of registry and default metatable per global state --- lgc.c | 20 ++++++++++++-------- lstate.c | 10 ++++------ lstate.h | 19 +++++++------------ 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/lgc.c b/lgc.c index d23e7a02..b7fc4c79 100644 --- a/lgc.c +++ b/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; otop; 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); } diff --git a/lstate.c b/lstate.c index a8136d1a..58631289 100644 --- a/lstate.c +++ b/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; diff --git a/lstate.h b/lstate.h index 94af29ad..a54ffa62 100644 --- a/lstate.h +++ b/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. */ };