public static void luaC_step(lua_State L) { global_State g = G(L); l_mem lim = (l_mem)((GCSTEPSIZE / 100) * g.gcstepmul); if (lim == 0) { lim = (l_mem)((MAX_LUMEM - 1) / 2); /* no limit */ } g.gcdept += g.totalbytes - g.GCthreshold; do { lim -= singlestep(L); if (g.gcstate == GCSpause) { break; } } while (lim > 0); if (g.gcstate != GCSpause) { if (g.gcdept < GCSTEPSIZE) { g.GCthreshold = g.totalbytes + GCSTEPSIZE; /* - lim/g.gcstepmul;*/ } else { g.gcdept -= GCSTEPSIZE; g.GCthreshold = g.totalbytes; } } else { setthreshold(g); } }
public static void LinyeeCStep(LinyeeState L) { GlobalState g = G(L); l_mem lim = (l_mem)((GCSTEPSIZE / 100) * g.gcstepmul); if (lim == 0) { lim = (l_mem)((MAXLUMEM - 1) / 2); /* no limit */ } g.gcdept += g.totalbytes - g.GCthreshold; do { lim -= SingleStep(L); if (g.gcstate == GCSpause) { break; } } while (lim > 0); if (g.gcstate != GCSpause) { if (g.gcdept < GCSTEPSIZE) { g.GCthreshold = g.totalbytes + GCSTEPSIZE; /* - lim/g.gcstepmul;*/ } else { g.gcdept -= GCSTEPSIZE; g.GCthreshold = g.totalbytes; } } else { SetThreshold(g); } }
/* ** set GCdebt to a new value keeping the value (totalbytes + GCdebt) ** invariant (and avoiding underflows in 'totalbytes') */ private static void luaE_setdebt(global_State g, l_mem debt) { l_mem tb = (l_mem)gettotalbytes(g); lua_assert(tb > 0); if (debt < tb - MAX_LMEM) { debt = tb - MAX_LMEM; /* will make 'totalbytes == MAX_LMEM' */ } g.totalbytes = tb - debt; g.GCdebt = debt; }
//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); }
private static void step(lua_State L) { global_State g = G(L); l_mem lim = g.gcstepmul; /* how much to work */ do /* always perform at least one single step */ { lim -= singlestep(L); } while (lim > 0 && g.gcstate != GCSpause); if (g.gcstate != GCSpause) { luaE_setdebt(g, g.GCdebt - GCSTEPSIZE); } else { luaE_setdebt(g, stddebt(g)); } }
public static void luaC_step(lua_State L) { global_State g = G(L); l_mem lim = (l_mem)((GCSTEPSIZE / 100) * g.gcstepmul); /* how much to work */ lu_mem debt = g.totalbytes - g.GCthreshold; lua_assert(g.gckind == KGC_NORMAL); do /* always perform at least one single step */ { lim -= singlestep(L); } while (lim > 0 && g.gcstate != GCSpause); g.GCthreshold = (uint)((g.gcstate != GCSpause) ? g.totalbytes + GCSTEPSIZE : (g.totalbytes / 100) * g.gcpause); //FIXME:(uint) /* compensate if GC is "behind schedule" (has some debt to pay) */ if (g.GCthreshold > debt) { g.GCthreshold -= debt; } }
/* ** Garbage-collection function */ public static int lua_gc(lua_State L, int what, int data) { int res = 0; global_State g; lua_lock(L); g = G(L); switch (what) { case LUA_GCSTOP: { g.gcrunning = 0; break; } case LUA_GCRESTART: { luaE_setdebt(g, 0); g.gcrunning = 1; break; } case LUA_GCCOLLECT: { luaC_fullgc(L, 0); break; } case LUA_GCCOUNT: { /* GC values are expressed in Kbytes: #bytes/2^10 */ res = cast_int(gettotalbytes(g) >> 10); break; } case LUA_GCCOUNTB: { res = cast_int(gettotalbytes(g) & 0x3ff); break; } case LUA_GCSTEP: { l_mem debt = 1; /* =1 to signal that it did an actual step */ /*int*/ byte oldrunning = g.gcrunning; //FIXME: int->byte g.gcrunning = 1; /* allow GC to run */ if (data == 0) { luaE_setdebt(g, -GCSTEPSIZE); /* to do a "small" step */ luaC_step(L); } else /* add 'data' to total debt */ { debt = ((l_mem)data) * 1024 + g.GCdebt; luaE_setdebt(g, debt); luaC_checkGC(L); } g.gcrunning = oldrunning; /* restore previous state */ if (debt > 0 && g.gcstate == GCSpause) /* end of cycle? */ { res = 1; /* signal it */ } break; } case LUA_GCSETPAUSE: { res = g.gcpause; g.gcpause = data; break; } case LUA_GCSETSTEPMUL: { res = g.gcstepmul; if (data < 40) { data = 40; /* avoid ridiculous low values (and 0) */ } g.gcstepmul = data; break; } case LUA_GCISRUNNING: { res = g.gcrunning; break; } default: res = -1; /* invalid option */ break; //FIXME: added } lua_unlock(L); return(res); }
/* ** 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; }