Пример #1
0
        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);
        }
Пример #2
0
        private static void GCTM(lua_State L)
        {
            global_State g     = G(L);
            GCObject     o     = g.tmudata.gch.next; /* get first element */
            Udata        udata = rawgco2u(o);
            TValue       tm;

            /* remove udata from `tmudata' */
            if (o == g.tmudata)        /* last element? */
            {
                g.tmudata = null;
            }
            else
            {
                g.tmudata.gch.next = udata.uv.next;
            }
            udata.uv.next     = g.mainthread.next;    /* return it to `root' list */
            g.mainthread.next = o;
            makewhite(g, o);
            tm = fasttm(L, udata.uv.metatable, TMS.TM_GC);
            if (tm != null)
            {
                lu_byte oldah = L.allowhook;
                lu_mem  oldt  = (lu_mem)g.GCthreshold;
                L.allowhook   = 0;                /* stop debug hooks during GC tag method */
                g.GCthreshold = 2 * g.totalbytes; /* avoid GC steps */
                setobj2s(L, L.top, tm);
                setuvalue(L, L.top + 1, udata);
                L.top += 2;
                luaD_call(L, L.top - 2, 0);
                L.allowhook   = oldah;        /* restore hooks */
                g.GCthreshold = (uint)oldt;   /* restore threshold */
            }
        }
Пример #3
0
        private static void GCTM(lua_State L, int propagateerrors)
        {
            global_State     g     = G(L);
            Udata            udata = udata2finalize(g);
            /*const*/ TValue tm    = gfasttm(g, udata.uv.metatable, TMS.TM_GC);

            if (tm != null && ttisfunction(tm))
            {
                int     status;
                lu_byte oldah = L.allowhook;
                lu_mem  oldt  = (lu_mem)g.GCthreshold;
                L.allowhook   = 0;                /* stop debug hooks during GC tag method */
                g.GCthreshold = 2 * g.totalbytes; /* avoid GC steps */
                setobj2s(L, L.top, tm);
                setuvalue(L, L.top + 1, udata);
                L.top += 2;
                status = luaD_pcall(L, dothecall, null, savestack(L, L.top - 2), 0);
                if (status != LUA_OK && propagateerrors != 0) /* error while running __gc? */
                {
                    if (status == LUA_ERRRUN)                 /* is there an error msg.? */
                    {
                        luaO_pushfstring(L, "error in __gc tag method (%s)",
                                         lua_tostring(L, -1));
                        status = LUA_ERRGCMM; /* error in __gc metamethod */
                    }
                    luaD_throw(L, status);    /* re-send error */
                }
                L.allowhook   = oldah;        /* restore hooks */
                g.GCthreshold = (uint)oldt;   /* restore threshold */
            }
        }
Пример #4
0
        private static void correctestimate(global_State g, correctestimate_delegate s)
        {
            lu_mem old = g.totalbytes; s();

            lua_assert(old >= g.totalbytes);
            g.estimate -= old - g.totalbytes;
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }
Пример #7
0
        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);
        }
Пример #8
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);
        }
Пример #9
0
        private static void GCTM(lua_State L)
        {
            global_State     g     = G(L);
            Udata            udata = udata2finalize(g);
            /*const*/ TValue tm    = fasttm(L, udata.uv.metatable, TMS.TM_GC);

            if (tm != null)
            {
                lu_byte oldah = L.allowhook;
                lu_mem  oldt  = (lu_mem)g.GCthreshold;
                L.allowhook   = 0;                /* stop debug hooks during GC tag method */
                g.GCthreshold = 2 * g.totalbytes; /* avoid GC steps */
                setobj2s(L, L.top, tm);
                setuvalue(L, L.top + 1, udata);
                L.top += 2;
                luaD_call(L, L.top - 2, 0);
                L.allowhook   = oldah;        /* restore hooks */
                g.GCthreshold = (uint)oldt;   /* restore threshold */
            }
        }
Пример #10
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;
            }
        }
Пример #11
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: {
                if (g.gckind == KGC_GEN)           /* generational mode? */
                {
                    res = (g.GCestimate == 0)?1:0; /* true if it will do major collection */
                    luaC_forcestep(L);             /* do a single step */
                }
                else
                {
                    lu_mem debt = (lu_mem)(data) * 1024 - GCSTEPSIZE;
                    if (g.gcrunning != 0)
                    {
                        debt += (uint)g.GCdebt;          /* include current debt */
                    }
                    luaE_setdebt(g, (int)debt);
                    luaC_forcestep(L);
                    if (g.gcstate == GCSpause) /* end of cycle? */
                    {
                        res = 1;               /* signal it */
                    }
                }
                break;
            }

            case LUA_GCSETPAUSE: {
                res       = g.gcpause;
                g.gcpause = data;
                break;
            }

            case LUA_GCSETMAJORINC: {
                res          = g.gcmajorinc;
                g.gcmajorinc = data;
                break;
            }

            case LUA_GCSETSTEPMUL: {
                res         = g.gcstepmul;
                g.gcstepmul = data;
                break;
            }

            case LUA_GCISRUNNING: {
                res = g.gcrunning;
                break;
            }

            case LUA_GCGEN: {          /* change collector to generational mode */
                luaC_changemode(L, KGC_GEN);
                break;
            }

            case LUA_GCINC: {          /* change collector to incremental mode */
                luaC_changemode(L, KGC_NORMAL);
                break;
            }

            default: res = -1;         /* invalid option */
                break;                 //FIXME: added
            }
            lua_unlock(L);
            return(res);
        }
Пример #12
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.GCthreshold = MAX_LUMEM;
                break;
            }

            case LUA_GCRESTART: {
                g.GCthreshold = g.totalbytes;
                break;
            }

            case LUA_GCCOLLECT: {
                luaC_fullgc(L, 0);
                break;
            }

            case LUA_GCCOUNT: {
                /* GC values are expressed in Kbytes: #bytes/2^10 */
                res = cast_int(g.totalbytes >> 10);
                break;
            }

            case LUA_GCCOUNTB: {
                res = cast_int(g.totalbytes & 0x3ff);
                break;
            }

            case LUA_GCSTEP: {
                lu_mem a = ((lu_mem)data << 10);
                if (a <= g.totalbytes)
                {
                    g.GCthreshold = (uint)(g.totalbytes - a);
                }
                else
                {
                    g.GCthreshold = 0;
                }

                while (g.GCthreshold <= g.totalbytes)
                {
                    luaC_step(L);
                }
                if (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;
                g.gcstepmul = data;
                break;
            }

            default:
                res = -1;                  /* invalid option */
                break;
            }
            lua_unlock(L);
            return(res);
        }
Пример #13
0
        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);
            }
        }
Пример #14
0
Файл: lgc.cs Проект: oathx/Six
		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;
		}
Пример #15
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.GCthreshold = MAX_LUMEM;
                break;
            }

            case LUA_GCRESTART: {
                g.GCthreshold = g.totalbytes;
                break;
            }

            case LUA_GCCOLLECT: {
                luaC_fullgc(L, 0);
                break;
            }

            case LUA_GCCOUNT: {
                /* GC values are expressed in Kbytes: #bytes/2^10 */
                res = cast_int(g.totalbytes >> 10);
                break;
            }

            case LUA_GCCOUNTB: {
                res = cast_int(g.totalbytes & 0x3ff);
                break;
            }

            case LUA_GCSTEP: {
                lu_mem oldts = g.GCthreshold;
                lu_mem a     = ((lu_mem)data << 10);
                g.GCthreshold = (a <= g.totalbytes) ? g.totalbytes - a : 0;
                while (g.GCthreshold <= g.totalbytes)
                {
                    luaC_step(L);
                    if (g.gcstate == GCSpause) /* end of cycle? */
                    {
                        res = 1;               /* signal it */
                        break;
                    }
                }
                if (oldts == MAX_LUMEM)        /* collector was stopped? */
                {
                    g.GCthreshold = oldts;     /* keep it that way */
                }
                break;
            }

            case LUA_GCSETPAUSE: {
                res       = g.gcpause;
                g.gcpause = data;
                break;
            }

            case LUA_GCSETSTEPMUL: {
                res         = g.gcstepmul;
                g.gcstepmul = data;
                break;
            }

            case LUA_GCISRUNNING: {
                res = (g.GCthreshold != MAX_LUMEM ? 1 : 0);
                break;
            }

            default: res = -1;         /* invalid option */
                break;                 //FIXME: added
            }
            lua_unlock(L);
            return(res);
        }
Пример #16
0
		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;
		}