Lines Matching +full:- +full:g +full:-

71 #define makewhite(g,x)	\  argument
72 (x->marked = cast_byte((x->marked & ~maskcolors) | luaC_white(g)))
75 #define set2gray(x) resetbits(x->marked, maskcolors)
80 (x->marked = cast_byte((x->marked & ~WHITEBITS) | bitmask(BLACKBIT)))
94 #define markvalue(g,o) { checkliveness(g->mainthread,o); \ argument
95 if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }
97 #define markkey(g, n) { if keyiswhite(n) reallymarkobject(g,gckey(n)); } argument
99 #define markobject(g,t) { if (iswhite(t)) reallymarkobject(g, obj2gco(t)); } argument
105 #define markobjectN(g,t) { if (t) markobject(g,t); } argument
107 static void reallymarkobject (global_State *g, GCObject *o);
126 switch (o->tt) { in getgclist()
127 case LUA_VTABLE: return &gco2t(o)->gclist; in getgclist()
128 case LUA_VLCL: return &gco2lcl(o)->gclist; in getgclist()
129 case LUA_VCCL: return &gco2ccl(o)->gclist; in getgclist()
130 case LUA_VTHREAD: return &gco2th(o)->gclist; in getgclist()
131 case LUA_VPROTO: return &gco2p(o)->gclist; in getgclist()
134 lua_assert(u->nuvalue > 0); in getgclist()
135 return &u->gclist; in getgclist()
146 #define linkgclist(o,p) linkgclist_(obj2gco(o), &(o)->gclist, &(p))
180 ** table. Non-collectable objects are never removed from weak
185 static int iscleared (global_State *g, const GCObject *o) { in iscleared() argument
186 if (o == NULL) return 0; /* non-collectable value */ in iscleared()
187 else if (novariant(o->tt) == LUA_TSTRING) { in iscleared()
188 markobject(g, o); /* strings are 'values', so are never weak */ in iscleared()
199 ** be changed directly to OLD, because it may still point to non-old
209 global_State *g = G(L); in luaC_barrier_() local
210 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); in luaC_barrier_()
211 if (keepinvariant(g)) { /* must keep invariant? */ in luaC_barrier_()
212 reallymarkobject(g, v); /* restore invariant */ in luaC_barrier_()
219 lua_assert(issweepphase(g)); in luaC_barrier_()
220 if (g->gckind == KGC_INC) /* incremental mode? */ in luaC_barrier_()
221 makewhite(g, o); /* mark 'o' as white to avoid other barriers */ in luaC_barrier_()
231 global_State *g = G(L); in luaC_barrierback_() local
232 lua_assert(isblack(o) && !isdead(g, o)); in luaC_barrierback_()
233 lua_assert((g->gckind == KGC_GEN) == (isold(o) && getage(o) != G_TOUCHED1)); in luaC_barrierback_()
237 linkobjgclist(o, g->grayagain); in luaC_barrierback_()
244 global_State *g = G(L); in luaC_fix() local
245 lua_assert(g->allgc == o); /* object must be 1st in 'allgc' list! */ in luaC_fix()
248 g->allgc = o->next; /* remove object from 'allgc' list */ in luaC_fix()
249 o->next = g->fixedgc; /* link it to 'fixedgc' list */ in luaC_fix()
250 g->fixedgc = o; in luaC_fix()
259 global_State *g = G(L); in luaC_newobjdt() local
262 o->marked = luaC_white(g); in luaC_newobjdt()
263 o->tt = tt; in luaC_newobjdt()
264 o->next = g->allgc; in luaC_newobjdt()
265 g->allgc = o; in luaC_newobjdt()
297 static void reallymarkobject (global_State *g, GCObject *o) { in reallymarkobject() argument
298 switch (o->tt) { in reallymarkobject()
310 markvalue(g, uv->v.p); /* mark its content */ in reallymarkobject()
315 if (u->nuvalue == 0) { /* no user values? */ in reallymarkobject()
316 markobjectN(g, u->metatable); /* mark its metatable */ in reallymarkobject()
324 linkobjgclist(o, g->gray); /* to be visited later */ in reallymarkobject()
335 static void markmt (global_State *g) { in markmt() argument
338 markobjectN(g, g->mt[i]); in markmt()
343 ** mark all objects in list of being-finalized
345 static lu_mem markbeingfnz (global_State *g) { in markbeingfnz() argument
348 for (o = g->tobefnz; o != NULL; o = o->next) { in markbeingfnz()
350 markobject(g, o); in markbeingfnz()
357 ** For each non-marked thread, simulates a barrier between each open
360 ** to act. The "barrier" does not need to check colors: A non-marked
367 static int remarkupvals (global_State *g) { in remarkupvals() argument
369 lua_State **p = &g->twups; in remarkupvals()
373 if (!iswhite(thread) && thread->openupval != NULL) in remarkupvals()
374 p = &thread->twups; /* keep marked thread with upvalues in the list */ in remarkupvals()
377 lua_assert(!isold(thread) || thread->openupval == NULL); in remarkupvals()
378 *p = thread->twups; /* remove thread from the list */ in remarkupvals()
379 thread->twups = thread; /* mark that it is out of list */ in remarkupvals()
380 for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) { in remarkupvals()
385 markvalue(g, uv->v.p); /* mark its value */ in remarkupvals()
394 static void cleargraylists (global_State *g) { in cleargraylists() argument
395 g->gray = g->grayagain = NULL; in cleargraylists()
396 g->weak = g->allweak = g->ephemeron = NULL; in cleargraylists()
403 static void restartcollection (global_State *g) { in restartcollection() argument
404 cleargraylists(g); in restartcollection()
405 markobject(g, g->mainthread); in restartcollection()
406 markvalue(g, &g->l_registry); in restartcollection()
407 markmt(g); in restartcollection()
408 markbeingfnz(g); /* mark any finalizing object left from previous cycle */ in restartcollection()
423 ** post-processing by 'correctgraylist'. (It could put all old objects
430 static void genlink (global_State *g, GCObject *o) { in genlink() argument
433 linkobjgclist(o, g->grayagain); /* link it back in 'grayagain' */ in genlink()
446 static void traverseweakvalue (global_State *g, Table *h) { in traverseweakvalue() argument
450 int hasclears = (h->alimit > 0); in traverseweakvalue()
456 markkey(g, n); in traverseweakvalue()
457 if (!hasclears && iscleared(g, gcvalueN(gval(n)))) /* a white value? */ in traverseweakvalue()
461 if (g->gcstate == GCSatomic && hasclears) in traverseweakvalue()
462 linkgclist(h, g->weak); /* has to be cleared later */ in traverseweakvalue()
464 linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ in traverseweakvalue()
473 ** the atomic phase, if table has any white->white entry, it has to
477 ** must be kept in some gray list for post-processing; this is done
480 static int traverseephemeron (global_State *g, Table *h, int inv) { in traverseephemeron() argument
483 int hasww = 0; /* true if table has entry "white-key -> white-value" */ in traverseephemeron()
489 if (valiswhite(&h->array[i])) { in traverseephemeron()
491 reallymarkobject(g, gcvalue(&h->array[i])); in traverseephemeron()
497 Node *n = inv ? gnode(h, nsize - 1 - i) : gnode(h, i); in traverseephemeron()
500 else if (iscleared(g, gckeyN(n))) { /* key is not marked (yet)? */ in traverseephemeron()
503 hasww = 1; /* white-white entry */ in traverseephemeron()
507 reallymarkobject(g, gcvalue(gval(n))); /* mark it now */ in traverseephemeron()
511 if (g->gcstate == GCSpropagate) in traverseephemeron()
512 linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ in traverseephemeron()
513 else if (hasww) /* table has white->white entries? */ in traverseephemeron()
514 linkgclist(h, g->ephemeron); /* have to propagate again */ in traverseephemeron()
516 linkgclist(h, g->allweak); /* may have to clean white keys */ in traverseephemeron()
518 genlink(g, obj2gco(h)); /* check whether collector still needs to see it */ in traverseephemeron()
523 static void traversestrongtable (global_State *g, Table *h) { in traversestrongtable() argument
528 markvalue(g, &h->array[i]); in traversestrongtable()
534 markkey(g, n); in traversestrongtable()
535 markvalue(g, gval(n)); in traversestrongtable()
538 genlink(g, obj2gco(h)); in traversestrongtable()
542 static lu_mem traversetable (global_State *g, Table *h) { in traversetable() argument
544 const TValue *mode = gfasttm(g, h->metatable, TM_MODE); in traversetable()
545 markobjectN(g, h->metatable); in traversetable()
551 traverseweakvalue(g, h); in traversetable()
553 traverseephemeron(g, h, 0); in traversetable()
555 linkgclist(h, g->allweak); /* nothing to traverse now */ in traversetable()
558 traversestrongtable(g, h); in traversetable()
559 return 1 + h->alimit + 2 * allocsizenode(h); in traversetable()
563 static int traverseudata (global_State *g, Udata *u) { in traverseudata() argument
565 markobjectN(g, u->metatable); /* mark its metatable */ in traverseudata()
566 for (i = 0; i < u->nuvalue; i++) in traverseudata()
567 markvalue(g, &u->uv[i].uv); in traverseudata()
568 genlink(g, obj2gco(u)); in traverseudata()
569 return 1 + u->nuvalue; in traverseudata()
578 static int traverseproto (global_State *g, Proto *f) { in traverseproto() argument
580 markobjectN(g, f->source); in traverseproto()
581 for (i = 0; i < f->sizek; i++) /* mark literals */ in traverseproto()
582 markvalue(g, &f->k[i]); in traverseproto()
583 for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ in traverseproto()
584 markobjectN(g, f->upvalues[i].name); in traverseproto()
585 for (i = 0; i < f->sizep; i++) /* mark nested protos */ in traverseproto()
586 markobjectN(g, f->p[i]); in traverseproto()
587 for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ in traverseproto()
588 markobjectN(g, f->locvars[i].varname); in traverseproto()
589 return 1 + f->sizek + f->sizeupvalues + f->sizep + f->sizelocvars; in traverseproto()
593 static int traverseCclosure (global_State *g, CClosure *cl) { in traverseCclosure() argument
595 for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ in traverseCclosure()
596 markvalue(g, &cl->upvalue[i]); in traverseCclosure()
597 return 1 + cl->nupvalues; in traverseCclosure()
604 static int traverseLclosure (global_State *g, LClosure *cl) { in traverseLclosure() argument
606 markobjectN(g, cl->p); /* mark its prototype */ in traverseLclosure()
607 for (i = 0; i < cl->nupvalues; i++) { /* visit its upvalues */ in traverseLclosure()
608 UpVal *uv = cl->upvals[i]; in traverseLclosure()
609 markobjectN(g, uv); /* mark upvalue */ in traverseLclosure()
611 return 1 + cl->nupvalues; in traverseLclosure()
618 ** ensures that the entire stack have valid (non-dead) objects.
627 static int traversethread (global_State *g, lua_State *th) { in traversethread() argument
629 StkId o = th->stack.p; in traversethread()
630 if (isold(th) || g->gcstate == GCSpropagate) in traversethread()
631 linkgclist(th, g->grayagain); /* insert into 'grayagain' list */ in traversethread()
634 lua_assert(g->gcstate == GCSatomic || in traversethread()
635 th->openupval == NULL || isintwups(th)); in traversethread()
636 for (; o < th->top.p; o++) /* mark live elements in the stack */ in traversethread()
637 markvalue(g, s2v(o)); in traversethread()
638 for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) in traversethread()
639 markobject(g, uv); /* open upvalues cannot be collected */ in traversethread()
640 if (g->gcstate == GCSatomic) { /* final traversal? */ in traversethread()
641 for (; o < th->stack_last.p + EXTRA_STACK; o++) in traversethread()
644 if (!isintwups(th) && th->openupval != NULL) { in traversethread()
645 th->twups = g->twups; /* link it back to the list */ in traversethread()
646 g->twups = th; in traversethread()
649 else if (!g->gcemergency) in traversethread()
658 static lu_mem propagatemark (global_State *g) { in propagatemark() argument
659 GCObject *o = g->gray; in propagatemark()
661 g->gray = *getgclist(o); /* remove from 'gray' list */ in propagatemark()
662 switch (o->tt) { in propagatemark()
663 case LUA_VTABLE: return traversetable(g, gco2t(o)); in propagatemark()
664 case LUA_VUSERDATA: return traverseudata(g, gco2u(o)); in propagatemark()
665 case LUA_VLCL: return traverseLclosure(g, gco2lcl(o)); in propagatemark()
666 case LUA_VCCL: return traverseCclosure(g, gco2ccl(o)); in propagatemark()
667 case LUA_VPROTO: return traverseproto(g, gco2p(o)); in propagatemark()
668 case LUA_VTHREAD: return traversethread(g, gco2th(o)); in propagatemark()
674 static lu_mem propagateall (global_State *g) { in propagateall() argument
676 while (g->gray) in propagateall()
677 tot += propagatemark(g); in propagateall()
689 static void convergeephemerons (global_State *g) { in convergeephemerons() argument
694 GCObject *next = g->ephemeron; /* get ephemeron list */ in convergeephemerons()
695 g->ephemeron = NULL; /* tables may return to this list when traversed */ in convergeephemerons()
699 next = h->gclist; /* list is rebuilt during loop */ in convergeephemerons()
701 if (traverseephemeron(g, h, dir)) { /* marked some value? */ in convergeephemerons()
702 propagateall(g); /* propagate changes */ in convergeephemerons()
723 static void clearbykeys (global_State *g, GCObject *l) { in clearbykeys() argument
724 for (; l; l = gco2t(l)->gclist) { in clearbykeys()
729 if (iscleared(g, gckeyN(n))) /* unmarked key? */ in clearbykeys()
742 static void clearbyvalues (global_State *g, GCObject *l, GCObject *f) { in clearbyvalues() argument
743 for (; l != f; l = gco2t(l)->gclist) { in clearbyvalues()
749 TValue *o = &h->array[i]; in clearbyvalues()
750 if (iscleared(g, gcvalueN(o))) /* value was collected? */ in clearbyvalues()
754 if (iscleared(g, gcvalueN(gval(n)))) /* unmarked value? */ in clearbyvalues()
771 switch (o->tt) { in freeobj()
780 luaM_freemem(L, cl, sizeLclosure(cl->nupvalues)); in freeobj()
785 luaM_freemem(L, cl, sizeCclosure(cl->nupvalues)); in freeobj()
796 luaM_freemem(L, o, sizeudata(u->nuvalue, u->len)); in freeobj()
802 luaM_freemem(L, ts, sizelstring(ts->shrlen)); in freeobj()
807 luaM_freemem(L, ts, sizelstring(ts->u.lnglen)); in freeobj()
818 ** white; change all non-dead objects back to white, preparing for next
824 global_State *g = G(L); in sweeplist() local
825 int ow = otherwhite(g); in sweeplist()
827 int white = luaC_white(g); /* current white */ in sweeplist()
830 int marked = curr->marked; in sweeplist()
832 *p = curr->next; /* remove 'curr' from list */ in sweeplist()
836 curr->marked = cast_byte((marked & ~maskgcbits) | white); in sweeplist()
837 p = &curr->next; /* go to next element */ in sweeplist()
869 static void checkSizes (lua_State *L, global_State *g) { in checkSizes() argument
870 if (!g->gcemergency) { in checkSizes()
871 if (g->strt.nuse < g->strt.size / 4) { /* string table too big? */ in checkSizes()
872 l_mem olddebt = g->GCdebt; in checkSizes()
873 luaS_resize(L, g->strt.size / 2); in checkSizes()
874 g->GCestimate += g->GCdebt - olddebt; /* correct estimate */ in checkSizes()
884 static GCObject *udata2finalize (global_State *g) { in udata2finalize() argument
885 GCObject *o = g->tobefnz; /* get first element */ in udata2finalize()
887 g->tobefnz = o->next; /* remove it from 'tobefnz' list */ in udata2finalize()
888 o->next = g->allgc; /* return it to 'allgc' list */ in udata2finalize()
889 g->allgc = o; in udata2finalize()
890 resetbit(o->marked, FINALIZEDBIT); /* object is "normal" again */ in udata2finalize()
891 if (issweepphase(g)) in udata2finalize()
892 makewhite(g, o); /* "sweep" object */ in udata2finalize()
894 g->firstold1 = o; /* it is the first OLD1 object in the list */ in udata2finalize()
901 luaD_callnoyield(L, L->top.p - 2, 0); in dothecall()
906 global_State *g = G(L); in GCTM() local
909 lua_assert(!g->gcemergency); in GCTM()
910 setgcovalue(L, &v, udata2finalize(g)); in GCTM()
914 lu_byte oldah = L->allowhook; in GCTM()
915 int oldgcstp = g->gcstp; in GCTM()
916 g->gcstp |= GCSTPGC; /* avoid GC steps */ in GCTM()
917 L->allowhook = 0; /* stop debug hooks during GC metamethod */ in GCTM()
918 setobj2s(L, L->top.p++, tm); /* push finalizer... */ in GCTM()
919 setobj2s(L, L->top.p++, &v); /* ... and its argument */ in GCTM()
920 L->ci->callstatus |= CIST_FIN; /* will run a finalizer */ in GCTM()
921 status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top.p - 2), 0); in GCTM()
922 L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */ in GCTM()
923 L->allowhook = oldah; /* restore hooks */ in GCTM()
924 g->gcstp = oldgcstp; /* restore state */ in GCTM()
927 L->top.p--; /* pops error object */ in GCTM()
937 global_State *g = G(L); in runafewfinalizers() local
939 for (i = 0; i < n && g->tobefnz; i++) in runafewfinalizers()
949 global_State *g = G(L); in callallpendingfinalizers() local
950 while (g->tobefnz) in callallpendingfinalizers()
960 p = &(*p)->next; in findlast()
972 static void separatetobefnz (global_State *g, int all) { in separatetobefnz() argument
974 GCObject **p = &g->finobj; in separatetobefnz()
975 GCObject **lastnext = findlast(&g->tobefnz); in separatetobefnz()
976 while ((curr = *p) != g->finobjold1) { /* traverse all finalizable objects */ in separatetobefnz()
979 p = &curr->next; /* don't bother with it */ in separatetobefnz()
981 if (curr == g->finobjsur) /* removing 'finobjsur'? */ in separatetobefnz()
982 g->finobjsur = curr->next; /* correct it */ in separatetobefnz()
983 *p = curr->next; /* remove 'curr' from 'finobj' list */ in separatetobefnz()
984 curr->next = *lastnext; /* link at the end of 'tobefnz' list */ in separatetobefnz()
986 lastnext = &curr->next; in separatetobefnz()
997 *p = o->next; in checkpointer()
1005 static void correctpointers (global_State *g, GCObject *o) { in correctpointers() argument
1006 checkpointer(&g->survival, o); in correctpointers()
1007 checkpointer(&g->old1, o); in correctpointers()
1008 checkpointer(&g->reallyold, o); in correctpointers()
1009 checkpointer(&g->firstold1, o); in correctpointers()
1018 global_State *g = G(L); in luaC_checkfinalizer() local
1020 gfasttm(g, mt, TM_GC) == NULL || /* or has no finalizer... */ in luaC_checkfinalizer()
1021 (g->gcstp & GCSTPCLS)) /* or closing state? */ in luaC_checkfinalizer()
1025 if (issweepphase(g)) { in luaC_checkfinalizer()
1026 makewhite(g, o); /* "sweep" object 'o' */ in luaC_checkfinalizer()
1027 if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */ in luaC_checkfinalizer()
1028 g->sweepgc = sweeptolive(L, g->sweepgc); /* change 'sweepgc' */ in luaC_checkfinalizer()
1031 correctpointers(g, o); in luaC_checkfinalizer()
1033 for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ } in luaC_checkfinalizer()
1034 *p = o->next; /* remove 'o' from 'allgc' list */ in luaC_checkfinalizer()
1035 o->next = g->finobj; /* link it in 'finobj' list */ in luaC_checkfinalizer()
1036 g->finobj = o; in luaC_checkfinalizer()
1037 l_setbit(o->marked, FINALIZEDBIT); /* mark it as such */ in luaC_checkfinalizer()
1057 static void setpause (global_State *g) { in setpause() argument
1059 int pause = getgcparam(g->gcpause); in setpause()
1060 l_mem estimate = g->GCestimate / PAUSEADJ; /* adjust 'estimate' */ in setpause()
1065 debt = gettotalbytes(g) - threshold; in setpause()
1067 luaE_setdebt(g, debt); in setpause()
1073 ** objects and turns the non dead to old. All non-dead threads---which
1074 ** are now old---must be in a gray list. Everything else is not in a
1079 global_State *g = G(L); in sweep2old() local
1082 lua_assert(isdead(g, curr)); in sweep2old()
1083 *p = curr->next; /* remove 'curr' from list */ in sweep2old()
1088 if (curr->tt == LUA_VTHREAD) { /* threads must be watched */ in sweep2old()
1090 linkgclist(th, g->grayagain); /* insert into 'grayagain' list */ in sweep2old()
1092 else if (curr->tt == LUA_VUPVAL && upisopen(gco2upv(curr))) in sweep2old()
1096 p = &curr->next; /* go to next element */ in sweep2old()
1106 ** non-dead objects, advance their ages and clear the color of
1109 ** here, because these old-generation objects are usually not swept
1113 static GCObject **sweepgen (lua_State *L, global_State *g, GCObject **p, in sweepgen() argument
1124 int white = luaC_white(g); in sweepgen()
1128 lua_assert(!isold(curr) && isdead(g, curr)); in sweepgen()
1129 *p = curr->next; /* remove 'curr' from list */ in sweepgen()
1134 int marked = curr->marked & ~maskgcbits; /* erase GC bits */ in sweepgen()
1135 curr->marked = cast_byte(marked | G_SURVIVAL | white); in sweepgen()
1142 p = &curr->next; /* go to next element */ in sweepgen()
1154 static void whitelist (global_State *g, GCObject *p) { in whitelist() argument
1155 int white = luaC_white(g); in whitelist()
1156 for (; p != NULL; p = p->next) in whitelist()
1157 p->marked = cast_byte((p->marked & ~maskgcbits) | white); in whitelist()
1167 ** Non-white threads also remain on the list; 'TOUCHED2' objects become
1182 else if (curr->tt == LUA_VTHREAD) { in correctgraylist()
1184 goto remain; /* keep non-white threads on the list */ in correctgraylist()
1203 static void correctgraylists (global_State *g) { in correctgraylists() argument
1204 GCObject **list = correctgraylist(&g->grayagain); in correctgraylists()
1205 *list = g->weak; g->weak = NULL; in correctgraylists()
1207 *list = g->allweak; g->allweak = NULL; in correctgraylists()
1209 *list = g->ephemeron; g->ephemeron = NULL; in correctgraylists()
1219 static void markold (global_State *g, GCObject *from, GCObject *to) { in markold() argument
1221 for (p = from; p != to; p = p->next) { in markold()
1226 reallymarkobject(g, p); in markold()
1233 ** Finish a young-generation collection.
1235 static void finishgencycle (lua_State *L, global_State *g) { in finishgencycle() argument
1236 correctgraylists(g); in finishgencycle()
1237 checkSizes(L, g); in finishgencycle()
1238 g->gcstate = GCSpropagate; /* skip restart */ in finishgencycle()
1239 if (!g->gcemergency) in finishgencycle()
1249 static void youngcollection (lua_State *L, global_State *g) { in youngcollection() argument
1250 GCObject **psurvival; /* to point to first non-dead survival object */ in youngcollection()
1252 lua_assert(g->gcstate == GCSpropagate); in youngcollection()
1253 if (g->firstold1) { /* are there regular OLD1 objects? */ in youngcollection()
1254 markold(g, g->firstold1, g->reallyold); /* mark them */ in youngcollection()
1255 g->firstold1 = NULL; /* no more OLD1 objects (for now) */ in youngcollection()
1257 markold(g, g->finobj, g->finobjrold); in youngcollection()
1258 markold(g, g->tobefnz, NULL); in youngcollection()
1262 g->gcstate = GCSswpallgc; in youngcollection()
1263 psurvival = sweepgen(L, g, &g->allgc, g->survival, &g->firstold1); in youngcollection()
1265 sweepgen(L, g, psurvival, g->old1, &g->firstold1); in youngcollection()
1266 g->reallyold = g->old1; in youngcollection()
1267 g->old1 = *psurvival; /* 'survival' survivals are old now */ in youngcollection()
1268 g->survival = g->allgc; /* all news are survivals */ in youngcollection()
1272 psurvival = sweepgen(L, g, &g->finobj, g->finobjsur, &dummy); in youngcollection()
1274 sweepgen(L, g, psurvival, g->finobjold1, &dummy); in youngcollection()
1275 g->finobjrold = g->finobjold1; in youngcollection()
1276 g->finobjold1 = *psurvival; /* 'survival' survivals are old now */ in youngcollection()
1277 g->finobjsur = g->finobj; /* all news are survivals */ in youngcollection()
1279 sweepgen(L, g, &g->tobefnz, NULL, &dummy); in youngcollection()
1280 finishgencycle(L, g); in youngcollection()
1290 static void atomic2gen (lua_State *L, global_State *g) { in atomic2gen() argument
1291 cleargraylists(g); in atomic2gen()
1293 g->gcstate = GCSswpallgc; in atomic2gen()
1294 sweep2old(L, &g->allgc); in atomic2gen()
1296 g->reallyold = g->old1 = g->survival = g->allgc; in atomic2gen()
1297 g->firstold1 = NULL; /* there are no OLD1 objects anywhere */ in atomic2gen()
1300 sweep2old(L, &g->finobj); in atomic2gen()
1301 g->finobjrold = g->finobjold1 = g->finobjsur = g->finobj; in atomic2gen()
1303 sweep2old(L, &g->tobefnz); in atomic2gen()
1305 g->gckind = KGC_GEN; in atomic2gen()
1306 g->lastatomic = 0; in atomic2gen()
1307 g->GCestimate = gettotalbytes(g); /* base for memory control */ in atomic2gen()
1308 finishgencycle(L, g); in atomic2gen()
1316 static void setminordebt (global_State *g) { in setminordebt() argument
1317 luaE_setdebt(g, -(cast(l_mem, (gettotalbytes(g) / 100)) * g->genminormul)); in setminordebt()
1327 static lu_mem entergen (lua_State *L, global_State *g) { in entergen() argument
1332 atomic2gen(L, g); in entergen()
1333 setminordebt(g); /* set debt assuming next cycle will be minor */ in entergen()
1343 static void enterinc (global_State *g) { in enterinc() argument
1344 whitelist(g, g->allgc); in enterinc()
1345 g->reallyold = g->old1 = g->survival = NULL; in enterinc()
1346 whitelist(g, g->finobj); in enterinc()
1347 whitelist(g, g->tobefnz); in enterinc()
1348 g->finobjrold = g->finobjold1 = g->finobjsur = NULL; in enterinc()
1349 g->gcstate = GCSpause; in enterinc()
1350 g->gckind = KGC_INC; in enterinc()
1351 g->lastatomic = 0; in enterinc()
1359 global_State *g = G(L); in luaC_changemode() local
1360 if (newmode != g->gckind) { in luaC_changemode()
1362 entergen(L, g); in luaC_changemode()
1364 enterinc(g); /* entering incremental mode */ in luaC_changemode()
1366 g->lastatomic = 0; in luaC_changemode()
1373 static lu_mem fullgen (lua_State *L, global_State *g) { in fullgen() argument
1374 enterinc(g); in fullgen()
1375 return entergen(L, g); in fullgen()
1397 ** field 'g->lastatomic' keeps this count from the last collection.
1398 ** ('g->lastatomic != 0' also means that the last collection was bad.)
1400 static void stepgenfull (lua_State *L, global_State *g) { in stepgenfull() argument
1402 lu_mem lastatomic = g->lastatomic; /* count from last collection */ in stepgenfull()
1403 if (g->gckind == KGC_GEN) /* still in generational mode? */ in stepgenfull()
1404 enterinc(g); /* enter incremental mode */ in stepgenfull()
1408 atomic2gen(L, g); /* return to generational mode */ in stepgenfull()
1409 setminordebt(g); in stepgenfull()
1412 g->GCestimate = gettotalbytes(g); /* first estimate */; in stepgenfull()
1415 setpause(g); in stepgenfull()
1416 g->lastatomic = newatomic; in stepgenfull()
1428 ** in 'g->GCestimate'), the function does a major collection. At the
1434 ** 'g->lastatomic' to signal that fact, so that the next collection will
1440 static void genstep (lua_State *L, global_State *g) { in genstep() argument
1441 if (g->lastatomic != 0) /* last collection was a bad one? */ in genstep()
1442 stepgenfull(L, g); /* do a full step */ in genstep()
1444 lu_mem majorbase = g->GCestimate; /* memory after last major collection */ in genstep()
1445 lu_mem majorinc = (majorbase / 100) * getgcparam(g->genmajormul); in genstep()
1446 if (g->GCdebt > 0 && gettotalbytes(g) > majorbase + majorinc) { in genstep()
1447 lu_mem numobjs = fullgen(L, g); /* do a major collection */ in genstep()
1448 if (gettotalbytes(g) < majorbase + (majorinc / 2)) { in genstep()
1451 lua_assert(g->lastatomic == 0); in genstep()
1454 g->lastatomic = numobjs; /* signal that last collection was bad */ in genstep()
1455 setpause(g); /* do a long wait for next (major) collection */ in genstep()
1459 youngcollection(L, g); in genstep()
1460 setminordebt(g); in genstep()
1461 g->GCestimate = majorbase; /* preserve base value */ in genstep()
1464 lua_assert(isdecGCmodegen(g)); in genstep()
1485 global_State *g = G(L); in entersweep() local
1486 g->gcstate = GCSswpallgc; in entersweep()
1487 lua_assert(g->sweepgc == NULL); in entersweep()
1488 g->sweepgc = sweeptolive(L, &g->allgc); in entersweep()
1498 GCObject *next = p->next; in deletelist()
1510 global_State *g = G(L); in luaC_freeallobjects() local
1511 g->gcstp = GCSTPCLS; /* no extra finalizers after here */ in luaC_freeallobjects()
1513 separatetobefnz(g, 1); /* separate all objects with finalizers */ in luaC_freeallobjects()
1514 lua_assert(g->finobj == NULL); in luaC_freeallobjects()
1516 deletelist(L, g->allgc, obj2gco(g->mainthread)); in luaC_freeallobjects()
1517 lua_assert(g->finobj == NULL); /* no new finalizers */ in luaC_freeallobjects()
1518 deletelist(L, g->fixedgc, NULL); /* collect fixed objects */ in luaC_freeallobjects()
1519 lua_assert(g->strt.nuse == 0); in luaC_freeallobjects()
1524 global_State *g = G(L); in atomic() local
1527 GCObject *grayagain = g->grayagain; /* save original list */ in atomic()
1528 g->grayagain = NULL; in atomic()
1529 lua_assert(g->ephemeron == NULL && g->weak == NULL); in atomic()
1530 lua_assert(!iswhite(g->mainthread)); in atomic()
1531 g->gcstate = GCSatomic; in atomic()
1532 markobject(g, L); /* mark running thread */ in atomic()
1534 markvalue(g, &g->l_registry); in atomic()
1535 markmt(g); /* mark global metatables */ in atomic()
1536 work += propagateall(g); /* empties 'gray' list */ in atomic()
1538 work += remarkupvals(g); in atomic()
1539 work += propagateall(g); /* propagate changes */ in atomic()
1540 g->gray = grayagain; in atomic()
1541 work += propagateall(g); /* traverse 'grayagain' list */ in atomic()
1542 convergeephemerons(g); in atomic()
1545 clearbyvalues(g, g->weak, NULL); in atomic()
1546 clearbyvalues(g, g->allweak, NULL); in atomic()
1547 origweak = g->weak; origall = g->allweak; in atomic()
1548 separatetobefnz(g, 0); /* separate objects to be finalized */ in atomic()
1549 work += markbeingfnz(g); /* mark objects that will be finalized */ in atomic()
1550 work += propagateall(g); /* remark, to propagate 'resurrection' */ in atomic()
1551 convergeephemerons(g); in atomic()
1554 clearbykeys(g, g->ephemeron); /* clear keys from all ephemeron tables */ in atomic()
1555 clearbykeys(g, g->allweak); /* clear keys from all 'allweak' tables */ in atomic()
1557 clearbyvalues(g, g->weak, origweak); in atomic()
1558 clearbyvalues(g, g->allweak, origall); in atomic()
1559 luaS_clearcache(g); in atomic()
1560 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ in atomic()
1561 lua_assert(g->gray == NULL); in atomic()
1566 static int sweepstep (lua_State *L, global_State *g, in sweepstep() argument
1568 if (g->sweepgc) { in sweepstep()
1569 l_mem olddebt = g->GCdebt; in sweepstep()
1571 g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX, &count); in sweepstep()
1572 g->GCestimate += g->GCdebt - olddebt; /* update estimate */ in sweepstep()
1576 g->gcstate = nextstate; in sweepstep()
1577 g->sweepgc = nextlist; in sweepstep()
1584 global_State *g = G(L); in singlestep() local
1586 lua_assert(!g->gcstopem); /* collector is not reentrant */ in singlestep()
1587 g->gcstopem = 1; /* no emergency collections while collecting */ in singlestep()
1588 switch (g->gcstate) { in singlestep()
1590 restartcollection(g); in singlestep()
1591 g->gcstate = GCSpropagate; in singlestep()
1596 if (g->gray == NULL) { /* no more gray objects? */ in singlestep()
1597 g->gcstate = GCSenteratomic; /* finish propagate phase */ in singlestep()
1601 work = propagatemark(g); /* traverse one gray object */ in singlestep()
1607 g->GCestimate = gettotalbytes(g); /* first estimate */; in singlestep()
1611 work = sweepstep(L, g, GCSswpfinobj, &g->finobj); in singlestep()
1615 work = sweepstep(L, g, GCSswptobefnz, &g->tobefnz); in singlestep()
1619 work = sweepstep(L, g, GCSswpend, NULL); in singlestep()
1623 checkSizes(L, g); in singlestep()
1624 g->gcstate = GCScallfin; in singlestep()
1629 if (g->tobefnz && !g->gcemergency) { in singlestep()
1630 g->gcstopem = 0; /* ok collections during finalizers */ in singlestep()
1634 g->gcstate = GCSpause; /* finish collection */ in singlestep()
1641 g->gcstopem = 0; in singlestep()
1651 global_State *g = G(L); in luaC_runtilstate() local
1652 while (!testbit(statesmask, g->gcstate)) in luaC_runtilstate()
1665 static void incstep (lua_State *L, global_State *g) { in incstep() argument
1666 int stepmul = (getgcparam(g->gcstepmul) | 1); /* avoid division by 0 */ in incstep()
1667 l_mem debt = (g->GCdebt / WORK2MEM) * stepmul; in incstep()
1668 l_mem stepsize = (g->gcstepsize <= log2maxs(l_mem)) in incstep()
1669 ? ((cast(l_mem, 1) << g->gcstepsize) / WORK2MEM) * stepmul in incstep()
1673 debt -= work; in incstep()
1674 } while (debt > -stepsize && g->gcstate != GCSpause); in incstep()
1675 if (g->gcstate == GCSpause) in incstep()
1676 setpause(g); /* pause until next cycle */ in incstep()
1679 luaE_setdebt(g, debt); in incstep()
1689 global_State *g = G(L); in luaC_step() local
1690 if (!gcrunning(g)) /* not running? */ in luaC_step()
1691 luaE_setdebt(g, -2000); in luaC_step()
1693 if(isdecGCmodegen(g)) in luaC_step()
1694 genstep(L, g); in luaC_step()
1696 incstep(L, g); in luaC_step()
1708 static void fullinc (lua_State *L, global_State *g) { in fullinc() argument
1709 if (keepinvariant(g)) /* black objects? */ in fullinc()
1715 lua_assert(g->GCestimate == gettotalbytes(g)); in fullinc()
1717 setpause(g); in fullinc()
1727 global_State *g = G(L); in luaC_fullgc() local
1728 lua_assert(!g->gcemergency); in luaC_fullgc()
1729 g->gcemergency = isemergency; /* set flag */ in luaC_fullgc()
1730 if (g->gckind == KGC_INC) in luaC_fullgc()
1731 fullinc(L, g); in luaC_fullgc()
1733 fullgen(L, g); in luaC_fullgc()
1734 g->gcemergency = 0; in luaC_fullgc()