Exemple #1
0
static lu_mem singlestep (lua_State *L) {
    global_State *g = G(L);
    switch (g->gcstate) {
    case GCSpause: {
        g->GCmemtrav = g->strt.size * sizeof(GCObject*);
        restartcollection(g);
        g->gcstate = GCSpropagate;
        return g->GCmemtrav;
    }
    case GCSpropagate: {
        g->GCmemtrav = 0;
        lua_assert(g->gray);
        propagatemark(g);
        if (g->gray == NULL)  /* no more gray objects? */
            g->gcstate = GCSatomic;  /* finish propagate phase */
        return g->GCmemtrav;  /* memory traversed in this step */
    }
    case GCSatomic: {
        lu_mem work;
        int sw;
        propagateall(g);  /* make sure gray list is empty */
        work = atomic(L);  /* work is what was traversed by 'atomic' */
        sw = entersweep(L);
        g->GCestimate = gettotalbytes(g);  /* first estimate */;
        return work + sw * GCSWEEPCOST;
    }
    case GCSswpallgc: {  /* sweep "regular" objects */
        return sweepstep(L, g, GCSswpfinobj, &g->finobj);
    }
    case GCSswpfinobj: {  /* sweep objects with finalizers */
        return sweepstep(L, g, GCSswptobefnz, &g->tobefnz);
    }
    case GCSswptobefnz: {  /* sweep objects to be finalized */
        return sweepstep(L, g, GCSswpend, NULL);
    }
    case GCSswpend: {  /* finish sweeps */
        makewhite(g, g->mainthread);  /* sweep main thread */
        checkSizes(L, g);
        g->gcstate = GCScallfin;
        return 0;
    }
    case GCScallfin: {  /* call remaining finalizers */
        if (g->tobefnz && g->gckind != KGC_EMERGENCY) {
            int n = runafewfinalizers(L);
            return (n * GCFINALIZECOST);
        }
        else {  /* emergency mode or no more finalizers */
            g->gcstate = GCSpause;  /* finish collection */
            return 0;
        }
    }
    default:
        lua_assert(0);
        return 0;
    }
}
Exemple #2
0
static lu_mem singlestep (lua_State *L) {
	global_State *g = G(L);
	switch (g->gcstate) {
	case GCSpause: {
		/* start to count memory traversed */
		g->GCmemtrav = g->strt.size * sizeof(GCObject*);
		lua_assert(!isgenerational(g));
		restartcollection(g);
		g->gcstate = GCSpropagate;
		return g->GCmemtrav;
	}
	case GCSpropagate: {
		if (g->gray) {
		lu_mem oldtrav = g->GCmemtrav;
		propagatemark(g);
		return g->GCmemtrav - oldtrav;  /* memory traversed in this step */
		}
		else {  /* no more `gray' objects */
		lu_mem work;
		int sw;
		g->gcstate = GCSatomic;  /* finish mark phase */
		g->GCestimate = g->GCmemtrav;  /* save what was counted */;
		work = atomic(L);  /* add what was traversed by 'atomic' */
		g->GCestimate += work;  /* estimate of total memory traversed */
		sw = entersweep(L);
		return work + sw * GCSWEEPCOST;
		}
	}
	case GCSsweepstring: {
		int i;
		for (i = 0; i < GCSWEEPMAX && g->sweepstrgc + i < g->strt.size; i++)
		sweepwholelist(L, &g->strt.hash[g->sweepstrgc + i]);
		g->sweepstrgc += i;
		if (g->sweepstrgc >= g->strt.size)  /* no more strings to sweep? */
		g->gcstate = GCSsweepudata;
		return i * GCSWEEPCOST;
	}
	case GCSsweepudata: {
		if (g->sweepfin) {
		g->sweepfin = sweeplist(L, g->sweepfin, GCSWEEPMAX);
		return GCSWEEPMAX*GCSWEEPCOST;
		}
		else {
		g->gcstate = GCSsweep;
		return 0;
		}
	}
	case GCSsweep: {
		if (g->sweepgc) {
		g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
		return GCSWEEPMAX*GCSWEEPCOST;
		}
		else {
		/* sweep main thread */
		GCObject *mt = obj2gco(g->mainthread);
		sweeplist(L, &mt, 1);
		checkSizes(L);
		g->gcstate = GCSpause;  /* finish collection */
		return GCSWEEPCOST;
		}
	}
	default: lua_assert(0); return 0;
	}
}