예제 #1
0
        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);
            }
        }
예제 #2
0
파일: lgc.cs 프로젝트: jiaguoxinzhi/KopiLua
        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);
            }
        }
예제 #3
0
        /*
        ** 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;
        }
예제 #4
0
        //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);
        }
예제 #5
0
        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));
            }
        }
예제 #6
0
        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;
            }
        }
예제 #7
0
        /*
        ** 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);
        }
예제 #8
0
 /*
 ** 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;
 }