summaryrefslogtreecommitdiff
path: root/src/lgc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lgc.c')
-rw-r--r--src/lgc.c90
1 files changed, 57 insertions, 33 deletions
diff --git a/src/lgc.c b/src/lgc.c
index cdd92e52..ce421637 100644
--- a/src/lgc.c
+++ b/src/lgc.c
@@ -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;
}