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); }
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(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 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); }
/* ** creates a new string object */ private static TString createstrobj(lua_State L, CharPtr str, uint l, int tag, uint h, GCObjectRef list) { TString ts; uint totalsize; /* total size of TString object */ totalsize = (uint)(GetUnmanagedSize(typeof(TString)) + ((l + 1) * GetUnmanagedSize(typeof(char)))); ts = luaC_newobj <TString>(L, tag, totalsize, list, 0).ts; ts.tsv.len = l; ts.tsv.hash = h; ts.tsv.extra = 0; memcpy(ts.str, str, l * 1); //FIXME:sizeof(char) == 1 ts.str[l] = '\0'; /* ending 0 */ return(ts); }
//FIXME:refer to luaM_new //public static object luaM_realloc_<T>(lua_State L) //T new_obj = (T)System.Activator.CreateInstance(typeof(T)); //AddTotalBytes(L, nsize); /* ** create a new collectable object and link it to '*list' */ public static GCObject luaC_newobj <T> (lua_State L, int tt, uint sz, GCObjectRef list, int offset) { global_State g = G(L); GCObject o = obj2gco(luaM_newobject <T>(L /*, tt, sz*/) /* + offset*/); //FIXME:???no offset if (o is TString) //FIXME:added { int len_plus_1 = (int)sz - GetUnmanagedSize(typeof(TString)); ((TString)o).str = new CharPtr(new char[len_plus_1]); } if (list == null) { list = new RootGCRef(g); /* standard list for collectable objects */ } gch(o).marked = luaC_white(g); gch(o).tt = (byte)tt; //FIXME:(byte) gch(o).next = list.get(); list.set(o); return(o); }
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; }
public static void sweepwholelist(lua_State L, GCObjectRef p) { sweeplist(L, p, MAX_LUMEM); }
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; }
public static void SweepWholeList(LuaState L, GCObjectRef p) { SweepList(L, p, MAXLUMEM); }