public static UpVal luaF_findupval (LuaState L, StkId level) { GlobalState g = G(L); GCObjectRef pp = new OpenValRef(L); UpVal p; UpVal uv; while (pp.get() != null && (p = ngcotouv(pp.get())).v >= level) { lua_assert(p.v != p.u.value); if (p.v == level) { /* found a corresponding upvalue? */ if (isdead(g, obj2gco(p))) /* is it dead? */ changewhite(obj2gco(p)); /* ressurect it */ return p; } pp = new NextRef(p); } uv = luaM_new<UpVal>(L); /* not found: create a new one */ uv.tt = LUA_TUPVAL; uv.marked = luaC_white(g); uv.v = level; /* current value lives in the stack */ uv.next = pp.get(); /* chain it in the proper position */ pp.set( obj2gco(uv) ); uv.u.l.prev = g.uvhead; /* double link it in `uvhead' list */ uv.u.l.next = g.uvhead.u.l.next; uv.u.l.next.u.l.prev = uv; g.uvhead.u.l.next = uv; lua_assert(uv.u.l.next.u.l.prev == uv && uv.u.l.prev.u.l.next == uv); return uv; }
public static UpVal luaF_findupval(lua_State L, StkId level) { global_State g = G(L); GCObjectRef pp = new OpenValRef(L); UpVal p; UpVal uv; while (pp.get() != null && (p = ngcotouv(pp.get())).v >= level) { lua_assert(p.v != p.u.value); if (p.v == level) { /* found a corresponding upvalue? */ if (isdead(g, obj2gco(p))) /* is it dead? */ { changewhite(obj2gco(p)); /* ressurect it */ } return(p); } pp = new NextRef(p); } uv = luaM_new <UpVal>(L); /* not found: create a new one */ uv.tt = LUA_TUPVAL; uv.marked = luaC_white(g); uv.v = level; /* current value lives in the stack */ uv.next = pp.get(); /* chain it in the proper position */ pp.set(obj2gco(uv)); uv.u.l.prev = g.uvhead; /* double link it in `uvhead' list */ uv.u.l.next = g.uvhead.u.l.next; uv.u.l.next.u.l.prev = uv; g.uvhead.u.l.next = uv; lua_assert(uv.u.l.next.u.l.prev == uv && uv.u.l.prev.u.l.next == uv); return(uv); }
public static UpVal luaF_findupval(lua_State L, StkId level) { global_State g = G(L); GCObjectRef pp = new OpenValRef(L); UpVal p; UpVal uv; while (pp.get() != null && (p = gco2uv(pp.get())).v >= level) { lua_assert(p.v != p.u.value); if (p.v == level) /* found a corresponding upvalue? */ { if (isdead(g, obj2gco(p))) /* is it dead? */ { changewhite(obj2gco(p)); /* ressurrect it */ } return(p); } pp = new NextRef(p); } /* not found: create a new one */ uv = luaC_newobj <UpVal>(L, LUA_TUPVAL, (uint)GetUnmanagedSize(typeof(UpVal)), pp, 0).uv; uv.v = level; /* current value lives in the stack */ uv.u.l.prev = g.uvhead; /* double link it in `uvhead' list */ uv.u.l.next = g.uvhead.u.l.next; uv.u.l.next.u.l.prev = uv; g.uvhead.u.l.next = uv; lua_assert(uv.u.l.next.u.l.prev == uv && uv.u.l.prev.u.l.next == uv); return(uv); }
private static GCObjectRef sweeplist(lua_State L, GCObjectRef p, lu_mem count) { GCObject curr; global_State g = G(L); int deadmask = otherwhite(g); while ((curr = p.get()) != null && count-- > 0) { int alive = (gch(curr).marked ^ WHITEBITS) & deadmask; if (ttisthread(gch(curr))) { sweepthread(L, gco2th(curr), alive); } if (alive != 0) { lua_assert(isdead(g, curr) || testbit(gch(curr).marked, FIXEDBIT)); makewhite(g, curr); /* make it white (for next cycle) */ p = new NextRef(gch(curr)); } else /* must erase `curr' */ { lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); p.set(gch(curr).next); /* remove 'curr' from list */ freeobj(L, curr); } } return(p); }
private static GCObjectRef SweepList(LuaState L, GCObjectRef p, lu_mem count) { GCObject curr; GlobalState g = G(L); int deadmask = OtherWhite(g); while ((curr = p.get()) != null && count-- > 0) { if (curr.gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */ { SweepWholeList(L, new OpenValRef(gco2th(curr))); } if (((curr.gch.marked ^ WHITEBITS) & deadmask) != 0) /* not dead? */ { LuaAssert(!IsDead(g, curr) || TestBit(curr.gch.marked, FIXEDBIT)); MakeWhite(g, curr); /* make it white (for next cycle) */ p = new NextRef(curr.gch); } else /* must erase `curr' */ { LuaAssert(IsDead(g, curr) || deadmask == BitMask(SFIXEDBIT)); p.set(curr.gch.next); if (curr == g.rootgc) /* is the first element of the list? */ { g.rootgc = curr.gch.next; /* adjust first */ } FreeObj(L, curr); } } return(p); }
private static GCObjectRef sweeplist(lua_State L, GCObjectRef p, lu_mem count) { GCObject curr; global_State g = G(L); int deadmask = otherwhite(g); while ((curr = p.get()) != null && count-- > 0) { if (ttisthread(gch(curr))) /* sweep open upvalues of each thread */ { sweepwholelist(L, new OpenValRef(gco2th(curr))); } if (((gch(curr).marked ^ WHITEBITS) & deadmask) != 0) /* not dead? */ { lua_assert(isdead(g, curr) || testbit(gch(curr).marked, FIXEDBIT)); makewhite(g, curr); /* make it white (for next cycle) */ p = new NextRef(gch(curr)); } else /* must erase `curr' */ { lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); p.set(gch(curr).next); /* remove 'curr' from list */ freeobj(L, curr); } } return(p); }
public void RecursiveAndCheckRef(ref ResolvableInfo info, bool isCreateWhenEmpty, out ResolvableBinder result) { if (IsSameRef(ref info)) { result = this; } else { if (NextRef == default) { if (isCreateWhenEmpty) { result = CreateResolvableRef(ref info, ref mTypeID); SetNextRef(result); } else { result = default; return; } } else { NextRef.RecursiveAndCheckRef(ref info, isCreateWhenEmpty, out result); } } }
/* ** move all unreachable objects that need finalization from list 'finobj' ** to list 'tobefnz' */ public static void luaC_separateudata(lua_State L, int all) { global_State g = G(L); GCObjectRef p = new FinobjRef(g); GCObject curr; GCObjectRef lastnext = new TobefnzRef(g); //FIXME:??????next??? /* find last 'next' field in 'tobefnz' list (to add elements in its end) */ while (lastnext.get() != null) { lastnext = new NextRef(gch(lastnext.get())); //FIXME:next???PtrRef??? } while ((curr = p.get()) != null) /* traverse all finalizable objects */ { lua_assert(!isfinalized(curr)); lua_assert(testbit(gch(curr).marked, SEPARATED)); if (!(all != 0 || iswhite(curr))) /* not being collected? */ { p = new NextRef(gch(curr)); /* don't bother with it */ } else { l_setbit(ref gch(curr).marked, FINALIZEDBIT); /* won't be finalized again */ p.set(gch(curr).next); /* remove 'curr' from 'finobj' list */ gch(curr).next = lastnext.get(); /* link at the end of 'tobefnz' list */ lastnext.set(curr); lastnext = new NextRef(gch(curr)); } } }
private static GCObjectRef sweeplist(lua_State L, GCObjectRef p, lu_mem count) { GCObject curr; global_State g = G(L); int deadmask = otherwhite(g); while ((curr = p.get()) != null && count-- > 0) { if (curr.gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */ { sweepwholelist(L, new OpenValRef(gco2th(curr))); } if (((curr.gch.marked ^ WHITEBITS) & deadmask) != 0) /* not dead? */ { lua_assert(isdead(g, curr) || testbit(curr.gch.marked, FIXEDBIT)); makewhite(g, curr); /* make it white (for next cycle) */ p = new NextRef(curr.gch); } else /* must erase `curr' */ { lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); p.set(curr.gch.next); if (curr == g.rootgc) /* is the first element of the list? */ { g.rootgc = curr.gch.next; /* adjust first */ } freeobj(L, curr); } } return(p); }
/* move 'dead' udata that need finalization to list 'tobefnz' */ public static uint luaC_separateudata(lua_State L, int all) { global_State g = G(L); uint deadmem = 0; /* total size of all objects to be finalized */ GCObjectRef p = new NextRef(g.mainthread); GCObject curr; GCObjectRef lastnext = new TobefnzRef(g); //FIXME:?????? /* find last 'next' field in 'tobefnz' list (to insert elements in its end) */ while (lastnext.get() != null) { lastnext = new NextRef(gch(lastnext.get())); } while ((curr = p.get()) != null) /* traverse all finalizable objects */ { lua_assert(ttisuserdata(gch(curr)) && !isfinalized(gco2u(curr))); lua_assert(testbit(gch(curr).marked, SEPARATED)); if (!(all != 0 || iswhite(curr))) /* not being collected? */ { p = new NextRef(gch(curr)); /* don't bother with it */ } else { l_setbit(ref gch(curr).marked, FINALIZEDBIT); /* won't be finalized again */ deadmem += sizeudata(gco2u(curr)); p.set(gch(curr).next); /* remove 'curr' from 'rootgc' list */ /* link 'curr' at the end of 'tobefnz' list */ gch(curr).next = lastnext.get(); lastnext.set(curr); lastnext = new NextRef(gch(curr)); } } return(deadmem); }
//private static GCObject nullp = null; //FIXME:see nullp in global_State /* ** sweep at most 'count' elements from a list of GCObjects erasing dead ** objects, where a dead (not alive) object is one marked with the "old" ** (non current) white and not fixed. ** In non-generational mode, change all non-dead objects back to white, ** preparing for next collection cycle. ** In generational mode, keep black objects black, and also mark them as ** old; stop when hitting an old object, as all objects after that ** one will be old too. ** When object is a thread, sweep its list of open upvalues too. */ private static GCObjectRef sweeplist(lua_State L, GCObjectRef p, lu_mem count) { global_State g = G(L); int ow = otherwhite(g); int toclear, toset; /* bits to clear and to set in all live objects */ int tostop; /* stop sweep when this is true */ l_mem debt = g.GCdebt; /* current debt */ if (isgenerational(g)) /* generational mode? */ { toclear = ~0; /* clear nothing */ toset = bitmask(OLDBIT); /* set the old bit of all surviving objects */ tostop = bitmask(OLDBIT); /* do not sweep old generation */ } else /* normal mode */ { toclear = maskcolors; /* clear all color bits + old bit */ toset = luaC_white(g); /* make object white */ tostop = 0; /* do not stop */ } while (p.get() != null && count-- > 0) { GCObject curr = p.get(); int marked = gch(curr).marked; if (isdeadm(ow, marked)) /* is 'curr' dead? */ { p.set(gch(curr).next); /* remove 'curr' from list */ freeobj(L, curr); /* erase 'curr' */ } else { if (gch(curr).tt == LUA_TTHREAD) { sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */ } if (testbits((byte)marked, tostop)) //FIXME:(byte) //static GCObject *nullp = NULL; //FIXME:moved, see upper { p = new NullpRef(g); /* stop sweeping this list */ break; } /* update marks */ gch(curr).marked = cast_byte((marked & toclear) | toset); p = new NextRef(gch(curr)); /* go to next element */ } } luaE_setdebt(g, debt); /* sweeping should not change debt */ return(p); }
/* move `dead' udata that need finalization to list `tmudata' */ public static uint luaC_separateudata(lua_State L, int all) { global_State g = G(L); uint deadmem = 0; GCObjectRef p = new NextRef(g.mainthread); GCObject curr; while ((curr = p.get()) != null) { if (!(iswhite(curr) || (all != 0)) || isfinalized(gco2u(curr))) { p = new NextRef(curr.gch); /* don't bother with them */ } else if (fasttm(L, gco2u(curr).metatable, TMS.TM_GC) == null) { markfinalized(gco2u(curr)); /* don't need finalization */ p = new NextRef(curr.gch); } else /* must call its gc method */ { deadmem += (uint)sizeudata(gco2u(curr)); markfinalized(gco2u(curr)); p.set(curr.gch.next); /* link `curr' at the end of `tmudata' list */ if (g.tmudata == null) /* list is empty? */ { g.tmudata = curr.gch.next = curr; /* creates a circular list */ } else { curr.gch.next = g.tmudata.gch.next; g.tmudata.gch.next = curr; g.tmudata = curr; } } } return(deadmem); }
/* ** if object 'o' has a finalizer, remove it from 'allgc' list (must ** search the list to find it) and link it in 'finobj' list. */ public static void luaC_checkfinalizer(lua_State L, GCObject o, Table mt) { global_State g = G(L); if (testbit(gch(o).marked, SEPARATED) || /* obj. is already separated... */ isfinalized(o) || /* ... or is finalized... */ gfasttm(g, mt, TMS.TM_GC) == null) /* or has no finalizer? */ { return; /* nothing to be done */ } else /* move 'o' to 'finobj' list */ { GCObjectRef p; for (p = new AllGCRef(g); p.get() != o; p = new NextRef(gch(p.get()))) { ; } p.set(gch(o).next); /* remove 'o' from root list */ gch(o).next = g.finobj; /* link it in list 'finobj' */ g.finobj = o; l_setbit(ref gch(o).marked, SEPARATED); /* mark it as such */ resetoldbit(o); /* see MOVE OLD rule */ } }
/* ** if userdata 'u' has a finalizer, remove it from 'allgc' list (must ** search the list to find it) and link it in 'udgc' list. */ public static void luaC_checkfinalizer(lua_State L, Udata u) { global_State g = G(L); if (testbit(u.uv.marked, SEPARATED) || /* userdata is already separated... */ isfinalized(u.uv) || /* ... or is finalized... */ gfasttm(g, u.uv.metatable, TMS.TM_GC) == null) /* or has no finalization? */ { return; /* nothing to be done */ } else /* move 'u' to 'udgc' list */ { GCObjectRef p; for (p = new AllGCRef(g); p.get() != obj2gco(u); p = new NextRef(gch(p.get()))) { ; } p.set(u.uv.next); /* remove 'u' from root list */ u.uv.next = g.udgc; /* link it in list 'udgc' */ g.udgc = obj2gco(u); l_setbit(ref u.uv.marked, SEPARATED); /* mark it as such */ resetoldbit(obj2gco(u)); /* see MOVE OLD rule */ } }
/* move `dead' udata that need finalization to list `tmudata' */ public static uint luaC_separateudata(lua_State L, int all) { global_State g = G(L); uint deadmem = 0; GCObjectRef p = new NextRef(g.mainthread); GCObject curr; while ((curr = p.get()) != null) { if (!(iswhite(curr) || (all!=0)) || isfinalized(gco2u(curr))) p = new NextRef(curr.gch); /* don't bother with them */ else if (fasttm(L, gco2u(curr).metatable, TMS.TM_GC) == null) { markfinalized(gco2u(curr)); /* don't need finalization */ p = new NextRef(curr.gch); } else { /* must call its gc method */ deadmem += (uint)sizeudata(gco2u(curr)); markfinalized(gco2u(curr)); p.set( curr.gch.next ); /* link `curr' at the end of `tmudata' list */ if (g.tmudata == null) /* list is empty? */ g.tmudata = curr.gch.next = curr; /* creates a circular list */ else { curr.gch.next = g.tmudata.gch.next; g.tmudata.gch.next = curr; g.tmudata = curr; } } } return deadmem; }
private static GCObjectRef sweeplist(lua_State L, GCObjectRef p, lu_mem count) { GCObject curr; global_State g = G(L); int deadmask = otherwhite(g); while ((curr = p.get()) != null && count-- > 0) { if (curr.gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */ sweepwholelist(L, new OpenValRef( gco2th(curr) )); if (((curr.gch.marked ^ WHITEBITS) & deadmask) != 0) { /* not dead? */ lua_assert(isdead(g, curr) || testbit(curr.gch.marked, FIXEDBIT)); makewhite(g, curr); /* make it white (for next cycle) */ p = new NextRef(curr.gch); } else { /* must erase `curr' */ lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); p.set( curr.gch.next ); if (curr == g.rootgc) /* is the first element of the list? */ g.rootgc = curr.gch.next; /* adjust first */ freeobj(L, curr); } } return p; }
private static GCObjectRef SweepList(LuaState L, GCObjectRef p, lu_mem count) { GCObject curr; GlobalState g = G(L); int deadmask = OtherWhite(g); while ((curr = p.get()) != null && count-- > 0) { if (curr.gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */ SweepWholeList(L, new OpenValRef( gco2th(curr) )); if (((curr.gch.marked ^ WHITEBITS) & deadmask) != 0) { /* not dead? */ LuaAssert(!IsDead(g, curr) || TestBit(curr.gch.marked, FIXEDBIT)); MakeWhite(g, curr); /* make it white (for next cycle) */ p = new NextRef(curr.gch); } else { /* must erase `curr' */ LuaAssert(IsDead(g, curr) || deadmask == BitMask(SFIXEDBIT)); p.set( curr.gch.next ); if (curr == g.rootgc) /* is the first element of the list? */ g.rootgc = curr.gch.next; /* adjust first */ FreeObj(L, curr); } } return p; }