[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Why GCTM stop gc step before calling userdata's finalizer?
- From: 张伟智 <robotk@...>
- Date: Sat, 9 Jan 2016 20:35:35 +0800 (CST)
Lua version is 5.2.4.
In lgc.c line 820, function GCTM,
g->gcrunning is set to 0 to avoid GC steps,
I think if g->gcrunning remains unchanged,
line 824 luaD_pcall will trigger luaC_step->luaC_forcestep->GCTM during executing __gc finalizer.
But what is the problem if recursive enter GCTM ?
809 static void GCTM (lua_State *L, int propagateerrors) {
810 global_State *g = G(L);
811 const TValue *tm;
812 TValue v;
813 setgcovalue(L, &v, udata2finalize(g));
814 tm = luaT_gettmbyobj(L, &v, TM_GC);
815 if (tm != NULL && ttisfunction(tm)) { /* is there a finalizer? */
816 int status;
817 lu_byte oldah = L->allowhook;
818 int running = g->gcrunning;
819 L->allowhook = 0; /* stop debug hooks during GC metamethod */
820 g->gcrunning = 0; /* avoid GC steps */
821 setobj2s(L, L->top, tm); /* push finalizer... */
822 setobj2s(L, L->top + 1, &v); /* ... and its argument */
823 L->top += 2; /* and (next line) call the finalizer */
824 status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0);
825 L->allowhook = oldah; /* restore hooks */
826 g->gcrunning = running; /* restore state */
1163 void luaC_forcestep (lua_State *L) {
1164 global_State *g = G(L);
1165 int i;
1166 if (isgenerational(g)) generationalcollection(L);
1167 else incstep(L);
1168 /* run a few finalizers (or all of them at the end of a collect cycle) */
1169 for (i = 0; g->tobefnz && (i < GCFINALIZENUM || g->gcstate == GCSpause); i++)
1170 GCTM(L, 1); /* call one finalizer */
1171 }
1172
1173
1174 /*
1175 ** performs a basic GC step only if collector is running
1176 */
1177 void luaC_step (lua_State *L) {
1178 global_State *g = G(L);
1179 if (g->gcrunning) luaC_forcestep(L);
1180 else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */
1181 }