/* ** performs a basic GC step */ void luaC_forcestep (lua_State *L) { global_State *g = G(L); int i; if (isgenerational(g)) generationalcollection(L); else incstep(L); /* run a few finalizers (or all of them at the end of a collect cycle) */ for (i = 0; g->tobefnz && (i < GCFINALIZENUM || g->gcstate == GCSpause); i++) GCTM(L, 1); /* call one finalizer */ }
/* ** call a few (up to 'g->gcfinnum') finalizers */ static int runafewfinalizers (lua_State *L) { global_State *g = G(L); unsigned int i; lua_assert(!g->tobefnz || g->gcfinnum > 0); for (i = 0; g->tobefnz && i < g->gcfinnum; i++) GCTM(L, 1); /* call one finalizer */ g->gcfinnum = (!g->tobefnz) ? 0 /* nothing more to finalize? */ : g->gcfinnum * 2; /* else call a few more next time */ return i; }
static l_mem singlestep(lua_State *L) { global_State *g = G(L); /*lua_checkmemory(L);*/ switch (g->gcstate) { case GCSpause: { markroot(L); /* start a new collection */ return 0; } case GCSpropagate: { if (g->gray) return propagatemark(g); else { /* no more `gray' objects */ atomic(L); /* finish mark phase */ return 0; } } case GCSsweepstring: { lu_mem old = g->totalbytes; sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ g->gcstate = GCSsweep; /* end sweep-string phase */ lua_assert(old >= g->totalbytes); g->estimate -= old - g->totalbytes; return GCSWEEPCOST; } case GCSsweep: { lu_mem old = g->totalbytes; g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); if (*g->sweepgc == NULL) { /* nothing more to sweep? */ checkSizes(L); g->gcstate = GCSfinalize; /* end sweep phase */ } lua_assert(old >= g->totalbytes); g->estimate -= old - g->totalbytes; return GCSWEEPMAX * GCSWEEPCOST; } case GCSfinalize: { if (g->tmudata) { GCTM(L); if (g->estimate > GCFINALIZECOST) g->estimate -= GCFINALIZECOST; return GCFINALIZECOST; } else { g->gcstate = GCSpause; /* end collection */ g->gcdept = 0; return 0; } } default: lua_assert(0); return 0; } }
// lua的gc状态机,执行顺序和下面的状态的从大到小开始一致 static l_mem singlestep (lua_State *L) { global_State *g = G(L); /*lua_checkmemory(L);*/ switch (g->gcstate) { case GCSpause: {// 初始状态 markroot(L); /* start a new collection */// 主要就是标记主线程对象(也就是从白色染成灰色) return 0; } case GCSpropagate: {// 这个状态也是一个标记过程,并且会被进入多次,也就是分布迭代 if (g->gray)// 如果gray对象一直存在的话,反复调用propagatemark函数,等所有的gray对象都被标记了,就会进入atomic函数处理 return propagatemark(g); else { /* no more `gray' objects */ atomic(L); /* finish mark phase */// 原子操作 return 0; } } case GCSsweepstring: {// 清理字符串的阶段 lu_mem old = g->totalbytes; sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ g->gcstate = GCSsweep; /* end sweep-string phase */ lua_assert(old >= g->totalbytes); g->estimate -= old - g->totalbytes; return GCSWEEPCOST; } case GCSsweep: { lu_mem old = g->totalbytes; g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); if (*g->sweepgc == NULL) { /* nothing more to sweep? */ checkSizes(L); g->gcstate = GCSfinalize; /* end sweep phase */ } lua_assert(old >= g->totalbytes); g->estimate -= old - g->totalbytes; return GCSWEEPMAX*GCSWEEPCOST; } case GCSfinalize: { if (g->tmudata) { GCTM(L); if (g->estimate > GCFINALIZECOST) g->estimate -= GCFINALIZECOST; return GCFINALIZECOST; } else { g->gcstate = GCSpause; /* end collection */ g->gcdept = 0; return 0; } } default: lua_assert(0); return 0; } }
/* ** Call all GC tag methods */ void luaC_callGCTM (lua_State *L) { while (G(L)->tmudata) GCTM(L); }
/* ** call all pending finalizers */ static void callallpendingfinalizers (lua_State *L, int propagateerrors) { global_State *g = G(L); while (g->tobefnz) GCTM(L, propagateerrors); }
/* ** call all pending finalizers */ static void callallpendingfinalizers (lua_State *L) { global_State *g = G(L); while (g->tobefnz) GCTM(L, 0); }