Browse Source

run GC tag methods in protected mod

v5-2
Roberto Ierusalimschy 23 years ago
parent
commit
21259a50e1
  1. 33
      lgc.c

33
lgc.c

@ -356,32 +356,30 @@ static void checkMbuffer (lua_State *L) {
}
static void callgcTM (lua_State *L, Udata *udata) {
static void do1gcTM (lua_State *L, Udata *udata) {
const TObject *tm = fasttm(L, udata->uv.eventtable, TM_GC);
if (tm != NULL && ttype(tm) == LUA_TFUNCTION) {
int oldah = L->allowhooks;
if (tm != NULL) {
StkId top = L->top;
L->allowhooks = 0; /* stop debug hooks during GC tag methods */
setobj(top, tm);
setuvalue(top+1, udata);
L->top += 2;
luaD_call(L, top);
L->top = top; /* restore top */
L->allowhooks = oldah; /* restore hooks */
}
}
static void callgcTMudata (lua_State *L) {
static void unprotectedcallGCTM (lua_State *L, void *pu) {
luaD_checkstack(L, 3);
L->top++; /* reserve space to keep udata while runs its gc method */
while (G(L)->tmudata != NULL) {
Udata *udata = G(L)->tmudata;
G(L)->tmudata = udata->uv.next; /* remove udata from list */
*(Udata **)pu = udata; /* keep a reference to it (in case of errors) */
setuvalue(L->top - 1, udata); /* and on stack (in case of recursive GC) */
udata->uv.next = G(L)->rootudata; /* resurect it */
G(L)->rootudata = udata;
setuvalue(L->top - 1, udata);
callgcTM(L, udata);
do1gcTM(L, udata);
/* mark udata as finalized (default event table) */
uvalue(L->top-1)->uv.eventtable = hvalue(defaultet(L));
}
@ -389,11 +387,26 @@ static void callgcTMudata (lua_State *L) {
}
static void callGCTM (lua_State *L) {
int oldah = L->allowhooks;
L->allowhooks = 0; /* stop debug hooks during GC tag methods */
while (G(L)->tmudata != NULL) {
Udata *udata;
if (luaD_runprotected(L, unprotectedcallGCTM, &udata) != 0) {
/* `udata' generated an error during its gc */
/* mark it as finalized (default event table) */
udata->uv.eventtable = hvalue(defaultet(L));
}
}
L->allowhooks = oldah; /* restore hooks */
}
void luaC_callallgcTM (lua_State *L) {
lua_assert(G(L)->tmudata == NULL);
G(L)->tmudata = G(L)->rootudata; /* all udata must be collected */
G(L)->rootudata = NULL;
callgcTMudata(L); /* call their GC tag methods */
callGCTM(L); /* call their GC tag methods */
}
@ -416,6 +429,6 @@ void luaC_collectgarbage (lua_State *L) {
luaC_collect(L, 0);
checkMbuffer(L);
G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */
callgcTMudata(L);
callGCTM(L);
}

Loading…
Cancel
Save