Example #1
0
        private static void GCTM(LinyeeState L)
        {
            GlobalState 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)
            {
                LinyeeByteType oldah = L.allowhook;
                ly_mem         oldt  = (ly_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;
                LinyeeDCall(L, L.top - 2, 0);
                L.allowhook   = oldah;        /* restore hooks */
                g.GCthreshold = (uint)oldt;   /* restore threshold */
            }
        }
Example #2
0
        private static GCObjectRef SweepList(LinyeeState L, GCObjectRef p, ly_mem count)
        {
            GCObject    curr;
            GlobalState g        = G(L);
            int         deadmask = OtherWhite(g);

            while ((curr = p.get()) != null && count-- > 0)
            {
                if (curr.gch.tt == LINYEE_TTHREAD)          /* sweep open upvalues of each thread */
                {
                    SweepWholeList(L, new OpenValRef(gco2th(curr)));
                }
                if (((curr.gch.marked ^ WHITEBITS) & deadmask) != 0)            /* not dead? */
                {
                    LinyeeAssert(!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' */
                {
                    LinyeeAssert(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);
        }
Example #3
0
        /*
        ** Garbage-collection function
        */

        public static int LinyeeGC(LinyeeState L, int what, int data)
        {
            int         res = 0;
            GlobalState g;

            LinyeeLock(L);
            g = G(L);
            switch (what)
            {
            case LINYEE_GCSTOP: {
                g.GCthreshold = MAXLUMEM;
                break;
            }

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

            case LINYEE_GCCOLLECT: {
                LinyeeCFullGC(L);
                break;
            }

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

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

            case LINYEE_GCSTEP: {
                ly_mem a = ((ly_mem)data << 10);
                if (a <= g.totalbytes)
                {
                    g.GCthreshold = (uint)(g.totalbytes - a);
                }
                else
                {
                    g.GCthreshold = 0;
                }
                while (g.GCthreshold <= g.totalbytes)
                {
                    LinyeeCStep(L);
                    if (g.gcstate == GCSpause) /* end of cycle? */
                    {
                        res = 1;               /* signal it */
                        break;
                    }
                }
                break;
            }

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

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

            default:
                res = -1;                  /* invalid option */
                break;
            }
            LinyeeUnlock(L);
            return(res);
        }
Example #4
0
        private static l_mem SingleStep(LinyeeState L)
        {
            GlobalState g = G(L);

            /*ly_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: {
                ly_mem old = (ly_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 */
                }
                LinyeeAssert(old >= g.totalbytes);
                g.estimate -= (uint)(old - g.totalbytes);
                return(GCSWEEPCOST);
            }

            case GCSsweep: {
                ly_mem old = (ly_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 */
                }
                LinyeeAssert(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: LinyeeAssert(0); return(0);
            }
        }