mirror of https://github.com/lua/lua
all collected userdata must go to the end of the list of finalizers
This commit is contained in:
parent
af39352632
commit
678d2fb2ac
40
lgc.c
40
lgc.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lgc.c,v 2.22 2005/01/18 17:18:09 roberto Exp roberto $
|
** $Id: lgc.c,v 2.23 2005/02/10 13:25:02 roberto Exp roberto $
|
||||||
** Garbage Collector
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -114,21 +114,23 @@ static void reallymarkobject (global_State *g, GCObject *o) {
|
||||||
|
|
||||||
|
|
||||||
static void marktmu (global_State *g) {
|
static void marktmu (global_State *g) {
|
||||||
GCObject *u;
|
GCObject *u = g->tmudata;
|
||||||
for (u = g->tmudata; u; u = u->gch.next) {
|
if (u) {
|
||||||
makewhite(g, u); /* may be marked, if left from previous GC */
|
do {
|
||||||
reallymarkobject(g, u);
|
u = u->gch.next;
|
||||||
|
makewhite(g, u); /* may be marked, if left from previous GC */
|
||||||
|
reallymarkobject(g, u);
|
||||||
|
} while (u != g->tmudata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* move `dead' udata that need finalization to list `tmudata' */
|
/* move `dead' udata that need finalization to list `tmudata' */
|
||||||
size_t luaC_separateudata (lua_State *L, int all) {
|
size_t luaC_separateudata (lua_State *L, int all) {
|
||||||
|
global_State *g = G(L);
|
||||||
size_t deadmem = 0;
|
size_t deadmem = 0;
|
||||||
GCObject **p = &G(L)->mainthread->next;
|
GCObject **p = &g->mainthread->next;
|
||||||
GCObject *curr;
|
GCObject *curr;
|
||||||
GCObject *collected = NULL; /* to collect udata with gc event */
|
|
||||||
GCObject **lastcollected = &collected;
|
|
||||||
while ((curr = *p) != NULL) {
|
while ((curr = *p) != NULL) {
|
||||||
if (!(iswhite(curr) || all) || isfinalized(gco2u(curr)))
|
if (!(iswhite(curr) || all) || isfinalized(gco2u(curr)))
|
||||||
p = &curr->gch.next; /* don't bother with them */
|
p = &curr->gch.next; /* don't bother with them */
|
||||||
|
@ -140,14 +142,16 @@ size_t luaC_separateudata (lua_State *L, int all) {
|
||||||
deadmem += sizeudata(gco2u(curr));
|
deadmem += sizeudata(gco2u(curr));
|
||||||
markfinalized(gco2u(curr));
|
markfinalized(gco2u(curr));
|
||||||
*p = curr->gch.next;
|
*p = curr->gch.next;
|
||||||
curr->gch.next = NULL; /* link `curr' at the end of `collected' list */
|
/* link `curr' at the end of `tmudata' list */
|
||||||
*lastcollected = curr;
|
if (g->tmudata == NULL) /* list is empty? */
|
||||||
lastcollected = &curr->gch.next;
|
g->tmudata = curr->gch.next = curr; /* creates a circular list */
|
||||||
|
else {
|
||||||
|
curr->gch.next = g->tmudata->gch.next;
|
||||||
|
g->tmudata->gch.next = curr;
|
||||||
|
g->tmudata = curr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* insert collected udata with gc event into `tmudata' list */
|
|
||||||
*lastcollected = G(L)->tmudata;
|
|
||||||
G(L)->tmudata = collected;
|
|
||||||
return deadmem;
|
return deadmem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,10 +447,14 @@ static void checkSizes (lua_State *L) {
|
||||||
|
|
||||||
static void GCTM (lua_State *L) {
|
static void GCTM (lua_State *L) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
GCObject *o = g->tmudata;
|
GCObject *o = g->tmudata->gch.next; /* get first element */
|
||||||
Udata *udata = rawgco2u(o);
|
Udata *udata = rawgco2u(o);
|
||||||
const TValue *tm;
|
const TValue *tm;
|
||||||
g->tmudata = udata->uv.next; /* remove udata from `tmudata' */
|
/* remove udata from `tmudata' */
|
||||||
|
if (o == g->tmudata) /* last element? */
|
||||||
|
g->tmudata = NULL;
|
||||||
|
else
|
||||||
|
g->tmudata->gch.next = udata->uv.next;
|
||||||
udata->uv.next = g->mainthread->next; /* return it to `root' list */
|
udata->uv.next = g->mainthread->next; /* return it to `root' list */
|
||||||
g->mainthread->next = o;
|
g->mainthread->next = o;
|
||||||
makewhite(g, o);
|
makewhite(g, o);
|
||||||
|
|
4
lstate.h
4
lstate.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lstate.h,v 2.12 2005/01/14 14:19:42 roberto Exp $
|
** $Id: lstate.h,v 2.13 2005/01/18 17:18:09 roberto Exp roberto $
|
||||||
** Global State
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -77,7 +77,7 @@ typedef struct global_State {
|
||||||
GCObject *gray; /* list of gray objects */
|
GCObject *gray; /* list of gray objects */
|
||||||
GCObject *grayagain; /* list of objects to be traversed atomically */
|
GCObject *grayagain; /* list of objects to be traversed atomically */
|
||||||
GCObject *weak; /* list of weak tables (to be cleared) */
|
GCObject *weak; /* list of weak tables (to be cleared) */
|
||||||
GCObject *tmudata; /* list of userdata to be GC */
|
GCObject *tmudata; /* last element of list of userdata to be GC */
|
||||||
Mbuffer buff; /* temporary buffer for string concatentation */
|
Mbuffer buff; /* temporary buffer for string concatentation */
|
||||||
lu_mem GCthreshold;
|
lu_mem GCthreshold;
|
||||||
lu_mem totalbytes; /* number of bytes currently allocated */
|
lu_mem totalbytes; /* number of bytes currently allocated */
|
||||||
|
|
Loading…
Reference in New Issue