diff options
author | Lua Team <team@lua.org> | 2012-03-21 12:00:00 +0000 |
---|---|---|
committer | repogen <> | 2012-03-21 12:00:00 +0000 |
commit | 1cb937cf2d4583482aadaff45b6628b39fdcd91e (patch) | |
tree | 614eba453350c41305e41d647e9e03d779314f89 /src/lgc.c | |
parent | 6ee889a587f9b600b564d5c0ba0350faab0387cd (diff) | |
download | lua-github-5.2.1-work1.tar.gz |
Lua 5.2.1-work15.2.1-work1
Diffstat (limited to 'src/lgc.c')
-rw-r--r-- | src/lgc.c | 90 |
1 files changed, 57 insertions, 33 deletions
@@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.116 2011/12/02 13:18:41 roberto Exp $ +** $Id: lgc.c,v 2.119 2012/01/25 21:05:40 roberto Exp $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -65,7 +65,11 @@ #define white2gray(x) resetbits(gch(x)->marked, WHITEBITS) #define black2gray(x) resetbit(gch(x)->marked, BLACKBIT) -#define stringmark(s) ((void)((s) && resetbits((s)->tsv.marked, WHITEBITS))) +/* +** dirty trick: we know that 'reallymarkobject' does not use 'g' when +** object is a string +*/ +#define stringmark(s) markobject(NULL, s) #define isfinalized(x) testbit(gch(x)->marked, FINALIZEDBIT) @@ -217,7 +221,8 @@ void luaC_checkupvalcolor (global_State *g, UpVal *uv) { GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list, int offset) { global_State *g = G(L); - GCObject *o = obj2gco(cast(char *, luaM_newobject(L, tt, sz)) + offset); + char *raw = cast(char *, luaM_newobject(L, novariant(tt), sz)); + GCObject *o = obj2gco(raw + offset); if (list == NULL) list = &g->allgc; /* standard list for collectable objects */ gch(o)->marked = luaC_white(g); @@ -239,18 +244,18 @@ GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list, /* -** mark an object. Userdata and closed upvalues are visited and turned -** black here. Strings remain gray (it is the same as making them -** black). Other objects are marked gray and added to appropriate list -** to be visited (and turned black) later. (Open upvalues are already -** linked in 'headuv' list.) +** mark an object. Userdata, strings, and closed upvalues are visited +** and turned black here. Other objects are marked gray and added +** to appropriate list to be visited (and turned black) later. (Open +** upvalues are already linked in 'headuv' list.) */ static void reallymarkobject (global_State *g, GCObject *o) { - lua_assert(iswhite(o) && !isdead(g, o)); white2gray(o); switch (gch(o)->tt) { - case LUA_TSTRING: { - return; /* for strings, gray is as good as black */ + case LUA_TSHRSTR: + case LUA_TLNGSTR: { + gray2black(o); + return; /* nothing else to mark */ } case LUA_TUSERDATA: { Table *mt = gco2u(o)->metatable; @@ -266,8 +271,13 @@ static void reallymarkobject (global_State *g, GCObject *o) { gray2black(o); /* make it black */ return; } - case LUA_TFUNCTION: { - gco2cl(o)->c.gclist = g->gray; + case LUA_TLCL: { + gco2lcl(o)->gclist = g->gray; + g->gray = o; + break; + } + case LUA_TCCL: { + gco2ccl(o)->gclist = g->gray; g->gray = o; break; } @@ -470,20 +480,20 @@ static int traverseproto (global_State *g, Proto *f) { } -static int traverseclosure (global_State *g, Closure *cl) { - if (cl->c.isC) { - int i; - for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */ - markvalue(g, &cl->c.upvalue[i]); - } - else { - int i; - lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues); - markobject(g, cl->l.p); /* mark its prototype */ - for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */ - markobject(g, cl->l.upvals[i]); - } - return TRAVCOST + cl->c.nupvalues; +static int traverseCclosure (global_State *g, CClosure *cl) { + int i; + for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ + markvalue(g, &cl->upvalue[i]); + return TRAVCOST + cl->nupvalues; +} + +static int traverseLclosure (global_State *g, LClosure *cl) { + int i; + lua_assert(cl->nupvalues == cl->p->sizeupvalues); + markobject(g, cl->p); /* mark its prototype */ + for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ + markobject(g, cl->upvals[i]); + return TRAVCOST + cl->nupvalues; } @@ -517,10 +527,15 @@ static int propagatemark (global_State *g) { g->gray = h->gclist; return traversetable(g, h); } - case LUA_TFUNCTION: { - Closure *cl = gco2cl(o); - g->gray = cl->c.gclist; - return traverseclosure(g, cl); + case LUA_TLCL: { + LClosure *cl = gco2lcl(o); + g->gray = cl->gclist; + return traverseLclosure(g, cl); + } + case LUA_TCCL: { + CClosure *cl = gco2ccl(o); + g->gray = cl->gclist; + return traverseCclosure(g, cl); } case LUA_TTHREAD: { lua_State *th = gco2th(o); @@ -640,13 +655,22 @@ static void clearvalues (GCObject *l, GCObject *f) { static void freeobj (lua_State *L, GCObject *o) { switch (gch(o)->tt) { case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; - case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break; + case LUA_TLCL: { + luaM_freemem(L, o, sizeLclosure(gco2lcl(o)->nupvalues)); + break; + } + case LUA_TCCL: { + luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues)); + break; + } case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; case LUA_TTABLE: luaH_free(L, gco2t(o)); break; case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break; case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break; - case LUA_TSTRING: { + case LUA_TSHRSTR: G(L)->strt.nuse--; + /* go through */ + case LUA_TLNGSTR: { luaM_freemem(L, o, sizestring(gco2ts(o))); break; } |