public FixedgcRef(global_State g) { this.g = g; }
public static void G_set(lua_State L, global_State s) { L.l_G = s; }
public FinobjRef(global_State g) { this.g = g; }
/* ** traverse one gray object, turning it to black. ** Returns `quantity' traversed. */ private static l_mem propagatemark(global_State g) { GCObject o = g.gray; lua_assert(isgray(o)); gray2black(o); switch (o.gch.tt) { case LUA_TTABLE: { Table h = gco2h(o); g.gray = h.gclist; if (traversetable(g, h) != 0) /* table is weak? */ black2gray(o); /* keep it gray */ return GetUnmanagedSize(typeof(Table)) + GetUnmanagedSize(typeof(TValue)) * h.sizearray + GetUnmanagedSize(typeof(Node)) * sizenode(h); } case LUA_TFUNCTION: { Closure cl = gco2cl(o); g.gray = cl.c.gclist; traverseclosure(g, cl); return (cl.c.isC != 0) ? sizeCclosure(cl.c.nupvalues) : sizeLclosure(cl.l.nupvalues); } case LUA_TTHREAD: { lua_State th = gco2th(o); g.gray = th.gclist; th.gclist = g.grayagain; g.grayagain = o; black2gray(o); traversestack(g, th); return GetUnmanagedSize(typeof(lua_State)) + GetUnmanagedSize(typeof(TValue)) * th.stacksize + GetUnmanagedSize(typeof(CallInfo)) * th.size_ci; } case LUA_TPROTO: { Proto p = gco2p(o); g.gray = p.gclist; traverseproto(g, p); return GetUnmanagedSize(typeof(Proto)) + GetUnmanagedSize(typeof(Instruction)) * p.sizecode + GetUnmanagedSize(typeof(Proto)) * p.sizep + GetUnmanagedSize(typeof(TValue)) * p.sizek + GetUnmanagedSize(typeof(int)) * p.sizelineinfo + GetUnmanagedSize(typeof(LocVar)) * p.sizelocvars + GetUnmanagedSize(typeof(TString)) * p.sizeupvalues; } default: lua_assert(0); return 0; } }
/* ** All marks are conditional because a GC may happen while the ** prototype is still being created */ private static void traverseproto(global_State g, Proto f) { int i; if (f.source != null) stringmark(f.source); for (i=0; i<f.sizek; i++) /* mark literals */ markvalue(g, f.k[i]); for (i=0; i<f.sizeupvalues; i++) { /* mark upvalue names */ if (f.upvalues[i] != null) stringmark(f.upvalues[i]); } for (i=0; i<f.sizep; i++) { /* mark nested protos */ if (f.p[i] != null) markobject(g, f.p[i]); } for (i=0; i<f.sizelocvars; i++) { /* mark local-variable names */ if (f.locvars[i].varname != null) stringmark(f.locvars[i].varname); } }
public static void makewhite(global_State g, GCObject x) { x.gch.marked = (byte)(x.gch.marked & maskmarks | luaC_white(g)); }
public static void setthreshold(global_State g) { g.GCthreshold = (uint)((g.estimate / 100) * g.gcpause); }
public static void makewhite(global_State g, GCObject x) { gch(x).marked = (byte)(gch(x).marked & maskcolors | luaC_white(g)); }
public static bool isdead(global_State g, GCObject v) { return(isdeadm(otherwhite(g), v.gch.marked)); }
/* ** set GCdebt to a new value keeping the value (totalbytes + GCdebt) ** invariant */ private static void luaE_setdebt(global_State g, l_mem debt) { g.totalbytes -= (uint)(debt - g.GCdebt); //FIXME:(uint) g.GCdebt = debt; }
private 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 != null) { return(propagatemark(g)); } else /* no more `gray' objects */ { atomic(L); /* finish mark phase */ return(0); } } case GCSsweepstring: { correctestimate(g, delegate() { sweepwholelist(L, new ArrayRef(g.strt.hash, g.sweepstrgc++)); }); if (g.sweepstrgc >= g.strt.size) /* nothing more to sweep? */ { g.sweepgc = new RootGCRef(g); g.gcstate = GCSsweep; /* sweep all other objects */ } return(GCSWEEPCOST); } case GCSsweep: { correctestimate(g, delegate() { g.sweepgc = sweeplist(L, g.sweepgc, GCSWEEPMAX); }); if (g.sweepgc.get() == null) /* nothing more to sweep? */ { g.gcstate = GCSfinalize; /* end sweep phase */ } return(GCSWEEPMAX * GCSWEEPCOST); } case GCSfinalize: { if (g.tobefnz != null) { GCTM(L, 1); if (g.estimate > GCFINALIZECOST) { g.estimate -= GCFINALIZECOST; } return(GCFINALIZECOST); } else { correctestimate(g, delegate() { checkSizes(L); }); g.gcstate = GCSpause; /* end collection */ g.gcdept = 0; return(0); } } default: lua_assert(0); return(0); } }
public RootGCRef(global_State g) { this.g = g; }
private static void preinit_state(lua_State L, global_State g) { G_set(L, g); L.stack = null; L.stacksize = 0; L.errorJmp = null; L.hook = null; L.hookmask = 0; L.basehookcount = 0; L.allowhook = 1; resethookcount(L); L.openupval = null; L.size_ci = 0; L.nCcalls = L.baseCcalls = 0; L.status = 0; L.base_ci = null; L.ci = null; L.savedpc = new InstructionPtr(); L.errfunc = 0; setnilvalue(gt(L)); }
public NullpRef(global_State g) { this.g = g; }
public static bool issweepphase(global_State g) { return (GCSsweepstring <= g.gcstate && g.gcstate <= GCSsweep); }
public static bool isdead(global_State g, GCObject v) { return (v.gch.marked & otherwhite(g) & WHITEBITS) != 0; }
public static bool isgenerational(global_State g) { return(g.gckind == KGC_GEN); }
public static void markvalue(global_State g, TValue o) { checkconsistency(o); if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); }
/* ** macro to tell when main invariant (white objects cannot point to black ** ones) must be kept. During a non-generational collection, the sweep ** phase may break the invariant, as objects turned white may point to ** still-black objects. The invariant is restored when sweep ends and ** all objects are white again. During a generational collection, the ** invariant must be kept all times. */ public static bool keepinvariant(global_State g) { return(isgenerational(g) || g.gcstate <= GCSatomic); }
private static void marktmu(global_State g) { GCObject u = g.tmudata; if (u != null) { do { u = u.gch.next; makewhite(g, u); /* may be marked, if left from previous GC */ reallymarkobject(g, u); } while (u != g.tmudata); } }
public static bool gcstopped(global_State g) { return(g.GCdebt == MIN_LMEM); }
private static void remarkupvals(global_State g) { UpVal uv; for (uv = g.uvhead.u.l.next; uv != g.uvhead; uv = uv.u.l.next) { lua_assert(uv.u.l.next.u.l.prev == uv && uv.u.l.prev.u.l.next == uv); if (isgray(obj2gco(uv))) markvalue(g, uv.v); } }
public static void stopgc(global_State g) { g.GCdebt = MIN_LMEM; }
private static int traversetable(global_State g, Table h) { int i; int weakkey = 0; int weakvalue = 0; /*const*/ TValue mode; if (h.metatable != null) markobject(g, h.metatable); mode = gfasttm(g, h.metatable, TMS.TM_MODE); if ((mode != null) && ttisstring(mode)) { /* is there a weak mode? */ weakkey = (strchr(svalue(mode), 'k') != null) ? 1 : 0 ; weakvalue = (strchr(svalue(mode), 'v') != null) ? 1 : 0; if ((weakkey!=0) || (weakvalue!=0)) { /* is really weak? */ h.marked &= (byte)~(KEYWEAK | VALUEWEAK); /* clear bits */ h.marked |= cast_byte((weakkey << KEYWEAKBIT) | (weakvalue << VALUEWEAKBIT)); h.gclist = g.weak; /* must be cleared after GC, ... */ g.weak = obj2gco(h); /* ... so put in the appropriate list */ } } if ((weakkey!=0) && (weakvalue!=0)) return 1; if (weakvalue==0) { i = h.sizearray; while ((i--) != 0) markvalue(g, h.array[i]); } i = sizenode(h); while ((i--) != 0) { Node n = gnode(h, i); lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); if (ttisnil(gval(n))) removeentry(n); /* remove empty entries */ else { lua_assert(ttisnil(gkey(n))); if (weakkey==0) markvalue(g, gkey(n)); if (weakvalue==0) markvalue(g, gval(n)); } } return ((weakkey != 0) || (weakvalue != 0)) ? 1 : 0; }
private static void reallymarkobject(global_State g, GCObject o) { lua_assert(iswhite(o) && !isdead(g, o)); white2gray(o); switch (o.gch.tt) { case LUA_TSTRING: { return; } case LUA_TUSERDATA: { Table mt = gco2u(o).metatable; gray2black(o); /* udata are never gray */ if (mt != null) { markobject(g, mt); } markobject(g, gco2u(o).env); return; } case LUA_TUPVAL: { UpVal uv = gco2uv(o); markvalue(g, uv.v); if (uv.v == uv.u.value) /* closed? */ { gray2black(o); /* open upvalues are never black */ } return; } case LUA_TFUNCTION: { gco2cl(o).c.gclist = g.gray; g.gray = o; break; } case LUA_TTABLE: { gco2h(o).gclist = g.gray; g.gray = o; break; } case LUA_TTHREAD: { gco2th(o).gclist = g.gray; g.gray = o; break; } case LUA_TPROTO: { gco2p(o).gclist = g.gray; g.gray = o; break; } default: lua_assert(0); break; } }
public AllGCRef(global_State g) { this.g = g; }
public static void checkliveness(global_State g, TValue obj) { lua_assert(!iscollectable(obj) || ((ttype(obj) == obj.value.gc.gch.tt) && !isdead(g, obj.value.gc))); }
public TobefnzRef(global_State g) { this.g = g; }
public static int otherwhite(global_State g) { return(g.currentwhite ^ WHITEBITS); }
public MtRef(global_State g) { this.g = g; }
public static bool isdead(global_State g, GCObject v) { return((v.gch.marked & otherwhite(g) & WHITEBITS) != 0); }
/* actual number of total bytes allocated */ public static uint gettotalbytes(global_State g) { return((uint)(g.totalbytes + g.GCdebt)); } //FIXME:(uint)
public static byte luaC_white(global_State g) { return((byte)(g.currentwhite & WHITEBITS)); }
public static byte luaC_white(global_State g) { return (byte)(g.currentwhite & WHITEBITS); }
public static void markobject(global_State g, object t) { if (iswhite(obj2gco(t))) reallymarkobject(g, obj2gco(t)); }
public static int otherwhite(global_State g) { return g.currentwhite ^ WHITEBITS; }
private static int traversetable(global_State g, Table h) { int i; int weakkey = 0; int weakvalue = 0; /*const*/ TValue mode; if (h.metatable != null) { markobject(g, h.metatable); } mode = gfasttm(g, h.metatable, TMS.TM_MODE); if ((mode != null) && ttisstring(mode)) /* is there a weak mode? */ { weakkey = (strchr(svalue(mode), 'k') != null) ? 1 : 0; weakvalue = (strchr(svalue(mode), 'v') != null) ? 1 : 0; if ((weakkey != 0) || (weakvalue != 0)) /* is really weak? */ { h.marked &= (byte)~(KEYWEAK | VALUEWEAK); /* clear bits */ h.marked |= cast_byte((weakkey << KEYWEAKBIT) | (weakvalue << VALUEWEAKBIT)); h.gclist = g.weak; /* must be cleared after GC, ... */ g.weak = obj2gco(h); /* ... so put in the appropriate list */ } } if ((weakkey != 0) && (weakvalue != 0)) { return(1); } if (weakvalue == 0) { i = h.sizearray; while ((i--) != 0) { markvalue(g, h.array[i]); } } i = sizenode(h); while ((i--) != 0) { Node n = gnode(h, i); lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); if (ttisnil(gval(n))) { removeentry(n); /* remove empty entries */ } else { lua_assert(!ttisnil(gkey(n))); if (weakkey == 0) { markvalue(g, gkey(n)); } if (weakvalue == 0) { markvalue(g, gval(n)); } } } return(((weakkey != 0) || (weakvalue != 0)) ? 1 : 0); }
private static void markmt(global_State g) { int i; for (i=0; i<NUM_TAGS; i++) if (g.mt[i] != null) markobject(g, g.mt[i]); }
private 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 != null) { return(propagatemark(g)); } else /* no more `gray' objects */ { atomic(L); /* finish mark phase */ return(0); } } case GCSsweepstring: { lu_mem old = (lu_mem)g.totalbytes; sweepwholelist(L, new ArrayRef(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 -= (uint)(old - g.totalbytes); return(GCSWEEPCOST); } case GCSsweep: { lu_mem old = (lu_mem)g.totalbytes; g.sweepgc = sweeplist(L, g.sweepgc, GCSWEEPMAX); if (g.sweepgc.get() == null) /* nothing more to sweep? */ { checkSizes(L); g.gcstate = GCSfinalize; /* end sweep phase */ } lua_assert(old >= g.totalbytes); g.estimate -= (uint)(old - g.totalbytes); return(GCSWEEPMAX * GCSWEEPCOST); } case GCSfinalize: { if (g.tmudata != null) { 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); } }
private static uint propagateall(global_State g) { uint m = 0; while (g.gray != null) m += (uint)propagatemark(g); return m; }
public static TValue gfasttm(global_State g, Table et, TMS e) { return((et == null) ? null : ((et.flags & (1 << (int)e)) != 0) ? null : luaT_gettm(et, e, g.tmname[(int)e])); }
private static void reallymarkobject(global_State g, GCObject o) { lua_assert(iswhite(o) && !isdead(g, o)); white2gray(o); switch (o.gch.tt) { case LUA_TSTRING: { return; } case LUA_TUSERDATA: { Table mt = gco2u(o).metatable; gray2black(o); /* udata are never gray */ if (mt != null) markobject(g, mt); markobject(g, gco2u(o).env); return; } case LUA_TUPVAL: { UpVal uv = gco2uv(o); markvalue(g, uv.v); if (uv.v == uv.u.value) /* closed? */ gray2black(o); /* open upvalues are never black */ return; } case LUA_TFUNCTION: { gco2cl(o).c.gclist = g.gray; g.gray = o; break; } case LUA_TTABLE: { gco2h(o).gclist = g.gray; g.gray = o; break; } case LUA_TTHREAD: { gco2th(o).gclist = g.gray; g.gray = o; break; } case LUA_TPROTO: { gco2p(o).gclist = g.gray; g.gray = o; break; } default: lua_assert(0); break; } }
public static void checkliveness(global_State g, TValue obj) { lua_longassert(!iscollectable(obj) || (righttt(obj) && !isdead(g, gcvalue(obj)))); }
private static void traverseclosure(global_State g, Closure cl) { markobject(g, cl.c.env); if (cl.c.isC != 0) { int i; for (i=0; i<cl.c.nupvalues; i++) /* mark its upvalues */ markvalue(g, cl.c.upvalue[i]); } else { int i; lua_assert(cl.l.nupvalues == cl.l.p.nups); markobject(g, cl.l.p); for (i=0; i<cl.l.nupvalues; i++) /* mark its upvalues */ markobject(g, cl.l.upvals[i]); } }
public TwupsRef(global_State g) { this.g = g; }
private static void traversestack(global_State g, lua_State l) { StkId o, lim; CallInfo ci; markvalue(g, gt(l)); lim = l.top; for (ci = l.base_ci[0]; ci <= l.ci; CallInfo.inc(ref ci)) { lua_assert(ci.top <= l.stack_last); if (lim < ci.top) lim = ci.top; } for (o = l.stack[0]; o < l.top; StkId.inc(ref o)) markvalue(g, o); for (; o <= lim; StkId.inc(ref o)) setnilvalue(o); checkstacksizes(l, lim); }
public static void G_set(lua_State L, global_State s) { L.l_G = s; } //FIXME:added, not used???
internal static void checkliveness(global_State g, TValue obj) { lua_assert(!iscollectable(obj) || ((ttype(obj) == obj.value.gc.gch.tt) && !isdead(g, obj.value.gc))); }
public static TValue gfasttm(global_State g, Table et, TMS e) { return (et == null) ? null : ((et.flags & (1 << (int)e)) != 0) ? null : luaT_gettm(et, e, g.tmname[(int)e]); }