Example #1
0
static void atomic (lua_State *L) {
  global_State *g = G(L);
  size_t udsize;  /* total size of userdata to be finalized */
  /* remark occasional upvalues of (maybe) dead threads */
  remarkupvals(g);
  /* traverse objects cautch by write barrier and by 'remarkupvals' */
  propagateall(g);
  /* remark weak tables */
  g->gray = g->weak;
  g->weak = NULL;
  lua_assert(!iswhite(obj2gco(g->mainthread)));
  markobject(g, L);  /* mark running thread */
  markmt(g);  /* mark basic metatables (again) */
  propagateall(g);
  /* remark gray again */
  g->gray = g->grayagain;
  g->grayagain = NULL;
  propagateall(g);
  udsize = luaC_separateudata(L, 0);  /* separate userdata to be finalized */
  marktmu(g);  /* mark `preserved' userdata */
  udsize += propagateall(g);  /* remark, to propagate `preserveness' */
  cleartable(g->weak);  /* remove collected objects from weak tables */
  /* flip current white */
  g->currentwhite = cast_byte(otherwhite(g));
  g->sweepstrgc = 0;
  g->sweepgc = &g->rootgc;
  g->gcstate = GCSsweepstring;
  g->estimate = g->totalbytes - udsize;  /* first estimate */
}
Example #2
0
static void atomic (lua_State *L) {
  global_State *g = G(L);
  GCObject *origweak, *origall;
  lua_assert(!iswhite(obj2gco(g->mainthread)));
  markobject(g, L);  /* mark running thread */
  /* registry and global metatables may be changed by API */
  markvalue(g, &g->l_registry);
  markmt(g);  /* mark basic metatables */
  /* remark occasional upvalues of (maybe) dead threads */
  remarkupvals(g);
  /* traverse objects caught by write barrier and by 'remarkupvals' */
  retraversegrays(g);
  convergeephemerons(g);
  /* at this point, all strongly accessible objects are marked. */
  /* clear values from weak tables, before checking finalizers */
  clearvalues(g->weak, NULL);
  clearvalues(g->allweak, NULL);
  origweak = g->weak; origall = g->allweak;
  separatetobefnz(L, 0);  /* separate objects to be finalized */
  markbeingfnz(g);  /* mark userdata that will be finalized */
  propagateall(g);  /* remark, to propagate `preserveness' */
  convergeephemerons(g);
  /* at this point, all resurrected objects are marked. */
  /* remove dead objects from weak tables */
  clearkeys(g->ephemeron, NULL);  /* clear keys from all ephemeron tables */
  clearkeys(g->allweak, NULL);  /* clear keys from all allweak tables */
  /* clear values from resurrected weak tables */
  clearvalues(g->weak, origweak);
  clearvalues(g->allweak, origall);
  g->sweepstrgc = 0;  /* prepare to sweep strings */
  g->gcstate = GCSsweepstring;
  g->currentwhite = cast_byte(otherwhite(g));  /* flip current white */
  /*lua_checkmemory(L);*/
}
Example #3
0
static l_mem atomic (lua_State *L) {
    global_State *g = G(L);
    l_mem work;
    GCObject *origweak, *origall;
    GCObject *grayagain = g->grayagain;  /* save original list */
    lua_assert(g->ephemeron == NULL && g->weak == NULL);
    lua_assert(!iswhite(g->mainthread));
    g->gcstate = GCSinsideatomic;
    g->GCmemtrav = 0;  /* start counting work */
    markobject(g, L);  /* mark running thread */
    /* registry and global metatables may be changed by API */
    markvalue(g, &g->l_registry);
    markmt(g);  /* mark global metatables */
    /* remark occasional upvalues of (maybe) dead threads */
    remarkupvals(g);
    propagateall(g);  /* propagate changes */
    work = g->GCmemtrav;  /* stop counting (do not recount 'grayagain') */
    g->gray = grayagain;
    propagateall(g);  /* traverse 'grayagain' list */
    g->GCmemtrav = 0;  /* restart counting */
    convergeephemerons(g);
    /* at this point, all strongly accessible objects are marked. */
    /* Clear values from weak tables, before checking finalizers */
    clearvalues(g, g->weak, NULL);
    clearvalues(g, g->allweak, NULL);
    origweak = g->weak;
    origall = g->allweak;
    work += g->GCmemtrav;  /* stop counting (objects being finalized) */
    separatetobefnz(g, 0);  /* separate objects to be finalized */
    g->gcfinnum = 1;  /* there may be objects to be finalized */
    markbeingfnz(g);  /* mark objects that will be finalized */
    propagateall(g);  /* remark, to propagate 'resurrection' */
    g->GCmemtrav = 0;  /* restart counting */
    convergeephemerons(g);
    /* at this point, all resurrected objects are marked. */
    /* remove dead objects from weak tables */
    clearkeys(g, g->ephemeron, NULL);  /* clear keys from all ephemeron tables */
    clearkeys(g, g->allweak, NULL);  /* clear keys from all 'allweak' tables */
    /* clear values from resurrected weak tables */
    clearvalues(g, g->weak, origweak);
    clearvalues(g, g->allweak, origall);
    luaS_clearcache(g);
    g->currentwhite = cast_byte(otherwhite(g));  /* flip current white */
    work += g->GCmemtrav;  /* complete counting */
    return work;  /* estimate of memory marked by 'atomic' */
}
Example #4
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;
    }
}
Example #5
0
/*
** retraverse all gray lists. Because tables may be reinserted in other
** lists when traversed, traverse the original lists to avoid traversing
** twice the same table (which is not wrong, but inefficient)
*/
static void retraversegrays (global_State *g) {
	GCObject *weak = g->weak;  /* save original lists */
	GCObject *grayagain = g->grayagain;
	GCObject *ephemeron = g->ephemeron;
	g->weak = g->grayagain = g->ephemeron = NULL;
	propagateall(g);  /* traverse main gray list */
	propagatelist(g, grayagain);
	propagatelist(g, weak);
	propagatelist(g, ephemeron);
}
Example #6
0
static l_mem atomic (lua_State *L) {
	global_State *g = G(L);
	l_mem work = -cast(l_mem, g->GCmemtrav);  /* start counting work */
	GCObject *origweak, *origall;
	lua_assert(!iswhite(obj2gco(g->mainthread)));
	markobject(g, L);  /* mark running thread */
	/* registry and global metatables may be changed by API */
	markvalue(g, &g->l_registry);
	markmt(g);  /* mark basic metatables */
	/* remark occasional upvalues of (maybe) dead threads */
	remarkupvals(g);
	propagateall(g);  /* propagate changes */
	work += g->GCmemtrav;  /* stop counting (do not (re)count grays) */
	/* traverse objects caught by write barrier and by 'remarkupvals' */
	retraversegrays(g);
	work -= g->GCmemtrav;  /* restart counting */
	convergeephemerons(g);
	/* at this point, all strongly accessible objects are marked. */
	/* clear values from weak tables, before checking finalizers */
	clearvalues(g, g->weak, NULL);
	clearvalues(g, g->allweak, NULL);
	origweak = g->weak; origall = g->allweak;
	work += g->GCmemtrav;  /* stop counting (objects being finalized) */
	separatetobefnz(L, 0);  /* separate objects to be finalized */
	markbeingfnz(g);  /* mark objects that will be finalized */
	propagateall(g);  /* remark, to propagate `preserveness' */
	work -= g->GCmemtrav;  /* restart counting */
	convergeephemerons(g);
	/* at this point, all resurrected objects are marked. */
	/* remove dead objects from weak tables */
	clearkeys(g, g->ephemeron, NULL);  /* clear keys from all ephemeron tables */
	clearkeys(g, g->allweak, NULL);  /* clear keys from all allweak tables */
	/* clear values from resurrected weak tables */
	clearvalues(g, g->weak, origweak);
	clearvalues(g, g->allweak, origall);
	g->currentwhite = cast_byte(otherwhite(g));  /* flip current white */
	work += g->GCmemtrav;  /* complete counting */
	return work;  /* estimate of memory marked by 'atomic' */
}
Example #7
0
File: lgc.c Project: charleeli/srpc
static void convergeephemerons (global_State *g) {
  int changed;
  do {
    GCObject *w;
    GCObject *next = g->ephemeron;  /* get ephemeron list */
    g->ephemeron = NULL;  /* tables may return to this list when traversed */
    changed = 0;
    while ((w = next) != NULL) {
      next = gco2t(w)->gclist;
      if (traverseephemeron(g, gco2t(w))) {  /* traverse marked some value? */
        propagateall(g);  /* propagate changes */
        changed = 1;  /* will have to revisit all ephemeron tables */
      }
    }
  } while (changed);
}
Example #8
0
static void propagatelist (global_State *g, GCObject *l) {
	lua_assert(g->gray == NULL);  /* no grays left */
	g->gray = l;
	propagateall(g);  /* traverse all elements from 'l' */
}